DIY:使用 Kubernetes 建立您自己的雲端(第 3 部分)
本文即將進入最有趣的階段,深入探討在 Kubernetes 內運行 Kubernetes。重點介紹了 Kamaji 和 Cluster API 等技術,以及它們與 KubeVirt 的整合。
之前的討論涵蓋了在裸機上準備 Kubernetes 和 如何將 Kubernetes 變成虛擬機器管理系統。本文總結了該系列,解釋了如何使用上述所有內容,您可以構建一個功能齊全的託管 Kubernetes,只需點擊一下即可運行虛擬 Kubernetes 叢集。
首先,讓我們深入探討 Cluster API。
Cluster API
Cluster API 是 Kubernetes 的擴充功能,允許將 Kubernetes 叢集作為自訂資源在另一個 Kubernetes 叢集中進行管理。
Cluster API 的主要目標是為描述 Kubernetes 叢集的基本實體和管理其生命週期提供統一介面。這使得創建、更新和刪除叢集的過程自動化,簡化了擴展和基礎設施管理。
在 Cluster API 的上下文中,有兩個術語:管理叢集和租戶叢集。
- 管理叢集是用於部署和管理其他叢集的 Kubernetes 叢集。此叢集包含所有必要的 Cluster API 組件,並負責描述、創建和更新租戶叢集。它通常僅用於此目的。
- 租戶叢集是使用者叢集或使用 Cluster API 部署的叢集。它們是通過描述管理叢集中的相關資源來創建的。然後,最終使用者使用它們來部署應用程式和服務。
重要的是要理解,實際上,租戶叢集不一定必須與管理叢集在同一個基礎設施上運行;更常見的是,它們在其他地方運行。
一個圖表顯示了使用 Cluster API 的管理 Kubernetes 叢集和租戶 Kubernetes 叢集之間的互動
為了運作,Cluster API 利用供應商的概念,這些供應商是負責正在創建的叢集的特定組件的獨立控制器。在 Cluster API 中,有幾種類型的供應商。主要的有
- 基礎設施供應商,負責提供計算基礎設施,例如虛擬機器或實體伺服器。
- 控制平面供應商,提供 Kubernetes 控制平面,即 kube-apiserver、kube-scheduler 和 kube-controller-manager 組件。
- 啟動程式供應商,用於為正在創建的虛擬機器和伺服器生成 cloud-init 配置。
要開始使用,您需要安裝 Cluster API 本身和每種類型的一個供應商。您可以在專案的文件中找到受支援供應商的完整列表。
對於安裝,您可以使用 clusterctl
实用程序,或 Cluster API Operator 作為更聲明式的方法。
選擇供應商
基礎設施供應商
要使用 KubeVirt 運行 Kubernetes 叢集,必須安裝 KubeVirt 基礎設施供應商。它啟用了在同一個管理叢集中為工作節點部署虛擬機器,Cluster API 在其中運行。
控制平面供應商
Kamaji 項目提供了一個現成的解決方案,用於在管理叢集內作為容器運行租戶叢集的 Kubernetes 控制平面。這種方法有幾個顯著優勢
- 成本效益:在容器中運行控制平面避免了為每個叢集使用單獨的控制平面節點,從而顯著降低了基礎設施成本。
- 穩定性:通過消除複雜的多層部署方案來簡化架構。不是順序啟動虛擬機器,然後在其內部安裝 etcd 和 Kubernetes 組件,而是一個簡單的控制平面,它作為 Kubernetes 內部的常規應用程式部署和運行,並由運營商管理。
- 安全性:叢集的控制平面對最終使用者隱藏,減少了其組件被洩露的可能性,並且還消除了使用者對叢集憑證儲存的訪問權限。這種組織對使用者不可見的控制平面的方法通常被雲端供應商使用。
啟動程式供應商
Kubeadm 作為啟動程式供應商 - 作為 Cluster API 中準備叢集的標準方法。此供應商是作為 Cluster API 本身的一部分開發的。它只需要一個安裝了 kubelet 和 kubeadm 的準備好的系統映像,並允許以 cloud-init 和 ignition 格式生成配置。
值得注意的是,Talos Linux 也支援通過 Cluster API 進行佈建,並且 有 供應商為此。雖然 之前的文章討論了使用 Talos Linux 在裸機節點上設定管理叢集,但要佈建租戶叢集,Kamaji+Kubeadm 方法具有更多優勢。它有助於在容器中部署 Kubernetes 控制平面,從而無需為控制平面實例使用單獨的虛擬機器。這簡化了管理並降低了成本。
它是如何運作的
Cluster API 中的主要物件是 Cluster 資源,它是所有其他資源的父級。通常,此資源引用另外兩個資源:描述控制平面的資源和描述基礎設施的資源,每個資源都由單獨的供應商管理。
與 Cluster 不同,這兩個資源未標準化,它們的類型取決於您正在使用的特定供應商
一個圖表顯示了 Cluster 資源及其在 Cluster API 中連結到的資源的關係
在 Cluster API 內,還有一個名為 MachineDeployment 的資源,它描述了一組節點,無論它們是實體伺服器還是虛擬機器。此資源的功能類似於標準 Kubernetes 資源,例如 Deployment、ReplicaSet 和 Pod,提供了一種用於聲明式描述一組節點和自動擴展的機制。
換句話說,MachineDeployment 資源允許您聲明式地描述叢集的節點,根據指定的參數和請求的副本數量自動化它們的創建、刪除和更新。
一個圖表顯示了 MachineDeployment 資源及其在 Cluster API 中的子資源的關係
為了創建機器,MachineDeployment 引用了一個用於生成機器本身的範本和一個用於生成其 cloud-init 配置的範本
一個圖表顯示了 MachineDeployment 資源及其在 Cluster API 中連結到的資源的關係
要使用 Cluster API 部署新的 Kubernetes 叢集,您需要準備以下資源集
- 一個通用的 Cluster 資源
- 一個 KamajiControlPlane 資源,負責由 Kamaji 運營的控制平面
- 一個 KubevirtCluster 資源,描述 KubeVirt 中的叢集配置
- 一個 KubevirtMachineTemplate 資源,負責虛擬機器範本
- 一個 KubeadmConfigTemplate 資源,負責生成令牌和 cloud-init
- 至少一個 MachineDeployment 來創建一些工作節點
完善叢集
在大多數情況下,這就足夠了,但根據使用的供應商,您可能還需要其他資源。您可以在 Kamaji 專案文檔中找到為每種類型供應商創建的資源範例。
在此階段,您已經擁有一個準備好的租戶 Kubernetes 叢集,但到目前為止,它僅包含 API 工作節點和一些標準包含在任何 Kubernetes 叢集安裝中的核心外掛程式:kube-proxy 和 CoreDNS。為了完全整合,您將需要安裝更多組件
要安裝其他組件,您可以使用單獨的 Cluster API Add-on Provider for Helm,或相同的 FluxCD,如之前的文章中所討論的。
在 FluxCD 中創建資源時,可以通過引用 Cluster API 生成的 kubeconfig 來指定目標叢集。然後,安裝將直接在其內部執行。因此,FluxCD 成為管理管理叢集和使用者租戶叢集中資源的通用工具。
一個圖表顯示了 fluxcd 的互動方案,它可以將組件安裝在管理和租戶 Kubernetes 叢集中
這裡討論的組件是什麼?通常,該集合包括以下內容
CNI 外掛程式
為了確保租戶 Kubernetes 叢集中 Pod 之間的通信,有必要部署 CNI 外掛程式。此外掛程式創建一個虛擬網路,允許 Pod 相互交互,並且傳統上作為 Daemonset 部署在叢集的工作節點上。您可以選擇並安裝您認為合適的任何 CNI 外掛程式。
一個圖表顯示了在嵌套 Kubernetes 叢集方案中安裝在租戶 Kubernetes 叢集內部的 CNI 外掛程式
Cloud Controller Manager
Cloud Controller Manager (CCM) 的主要任務是將 Kubernetes 與雲端基礎設施供應商的環境整合 (在您的情況下,它是所有租戶 Kubernetes 工作節點都在其中佈建的管理 Kubernetes 叢集)。以下是它執行的一些任務
- 當創建 LoadBalancer 類型的服務時,CCM 會啟動創建雲端負載平衡器的過程,該負載平衡器將流量定向到您的 Kubernetes 叢集。
- 如果從雲端基礎設施中刪除了節點,CCM 會確保也從您的叢集中刪除它,從而維護叢集的當前狀態。
- 使用 CCM 時,節點會添加到叢集中,並帶有一個特殊的汙點
node.cloudprovider.kubernetes.io/uninitialized
,如果需要,這允許處理額外的業務邏輯。成功初始化後,此汙點將從節點中移除。
根據雲端供應商的不同,CCM 可以在租戶叢集內部和外部運行。
KubeVirt Cloud Provider 旨在安裝在外部父管理叢集中。因此,在租戶叢集中創建 LoadBalancer 類型的服務會啟動在父叢集中創建 LoadBalancer 服務,這些服務將流量定向到租戶叢集。
一個圖表顯示了在嵌套 Kubernetes 叢集方案中安裝在租戶 Kubernetes 叢集外部的 Cloud Controller Manager,以及它管理的從父 Kubernetes 叢集到子 Kubernetes 叢集的服務映射
CSI Driver
容器儲存介面 (CSI) 分為兩個主要部分,用於與 Kubernetes 中的儲存進行交互
- csi-controller:此組件負責與雲端供應商的 API 交互,以創建、刪除、附加、分離和調整卷大小。
- csi-node:此組件在每個節點上運行,並有助於將卷掛載到 kubelet 請求的 Pod。
在使用 KubeVirt CSI Driver 的上下文中,出現了一個獨特的機會。由於 KubeVirt 中的虛擬機器在管理 Kubernetes 叢集內運行,其中提供了功能齊全的 Kubernetes API,這為在使用者租戶叢集外部運行 csi-controller 開闢了道路。這種方法在 KubeVirt 社群中很流行,並具有幾個關鍵優勢
- 安全性:此方法向最終使用者隱藏了內部雲端 API,僅通過 Kubernetes 介面提供對資源的訪問權限。因此,它降低了從使用者叢集直接訪問管理叢集的風險。
- 簡潔性和便利性:使用者無需在其叢集中管理其他控制器,從而簡化了架構並減輕了管理負擔。
但是,CSI-node 必須在租戶叢集內部運行,因為它直接與每個節點上的 kubelet 交互。此組件負責將卷掛載和卸載到 Pod 中,需要與直接在叢集節點上發生的進程緊密整合。
KubeVirt CSI Driver 充當訂購卷的代理。當在租戶叢集中創建 PVC 時,將在管理叢集中創建 PVC,然後將創建的 PV 連接到虛擬機器。
一個圖表顯示了在嵌套 Kubernetes 叢集方案中安裝在租戶 Kubernetes 叢集內部和外部的 CSI 外掛程式組件,以及它管理的從父 Kubernetes 叢集到子 Kubernetes 叢集的持久卷映射
叢集自動擴展器
叢集自動擴展器是一個多功能組件,可以與各種雲端 API 一起使用,它與 Cluster-API 的整合只是可用的功能之一。為了正確配置,它需要訪問兩個叢集:租戶叢集,以跟蹤 Pod 並確定是否需要新增節點,以及管理 Kubernetes 叢集 (管理 Kubernetes 叢集),它在其中與 MachineDeployment 資源交互並調整副本數量。
雖然叢集自動擴展器通常在租戶 Kubernetes 叢集內部運行,但在這種情況下,建議將其安裝在外部,原因與之前描述的相同。這種方法更易於維護且更安全,因為它可以防止租戶叢集的使用者訪問管理叢集的管理 API。
一個圖表顯示了在嵌套 Kubernetes 叢集方案中安裝在租戶 Kubernetes 叢集外部的叢集自動擴展器
Konnectivity
我想提及另一個附加組件 - Konnectivity。您稍後可能需要它來使 Webhook 和 API 聚合層在您的租戶 Kubernetes 叢集中工作。在我的之前的一篇文章中詳細介紹了這個主題。
與上面介紹的組件不同,Kamaji 允許您輕鬆啟用 Konnectivity 並將其作為租戶叢集的核心組件之一進行管理,與 kube-proxy 和 CoreDNS 並行。
結論
現在,您擁有一個功能齊全的 Kubernetes 叢集,具有動態擴展、自動佈建卷和負載平衡器的能力。
展望未來,您可能會考慮從租戶叢集中收集指標和日誌,但這超出了本文的範圍。
當然,部署 Kubernetes 叢集所需的所有組件都可以打包到一個 Helm chart 中,並作為一個統一的應用程式部署。這正是我們如何在我們的開放 PaaS 平台 Cozystack 上,通過點擊按鈕來組織託管 Kubernetes 叢集的部署方式,您可以在其中免費試用本文中描述的所有技術。