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動作
NoScheduleTolerationなしの新しい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に分散配置)。