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) はい、ただしPerformanceが低下する
- 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に分散配置)。