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 |
| 新增 Taint | kubectl taint node NODE key=value:Effect |
| 移除 Taint | kubectl 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)。