AWS企業帳號註冊 Kubernetes 架構解析:控制平面與工作節點的運作機制

亞馬遜雲AWS / 2026-10-21 15:52:21

# Kubernetes 架構解析:控制平面與工作節點的運作機制

當使用者搜尋這個主題時,通常不是想看概念性介紹,而是正在部署或維運 Kubernetes 叢集,想弄清楚:

- API Server、Scheduler、Controller Manager、etcd 之間到底怎麼配合
- Pod 為什麼建立了卻一直 Pending
- 工作節點為什麼顯示 NotReady
- kubelet、container runtime、kube-proxy 在節點上各自負責什麼
- 請求從 `kubectl apply` 到 Pod 真正跑起來,中間經過了哪些步驟

這篇文章以操作與排錯為主,直接拆解 Kubernetes 控制平面與工作節點的實際工作流程,並補充常見故障的檢查方法。

---

## 一、先從實際問題理解 Kubernetes 架構

在生產環境中,很多問題都能回到兩個層面:

1. **控制平面是否正常下發狀態**
2. **工作節點是否正常執行狀態**

你可以先把 Kubernetes 理解成一套「宣告目標狀態,再由各元件持續逼近這個狀態」的系統。

例如你提交一個 Deployment:

```bash
kubectl apply -f nginx-deploy.yaml
```

這條命令背後不是直接把容器跑起來,而是:

1. `kubectl` 把請求送到 **kube-apiserver**
2. API Server 驗證後,把資料寫進 **etcd**
3. **Controller Manager** 發現新的 Deployment,需要建立 ReplicaSet 和 Pod
4. **Scheduler** 為尚未指派節點的 Pod 選擇合適 Node
5. Node 上的 **kubelet** 監聽到有 Pod 被分配給自己
6. kubelet 呼叫 **container runtime** 拉取映像並啟動容器
7. **kube-proxy** 更新 Service 轉發規則,讓流量能進入 Pod

如果其中任何一段異常,就會出現常見故障,例如:

- `kubectl apply` 成功,但 Pod 不啟動
- Pod 一直 `Pending`
- Pod 已 Running,但 Service 無法存取
- Node 存活,但容器一直重建

所以理解 Kubernetes 架構,核心不在元件名稱,而在於**請求如何流轉、狀態如何同步、故障如何定位**。

---

## 二、控制平面由哪些元件組成,分別做什麼

控制平面主要負責接收請求、保存狀態、做調度決策、維持資源期望值。

### 1. kube-apiserver:所有操作的入口

在 Kubernetes 中,幾乎所有元件都透過 API Server 溝通。它是整個叢集的控制中樞。

你平時的這些操作:

```bash
kubectl get pods
kubectl describe node node-1
kubectl apply -f app.yaml
```

本質上都是在呼叫 API Server。

**它負責:**

- 驗證請求是否合法
- 做認證與授權
- 處理資源物件的新增、查詢、更新、刪除
- 將最終狀態寫入 etcd
- 提供 watch 機制給 scheduler、controller、kubelet 等元件監聽

**實際排查重點:**

如果你發現 `kubectl` 卡住、回傳 timeout、無法列出資源,優先檢查 API Server 是否正常。

AWS企業帳號註冊 ```bash
kubectl get componentstatuses
kubectl get --raw='/readyz?verbose'
```

若是使用 `kubeadm` 建置,也可以在控制平面節點查看靜態 Pod 狀態:

```bash
kubectl get pods -n kube-system
kubectl logs -n kube-system kube-apiserver-
```

常見異常:

- 憑證過期
- 與 etcd 通訊失敗
- API Server 所在節點 CPU 飆高
- admission webhook 響應過慢

---

### 2. etcd:叢集狀態資料庫

etcd 儲存 Kubernetes 的關鍵資料,例如:

- Node 資訊
- Pod、Deployment、Service 定義
- ConfigMap、Secret
- 調度結果
- Leader election 狀態

如果 etcd 出問題,叢集通常會直接失去控制能力。

**操作建議:**

- 正式環境至少做定期快照備份
- 不要把 etcd 和高負載業務混跑在資源緊張的節點上
- 確保磁碟延遲穩定,避免慢 I/O 影響整體控制面

**備份示例:**

```bash
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
```

AWS企業帳號註冊 **檢查健康狀態:**

```bash
ETCDCTL_API=3 etcdctl endpoint health \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
```

**常見問題:**

- 磁碟空間不足導致寫入失敗
- 節點時間不同步造成叢集異常
- 單節點 etcd 無容錯,節點損壞後無法恢復控制面

