寫這篇想要分享的重點:
帶領讀者瞭解 Kubernetes Cluster(Control Plane 與 Worker Node)的更細部的工作模式,並掌握組件之間的協同運作流程與除錯觀念。
這篇想要講什麼:
- Control Plane 與 Worker Node 的核心組件職責劃分。
- 一個 Pod 被建立時,背後跨組件的 5 大步驟。
- Static Pods & DaemonSet 概念
為何要寫這篇:
延續前一章我們有了清楚的架構圖之後,我們要深入理解 Control Plane 和 Worker Node 的內部細節。
Control Plane: 主控面板
Worker Node: 工作節點
Scheduler: 調度器
Controller Manager: 控制器管理器
adapter: 轉接器
我們重新recap一下架構全景, Kubernetes 採用經典的主從式(Master-Worker)架構, 其中可以直接劃分為兩大部份:
+-----------------------------------------------------------------------+
| Control Plane (Master) |
| |
| +-------------------+ +------------------+ +-------------+ |
| | etcd (KV) |<--->| kube-apiserver |<---| scheduler | |
| +-------------------+ +------------------+ +-------------+ |
| ^ |
| | +-------------+ |
| +--------------| controller- | |
| | manager | |
| +-------------+ |
+-----------------------------------------------------------------------+
^
gRPC / HTTPS | (TLS Standard Port 6443)
v
+-----------------------------------------------------------------------+
| Worker Node |
| |
| +-------------------+ +------------------+ +-------------+ |
| | kubelet |<--->| Container Engine | | kube-proxy | |
| +-------------------+ | (containerd/CRI) | +-------------+ |
| +------------------+ |
+-----------------------------------------------------------------------+
Control Plane 負責控管 Worker Node 的大小事,但實際上執行具體容器任務的是 Worker Nodes。這有點像是公司的管理層(Control Plane)負責制定策略、調度資源與監督進度,而不會直接跑去第一線經手各部門(Worker Node)的具體業務。
具體來說,Control Plane 負責整個 Cluster 的全域決策(如 Pod 調度)、監控 Cluster 狀態,以及回應 Cluster 事件。
kube-apiserver(Cluster 的總經理 / 唯一對外窗口)kubectl、kubelet、scheduler 等)都只能透過 API Server 交換資訊,組件之間不直接通信。etcd(Cluster 的中央資料庫 / 機密檔案室)kube-apiserver 可以直接讀寫 etcd,其他組件(Components)想查資料都必須透過 API Server (kuber-apiserver)。etcd 進行 Snapshot 備份與恢復演練。kube-scheduler(資源調度主管)職責:有點像專案經理(PM),負責看哪裡有新任務(container)要弄一個人(Pod)來做,評估各部門(Node)的負載與能力,把任務指派給最合適的部門,但自己不經手實際業務。
Schedule 兩大階段:
kube-controller-manager(營運稽核主管 / 自動化維護者)💡 簡單白話來說,Desired State(預期狀態 / 期望狀態) 就是你在 YAML 檔裡面寫下的「理想目標」。
- 用我們的智慧工廠比喻:
- Desired State(預期狀態):老闆向中控室下達的命令,例如:「這間工廠裡面,無論如何都必須要維持 3 台 Nginx 伺服器在運作!」
- Current State(實際狀態):廠房第一線現在實際上的狀況。例如:「糟糕,剛剛有一台 Node 機器壞掉,現在只剩 2 台 Nginx 還活著。」
Worker Node 負責提供運算資源,並運行實際的 Container 應用工作負載。
kubelet(現場主管 / 廠長)PodSpec 任務。kubelet 是直接以 systemd 服務的形式常駐在 Node OS 上,而非以 Container 方式運行。若 kubelet 掛掉,無法透過 K8s 遠端除錯,必須直接 SSH 進到該 Worker Node 檢查 systemd 服務狀態與系統日誌(journalctl -u kubelet)。💡 這裡看到CRI, 後面會遇到好多XXI, 其實他們都只是抽象化的interface拉
kubelet 的指令後,真正去拉取 Image(容器映像檔)、創建並啟動/停止容器。cri-dockerd 的轉接器來當翻譯官。kube-proxy(跑腿送文件的小助理)iptables 或 IPVS 規則,實現 Pod 之間的負載均衡與 ClusterIP 流量轉發。筆者認為這三者應該要理解清楚, 一層一層的說明(有點像是俄羅斯娃娃XD):
最外層-> Pod: 用來跑Container的Component
內層-> Container: 用來實際跑起來你的程式的虛擬環境
內核-> Image: 用來生成Container的藍圖
+-----------------------------------------------------------------------------------+
| POD (多功能機台 / 獨立運作環境) |
| - K8s 最小調度單元 |
| - 提供共享資源:專屬 Pod IP / 共享 Volume (磁碟空間) / Network Namespace |
| |
| +------------------------------------+ +--------------------------------+ |
| | Container 1 (主應用程式) | | Container 2 (輔助組件 Log) | |
| | | | | |
| | 實體:運作中的 Process / 虛擬環境 | | 實體:運作中的 Process / 虛擬環境 | |
| | - 真正吃 CPU / Memory 處理資料 | | - 真正吃 CPU / Memory 處理資料 | |
| +------------------^-----------------+ +---------------^----------------+ |
| | (實體化生產) | (實體化生產) |
+----------------------|---------------------------------------|--------------------+
| |
+------------+------------+ +------------+------------+
| Image (設計藍圖 A) | | Image (設計藍圖 B) |
| - 唯讀規格檔案 (App) | | - 唯讀規格檔案 (Sidecar) |
+-------------------------+ +-------------------------+
你的程式實際上不是跑在Pod上, 而是跑在Container的環境裡面
當你在 Terminal 輸入 kubectl create deployment nginx --image=nginx 時,背後其實發生了一堆事情:
kubectl 將 YAML/命令行請求發送給 kube-apiserver。API Server 驗證身份(Authentication)與權限(Authorization),將 Deployment 物件寫入 etcd。Deployment Controller 透過 API Server 的 Watch 機制察覺到新 Deployment,建立對應的 ReplicaSet;ReplicaSet Controller 接著生成對應的 Pod 物件(此時 Pod 的 spec.nodeName 為空,處於 Pending 狀態),並寫入 etcd。kube-scheduler 監聽到未分配 Node 的 Pod,執行 Filtering 與 Scoring 流程選定最佳 Node(例如 node-01),並向 API Server 發送 Binding 請求,將 node-01 寫入 Pod 的 spec.nodeName 欄位。node-01 的 kubelet 透過 Watch 發現有分配給自己的 Pod,向 API Server 獲取細節後,透過 CRI 介面呼叫 containerd 下載 Image 並啟動 Pod 內的容器。kubelet 向 API Server 更新 Pod 狀態為 Running。同時,各節點上的 kube-proxy 更新 iptables/IPVS 規則,確保該 Pod 的流量可被正確路由。在 Kubernetes 中,並非所有 Pod 都是透過下指令產生的,有兩種特殊案例:
運作機制:由特定節點上的 kubelet 直接管理與啟動,不須透過 kube-apiserver 與 kube-scheduler。
配置方式:kubelet 會定期讀取本地端特定目錄(預設常見為 /etc/kubernetes/manifests)下的 YAML 檔,並根據這些檔案直接管理容器。
常見應用場景:
kubeadm 建置Cluster時,apiserver、etcd、scheduler 與 controller-manager 本身通常就是以 Static Pods 的形式跑在 Control Plane Node 上。除錯重點:當 Control Plane 組件出問題導致 API 無法回應時,需直接登入主機查看 /etc/kubernetes/manifests 目錄,或透過系統日誌(journalctl -u kubelet)來進行除錯。
DaemonSet Controller 管理,確保 Cluster 中每一個(或符合特定條件的)Node 上,都剛好運行一個 Pod。每當有新 Node 加入 Cluster 時,Pod 會自動在該 Node 上被建立;當 Node 被移除時,該 Pod 也會自動被垃圾回收(Garbage Collected)。Calico、Flannel(需在每台 Node 上做網路轉發與tunnel)。Fluentd、Logstash。Prometheus Node Exporter。| 項目 | Static Pods | DaemonSet |
|---|---|---|
| 由誰控管 | 該節點上的 kubelet |
Control Plane 的 DaemonSet Controller |
| 建立機制 | 由Node 上的 YAML 資料直接建立 | 透過 API Server 配合 Scheduler 與 Taints/Tolerations |
| 主要用途 | Control Plane 核心組件 | 部署全叢集基礎設施 Agent(CNI, 日誌, 監控) |
kubelet 與 CRI Runtime (Containerd)。組件之間全數透過 API Server 交換訊息,展現了高解耦的架構設計。crictl、nerdctl 與 ctr 的實際操作!