iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
Kubernetes

Kubernetes學習心得分享系列 第 6

Day 06:【排程】 節點分配與手動調度控制

  • 分享至 

  • xImage
  •  

前言

寫這篇想要分享的重點:
深入剖析 Kubernetes 調度器(Scheduler)的背後運作機制,並針對惡夢般的 Pending 狀態提供一套搭配真實 Terminal 畫面的系統化除錯;同時掌握透過 nodeName 以及 Labels / Selectors 進行手動調度與分配的作法。

這篇想要講什麼:

  1. Scheduler 如何運作?從 Filtering 到 Scoring 的選定過程。
  2. debug惡夢 Pending:透過 Terminal 畫面與 kubectl describe 快速找到資源不足、標籤不符或 nodeName 綁定錯誤的bug。
  3. 手動指定節點:nodeName 強制綁定 vs. 透過 Labels 與 NodeSelector 進行彈性調度。
  4. Labels、Selectors 與 Annotations 的概念釐清與進階篩選。

為何要寫這篇:
前面幾天我們學會了如何寫 Pod 的 YAML。但在真實的多節點叢集中,當你一口氣部署了數十個 Pod,K8s 究竟是怎麼決定要把哪一個 Pod 放到哪一台機器的?當 Pod 遲遲無法啟動、卡 Pending 時,光看 YAML 往往找不出問題,必須靠SOP才能抓出兇手。這篇將帶你揭開節點調度的真相!


名詞對應

Scheduler: 調度器 / 排程器
Filtering / Predicates: 過濾階段 / 預選條件
Scoring / Priorities: 評分階段 / 優選條件
NodeSelector: 節點選擇器
Annotations: 註釋 / 附加標註資訊


1. Scheduler 運作機制與 Pending 狀態

當我們建立 Pod 時,若未指定特定的 Worker Node,調度器(Scheduler)便會介入尋找最合適的執行目標。

調度器的兩大核心步驟

  • 過濾階段(Filtering):檢查所有節點是否符合 Pod 的基本條件(例如資源是否充足),不合格的節點會直接被刷掉。

  • 評分階段(Scoring):針對通過過濾的節點進行評分,選出最優質的節點來調度。

SOP:當 Pod 卡在 Pending 該怎麼辦?

當 Pod 遲遲無法啟動、卡在 Pending 狀態時,執行 kubectl explain pod.spec 這類查詢指令是看不出原因的。這時必須透過除錯步驟來找出問題原因:

步驟一:檢查 Pod 狀態與 Events

使用 kubectl describe pod <pod-name> 指令,將畫面直接拉到最底部的 Events 區段,這是鎖定問題的關鍵:

kubectl describe pod frontend-app

Terminal 畫面與錯誤範例:

Name:         frontend-app
Namespace:    default
Priority:     0
Node:         <none>
Labels:       app=frontend
Annotations:  <none>
Status:       Pending
IP:           
IPs:          <none>
Containers:
  app:
    Image:   nginx:latest
    ...
Conditions:
  Type           Status
  PodScheduled   False 
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  12s   default-scheduler  0/3 nodes are available: 3 Insufficient cpu.

從上面的 Terminal 輸出可以清楚看出原因:

  • 0/3 nodes are available: 3 Insufficient cpu:代表叢集中的 3 台節點資源已經空空,沒有足夠的 CPU 容納這個 Pod。

  • 其他常見訊息還包含 node(s) didn't match Pod's node affinity / selector(找不到符合標籤的節點)或 node(s) had untolerated taint(被節點污點擋下)。

步驟二:確認是否有指定 nodeName

如果一個 Pod 從頭到尾都沒有被 Scheduler 處理,很可能是因為它在 YAML 中被手動指定了錯誤的 nodeName,導致調度器直接略過不處理。

Terminal 範例(檢查 YAML):

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeName: non-existent-node  # ⚠️ 寫錯或指派了一台不存在的機器名稱
  containers:
  - name: nginx
    image: nginx

當你執行 kubectl describe pod nginx 時,會發現 Node: 欄位直接被寫錯指到不存在的機器,導致 Pod 永遠無法被調度:

Name:         nginx
Namespace:    default
Node:         non-existent-node/
Status:       Pending
...
Events:
  <none>  # 因為有指定 nodeName,Scheduler 會直接忽略它,甚至連 FailedScheduling 事件都不會產生!

步驟三:重新建立 Pod 的排除錯誤方法

