KubernetesのPod分散手法一覧 (Affinity/Taint/Tolerations/PTSC/Descheduler等)

2024/07/17に公開

Kubernetes上でPodのNode分散配置に使用できる機能一覧をまとめます。

※注意
2024/07/17時点で、Perplexity Pro(GPT4-Omni)の出力結果を簡単にまとめました。内容は自分が確認した限り正確でした。具体例の追記含めて後日正筆します。

Pod分散配置方法の一覧表

機能 特徴 ユースケース メリット デメリット
nodeSelector 特定のラベルを持つノードにのみPodをスケジューリングする単純な方法。 特定のノードにPodを配置したい場合。 設定が簡単で理解しやすい。 柔軟性が低く、複雑な条件を指定できない。
Node Affinity nodeSelectorよりも柔軟で、複雑な条件を指定できる。 特定の条件を満たすノードにPodを配置したい場合。 柔軟な条件指定が可能。 設定が複雑で、理解に時間がかかる場合がある。
Pod Affinity 特定のPodが存在するノードにPodをスケジューリングする。 特定のPodが存在するノードに新しいPodを配置したい場合。 特定のPodが存在するノードに集約できる。 他のPodの存在に依存するため、スケジューリングが制約される場合がある。
Pod Anti-Affinity 特定のPodが存在しないノードにPodをスケジューリングする。 高可用性を確保するために、特定のPodが存在しないノードに新しいPodを配置したい場合。 特定のPodが存在しないノードに分散できる。 他のPodの存在に依存するため、スケジューリングが制約される場合がある。
Taints / Tolerations Taintsは特定のノードにPodをスケジューリングしないための設定、Tolerationsはその逆。 特定のノードに特定のPodしかスケジューリングされないようにしたい場合。 ノードのリソースを特定のPodに専用化できる。 設定が複雑で、誤設定が発生しやすい。
Pod Topology Spread Constraints クラスター内でPodが均等に分散されるようにするための設定。 高可用性を確保するために、Podをクラスター内で均等に分散させたい場合。 クラスター全体でリソースの効率的な利用が可能。 設定が複雑で、理解に時間がかかる場合がある。
Descheduler クラスター内のPodの再配置を行うツール。
evictを行うのみで再配置はKubernetes上の設定に準拠するため注意!
ノードのリソース使用率のバランスを取りたい場合や、特定のポリシーに基づいてPodを再配置したい場合。 クラスターのリソース使用率を最適化できる。 設定や運用が複雑で、適切なタイミングでの実行が必要。

nodeSelector

https://kubernetes.io/ja/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector
nodeSelectorは、特定のノードにPodをスケジューリングするための最もシンプルな方法。

PodのspecにnodeSelectorフィールドを追加し、ターゲットノードが持つべきラベルを指定。指定されたラベルを持つノードにのみPodがスケジューリングされる。

サンプル:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: main
    image: nginx
  nodeSelector:
    disktype: ssd

Node Affinity

https://kubernetes.io/ja/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity
Node Affinityは、nodeSelectorよりも柔軟で強力なノード選択方法。

requiredDuringSchedulingIgnoredDuringExecution(必須)とpreferredDuringSchedulingIgnoredDuringExecution(優先)の2種類のルールを使用し、強制力を分けながらスケジューリングできる。

サンプル:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: main
    image: nginx
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd

Pod Affinity / Anti-Affinity

https://kubernetes.io/ja/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity
Pod Affinityは、特定のPodが存在するノードにPodをスケジューリング。
Pod Anti-Affinityは特定のPodが存在しないノードにPodをスケジューリング。

Node Affinityと同様、requiredDuringSchedulingIgnoredDuringExecution(必須)とpreferredDuringSchedulingIgnoredDuringExecution(優先)の2種類のルールを使用し、強制力を分けながらスケジューリングできる。

サンプル:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: main
    image: nginx
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - frontend
        topologyKey: "kubernetes.io/hostname"

Taints / Tolerations

https://kubernetes.io/ja/docs/concepts/scheduling-eviction/taint-and-toleration/
Taintsは特定のノードにPodをスケジューリングしないための設定。
Tolerationsは逆に、特定のノードにPodをスケジューリングするための許容設定。
特定のノードに特定のPodしかスケジューリングされないように制御可能。

サンプル:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: main
    image: nginx
  tolerations:
  - key: "key1"
    operator: "Equal"
    value: "value1"
    effect: "NoSchedule"

Pod Topology Spread Constraints

https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/
Pod Topology Spread Constraintsは、Podがクラスター内で均等に分散されるようにするための設定。特定のゾーンやノードにPodが集中しないように制御可能。

サンプル:

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: main
    image: nginx
  topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: "kubernetes.io/hostname"
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: my-app

Descheduler

https://github.com/kubernetes-sigs/descheduler
Deschedulerは、クラスター内のPodの再配置を行うためのツール。

※注意

  • evictを行うのみでevict後の再配置先はKubernetes上の設定に準拠する
  • 標準機能ではないため、Helm等で追加インストールが必要。

ノードのリソース使用率のバランスを取ったり、特定のポリシーに基づいてPodを再配置が可能。
起動後のPodに対してもルールに沿って再配置を促したり、複数のStrategyに沿って分散配置を定義できる。
外部ツールのHelm chart内でaffinity/nodeSelectorが利用できない時に活用できる。

https://sreake.com/blog/kubernetes-descheduler/

サンプル:

apiVersion: "descheduler/v1alpha1"
kind: "DeschedulerPolicy"
strategies:
  RemoveDuplicates:
    enabled: true
    params:
      removeDuplicates:
        excludeOwnerKinds:
        - "Job"
        namespaces:
          include:
          - "namespace1"
          - "namespace2"

参考

Discussion