本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
走出雲端,落地生根:如何讓 Kubernetes 在任何地方都達到生產級別
這篇部落格提供了一些在本地資料中心或邊緣位置等環境中執行生產級 Kubernetes 叢集的指南。
“生產級”意味著什麼?
- 安裝是安全的
- 部署透過可重複和記錄的過程進行管理
- 效能可預測且一致
- 更新和配置更改可以安全應用
- 日誌和監控到位,以檢測和診斷故障和資源短缺
- 考慮到可用資源,包括金錢、物理空間、電力等限制,服務“高可用性足夠好”
- 在發生故障時,恢復過程可用、有文件記錄並經過測試
簡而言之,生產級意味著預見事故並準備好以最小的痛苦和延遲進行恢復。
本文針對基於管理程式或裸機平臺的本地 Kubernetes 部署,與主要的公共雲的可擴充套件性相比,這些部署面臨有限的後端資源。但是,如果預算限制了您選擇使用的資源,其中一些建議也可能在公共雲中發揮作用。
單節點裸機 Minikube 部署可能便宜且簡單,但並非生產級。反之,您不太可能在零售店、分支機構或邊緣位置獲得 Google Borg 的體驗,您也不太可能需要它。
這篇部落格提供了一些關於實現生產級 Kubernetes 部署的指導,即使在資源受限的情況下也是如此。
Kubernetes 叢集中的關鍵元件
在深入瞭解細節之前,瞭解 Kubernetes 的整體架構至關重要。
Kubernetes 叢集是一個高度分散式的系統,基於控制平面和叢集工作節點架構,如下圖所示。
通常,API 伺服器、控制器管理器和排程器元件共存於控制平面(也稱為主節點)的多個例項中。主節點通常也包含 etcd,儘管在需要將 etcd 執行在獨立主機上的高可用性場景和大型叢集場景中有所不同。這些元件可以作為容器執行,並可選擇由 Kubernetes 監督,即作為靜態 Pod 執行。
為了實現高可用性,使用了這些元件的冗餘例項。其重要性和所需的冗餘程度各不相同。
從高可用性角度看 Kubernetes 元件
這些元件面臨的風險包括硬體故障、軟體錯誤、不良更新、人為錯誤、網路中斷和系統過載導致的資源耗盡。冗餘可以減輕其中許多危害的影響。此外,管理程式平臺的資源排程和高可用性功能有助於超越僅使用 Linux 作業系統、Kubernetes 和容器執行時所能實現的功能。
API 伺服器使用負載均衡器後面的多個例項來實現規模和可用性。負載均衡器是高可用性目的的關鍵元件。如果您沒有負載均衡器,多個 DNS API Server “A” 記錄可能是一種替代方案。
kube-scheduler 和 kube-controller-manager 採用領導者選舉過程,而不是使用負載均衡器。由於 cloud-controller-manager 用於選定的託管基礎設施型別,並且這些型別有實現差異,因此除了指出它們是控制平面元件之外,本文將不予討論。
執行在 Kubernetes 工作節點上的 Pod 由 kubelet 代理管理。每個工作例項都執行 kubelet 代理和一個 CRI 相容的容器執行時。Kubernetes 本身旨在監控和從工作節點故障中恢復。但對於關鍵工作負載,管理程式資源管理、工作負載隔離和可用性功能可用於增強可用性並使效能更可預測。
etcd
etcd 是所有 Kubernetes 物件的持久儲存。etcd 叢集的可用性和可恢復性應該是生產級 Kubernetes 部署中的首要考慮。
如果資源允許,一個五節點的 etcd 叢集是最佳實踐。為什麼?因為您可以在一個節點進行維護,同時仍能容忍一個故障。即使只有一個管理程式主機可用,三節點叢集也是生產級服務的最小建議。除了跨多個可用區非常大的安裝之外,不建議使用超過七個節點。
託管 etcd 叢集節點的最低建議配置是 2GB 記憶體和 8GB SSD 硬碟。通常,8GB 記憶體和 20GB 硬碟就足夠了。磁碟效能會影響故障節點的恢復時間。有關更多資訊,請參閱 https://coreos.com/etcd/docs/latest/op-guide/hardware.html。
在特殊情況下考慮多個 etcd 叢集
對於非常大的 Kubernetes 叢集,請考慮為 Kubernetes 事件使用獨立的 etcd 叢集,這樣事件風暴就不會影響主要的 Kubernetes API 服務。如果您使用 flannel 網路,它會在 etcd 中保留配置,並且可能具有與 Kubernetes 不同的版本要求,這會使 etcd 備份複雜化——考慮為 flannel 使用專用的 etcd 叢集。
單主機部署
可用性風險清單包括硬體、軟體和人員。如果您僅限於一臺主機,使用冗餘儲存、糾錯記憶體和雙電源可以減少硬體故障的暴露。在物理主機上執行虛擬機器監控程式將允許操作冗餘軟體元件,並增加與部署、升級和資源消耗治理相關的操作優勢,在壓力下提供可預測和可重複的效能。例如,即使您只能負擔執行主服務的單例,它們也需要在與應用程式工作負載競爭時受到過載和資源耗盡的保護。虛擬機器監控程式比配置 Linux 排程器優先順序、cgroups、Kubernetes 標誌等更有效且更易於管理。
如果主機上的資源允許,您可以部署三個 etcd 虛擬機器。每個 etcd 虛擬機器都應該由不同的物理儲存裝置支援,或者它們應該使用具有冗餘(映象、RAID 等)的後端儲存的獨立分割槽。
如果您的單主機有資源,API 伺服器、排程器和控制器管理器的雙冗餘例項將是下一個升級。
單主機部署選項,從最不適合生產到更好
雙主機部署
對於雙主機,etcd 的儲存問題與單主機相同,您需要冗餘。並且您最好執行 3 個 etcd 例項。儘管可能違反直覺,但最好將所有 etcd 節點集中在一臺主機上。透過在兩臺主機上進行 2+1 分割並不能獲得可靠性——因為持有多數 etcd 例項的節點丟失會導致停機,無論多數是 2 個還是 3 個。如果主機不相同,則將整個 etcd 叢集放在最可靠的主機上。
建議執行冗餘的 API 伺服器、kube-scheduler 和 kube-controller-manager。這些元件應跨主機部署,以最大程度地降低容器執行時、作業系統和硬體故障帶來的風險。
在物理主機上執行虛擬機器管理程式層將允許操作具有資源消耗治理的冗餘軟體元件,並可以帶來計劃性維護操作優勢。
雙主機部署選項,從最不適合生產到更好
三(或更多)主機部署——邁向不妥協的生產級服務 建議將 etcd 分佈在三臺主機上。單個硬體故障將降低應用程式工作負載容量,但不應導致完全服務中斷。
對於超大型叢集,將需要更多的 etcd 例項。
執行虛擬機器管理程式層提供操作優勢和更好的工作負載隔離。這超出了本文的範圍,但在三臺或更多主機級別上,可能會提供高階功能(叢集冗餘共享儲存、帶動態負載均衡的資源治理、帶即時遷移或故障轉移的自動化健康監控)。
三(或更多)主機選項,從最不適合生產到更好
Kubernetes 配置設定
主節點和工作節點應受到保護,防止過載和資源耗盡。虛擬機器管理程式功能可用於隔離關鍵元件和保留資源。還有 Kubernetes 配置設定,可以限制 API 呼叫速率和每個節點的 Pod 數量等。一些安裝套件和商業發行版會處理這些問題,但如果您正在執行自定義 Kubernetes 部署,您可能會發現預設值不合適,特別是當您的資源較少或叢集較大時。
控制平面的資源消耗將與 Pod 數量和 Pod 流失率相關。超大型和超小型叢集將受益於非預設的 kube-apiserver 請求限流和記憶體設定。設定過高可能導致請求限制超出和記憶體不足錯誤。
在工作節點上,應根據每個節點合理支援的工作負載密度配置 節點可分配資源。可以建立名稱空間將工作節點叢集細分為多個虛擬叢集,並設定資源 CPU 和記憶體配額。可以配置 kubelet 處理資源不足的情況。
安全
每個 Kubernetes 叢集都有一個叢集根證書頒發機構 (CA)。控制器管理器、API 伺服器、排程器、kubelet 客戶端、kube-proxy 和管理員證書需要生成並安裝。如果您使用安裝工具或發行版,這可能已為您處理。此處介紹了手動過程:https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/docs/04-certificate-authority.md。您應該準備好在節點替換或擴充套件時重新安裝證書。
由於 Kubernetes 完全由 API 驅動,因此控制和限制誰可以訪問叢集以及他們被允許執行哪些操作至關重要。此文件中介紹了加密和身份驗證選項。
Kubernetes 應用程式工作負載基於容器映象。您需要確保這些映象的來源和內容是可信的。這幾乎總是意味著您將託管一個本地容器映象倉庫。從公共網際網路拉取映象可能會帶來可靠性和安全問題。您應該選擇一個支援映象簽名、安全掃描、對映象推送和拉取進行訪問控制以及活動日誌記錄的倉庫。
必須有支援主機韌體、虛擬機器管理程式、作業系統、Kubernetes 和其他依賴項更新的流程。應建立版本監控以支援審計。
建議
- 收緊控制平面元件的安全設定,超越預設值(例如,鎖定工作節點)
- 利用 Pod 安全策略
- 考慮您的網路解決方案提供的 NetworkPolicy 整合,包括如何實現跟蹤、監控和故障排除。
- 使用 RBAC 驅動授權決策和強制執行。
- 考慮物理安全,特別是在部署到可能無人看管的邊緣或遠端辦公地點時。包括儲存加密以限制被盜裝置的暴露,並防止連線惡意裝置(如 USB 金鑰)。
- 保護 Kubernetes 明文雲提供商憑證(訪問金鑰、令牌、密碼等)
Kubernetes Secret 物件適用於儲存少量敏感資料。這些資料保留在 etcd 中。它們可以很容易地用於儲存 Kubernetes API 的憑證,但有時工作負載或叢集本身的擴充套件需要更全面的解決方案。如果您需要比內建 Secret 物件提供的更多功能,HashiCorp Vault 專案是一個流行的解決方案。
災難恢復和備份
透過使用多個主機和虛擬機器來實現冗餘有助於減少某些型別的停機,但諸如站點範圍的自然災害、錯誤的更新、被駭客攻擊、軟體錯誤或人為錯誤等情況仍可能導致停機。
生產部署的關鍵部分是預測未來可能發生的恢復。
值得注意的是,如果您需要在多個站點進行大規模複製部署,那麼您在設計、記錄和自動化恢復過程方面的一些投入也可能被重新利用。
災難恢復計劃的要素包括備份(以及可能的副本)、替換、計劃流程、能夠執行流程的人員以及定期培訓。定期測試演練和混沌工程原則可用於審計您的準備情況。
您的可用性要求可能要求您保留作業系統、Kubernetes 元件和容器映象的本地副本,以便即使在網際網路中斷期間也能進行恢復。“空隙”場景下部署替換主機和節點的能力還可以提供安全性和部署速度優勢。
所有 Kubernetes 物件都儲存在 etcd 上。定期備份 etcd 叢集資料對於在災難場景下恢復 Kubernetes 叢集至關重要,例如丟失所有主節點。
etcd 叢集的備份可以透過 etcd 的內建快照機制完成,並將生成的檔案複製到不同故障域的儲存中。快照檔案包含所有 Kubernetes 狀態和關鍵資訊。為了確保敏感的 Kubernetes 資料安全,請加密快照檔案。
使用基於磁碟卷的 etcd 快照恢復可能會出現問題;請參閱#40027。基於 API 的備份解決方案(例如,Ark)可以提供比 etcd 快照更精細的恢復,但速度也可能更慢。您可以同時使用快照和基於 API 的備份,但至少應執行一種形式的 etcd 備份。
請注意,某些 Kubernetes 擴充套件可能會在獨立的 etcd 叢集、持久卷或透過其他機制維護狀態。如果此狀態至關重要,則應制定備份和恢復計劃。
一些關鍵狀態儲存在 etcd 之外。證書、容器映象以及其他與配置和操作相關的狀態可能由您的自動化安裝/更新工具管理。即使這些專案可以重新生成,備份或複製也可能允許在故障後更快地恢復。考慮對這些專案進行備份並制定恢復計劃
- 證書和金鑰對
- CA
- API 伺服器
- Apiserver-kubelet-client
- ServiceAccount 簽名
- “前端代理”
- 前端代理客戶端
- 關鍵 DNS 記錄
- IP/子網分配和預留
- 外部負載均衡器
- kubeconfig 檔案
- LDAP 或其他身份驗證詳細資訊
- 雲提供商特定的賬戶和配置資料
您的生產工作負載的注意事項
反親和性規範可用於將叢集服務拆分到後端主機,但目前這些設定僅在 Pod 排程時使用。這意味著 Kubernetes 可以重新啟動您的叢集應用程式的故障節點,但沒有原生機制在故障恢復後重新平衡。這是一個值得單獨撰寫部落格的話題,但補充邏輯可能有助於在主機或工作節點恢復或擴充套件後實現最佳工作負載放置。Pod 優先順序和搶佔功能可用於在因故障或突發工作負載導致的資源短缺時指定首選的優先順序。
對於有狀態服務,外部附加捲掛載是 Kubernetes 對非叢集服務(例如,典型的 SQL 資料庫)的標準建議。目前,Kubernetes 對這些外部卷的快照管理屬於路線圖功能請求類別,可能與容器儲存介面 (CSI) 整合保持一致。因此,對此類服務執行備份將涉及應用程式特定的、容器內的活動,這超出了本文的範圍。在等待 Kubernetes 更好地支援快照和備份工作流的同時,將資料庫服務執行在虛擬機器而不是容器中,並將其暴露給您的 Kubernetes 工作負載可能值得考慮。
叢集分散式有狀態服務(例如 Cassandra)可以受益於跨主機拆分,如果資源允許,可以使用本地持久卷。這將需要部署多個 Kubernetes 工作節點(可以是虛擬機器管理程式主機上的虛擬機器)以在單點故障下保持仲裁。
其他注意事項
日誌和指標(如果收集並持久保留)對於診斷中斷很有價值,但鑑於可用技術的種類繁多,本文將不予討論。如果 Internet 連線可用,則可能需要將日誌和指標外部保留在中心位置。
您的生產部署應使用自動化安裝、配置和更新工具(例如,Ansible、BOSH、Chef、Juju、kubeadm、Puppet 等)。手動過程將存在重複性問題、勞動密集、容易出錯且難以擴充套件。經過認證的發行版可能包含在更新中保留配置設定的功能,但如果您實現自己的安裝和配置工具鏈,那麼配置工件的保留、備份和恢復至關重要。考慮將部署元件和設定置於版本控制系統(如 Git)下。
中斷恢復
記錄恢復過程的操作手冊應經過測試並離線儲存——甚至可以打印出來。當一名值班人員在週五凌晨 2 點被叫醒時,可能不是一個很好的即興發揮的時機。最好是根據預先計劃、經過測試的清單執行——並由遠端和現場人員共享訪問。
結語
購買商業航空公司的機票既方便又安全。但是當您前往跑道較短的偏遠地區時,那趟商業空客 A320 航班就不是一個選擇。這並不意味著航空旅行被排除在外。它確實意味著需要做出一些妥協。
航空界的諺語是,在單引擎飛機上,引擎故障意味著墜機。對於雙引擎飛機,至少您可以有更多的墜機地點選擇。少量主機上的 Kubernetes 也是如此,如果您的業務案例證明其合理性,您可以擴大到更大的混合大小車輛機隊(例如,聯邦快遞、亞馬遜)。
那些設計生產級 Kubernetes 解決方案的人有很多選擇和決策。一篇部落格文章無法提供所有答案,也無法瞭解您的具體優先順序。我們希望這能提供一份值得考慮的事項清單,以及一些有用的指導。有些選項被“擱置”(例如,使用自託管而不是靜態 Pod 執行 Kubernetes 元件)。如果有人感興趣,這些可能會在後續文章中介紹。此外,Kubernetes 的高增強率意味著,如果您的搜尋引擎在 2019 年之後發現了這篇文章,某些內容可能已經過期。