---

### 3. kube-scheduler:決定 Pod 應該落在哪個節點

Scheduler 不負責啟動容器,它只負責「選擇節點」。

當 Pod 尚未綁定 Node 時,Scheduler 會根據條件篩選可用節點,再從中挑選最合適的一台。

**調度時通常會考慮:**

- CPU / 記憶體是否足夠
- NodeSelector / NodeAffinity
- Taints / Tolerations
- Pod Affinity / Anti-Affinity
- 拓撲分散策略
- PVC 是否能在該節點或可用區掛載

**Pod Pending 的常見原因:**

1. 節點資源不足
2. PVC 未綁定成功
3. 節點被 taint,但 Pod 沒 toleration
4. 指定了不存在的 label
5. 多可用區場景中,存儲卷和節點不在同一區

**排查命令:**

```bash
kubectl describe pod
```

重點看 Events,例如:

- `0/3 nodes are available: 3 Insufficient cpu`
- `node(s) had untolerated taint`
- `pod has unbound immediate PersistentVolumeClaims`

---

### 4. kube-controller-manager:持續把實際狀態拉回期望狀態

Controller Manager 內含多種控制器,它們會持續觀察 API Server 中的資源變化,並採取修正動作。

常見控制器包括:

- Node Controller
- Deployment Controller
- ReplicaSet Controller
- Job Controller
- EndpointSlice Controller
- Namespace Controller

舉例來說,你定義:

```yaml
replicas: 3
```

如果目前只有 2 個 Pod 存活,ReplicaSet Controller 就會再補 1 個。

如果某個 Node 長時間失聯,Node Controller 會標記該節點異常,並在條件滿足時觸發 Pod 驅逐。

**常見維運現象:**

- Deployment 明明設了 3 副本,但只有 1 個
- 某節點故障後,Pod 很久沒有重建
- Job 卡在未完成狀態

這類問題多半要從控制器事件與資源關聯去看。

**建議排查:**

```bash
kubectl get deployment,rs,pods
kubectl describe deployment
kubectl describe rs
```

---

## 三、工作節點負責什麼,為什麼它是業務真正落地的位置

工作節點是真正執行 Pod 的地方。控制平面只做決策,業務容器、網路轉發、卷掛載都在 Worker Node 上發生。

### 1. kubelet:節點上的核心代理

kubelet 會持續從 API Server 監聽分配到本節點的 PodSpec,然後確保容器照著定義執行。

**它負責:**

- 接收 Pod 任務
- 呼叫 container runtime 啟動容器
- 掛載 Volume
- 執行 liveness/readiness/startup probe
- 回報節點與 Pod 狀態

如果 kubelet 異常,常見現象是:

- Node 變成 `NotReady`
- Pod 無法啟動
- 探針失敗後持續重建
- Secret / ConfigMap 未正確掛載

AWS企業帳號註冊 **檢查方式:**

在節點上執行:

```bash
systemctl status kubelet
journalctl -u kubelet -f
```

**高頻問題:**

- cgroup driver 不一致
- container runtime 未啟動
- 磁碟空間滿了
- 節點 DNS 配置有誤
- 憑證輪轉失敗

---

### 2. container runtime:真正拉鏡像與啟動容器

現在常見 runtime 是 containerd。它負責:

- 拉取映像
- 建立容器
- 啟動與停止容器
- 提供容器執行時資訊給 kubelet

**如果 Pod 啟動失敗,可優先檢查:**

- 映像是否存在
- 私有鏡像倉庫憑證是否正確
- 節點是否能解析 registry 網域
- container runtime 是否正常

**示例命令:**

```bash
crictl ps -a
crictl images
crictl logs
systemctl status containerd
```

**常見報錯:**

AWS企業帳號註冊 - `ImagePullBackOff`
- `ErrImagePull`
- `CreateContainerConfigError`
- `CrashLoopBackOff`

其中:

- `ImagePullBackOff` 多半是鏡像拉取失敗
- `CreateContainerConfigError` 常和 Secret、ConfigMap、環境變數配置有關
- `CrashLoopBackOff` 則代表容器啟動後很快退出,需要看應用日誌

---

### 3. kube-proxy:讓 Service 能把流量轉到正確 Pod

kube-proxy 主要處理 Service 對應的網路轉發規則,常見模式是 iptables 或 IPVS。

AWS企業帳號註冊 當你建立一個 Service:

```bash
kubectl expose deployment nginx --port=80 --target-port=8080
```

kube-proxy 會在節點上更新規則,讓流量能從 Service IP 轉到後端 Pod。

