iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0

前一天先說明了這次準備遷移的微服務、container 與外部依賴服務,從今天開始就正式進入 Kubernetes 的主題。

首先我想從 Control Plane 開始,並先認識四個主要參與 Kubernetes 叢集生命週期的元件:API Server、etcd、Scheduler 與 Controller Manager
預期上是希望能夠先釐清 Kubernetes 底層是怎麼運作的,
以及分別由哪些服務角色維持、協調與控制整個叢集,
了解這些角色之後,後續在看 Pod 為什麼會被派發到某個 Node、如何被建立,以及 Deployment 的 Rolling Update 為什麼能持續替換版本時才會有更具體的畫面。

Kubernetes 叢集運作時,Node 大致可依責任區分為 Control Plane NodeWorker Node
所謂 Node,可以先把它理解成提供 CPU、Memory、網路與儲存資源給 Kubernetes 使用的一台主機,
而在企業環境中,它通常是一台安裝 Linux 的 VM,但也可能是實體伺服器。

Control Plane Node 負責叢集的管理與決策,Worker Node 則負責實際運作 Pod,當然也有服務是 Control Plane 與 Worker 都需要一起運作的,例如監控類的 Prometheus。

兩類 Node 的數量、資源大小與分布方式,會直接影響叢集的可用性與可配置資源,
例如 Control Plane 是否具備高可用性,Worker Node 是否有足夠 CPU/Memory 讓 Scheduler 分派 Pod,都是後續會遇到的議題。

Kubernetes 掌管的是期望的狀態

在 Docker Compose 的概念中,我們常常是下達一個立即命令:把某個 container 跑起來或是下架,但在 Kubernetes 中,操作的概念比較偏向是描述結果,例如「我要三個 api-a Pod,而且它們必須使用這個 image」,而這樣的描述是期望狀態(desired state)

實際上跑著幾個 Pod、它們在哪個 Node、是否健康則是實際狀態(actual state)

Control Plane 會不斷觀察兩者是否一致,當兩者狀態不一致時,就會開始嘗試對叢集這些不一致的資源進行一系列的溝通與動作(例如重新啟動 Pod),直到整體狀態都達到當初宣告的期望狀態,
這就是 Kubernetes 能讓 Pod 自我修復與滾動更新的基本概念。

https://ithelp.ithome.com.tw/upload/images/20260919/20124323OZmzuuiar0.png

四大元件各自負責什麼?

元件 角色 主要責任 它不負責什麼
API Server 叢集的唯一受理窗口 驗證請求、認證、授權、准許控制,並提供所有元件共同使用的 API 不直接替你挑 Node 或執行 container
etcd 叢集的記憶 保存 Kubernetes 物件與叢集狀態 不會主動建立或修復 Pod
Scheduler 排班/派工者 為尚未綁定 Node 的 Pod 選出合適 Node 不會在 Node 上啟動 container
Controller Manager 持續巡邏的管理者 用控制迴路讓實際狀態回到期望狀態 不會自己取代 API Server 成為窗口

這四個元件通常在 Control Plane Node 上運作,而相對的,真正執行應用程式 container 的是 Worker Node;

Worker Node 上的 kubelet 才會依照分派給自己的 PodSpec 呼叫 Container Runtime。

API Server:所有操作的唯一入口

當我們輸入:

kubectl apply -f api-a-deployment.yaml

kubectl 是操控 Kubernetes 最重要的工具,後續開始進行部署時都會跟這個工具脫離不了關係。
以套用 YAML 情境來看,送出 kubectl apply -f api-a-deployment.yaml 指令就是在告訴 Kubernetes 我們希望的狀態,
而這個指令的背後實際上是把 YAML 轉成 HTTPS API 請求送往 API Server。

而 CI/CD、Kubernetes Dashboard、Operator 與其他 control-plane 元件也走同一個入口,
這個設計讓所有變更都能用一致的身分驗證、權限控管來建立操作限制。

一個建立或更新的請求大致會經過四道關卡:

  1. Authentication:你是誰?例如憑證、Token 或外部身分系統。
  2. Authorization:你是否有權在目標 Namespace 做這個操作?(這就是後續 RBAC 要處理的事情)
  3. Admission:這個請求是否符合叢集政策?例如是否缺少必要標籤、是否違反安全規則。
  4. Validation 與持久化:格式與欄位正確後,API Server 才將新的物件狀態寫進 etcd。

https://ithelp.ithome.com.tw/upload/images/20260920/20124323mY0SyLsuAs.png

API Server 是狀態的最主要入口,不會負責工作排程,也沒有直接部署服務的能力,
而是與其他元件溝通,透過 watch API 看到物件變化之後再做回應。

etcd:叢集的記憶

etcd 是一個分散式 key-value 儲存系統,
Deployment、Pod、Service、ConfigMap、Secret 等 Kubernetes 物件的宣告與狀態,
都以 API Server 管理的形式保存其中,
以及當 Control Plane 故障後能否回復,etcd 的資料與備份也會是必要的達成條件。

