Chuyển đến nội dung chính

第5課:排程、Taints & Affinity

nodeSelector、nodeAffinity、podAffinity/podAntiAffinity。 Taints & Tolerations。手動排程與 CKA 考試的排程問題。

Kubernetes 排程機制 — nodeAffinity、Taints & Tolerations

1. nodeSelector

# 為節點新增標籤
kubectl label node worker1 disktype=ssd

# 在 Pod 中使用 nodeSelector
apiVersion: v1
kind: Pod
metadata:
  name: ssd-pod
spec:
  nodeSelector:
    disktype: ssd    # 排程到有 ssd 標籤的節點
  containers:
  - name: app
    image: nginx

2. Node Affinity

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  # 必要條件
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values: ["ssd", "nvme"]
      preferredDuringSchedulingIgnoredDuringExecution:  # 偏好條件
      - weight: 80
        preference:
          matchExpressions:
          - key: zone
            operator: In
            values: ["zone-a"]
類型行為
required...IgnoredDuring...沒有符合條件的節點時,Pod 維持 Pending
preferred...IgnoredDuring...偏好但非必要,沒有符合的節點仍可排程到其他節點

3. Taints & Tolerations

# 為節點新增 Taint
kubectl taint nodes worker1 env=production:NoSchedule

# 只有具備 Toleration 的 Pod 才能排程
spec:
  tolerations:
  - key: "env"
    operator: "Equal"
    value: "production"
    effect: "NoSchedule"

# 移除 Taint(末尾加 "-")
kubectl taint nodes worker1 env=production:NoSchedule-
Effect行為
NoSchedule不排程沒有 Toleration 的新 Pod
PreferNoSchedule盡量避免排程,但沒有其他選擇時仍允許
NoExecute現有的 Pod 如果沒有 Toleration 也會被驅逐

考試重點:Taints & Tolerations 和 Node Affinity 的差異:Taint 是節點端的「拒絕」,Affinity 是 Pod 端的「偏好」。兩者結合可以實現「特定 Pod 只在特定節點上運行」。

4. Pod Affinity / Anti-Affinity

spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app: web
        topologyKey: kubernetes.io/hostname  # 不放在同一節點

    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: cache
          topologyKey: kubernetes.io/hostname  # 跟 cache 放在同一節點

5. 速查表

任務指令
新增節點標籤kubectl label node NODE key=value
新增 Taintkubectl taint node NODE key=value:Effect
移除 Taintkubectl taint node NODE key=value:Effect-
查看節點標籤kubectl get nodes --show-labels
查看 Pod 排程位置kubectl get pod -o wide

6. 練習題

Q1:節點 worker1 有 Taint "gpu=true:NoSchedule"。沒有 Toleration 的新 Pod 會排程到這個節點嗎?

  • A) 會,Taint 會被忽略
  • B) 不會,Pod 會排程到其他節點或維持 Pending ✓
  • C) 會,但效能會降低
  • D) Taint 不影響新 Pod

解析:NoSchedule 的 Taint 會拒絕沒有對應 Toleration 的 Pod 排程。Pod 需要新增 Toleration 或排程到其他節點。

Q2:requiredDuringSchedulingIgnoredDuringExecution 的 nodeAffinity,如果沒有符合條件的節點,Pod 會怎樣?

  • A) 隨機排程到某個節點
  • B) Pod 維持 Pending 狀態,等待符合條件的節點可用 ✓
  • C) Pod 會自動被刪除
  • D) Pod 會因錯誤失敗

解析:"required" 是必要條件。沒有符合的節點時 Pod 會維持 Pending。使用 "preferred" 則條件是偏好但非必要。

Q3:使用 podAntiAffinity 配合 topologyKey: kubernetes.io/hostname 的目的是?

  • A) 將 Pod 放在同一個區域
  • B) 將相同標籤的 Pod 分散到不同節點 ✓
  • C) 限制 Pod 到特定可用區
  • D) 將 Pod 集中到同一節點

解析:podAntiAffinity 配合 topologyKey: kubernetes.io/hostname 確保匹配的 Pod 不會放在同一節點。這是實現高可用性的常見模式(例:Web 副本分散到節點 B、C、D)。