Kubernetes 叢集的運作仰賴多個核心元件協同合作,etcd 負責儲存叢集資料,API Server 作為與 etcd 互動的唯一入口,Scheduler 負責 Pod 的排程,Controller Manager 則確保叢集狀態符合預期。在節點層級,Kubelet 管理容器生命週期,kube-proxy 則負責服務的負載平衡。這些元件共同構成了 Kubernetes 的控制平面和資料平面,確保容器化應用程式穩定可靠地執行。深入理解這些元件的功能和互動,有助於更好地管理和維護 Kubernetes 叢集。
Kubernetes 架構深度解析
Kubernetes 叢集的核心運作依賴於多個關鍵元件的協同工作,這些元件共同構成了 Kubernetes 的基礎架構。本文將探討這些元件的功能及其在叢集中的角色。
etcd:叢集的資料儲存核心
etcd 是 Kubernetes 叢集的心臟,負責實作鍵值儲存,所有 Kubernetes 物件都持久化儲存在此。etcd 伺服器採用 Raft 共識演算法,確保即使某個儲存伺服器故障,仍有足夠的資料備份來維護資料完整性,並在故障伺服器還原後重新加入叢集。
etcd 提供了兩個重要的功能:
樂觀平行控制:每個儲存在 etcd 中的值都有對應的資源版本。當寫入鍵值對時,可以根據特定的資源版本進行條件寫入。這使得 etcd 能夠實作比較後交換(compare and swap),這是任何平行控制系統的核心。比較後交換允許使用者讀取一個值並更新它,同時確保系統中沒有其他元件同時更新該值。這種機制使得多個執行緒能夠安全地操作 etcd 中的資料,而無需使用悲觀鎖,從而顯著提高伺服器的吞吐量。
監控協定:etcd 實作了一個監控協定,允許客戶端有效地監控鍵值儲存中整個目錄的變化。例如,所有 Namespace 中的物件都儲存在 etcd 的一個目錄下。使用監控功能,客戶端可以有效地等待並對變化做出反應,而無需持續輪詢 etcd 伺服器。
API 伺服器:叢集的中心樞紐
儘管 etcd 是 Kubernetes 叢集的核心,但實際上只有 API 伺服器被允許直接存取叢集。API 伺服器是 Kubernetes 叢集的中心,負責協調客戶端與儲存在 etcd 中的 API 物件之間的互動。因此,它是所有元件的匯集點。由於其重要性,API 伺服器值得更深入的研究,將在第 4 章中詳細介紹。
排程器:Pod 的佈署決策者
當 etcd 和 API 伺服器正常運作後,Kubernetes 叢集在某些方面已經具備了基本功能,可以建立不同的 API 物件,如 Deployments 和 Pods。然而,這些 Pod 不會自動開始執行。為 Pod 找到合適的執行位置是 Kubernetes 排程器的任務。排程器掃描 API 伺服器以尋找未排程的 Pod,然後決定最佳的節點來執行它們。與 API 伺服器一樣,排程器是一個複雜且豐富的話題,將在第 5 章中探討。
控制管理器:實作複雜功能的核心
當 etcd、API 伺服器和排程器都運作正常後,您可以成功建立 Pod 並將其排程到節點上,但會發現 ReplicaSets、Deployments 和 Services 的行為與預期不符。這是因為實作這些功能所需的調解控制迴圈尚未執行。執行這些迴圈是控制管理器的任務。控制管理器是 Kubernetes 元件中最多樣化的,因為它包含了多個不同的調解控制迴圈,以實作整體 Kubernetes 系統的許多部分。
節點上的元件
除了在主節點上執行的元件外,還有一些元件存在於 Kubernetes 叢集的所有節點上。這些元件實作了所有節點上所需的基本功能。
Kubelet:節點代理
Kubelet 是所有作為 Kubernetes 叢集一部分的機器上的節點守護程式。Kubelet 是將節點上的可用 CPU、磁碟和記憶體納入大型 Kubernetes 叢集的橋樑。Kubelet 與 API 伺服器通訊,以找出應該在其節點上執行的容器。同樣,Kubelet 將這些容器的狀態回傳給 API 伺服器,以便其他調解控制迴圈可以觀察這些容器的當前狀態。
除了排程和報告在其機器上執行的容器狀態外,Kubelet 還負責健康檢查和重新啟動在其機器上執行的容器。如果將所有健康狀態資訊回傳給 API 伺服器,以便調解迴圈能夠採取行動修復特定機器上的容器健康狀態,將會非常低效。相反,Kubelet 直接執行調解迴圈。因此,如果由 Kubelet 執行的容器死亡或健康檢查失敗,Kubelet 將重新啟動它,同時將此健康狀態(以及重新啟動)回傳給 API 伺服器。
kube-proxy:服務負載平衡器
在所有機器上執行的另一個元件是 kube-proxy。kube-proxy 負責實作 Kubernetes Service 負載平衡網路模型。kube-proxy 不斷監控 Kubernetes 叢集中所有 Service 的端點物件。然後,kube-proxy 在其節點上程式設計網路,以便將對 Service 虛擬 IP 位址的網路請求路由到實作此 Service 的端點。Kubernetes 中的每個 Service 都獲得一個虛擬 IP 位址,而 kube-proxy 是負責定義和實作此虛擬 IP 位址的守護程式。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title kube-proxy:服務負載平衡器
rectangle "儲存資料" as node1
rectangle "排程Pod" as node2
rectangle "管理控制迴圈" as node3
rectangle "報告狀態" as node4
rectangle "執行容器" as node5
rectangle "實作Service負載平衡" as node6
node1 --> node2
node2 --> node3
node3 --> node4
node4 --> node5
node5 --> node6
@enduml
此圖示說明瞭 Kubernetes 中各個元件之間的關係。
詳細解析
- etcd 是資料儲存的核心,所有 Kubernetes 物件都儲存在此。
- API Server 是叢集的中心樞紐,負責協調客戶端與儲存在 etcd 中的 API 物件之間的互動。
- Scheduler 負責為 Pod 找到合適的執行位置。
- Controller Manager 執行調解控制迴圈,以實作 ReplicaSets、Deployments 和 Services 等功能。
- Kubelet 是節點上的代理,負責執行容器、報告狀態和健康檢查。
- kube-proxy 實作了 Service 的負載平衡網路模型,將網路請求路由到正確的端點。
Kubernetes 的架構設計使其能夠高效地管理和協調容器化應用程式,提供了一個強大且靈活的平台,用於佈署和管理現代應用程式。
Kubernetes 架構深入解析
Kubernetes 是一個複雜的分散式系統,包含了多個不同元件以實作完整的 Kubernetes API。本章節將探討 Kubernetes 的核心元件及其運作原理。
Kubernetes 的基本元件
Kubernetes 的基本元件包括控制平面(control plane)節點和工作節點(worker nodes)。控制平面節點負責執行 API 伺服器、etcd 叢集等核心元件,而工作節點則負責執行實際的容器化應用程式。
控制平面元件
- API 伺服器:作為 Kubernetes 叢集的入口點,API 伺服器負責處理所有 API 請求,並將 API 物件儲存在永續性儲存後端。
- etcd 叢集:作為 Kubernetes 的永續性儲存後端,etcd 叢集負責儲存所有 API 物件的狀態。
- 排程器(Scheduler):負責將容器化應用程式排程到特定的工作節點上執行。
- 控制器管理器(Controller Manager):負責執行大多數控制迴圈,以保持叢集的正確運作。
工作節點元件
- Kubelet:負責管理工作節點上的容器化應用程式,包括啟動、停止和監控容器。
- Kube-proxy:負責實作 Kubernetes Service 的負載平衡功能,將流量路由到正確的容器化應用程式。
額外的排程元件
除了基本元件之外,Kubernetes 還有一些額外的排程元件,包括:
- KubeDNS:負責為 Kubernetes Service 提供 DNS 解析功能,使得應用程式可以透過 DNS 名稱存取 Service。
- CoreDNS:KubeDNS 的替代方案,提供更高效的 DNS 解析功能。
- Heapster:負責收集叢集中容器化應用程式的效能指標,例如 CPU 使用率、網路流量等。
Heapster 的工作原理
Heapster 透過收集容器化應用程式的效能指標,為 Kubernetes 的自動擴充套件功能提供資料支援。其工作原理如下:
graph LR
A[Heapster] -->|收集指標|> B[容器化應用程式]
B -->|提供指標|> C[InfluxDB]
C -->|儲存指標|> D[監控系統]
此圖示展示了 Heapster 如何收集容器化應用程式的效能指標,並將其儲存在 InfluxDB 中,供監控系統使用。
程式碼範例:Heapster 的組態
apiVersion: v1
kind: Pod
metadata:
name: heapster
spec:
containers:
- name: heapster
image: k8s.gcr.io/heapster-amd64:v1.5.4
command:
- /heapster
- --source=kubernetes.summary_api:''?useServiceAccount=true&kubeletPort=10255&insecure=true
內容解密:
apiVersion和kind指定了此 YAML 檔案的版本和型別。metadata部分定義了 Pod 的名稱。spec部分定義了 Pod 的規格,包括容器名稱、映像檔和命令。--source引數指定了 Heapster 的資料來源為 Kubernetes summary API。
Kubernetes API 伺服器深度解析
Kubernetes API 伺服器是整個叢集的核心樞紐,負責處理來自客戶端的 API 請求。瞭解其內部運作機制對於深入掌握 Kubernetes 架構至關重要。本文將詳細探討 API 伺服器的核心組成部分及其運作原理。
API 管理機制
在處理個別客戶端請求之前,客戶端必須瞭解如何與 API 伺服器進行通訊。這涉及到 API 的公開和管理,主要涵蓋以下幾個關鍵導向:
- API 路徑結構
- 所有 Kubernetes 請求均遵循 RESTful API 模式
- 請求路徑由 HTTP 路徑定義,主要分為兩類別:
/api/字首用於核心 API 物件/apis/字首用於分組的 API 物件
- 資源路徑需考慮名稱空間影響:
# 名稱空間資源路徑格式 /api/v1/namespaces/<namespace-name>/<resource-type-name>/<resource-name> /apis/<api-group>/<api-version>/namespaces/<namespace-name>/<resource-type-name>/<resource-name> # 非名稱空間資源路徑格式 /api/v1/<resource-type-name>/<resource-name> /apis/<api-group>/<api-version>/<resource-type-name>/<resource-name>
內容解密:
- Kubernetes 使用不同的路徑字首來區分核心物件與分組 API 物件
- 資源路徑設計充分考慮了名稱空間的影響
- 正確理解路徑結構對於使用
kubectl和 API 互動至關重要
API 探索機制
客戶端需要透過 API 探索來瞭解可用的 API 物件。以下是具體的操作步驟:
啟動本地代理伺服器
kubectl proxy此命令在本地 8001 連線埠啟動一個簡單的伺服器,方便進行 API 探索。
查詢 API 版本資訊
curl localhost:8001/api回應結果包含可用的 API 版本資訊:
{ "kind": "APIVersions", "versions": ["v1"], "serverAddressByClientCIDRs": [...] }查詢特定版本的資源列表
curl localhost:8001/api/v1回應結果包含該版本下的資源列表,例如:
{ "kind": "APIResourceList", "groupVersion": "v1", "resources": [ { "name": "namespaces", "namespaced": false, "kind": "Namespace", "verbs": ["create", "delete", "get", "list", ...] }, { "name": "pods", "namespaced": true, "kind": "Pod", "verbs": ["create", "delete", "get", "list", ...] } ] }
內容解密:
- API 探索機制允許客戶端動態發現可用的 API 資源
kubectl proxy命令簡化了本地開發和除錯過程- 資源列表中包含了資源的關鍵屬性,如是否支援名稱空間、支援的操作等
OpenAPI/Swagger 定義解析
Kubernetes API 伺服器提供了 OpenAPI/Swagger 定義,用於描述 API 的詳細資訊。以 Pod 物件為例:
{
"name": "pods",
"singularName": "",
"namespaced": true,
"kind": "Pod",
"verbs": ["create", "delete", "get", "list", ...],
"shortNames": ["po"],
"categories": ["all"]
}
內容解密:
- OpenAPI 定義提供了豐富的元資料資訊
- 詳細描述了資源的屬性,如名稱、是否支援名稱空間、支援的操作等
- 為客戶端實作提供了重要的參考資訊
Kubernetes API 伺服器解析
Kubernetes API 伺服器是整個叢集的核心元件,負責處理所有 API 請求。瞭解其內部工作原理對於開發者和維運人員至關重要。
API 資源物件結構
當我們查詢 API 資源物件時,可以得到一個詳細的描述結構,例如:
{
"name": "pods/attach",
"singularName": "",
"namespaced": true,
"kind": "Pod",
"verbs": []
}
內容解密:
name欄位提供資源的名稱,同時也表示這些資源的子路徑。singularName欄位用於表示單一例項的名稱,因為推斷英文單詞的複數形式可能很困難。namespaced欄位指出該物件是否屬於名稱空間範圍。kind欄位提供 API 物件 JSON 表示中的字串,用於指示物件的型別。verbs欄位是最重要的欄位之一,因為它指示了可以對該物件執行的操作型別。
API 資源的操作型別
API 資源的操作型別包括 watch 和 proxy 等。其中,watch 表示可以為資源建立監控,提供有關物件變更的通知;proxy 是一種特殊的操作,建立透過 API 伺服器到網路埠的代理網路連線。
子資源的概念
某些操作被建模為子資源,例如 attach 命令被建模為子資源:
{
"name": "pods/attach",
"singularName": "",
"namespaced": true,
"kind": "Pod",
"verbs": []
}
內容解密:
attach提供將終端機附加到 Pod 中執行中的容器。exec功能允許在 Pod 中執行命令,也以類別似方式建模。
OpenAPI 規範服務
API 伺服器提供路徑來提供 Kubernetes 資源的結構描述資訊。這些結構描述使用 OpenAPI 語法表示。您可以透過以下路徑取得 OpenAPI 規範:
/swaggerapi(Kubernetes 1.10 之前)/openapi/v2(Kubernetes 1.10 及之後)
內容解密:
- OpenAPI 規範是一種完整的規範主題,超出了本文的範圍。
- 各種客戶端程式語言函式庫都是使用這些 OpenAPI 規範生成的。
API 版本管理
Kubernetes 中的 API 起初是 alpha 版本,然後逐漸演進到 beta 版本,最終成為正式版本(GA)。不同版本的 API 對應不同的穩定性和相容性保證。
內容解密:
- Alpha 版本的 API 不穩定,不適合生產環境。
- Beta 版本的 API 較為穩定,但仍可能存在錯誤或最終 API 的調整。
- GA 版本的 API 穩定,具有向後相容性和棄用保證。
請求管理
API 伺服器接收和處理來自 Kubernetes 系統其他元件或終端使用者的 HTTP 請求。請求型別包括 GET、LIST、POST、PUT 等。
內容解密:
- GET 請求用於檢索特定資源的資料。
- LIST 請求用於列出多個資源,可以選擇性地指定標籤查詢。
- POST 請求用於建立新資源。
- PUT 請求用於更新現有資源。