首頁 >後端開發 >Golang >Kubernetes 雲端控制器管理器

Kubernetes 雲端控制器管理器

Patricia Arquette
Patricia Arquette原創
2024-12-24 09:25:21694瀏覽

請注意,這篇文章最初是我在medium.com 上發布的,此後我決定轉到dev.to!

The Kubernetes Cloud Controller Manager

本文假設您對操作/運行 Kubernetes 以及一些 Go 程式語言概念有一定的經驗。

在過去的一年半中,我們在 Etraveli Group 與 OpenStack 和 Kubernetes 進行了大量合作。我們是我們自己的雲端供應商,最終用戶是開發人員和開發組織中的周邊團隊。

在 OpenStack 之上運行 Kubernetes 的關鍵元件之一是雲端控制器管理器。它是將兩個平台粘合在一起的部件之一。對於那些在公有雲(或私有雲)中使用託管 Kubernetes 服務的人來說,已經為您解決了這個問題。 Kubernetes 控制平面對你來說或多或少是遙不可及的。

那為什麼要寫一些關於雲端控制器管理器的內容呢?主要驅動因素是我的一位同事提出的最簡單的問題:

「(OpenStack)雲端控制器管理員到底做什麼?」

我試圖回答這個問題,但我基本上不知道我在說什麼,我知道它負責在創建 LoadBalancer 類型的 Service 物件時在底層雲中創建負載平衡器。

我立即決定深入研究這個問題,最終我進行了相當深入的研究,試圖理解這個難題的每一點,在這篇文章中我將總結我的發現。

在這篇文章中我將參考:

  • 雲端控制器管理器作為「CCM

  • Kubernetes 主原始碼儲存庫為「k/k

  • Kubernetes 為「k8s

當我開始寫這篇文章時,我創建了一個小專案和儲存庫,在其中我按照規定建立了自己的雲端控制器管理器,並將兩個小型Kubernetes (v1.18.2) 叢集相互進行比較,其中一個運行CCM 和沒有的。這是一個概念驗證,旨在向您展示運行自己的 CCM 到底需要什麼。從構成 CCM 的程式碼到 k8s 清單的所有內容都表明您需要部署它。

在我們開始之前,很高興知道這篇文章連結到 k8s 原始碼儲存庫的各個部分,我使用了 v1.18.0 標籤。

所有插圖都是我自己的。

享受吧!

請留下一兩則評論(!),我們非常感謝任何回饋!

雲端控制器管理器

從高層次的角度來看,雲端控制器管理器可以被描述為三個不同的事物:

  • 二進位

  • 多重控制循環

  • k8s 和雲之間的一部分黏合劑

程式碼方面,CCM 是 k/k 儲存庫的一部分,請查看此處。正如官方 k8s 文件中所提到的,k/k 中的 CCM 程式碼可以用作您自己實現的框架。差別在於您提供和匯入的用於與雲端互動的程式碼(包)。

CCM 通常會透過 k8s 清單和內建於從眾所周知的容器註冊表中提取的(Docker)容器中的二進位檔案進行部署。

值得注意的是,CCM 將被分配到連接埠 10258,如果需要,您需要公開它。開箱即用的 CCM 將公開 /healthz 端點來檢查服務的運作狀況。

在GitHub 中查看k8s 組織時,您會發現許多不同的CCM 實現,它們也稱為外部CCM,因為它們位於k/k 存儲庫之外,並且由一組精心設計的Golang 接口組成,如下所示以及任何人創建自己的CCM 的最低限度。

稍後我們將詳細了解這一切。

CCM 的核心由四個運行控制循環的(雲)控制器組成,您可以選擇與其他控制器一起運行自己的控制器。

The Kubernetes Cloud Controller Manager

我們將在接下來的部分中更深入地了解 CCM 中運行的每個雲控制器。

節點控制器

節點控制器確保您的雲端節點(例如虛擬機器)使用雲端供應商提供的其他相關資訊進行標記、污染和更新。控制器將定期在無序列表中執行以下操作:

