広告

kubernetes – Inter-Pod Affinity/Anti-Affinity

infrastructure as code

Affinityの手法一覧

  • nodeSelector:シンプルなNode Affinity機能
  • Node Affinity:特定条件/特定条件以外のNode上だけ実行する
  • Inter-Pod Affinity:特定のPodがいるドメイン(Node、ゾーンなど)上で実行する
  • Inter-Pod Anti-Affinity:特定のPodがいないドメイン(Node、ゾーンなど)上で実行する

Inter-Pod Affinity/Anti-Affinity

公式ドキュメントでは以下のように述べています。

Inter-Pod Affinity と Anti-Affinityは、Nodeのラベルではなく、既にNode上で稼働しているPodのラベルに従って、スケジューリングされるNodeを制限します。

Inter-Pod Affinity/Anti-Affinityでは、以下の2ステップでスケジューリング先のNodeを絞ります。

  1. labelSelectorの条件に満たすPodを見つけ出し、そのPodがホストしているNodeを洗い出す
  2. topologyKeyでNodeのラベルを指定し、1.で洗い出したNodeのこのラベルと一致するすべてのNodeがスケジューリング先の対象とする

上記の内容から、Inter-Pod Affinity/Anti-Affinityを使用する前提条件としては、K8sクラスタにすでにPodがスケジューリングされていることですね。

また、Inter-Pod Affinity/Anti-AffinityもNode Affinityと同じ、Pod配置の必須条件と優先条件設定を持っています。

  • requiredDuringSchedulingIgnoredDuringExecution
  • preferredDuringSchedulingIgnoredDuringExecution
    ※この部分については、Node Affinityをご参照ください。

Inter-Pod Affinity

Inter-Pod Affinityでは、条件に合うNodeがスケジューリング先対象とします。

Inter-Pod Affinity例

apiVersion: v1
kind: Pod
metadata:
  name: pod-affinity
spec:
  affinity:
    podAffinity:  # Inter-Pod Affinity
      requiredDuringSchedulingIgnoredDuringExecution:  # 必須条件
      - labelSelector:  # ステップ1:PodのラベルでNodeを絞る
          matchExpressions:  # Podのラベル条件
          - key: label1
            operator: In
            values:
            - foo
        topologyKey: failure-domain.beta.kubernetes.io/zone  # ステップ2:絞り出したNodeと同じゾーンのすべてのNodeをスケジューリング先対象とする
      - labelSelector:  # 複数の条件の条件も定義可能
          matchExpressions:
          - key: label2
            operator: In
            values:
            - bar
        topologyKey: failure-domain.beta.kubernetes.io/zone  # このラベルは同じゾーンを意味する
      preferredDuringSchedulingIgnoredDuringExecution:  # 優先条件
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: label3
              operator: In
              values:
              - app
          topologyKey: kubernetes.io/hostname  # このラベルは同じホスト名を意味する
  containers:
  - name: nginx
    image: nginx

この例では、以下のような絞り条件になります。

  • ラベルlabel1のValueがfooのPodが配置されているNodeと、同じZoneにあるノードにスケジューリング
  • または(OR)、ラベルlabel2のValueがbarのPodが配置されているNodeと、同じZoneにあるノードにスケジューリング
  • 両方条件満たしている場合、ラベルlabel3のValueがappのPodが配置されているNodeが優先される

Inter-Pod Anti-Affinity

Inter-Pod Anti-Affinityは逆で、条件に合うNodeがスケジューリング先対象としません。

下記かたはInter-Pod Affinityとほぼ同じで、spec.affinity.podAffinityspec.affinity.podAntiAffinityに変更するだけで、真逆のスケジューリング条件を付けれます。

Inter-Pod Anti-Affinity例

apiVersion: v1
kind: Pod
metadata:
  name: pod-anti-affinity
spec:
  affinity:
    podAntiAffinity:  # Inter-Pod Anti-Affinity
      requiredDuringSchedulingIgnoredDuringExecution:  # 必須条件
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - foo
            - bar
        topologyKey: kubernetes.io/hostname  # 同じホスト名 → 同じNode
  containers:
  - name: nginx
    image: nginx

この例では、ラベルappのValueがfooかbarのPodが配置されているNodeにスケジューリングしません

注意点

公式ドキュメントでは、以下の備考が書かれています。

Inter-Pod AffinityとAnti-Affinityは、大規模なクラスター上で使用する際にスケジューリングを非常に遅くする恐れのある多くの処理を要します。 そのため、数百台以上のNodeから成るクラスターでは使用することを推奨されません。

そんな大規模の環境を触る機会はめったにないかと思いますが、念のため頭のどこかに入れといたほうがいいかもしれません。

また、Inter-Pod Affinity/Anti-AffinityもNode Affinityと同じく、スケジューリング時のみ処理する。スケジューリング済みのPodは関与しない

最後に

Inter-Pod Affinity/Anti-Affinityは以前ご紹介したNode Affinityと併用することも可能です。
どこにスケジューリングするかは要件に応じて自由にコントロールしましょう。

ここまで読んでいただいて、お疲れ様でした。

コメント

タイトルとURLをコピーしました