在 K8s 中,你無法直接將執行中的 Pod 從一個節點移動到另一個節點,因為運行中的行程是直接由各節點的 kubelet 來管控的。若要更換節點或修改如 nodeName 等無法動態調整的欄位,只能將 Pod 刪除,並在正確的環境中重新建立。

Terminal 範例(使用 --force 強制替換重建):

$ kubectl replace --force -f nginx.yaml
pod "nginx" deleted
pod/nginx replaced

透過 --force 參數,系統會幫你強制執行刪除並用新的 YAML 內容重新長出一顆 Pod,讓排程重新啟動。


2. Labels、Selectors 與 Annotations 應用

Labels 與 Selectors 可以讓我們輕鬆對各種 K8s 物件進行分組與篩選。

  • 基本篩選:使用 --selector 過濾特定標籤。
# 查詢目前命名空間下的所有 Kubernetes 物件 (包含 Pods, Services, Deployments 等)
kubectl get all \
  # 使用 --selector (可簡寫為 -l) 進行多條件複合篩選
  --selector \
    env=prod, \      # 條件一:環境必須是生產環境 (Production)
    bu=finance, \    # 條件二:業務單位必須是財務部門 (Finance)
    tier=frontend    # 條件三:架構層級必須是前端 (Frontend)
    # 註:多個條件以逗號分隔代表「AND」邏輯,必須同時符合以上三個條件的物件才會被顯示
  • ReplicaSet 與 Services 中的 Labels:如果覺得可能有多個 Pod 擁有相同的 Label 但功能不同,可以指定多個 Labels 來確保正確對應。

  • Annotations:與用來分組和選擇的 Labels 不同,Annotations 是用來記錄像是工具版本、建置資訊、聯絡電話或email等供參考與整合用途的詳細資料。


3. 手動指定節點:nodeName 與 NodeSelector

除了依靠調度器自動選擇外,我們也可以透過手動方式將 Pod 指到特定的節點上。

  • NodeSelector 運作方式
    先為節點貼上標籤:
# 為特定的 K8s Worker 節點新增自定義標籤,標記該節點具備 SSD 硬碟
kubectl label nodes <your-node-name> disktype=ssd
# 指令拆解:
# - kubectl label nodes:指定要對節點(Node)進行標籤操作的指令
# - <your-node-name>:你想要貼標籤的目標節點名稱(可透過 kubectl get nodes 查詢)
# - disktype=ssd:以 Key=Value 形式定義的標籤內容,供後續 Pod 的 nodeSelector 進行比對

接著在 Pod 的 YAML 規格中加入 nodeSelector,調度器便會利用這些鍵值對來找出正確的節點。不過需要注意的是,nodeSelector 只能進行簡單的 Key-Value 比對,無法直接做到像 "OR" 邏輯或範圍判斷的多條件選擇。


結語

  • 本篇總結:
    說明了 Scheduler 從過濾到評分的運作流程,透過Terminal 畫面與 kubectl describe 系統化確認 Pending 狀態(包含 Insufficient 資源與 nodeName 綁定錯誤)的指令技巧, 一步一步除錯,並掌握透過 Labels、Selectors 與 NodeSelector 進行手動與條件式調度的應用。

  • 下一篇預告:
    掌握了基礎的節點分配與選擇器後,明天 Day 07:【調度】進階節點親和性與污點容忍機制 將帶大家解鎖更進階的 Node Affinity(支援 InNotInExists 等複雜條件)以及 Taints & Tolerations(污點與容忍機制),教你如何像管理 VIP 專區一樣,把核心服務綁定在特定的硬體規格上,千萬別錯過!

Takeaway

  • 排程機制:Scheduler 透過 Filtering 淘汰不合格節點,再經由 Scoring 挑選出最佳的 Worker Node。
  • Pending 除錯法:善用 kubectl describe pod 檢查底部 Events 畫面,透過 Insufficient 或配對錯誤找出資源或標籤問題。
  • nodeName 陷阱:若直接在 YAML 寫錯 nodeName 且機器不存在,Scheduler 會直接略過,導致 Events 空白,必須特別注意。
  • Pod修改限制:若執行中的 Pod 無法直接修改,則須透過刪除並重新建立(如 kubectl replace --force)來觸發重新排程。
  • 標籤與註解的區別:Labels 用於分組與物件選擇,而 Annotations 則用於記錄版本與聯絡資訊等補充細節。

上一篇
Day 05:【指令】聲明式 vs 命令式:Imperative vs Declarative 操作
系列文
Kubernetes學習心得分享6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言