🗂

KubernetesにおけるNode・Pod配置制御の手法まとめ

に公開

概要

Kubernetesには複数のスケジューリング制御方法がある。本記事では、nodeSelector、Node Affinity、Pod Affinity、Taints/Tolerations、Pod Topology Spread Constraintsについて、それぞれの特徴と使い分けについて記述する。

1. nodeSelector

最もシンプルなノード選択の仕組み。ノードのラベルに基づいて、Podを配置するノードを指定する。

設定例

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeSelector:
    disktype: ssd

特徴

  • シンプルで分かりやすい
  • 柔軟性に欠ける(完全一致のみ)
  • 後述のNode Affinityのほうがより柔軟

2. Node Affinity

より柔軟なノード選択の仕組み。

設定例

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd
            - nvme
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-label
            operator: In
            values:
            - another-value

特徴

  • より柔軟な条件指定が可能(In、NotIn、Exists、DoesNotExist等)
  • 必須条件(required)と優先条件(preferred)の指定が可能
  • 重み付けによる優先度の調整が可能

3. Pod Affinity

Pod間の関係に基づいてスケジューリングを制御する仕組み。

設定例

apiVersion: v1
kind: Pod
metadata:
  name: web-pod
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - cache
        topologyKey: kubernetes.io/hostname
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
              - web
          topologyKey: kubernetes.io/hostname

特徴

  • Pod間のAffinityやAntiAffinityを制御可能
  • トポロジーキーによる配置範囲の制御が可能
  • パフォーマンスや可用性の最適化に有効

4. Taints/Tolerations

ノードに対する制約とその許容を制御する仕組み。

設定例

# ノードへのTaint設定
kubectl taint nodes node1 key=value:NoSchedule

# Pod側のToleration設定
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"

特徴

  • ノードを特定の用途に制限可能
  • 問題のあるノードの隔離に有効
  • 3種類のeffect(NoSchedule、PreferNoSchedule、NoExecute)を使用可能

5. Pod Topology Spread Constraints

クラスター全体でのPodの分散を制御する仕組み。

設定例

apiVersion: v1
kind: Pod
metadata:
  name: web-server
spec:
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: web

特徴

  • クラスター全体でのPod分散を制御可能
  • トポロジードメイン(ノード、ゾーン、リージョン等)での分散が可能
  • maxSkewによる分散の度合いを制御可能

使い分けの指針

  1. シンプルなノード選択

    • nodeSelector: 単純な条件での選択
    • Node Affinity: より複雑な条件や優先度が必要な場合
  2. Pod間の関係制御

    • Pod Affinity: 特定のPod同士の配置関係が重要な場合
    • Pod AntiAffinity: 特定のPod同士の分散が必要な場合
  3. ノードの用途制限

    • Taints/Tolerations: 特定のノードを特定の用途に制限したい場合
  4. 全体的な分散制御

    • Pod Topology Spread Constraints: クラスター全体でのPod分散が必要な場合

実践的な組み合わせ例

高可用性アプリケーションの例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: high-availability-app
spec:
  template:
    spec:
      # ノード要件の指定
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-type
                operator: In
                values:
                - production
      
      # Pod分散の制御
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: kubernetes.io/hostname
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: web
      
      # 同一アプリケーションの分散
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: web
            topologyKey: kubernetes.io/hostname

まとめ

複数のスケジューリング制御機能を適切に組み合わせることで、より細かい制御が可能となる。運用要件を明確に理解し、それに合わせた最適な制御方法を選択することが重要。また、複雑な設定は運用コストの増加につながる可能性があるため、必要最小限の制御にとどめることも検討すべき。

Discussion