AWS企業帳號註冊 **如果 Service 無法連通,優先檢查:**

1. Pod 是否真的 Ready
2. Service selector 是否選到正確 Pod
3. Endpoint 是否存在
4. kube-proxy 是否正常
5. 節點防火牆是否擋住相關流量

**排查命令:**

```bash
kubectl get svc
kubectl get endpoints
kubectl get pod -o wide
kubectl logs -n kube-system
```

很多人以為 Service 建立完就一定能通,實際上只要 selector 寫錯,Endpoint 就會是空的。

---

## 四、從一次 Pod 建立流程,完整看控制平面與工作節點如何協作

下面用一次典型的建立流程來串起整體架構。

### 步驟 1:提交 YAML

```bash
kubectl apply -f deployment.yaml
```

`kubectl` 先把 YAML 送給 API Server。

### 步驟 2:API Server 驗證與入庫

API Server 完成:

- 身份驗證
- 權限校驗
- Schema 驗證
- Admission 控制
- 寫入 etcd

如果這一步失敗,通常會直接收到錯誤,例如:

- 權限不足
- YAML 欄位不合法
- webhook 拒絕請求

### 步驟 3:Controller 建立對應資源

Deployment Controller 發現有新 Deployment,建立 ReplicaSet;ReplicaSet 再建立 Pod。

### 步驟 4:Scheduler 為 Pod 選擇節點

如果 Pod 尚未分配節點,Scheduler 會做篩選與打分,然後把結果回寫到 API Server。

### 步驟 5:目標節點 kubelet 接收任務

被選中的 Node 上,kubelet 監聽到新的 PodSpec,開始準備:

- 建立 sandbox
- 配置網路
- 掛載卷
- 拉取映像
- 啟動容器

### 步驟 6:CNI 配置 Pod 網路

AWS企業帳號註冊 如果使用 Calico、Flannel、Cilium 等 CNI,這一步會為 Pod 分配 IP,配置路由與網路策略。

### 步驟 7:探針與狀態回報

kubelet 會根據探針結果決定容器是否健康、是否可對外提供流量。

### 步驟 8:Service 納入後端端點

只有當 Pod Ready 後,對應 Endpoint / EndpointSlice 才會更新,Service 才能把流量送進來。

這就是為什麼很多情況下:

- Pod 顯示 Running
- 但 Service 還是打不通

因為 **Running 不等於 Ready**。

---

## 五、控制平面與工作節點的部署實踐建議

這部分不是泛泛而談,而是部署時經常要做的選擇。

### 1. 單控制平面還是多控制平面

AWS企業帳號註冊 如果只是測試環境,單控制平面可以快速部署。

如果是正式環境,建議至少多控制平面節點,避免單點故障。常見方式:

- 3 台控制平面節點
- 前方放負載平衡器給 API Server
- etcd 採奇數節點部署

**注意:**

- 控制平面節點要預留足夠 CPU、記憶體、磁碟 IOPS
- 不要把高資源消耗業務 Pod 與控制面混跑
- 控制面節點的時間同步必須正常

### 2. 工作節點如何分組

實務上建議依業務類型分 Node Pool:

- 通用應用節點
- 高記憶體節點
- 計算型節點
- GPU 節點
- 系統服務專用節點

再透過:

- label
- taint
- affinity

控制 Pod 落點,避免混部造成干擾。

### 3. 地域與可用區選擇

如果叢集建在雲上,建立節點時要先考慮:

- 應用主要服務哪個地區的使用者
- 跨可用區流量是否增加延遲與成本
- 卷存儲是否支援跨區掛載
- 資料庫與應用是否應位於同可用區

**常見踩坑:**

- Pod 被調度到 A 區,但磁碟卷在 B 區,導致掛載失敗
- 跨區訪問資料庫,延遲偏高
- 對外流量經 NAT 或公網出口繞行,導致吞吐下降

---

## 六、常見故障場景與排查順序

這一部分最接近實際維運。

### 場景 1:Pod 一直 Pending

**排查順序:**

```bash
kubectl get pod -o wide
kubectl describe pod
kubectl get nodes
kubectl describe node
```

**重點看:**

- 資源是否不足
- 是否有 taint / toleration 問題
- PVC 是否成功綁定
- 調度條件是否過嚴
- 節點是否 Ready

---

### 場景 2:Pod 一直 CrashLoopBackOff

**排查順序:**

```bash
kubectl logs
kubectl logs --previous
kubectl describe pod
```

**重點看:**