The Kubernetes Cloud Controller Manager

  • 使用下列污點初始化新增至雲端提供者的新節點:node.cloudprovider.kubernetes.io/uninitialized 設定為 true 並將污點效果設為 NoSchedule。當節點初始化時,節點控制器將刪除此污點,從而允許在節點上調度工作負載。對於例如至關重要的 Pod運行叢集當然會在已經受污染的節點上安排所需的容忍度。

  • 透過將雲端提供者中的 IP 位址與 k8s API 中 Node 物件中儲存的 IP 位址進行比較來更新節點 IP 位址。

  • 使用雲端提供的資訊來新增或更新節點標籤,其中包括:實例類型區域故障域區域區域。區域特定資訊不是強制性的,我們稍後會看到。

關於節點標籤以及如何取得上面提到的實例資訊並將其新增至 Node 物件。舉個例子,OpenStack 外部 CCM 透過從磁碟(配置磁碟)讀取元資料或使用每個節點內可存取的元資料服務端點來執行此操作。

服務控制器

服務控制器將處理與在雲端中建立的基於服務物件的負載平衡器的生命週期相關的所有內容。服務提供了一種從 k8s 叢集的角度內部和/或外部公開應用程式的方法。

這個特定的控制器將只處理 LoadBalancer 類型的 Service 物件。這意味著,從雲端提供者的角度來看,它將確保在您的雲端中建立、刪除和更新某種類型的負載平衡器。

The Kubernetes Cloud Controller Manager

根據您的 CCM 如何實現服務控制器邏輯,您可以建立一個雲端負載平衡器,在雲端內部對網路流量進行負載平衡。這通常透過在服務對象的元資料部分定義一組註解來完成。

請注意,預設行為,正如我在例如中所指出的那樣OpenStack 是在應用簡單的 Service 物件(類型為 LoadBalancer)清單時將建立以下物件:

  • 雲端負載平衡器,其中包含流量將負載平衡到的節點的填充清單。負載平衡器將使用產生的隨機 NodePort

  • 指向每個節點
  • NodePort 類型的 Service 物件

如上所示,實際上有很多東西構成了 k8s 和雲端提供者中的 Service 物件。對於用戶來說,這意味著 EXTERNAL-IP 列將填充雲端負載平衡器的雲端提供者 IP。使用 kubectl 列出服務物件時可見:

$> kubectl get service my-app-svc
NAME       TYPE         CLUSTER-IP    EXTERNAL-IP     PORT(S)
my-app-svc LoadBalancer 172.20.10.100 123.123.123.123 80:31147/TCP

路線控制器

在四個控制器中,有一個有點特殊,那就是(雲)路由控制器,除非您提供--allocate-node-cidrs 或--configure-cloud-routes 標誌,否則它不會啟動CCM 。另外,如果您還沒有實作任何路由處理邏輯,那麼該控制器將不會啟動,稍後會詳細介紹。

The Kubernetes Cloud Controller Manager

此控制器將定期嘗試執行以下操作:

  • 列出與 k8s 叢集關聯的所有路由,這是透過查詢雲端提供者 API 來完成的。

  • 透過查詢 k8s API 列出所有節點。

  • 循環遍歷節點規範的每個節點和 podCIDRs 欄位。 Pod CIDR 和節點名稱將用於透過雲端提供者 API 建立路由。

此外,在控制循環期間,控制器將刪除未使用的路由。當所有路由都建立完成後,節點將被視為就緒,這表示 NetworkUnavailable 的節點條件欄位將設定為 false 。如果節點沒有任何與其關聯的路由,則 NetworkUnavailable 欄位將設為 true 。這些條件由 NodeLifeCycle 控制器轉換為污點,不要與 CCM 負責的條件混淆。

生命週期控制器

如果從雲端刪除節點,(雲節點)生命週期控制器將確保以 Kubernetes API 節點物件表示的節點也被刪除。

The Kubernetes Cloud Controller Manager

此外,如果節點處於雲端提供者指定的關閉狀態,則該節點會相應地受到 node.cloudprovider.kubernetes.io/shutdown 和 NoSchedule 的污染效果的污染。

