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を絞ります。
- labelSelectorの条件に満たすPodを見つけ出し、そのPodがホストしているNodeを洗い出す
- 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.podAffinity
→spec.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と併用することも可能です。
どこにスケジューリングするかは要件に応じて自由にコントロールしましょう。
ここまで読んでいただいて、お疲れ様でした。
コメント