- 應用啟動參數是否錯誤
- 環境變數是否缺失
- Secret / ConfigMap 是否載入成功
- 探針是否過嚴
- 依賴的資料庫、Redis、API 是否可連通

AWS企業帳號註冊 ---

### 場景 3:Node 變成 NotReady

**排查順序:**

在節點上:

```bash
systemctl status kubelet
systemctl status containerd
journalctl -u kubelet -n 200
df -h
free -m
```

**常見原因:**

- kubelet 掛掉
- container runtime 異常
- 節點磁碟滿了
- 網路插件故障
- API Server 無法連通

如果是雲伺服器,還要額外檢查:

- 安全組是否放通必要節點通訊端口
- 主機防火牆是否攔截
- 私網路由是否正常

AWS企業帳號註冊 ---

### 場景 4:Service 無法訪問 Pod

**排查順序:**

```bash
kubectl get svc
kubectl get endpoints
kubectl describe svc
kubectl get pod --show-labels
```

**重點看:**

- selector 是否匹配到 Pod
- Pod 是否 Ready
- targetPort 是否對應容器實際監聽端口
- NetworkPolicy 是否阻擋流量
- kube-proxy / CNI 是否異常

---

AWS企業帳號註冊 ### 場景 5:PVC 一直 Pending 或掛載失敗

**排查命令:**

```bash
kubectl get pvc,pv
kubectl describe pvc
kubectl describe pod
```

**常見原因:**

- StorageClass 設錯
- 動態供應器未正常運作
- 卷與節點不在同可用區
- 已超出雲硬碟配額
- 節點缺少掛載套件

AWS企業帳號註冊 ---

## 七、日常維運中應建立的檢查習慣

如果你要穩定維運 Kubernetes,建議固定檢查以下項目。

### 1. 檢查節點與系統 Pod 狀態

```bash
kubectl get nodes
kubectl get pods -n kube-system
```

重點不是只看 Running,而是看是否有頻繁重啟、是否有節點異常。

### 2. 檢查事件

```bash
kubectl get events -A --sort-by='.lastTimestamp'
```

很多調度、掛載、探針失敗問題,事件裡會直接給出線索。

### 3. 檢查資源壓力

```bash
kubectl top nodes
kubectl top pods -A
```

如果沒有 metrics-server,需要先部署。

### 4. 做 etcd 備份與測試恢復

備份不是只執行 snapshot,而是要確認恢復流程可行。

### 5. 升級前先驗證相容性

尤其是:

- CNI 插件版本
- Ingress Controller
- CSI 驅動
- admission webhook
- 自訂 CRD 與 operator

很多升級事故不是 Kubernetes 本身,而是周邊元件版本不匹配。

---

## 八、一個實用的理解方式:誰負責決策,誰負責執行

如果你總記不住 Kubernetes 架構,可以用這個方式理解:

### 控制平面負責

- 接收請求
- 儲存狀態
- 分析差異
- 做調度與控制決策

### 工作節點負責

- 啟動容器
- 配置網路
- 掛載存儲
- 回報運行狀態

也就是說:

- **控制平面管「應該怎麼樣」**
- **工作節點管「實際跑成什麼樣」**

當兩者不一致時,控制器會不斷嘗試修正,這就是 Kubernetes 能持續維持服務狀態的核心機制。

---

AWS企業帳號註冊 ## 九、結語:真正重要的是理解故障在哪一層發生

Kubernetes 架構看似複雜,但實際排查時可以簡化成幾個問題:

1. 請求有沒有成功進入 API Server
2. 資源狀態有沒有正確寫入 etcd
3. Controller 有沒有建立對應物件
4. Scheduler 有沒有成功選到節點
5. kubelet 有沒有在節點上執行 Pod
6. runtime 有沒有成功拉鏡像並啟動容器
7. 網路與 Service 有沒有把流量導到正確 Pod

只要沿著這條鏈路排查,大多數 Kubernetes 問題都能快速縮小範圍。

如果你正在實際操作叢集,最有用的方法不是背元件定義,而是結合下面這組命令反覆驗證:

AWS企業帳號註冊 ```bash
kubectl get pods -A -o wide
kubectl describe pod
kubectl get events -A --sort-by='.lastTimestamp'
kubectl get nodes
kubectl logs
journalctl -u kubelet -f
```

把控制平面看成「狀態管理中心」,把工作節點看成「任務執行現場」,你就能更容易理解 Kubernetes 的運作機制,也更容易在部署、調度、網路、存儲和故障排查中找到正確入口。

Telegram售前客服
客服ID
@cloudcup
联系
Telegram售后客服
客服ID
@yanhuacloud
联系