因此有兩個重要原則:

  • 應用程式的業務資料會放在專用資料庫(例如 SQL Server),不是 etcd。
  • Secret 雖然是 Kubernetes 物件,也不代表可以把它當成一般文字設定,必須配合存取權限、加密設定與備份保護。

在受管控 Kubernetes 平台中,etcd 通常由平台團隊維護,並且規劃與處理備份、還原的相關規範。

Scheduler:Pod 的安排者

當 Controller 建立一個新的 Pod 時,Pod 一開始可能還沒有 nodeName
而 Scheduler 會監視這些尚未被排程的 Pod,
依據多個條件去選出最合適的 Node,然後透過 API Server 回寫綁定結果。

它的工作可以大概如下:

  1. Filtering:先排除不可能的 Node,例如 CPU/Memory request 不足、Node 有設定 taint、Node selector 不符合,或 affinity 規則不成立。
  2. Scoring:剩下的候選 Node 中,依據資源分布、Pod anti-affinity 或 topology spread 等,去選出一個最適合、符合條件的 Node。

所以如果 K8s 規劃者不清楚整個 AP 系統的 CPU、Memory 資源使用率,後續將這些容器部署到 K8s 內時,
設定這些 Pod 的資源最高、最低需求限制時就很容易沒有頭緒或是設計出偏離現實的配置,如此就會導致 Pod 無法被正確啟動並且以為是 Worker Node 資源不足,進而再擴充 Node 的資源,甚至是實體機的硬體設備導致浪費。

Scheduler 做完決策後不會替 Node 啟動 container,而是在被選中的 Node 透過 kubelet 看到屬於自己的 Pod 後,才會透過 Container Runtime 拉取 image、建立 container,並回報狀態。

Controller Manager:維持期望狀態的控制迴路

Controller Manager 是多個 controller 的集合,每個 controller 都遵循這樣的流程:

觀察(observe)→ 比對(diff)→ 調整(act)→ 再觀察,所以並不是在送出 kubectl apply 後只執行一次,而是持續不斷的運作。

https://ithelp.ithome.com.tw/upload/images/20260920/20124323AJG81Edasa.png

以 Deployment 為例:

  1. 我們宣告 replicas: 3,Deployment Controller 看到這個期望。
  2. 它建立或調整對應的 ReplicaSet。
  3. ReplicaSet Controller 發現現在只有兩個 Pod,則建立一個新的 Pod。
  4. Scheduler 選擇 Node,kubelet 啟動 container。
  5. 如果其中一個 Pod 被刪除或 Node 故障,ReplicaSet Controller 再次發現副本不足,重新補足。

除了 Deployment 與 ReplicaSet,還有 Node Controller、Job Controller、EndpointSlice Controller 等許多 controller,每個 Controller 都有不同職責,藉此維持各種資源的期望狀態。

從 Deployment 到 Pod Running 來看整個流程

現在把四大元件透過「部署三個 api-a 副本」的例子來說明整個流程:

https://ithelp.ithome.com.tw/upload/images/20260920/20124323WmvACdbbtT.png

  1. 工程師或 CI/CD 將 Deployment 送到 API Server。
  2. API Server 完成驗證與授權,將 Deployment 的期望狀態存到 etcd。
  3. Deployment Controller 觀察到新的 Deployment,建立 ReplicaSet;ReplicaSet Controller 再建立所需 Pod。
  4. Scheduler 為每個未排程 Pod 選定 Node,並將 binding 狀態透過 API Server 寫進 etcd。
  5. 目標 Node 的 kubelet 看到 Pod 已分派給自己,呼叫 Container Runtime 建立 container。
  6. kubelet 將 Pod 狀態透過 API Server 寫進 etcd,而 Controller 持續觀察是否仍符合期望副本數。

注意這不是一條單向的流程,第 6 步之後,Kubernetes 仍會持續確認目前的實際狀態是否符合我們在 Deployment 中宣告的目標,
如果 Pod 異常、被手動刪除、Node 不可用,或是我們修改了副本數,Controller 就會再次採取動作,
盡量把叢集恢復成原本要求的狀態。

結論

今天先認識了 Kubernetes Control Plane 的四大元件:

  • API Server 統一受理與保護操作
  • etcd 保存叢集狀態
  • Scheduler 為 Pod 選擇 Node
  • Controller Manager 則用持續的控制迴路讓實際狀態回到期望狀態。

下一篇會接著說明 Worker Node:kubelet、Container Runtime 如何接手已經被排程的 Pod,了解 container 是如何在 Worker Node 上運行。


上一篇
Day 4 - 本次微服務範例:Portal、Gateway、API 與 Stateless
下一篇
Day 6 - Worker Node 與 Pod 如何被啟動
系列文
初見 Kubernetes - 純網站後端開發踏入 K8s 世界的經驗分享9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言