這就是您將從CCM 獲得的所有功能,大多數時候您的雲可能有自己的控制器(以來自單獨存儲庫的單獨二進位提供)來處理Ingress 類型的k8s 對象,或者幫助您與底層網路基礎設施原生整合。

CCM 不會是一站式解決方案,它只是一個更大拼圖的一部分。

如果您一直在關注,並且可能查看了 CCM 處理的不同控制器的源代碼,您可能會注意到沒有任何雲端提供者特定的代碼。只是對各種物件上有些神秘的方法進行了一堆呼叫。

雲端提供者特定的程式碼及其連線將是這個 CCM 難題中缺少的一塊。

The Kubernetes Cloud Controller Manager

看看後視鏡

在討論雲端提供者套件 (k8s.io/cloud-provider)(CCM 難題中缺少的一塊)之前,我們將回顧 CCM 和雲端提供者背後的一些歷史。這些年來它們是如何演變的以及一切是如何形成的。

出於顯而易見的原因,從一開始,雲端整合就一直是 k8s 的一部分的基礎。讓我們來看看在 2015 年 7 月發布的 v1.0 的 k8s 儲存庫 (k/k) 中擁有特定提供者程式碼的雲端提供者:

  • AWS
  • GCE
  • Mesos
  • OpenStack
  • 奧維爾特
  • 機架空間
  • 流浪者

您可能認識以上所有“雲端供應商”,其中一些是虛擬化技術,並不完全符合我們通常所認為的雲端供應商。至少可以說。

早在 2015 年 7 月,所有雲端供應商特定程式碼均由 kubelet 匯入和使用,kubelet 是構成 k8s 叢集節點的關鍵節點元件之一。

k8s 社群已經認識到雲端提供者特定程式碼的原始實作存在許多問題,並且到目前為止正在努力解決。

以下是這些年來出現的一些問題:

  • kubelet 不應執行雲端提供者特定的控制循環。現已移至 CCM。

  • 雲端提供者不應成為k/k(樹內)的一部分,原因是雲端提供者程式碼將綁定到k8s 發布週期,並且可以將程式碼提交到k/k一項乏味的任務。

  • 透過提供單獨的套件以及將雲端與 k8s 整合的可插拔方式來支援外部(樹外)雲端提供者。這成為 k8s.io/cloud-provider 套件。

  • CCM 使用的所有雲端控制器程式碼都應移至 k8s.io/cloud-provider 套件中,樹中仍有剩餘程式碼將被移動。

出於向後相容性的原因,樹內的程式碼將存在一段時間,但現在它是自己的套件(k8s.io/legacy-cloud-providers)。

我試圖透過挖掘 k8s 組織中的各個儲存庫來了解 CCM 和 k8s.io/cloud-provider 是如何形成的,就像數位考古一樣。以下是一些亮點:

  • 2016 年 9 月,創建了增強 #88 (KEP) 問題以支援樹外雲供應商(可插入)。

  • 開始將 (kube) 控制器管理器分成兩部分,2016 年 10 月。請注意,此 PR 提到了volumeController,這是 CSI 之前的時間。此後該控制器已從 CCM 中刪除。

  • 雲端控制器管理器討論 2017 年 7 月。在 v1.11 進入測試版。

  • 這裡很好地解釋了 kubelet 和雲端供應商曾經的緊密耦合程度。關於如何解耦 kubelet 和雲端供應商,有以下三種方法。

雲端提供者包

雲端提供者套件在 CCM 中以 k8s.io/cloud-provider 匯入,並定義了許多 (Golang) 介面。主要的一個是 Interface 接口,這使得這個包可以為雲端提供者插入。

The Kubernetes Cloud Controller Manager

介面定義了一組方法,其中一些方法傳回其他介面。這些傳回的介面也在雲端提供者包的cloud.go檔案中定義。

$> kubectl get service my-app-svc
NAME       TYPE         CLUSTER-IP    EXTERNAL-IP     PORT(S)
my-app-svc LoadBalancer 172.20.10.100 123.123.123.123 80:31147/TCP

如您在上面看到的,方法簽章在傳回的介面旁邊指定了一個 bool 回傳值,這表示您可以啟用/停用 CCM 無法或不應該實現的功能。這是在實作介面定義的功能的控制器初始化期間檢查的內容。

