Affinityの手法一覧
- nodeSelector:シンプルなNode Affinity機能
- Node Affinity:特定条件/特定条件以外のNode上だけ実行する
- Inter-Pod Affinity:特定のPodがいるドメイン(Node、ゾーンなど)上で実行する
- Inter-Pod Anti-Affinity:特定のPodがいないドメイン(Node、ゾーンなど)上で実行する
Node Affinity
Node Affinityを使うことで、さらなる柔軟なスケジューリングができるようになります。
その代わりに、設定方法もnodeSelectorより複雑です。
Node Affinityで以下のような設定が可能になります。
requiredDuringSchedulingIgnoredDuringExecution
:Pod配置の必須条件- 設定箇所:
spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution
- 設定箇所:
preferredDuringSchedulingIgnoredDuringExecution
:Pod配置の優先条件- 設定箇所:
spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
- 設定箇所:
NodeがrequiredDuringSchedulingIgnoredDuringExecution
の条件に合わない場合、絶対にスケジューリングされないようになっています。
一方で、NodeがpreferredDuringSchedulingIgnoredDuringExecution
の条件に合わない場合、他に合うNodeがなければ、スケジューリングされます。
また、Node Affinityも基本Nodeのlabelsを条件として使用します。
使用例
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 必須条件
nodeSelectorTerms: # 条件
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution: # 優先条件
- weight: 1 # 優先度
preference: # 条件
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
containers:
- name: with-node-affinity
image: k8s.gcr.io/pause:2.0
※公式ドキュメント例
requiredDuringSchedulingIgnoredDuringExecutionの条件
公式ドキュメントでは、以下のように述べています。
If you specify multiple nodeSelectorTerms associated with nodeAffinity types, then the pod can be scheduled onto a node if one of the nodeSelectorTerms can be satisfied.
If you specify multiple matchExpressions associated with nodeSelectorTerms, then the pod can be scheduled onto a node only if all matchExpressions is satisfied.
If you remove or change the label of the node where the pod is scheduled, the pod won’t be removed. In other words, the affinity selection works only at the time of scheduling the pod.
すなわち、以下のことを言っています。
- nodeSelectorTerms[].matchExpressionsがどれか1つでも合格したら、合格になる(OR処理)
- nodeSelectorTerms[].matchExpressions[]中の条件、どれか1つでも不合格したら、このmatchExpressionsが不合格になる(AND処理)
- node Affinityはスケジューリング時のみ処理する。スケジューリング済みのPodには関与しない
requiredDuringSchedulingIgnoredDuringExecution
例:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: # 必須条件
nodeSelectorTerms: # 条件
- matchExpressions: # OR
- key: cloud.google.com/gke-nodepool # AND
operator: In # In演算子
values:
- default-pool
- pool-1
- key: node-label-name # AND
operator: NotIn # NotIn演算子
values:
- label1
- label2
- label3
- key: foo # AND
operator: Exists # Exists演算子
- key: bar # AND
operator: NotExists # NotExits演算子
- key: node-lable-number # AND
operator: Gt # Gt演算子
value: 100
- key: node-lable-number # AND
operator: Lt # Lt演算子
value: 200
- matchExpressions: # OR
- key: cloud.google.com/gke-nodepool # AND
operator: In
values:
- default-pool
- key: kubernetes.io/os # AND
operator: In
values:
- linux
containers:
- name: nginx
image: nginx
matchExpressionsの演算子
上記の例では、matchExpressionsの下記の演算子も例として出しています。
- In:NodeのKeyラベルのValue値がValuesの中に含まれている
- NotIn:NodeのKeyラベルのValue値がValuesの中に含まない
- Exists:Nodeに指定のKeyラベルが存在する
- NotExists:Nodeに指定のKeyラベルが存在しない
- Gt:NodeのKeyラベルのValue値がValuesの値より大きい
- Lt:NodeのKeyラベルのValue値がValuesの値より小さい
preferredDuringSchedulingIgnoredDuringExecutionの条件
requiredDuringSchedulingIgnoredDuringExecution
はmatchExpressions[]しかないので、AND演算しかありません。
その代わり、優先度を決めるためのweight属性を持っています。
公式ドキュメントでは以下のように述べています。
The weight field in preferredDuringSchedulingIgnoredDuringExecution is in the range 1-100. For each node that meets all of the scheduling requirements (resource request, RequiredDuringScheduling affinity expressions, etc.), the scheduler will compute a sum by iterating through the elements of this field and adding “weight” to the sum if the node matches the corresponding MatchExpressions.
すなわち、Nodeが複数のmatchExpressionsにマッチする場合、weightが足し算され、最終的にscoreが一番高いNodeにスケジューリングされる仕組みとなります。
また、weightの付与範囲は1-100です。
preferredDuringSchedulingIgnoredDuringExecution
例:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 優先条件
- weight: 1 # 優先度
preference: # 条件
matchExpressions:
- key: cloud.google.com/gke-nodepool # AND
operator: In
values:
- default-pool
- pool-1
- key: foo # AND
operator: Exists
- weight: 3 # 優先度
preference: # 条件
matchExpressions:
- key: node-label-name # AND
operator: NotIn
values:
- label1
- label2
- label3
- key: bar # AND
operator: NotExists
containers:
- name: nginx
image: nginx
この例では、両方のpreference同時に満たしている場合、weightが 1+3 で4となります。
最後に
今回はNode Affinityについてご紹介しました。
ついでに、以前Workloadsで触れていたけど、説明できなかったmatchExpressionsについても補足しました。
すなわち、matchExpressionsはReplicaSetのSelectorでも使用可能です。
ここまで読んでいただいて、お疲れ様でした。
コメント