以下是哪個控制器使用哪些 k8s.io/cloud-provider 介面方法的快速概述:

  • 實例介面方法將從節點和生命週期控制器呼叫。

  • Zones 介面方法將從 Node 和 Lifecycle 控制器呼叫。

  • Route 介面方法將從 Route 控制器呼叫。

  • LoadBalancer 介面方法將從服務控制器呼叫。

  • 叢集介面僅供 GCP 外部雲端供應商使用。

請注意,k/k 儲存庫中的許多位置都呼叫了上述介面中的各種方法,例如在 kubelet 和 API 伺服器中。

除了 k8s.io/cloud-provider 套件上面的介面之外,還包括使用 CCM 註冊和初始化雲端提供者所需的一切。

讓我們來看看LoadBalancer接口,你會看到一堆需要實現的方法:

LoadBalancer() (LoadBalancer, bool)
Instances() (Instances, bool)
Zones() (Zones, bool)
Clusters() (Clusters, bool)
Routes() (Routes, bool)

這些方法將由在 CCM 中運行的服務控制器調用,我將這些方法作為範例進行展示,因為您將看到這些方法在服務控制器的原始程式碼中被調用。

實際上在整個 CCM 中傳遞的是您的實例化對象,它將充當雲端提供者(滿足所有雲端提供者介面)。

這就是 CCM 維護的雲端控制器如何在您的雲端中建立、更新和刪除資源。

The Kubernetes Cloud Controller Manager

k8s.io/cloud-provider 套件不會定義任何連接方式,例如向您的雲端進行身份驗證。您必須將這種邏輯建置到 CCM 中。

當您滿足了 k8s.io/cloud-provider 套件中定義的所有介面並將所有內容連接在一起時,您就成功成為了雲端提供者。剩下的唯一事情就是建置 CCM 二進位檔案並將其打包到容器中並將其部署到 k8s!

展望未來,在查看k/k 儲存庫的雲端供應商部分時,實際上會發生很多事情,在撰寫本文時,正在採取一項持續的舉措來重組並使k8s.io/cloud-provider或多或少獨立的。意思是例如雲端控制器將成為 k8s.io/cloud-provider 套件的一部分,這意味著最終您將作為雲端提供者匯入一個包,以便能夠建置和實作您自己的 CCM 和外部雲端提供者。

從 Kubernetes 的角度來看

為了能夠運行新組裝且 Docker 打包的 CCM,在啟動 k8s 控制平面時需要配置一些內容:

  • kubelet 應以 --cloud-provider=external 標誌啟動,這向 kubelet 發出訊號,表示有另一個控制器正在初始化節點。

正如本文開頭所提到的,我在這個儲存庫中展示並解釋了運行您自己的外部雲端供應商 CCM 的技術方面。

如果您現在在 AWS 上在 EC2 執行個體上執行自己的 k8s 集群,並且希望與 AWS 進行更原生的集成,那麼您可能會部署雲端提供者 AWS CCM。您也可以(儘管不建議)僅在 kubelet 上指定 --cloud-provider=aws。這就是您向 k8s 發出信號表示您想要使用樹內雲端提供者的方式,其中只有少數已實現。任何「較新」的私有/公有雲都會有一個外部雲端提供者 CCM。

樹內雲端提供者的程式碼是透過k8s.io/legacy-cloud-providers 匯入的,請注意,當您使用k/k 中的CCM 框架程式碼時,您將從一開始就匯入此套件.

資源

要了解 k8s 背景下與雲端供應商相關的一切動態,請參閱以下資源:

  • SIG 雲端供應商

  • k8s Slack 空間中的 sig-cloud-provider 頻道

  • 所有帶有 sig/cloud-provider 標籤的 k8s 增強問題

這是外部雲端供應商的列表,非常適合用作參考,或者如果您只是對其他人的做法感到好奇:

  • OpenStack

  • 數位海洋

  • AWS

  • GCP

  • 阿里雲

  • 華為雲

  • 百度雲

  • vSphere

  • 天藍

以上是Kubernetes 雲端控制器管理器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn