メモ。
以下の続きです。
k8s での Pod のスケジューリングについて確認した時のメモ(nodeSelector まで)
k8s での Pod のスケジューリングについて確認した時のメモ(NodeAffinity)
まとめ
- Inter-Pod Affinity/Anti-Affinity を使うことですでにノードで稼働している Pod のラベルに従って Pod がスケジュールされるノードを制限
- Inter-Pod Affinity では スケジュールの条件を指定 する(例: app=sample-app というラベルを持つ Pod と同じ AZ に Pod をスケジューリングしたい)
- Inter-Pod Anti-Affinity では スケジュールして欲しくない条件を指定 する(例: app=sample-app というラベルを持つ Pod と同じ AZ 以外に Pod をスケジューリングしたい)
- 条件は必須条件と優先条件がある
環境
以下の記事と同じ。
k8s での Pod のスケジューリングについて確認した時のメモ(nodeSelector まで)
Inter-Pod Affinity/Anti-Affinity
Inter-Pod Affinity/Anti-Affinity
nodeSelector や Nodeaffinity/Node Anti-Affinity は Node に設定されたラベル を利用してスケジューリングの制御を行う。
一方、Inter-Pod Affinity/Anti-Affinity は すでにNodeで稼働しているPodのラベルに従ってPodがスケジュールされるNodeを制限 する。
Node Affinityと同様に、Pod AffinityとPod Anti-Affinityにも必須条件と優先条件を示すものがある。
- requiredDuringSchedulingIgnoredDuringExecution:スケジューリングの必須要件
- preferredDuringSchedulingIgnoredDuringExecution:スケジューリング時の優先要件
検証
検証に利用する Node
以下の通り2つの Node が配置された環境を利用する。
デフォルトで付与されてるラベルは以下の通り
$k get nodes -o json|jq ".items[]|.metadata.labels"
{
"alpha.eksctl.io/cluster-name": "test-cluster",
"alpha.eksctl.io/instance-id": "i-0282a2ef8130cbff1",
"alpha.eksctl.io/nodegroup-name": "standard-workers",
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/instance-type": "t3.medium",
"beta.kubernetes.io/os": "linux",
"failure-domain.beta.kubernetes.io/region": "ap-northeast-1",
"failure-domain.beta.kubernetes.io/zone": "ap-northeast-1c",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "ip-192-168-48-33.ap-northeast-1.compute.internal",
"kubernetes.io/os": "linux"
}
{
"alpha.eksctl.io/cluster-name": "test-cluster",
"alpha.eksctl.io/instance-id": "i-03a676eba6a541672",
"alpha.eksctl.io/nodegroup-name": "standard-workers",
"beta.kubernetes.io/arch": "amd64",
"beta.kubernetes.io/instance-type": "t3.medium",
"beta.kubernetes.io/os": "linux",
"failure-domain.beta.kubernetes.io/region": "ap-northeast-1",
"failure-domain.beta.kubernetes.io/zone": "ap-northeast-1a",
"kubernetes.io/arch": "amd64",
"kubernetes.io/hostname": "ip-192-168-74-169.ap-northeast-1.compute.internal",
"kubernetes.io/os": "linux"
}
上記の通り、Node は ap-northeast-1c 及び ap-northeast-1d に起動されている。
やってみる(Inter-Pod Affinity)
まずは以下のような app = sample
というラベルが付与された Pod を作成する。
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
app: sample-app
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
$k apply -f web.yaml
$k get pods -l app=sample-app -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
static-web 1/1 Running 0 87s 192.168.60.7 ip-192-168-48-33.
ap-northeast-1.compute.internal <none> <none>
ap-northeast-1c のインスタンス上に Pod が起動された事が分かる。
次に app=sample-app のラベルを持つ Pod と同じノードにスケジュールする 為に Inter-Pod Affinity を使う。
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- sample-app
topologyKey: kubernetes.io/hostname
containers:
- name: with-pod-affinity
image: k8s.gcr.io/pause:2.0
$k apply -f pod-with-pod-affinity.yaml
pod/with-pod-affinity created
$k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
static-web 1/1 Running 0 7m21s 192.168.60.7 ip-192-168-48-33.ap-northeast-1.compute.internal <none> <none>
with-pod-affinity 1/1 Running 0 12s 192.168.34.56 ip-192-168-48-33.ap-northeast-1.compute.internal <none> <none>
同じ先程起動した Pod と同じノード上に起動する事を確認出来た。
今回 topologyKey
が kubernetes.io/hostname
で合ったため、同じノード上に起動した。
もし値が failure-domain.beta.kubernetes.io/zone
となる場合、app=sample-app のラベルを持つ Pod と同じ AZ にスケジュールする という条件でスケジューリングする。
一応試す
# 削除
$k delete pod with-pod-affinity
pod "with-pod-affinity" deleted
# topologyKey を failure-domain.beta.kubernetes.io/zone に変える
$vi pod-with-pod-affinity.yaml
$k apply -f pod-with-pod-affinity.yaml
pod/with-pod-affinity created
$k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
static-web 1/1 Running 0 12m 192.168.60.7 ip-192-168-48-33.ap-northeast-1.compute.internal <none> <none>
with-pod-affinity 1/1 Running 0 4s 192.168.34.56 ip-192-168-48-33.ap-northeast-1.compute.internal <none> <none>
今回の検証では各 AZ にノードが一つしかないので、Pod と同じノード上に起動している。
ただし、こちらのマニュフェストの場合、Pod が起動してる AZ に他のノードがある場合、こちらへの起動も許容する。
逆に最初の kubernetes.io/hostname
の場合、上記は許容せず、同じノード上への起動とさせる(その場合、Pod で複数コンテナを定義した方が良いのではという気がしなくもない...)
やってみる(Inter-Pod Anti-Affinity)
今度は Inter-Pod Anti-Affinity を使ってみる
先程のマニュフェストを変えて app=sample-app のラベルを持つ Pod と同じ AZ にスケジューリングしない ようにする
具体的には podAffinity
を podAntiAffinity
に変えた
これを使う。
# 削除
$k delete pod with-pod-affinity
pod "with-pod-affinity" deleted
# podAffinity を podAntiAffinity にする
$vi pod-with-pod-anti-affinity.yaml
# diff でも確認
$ diff pod-with-pod-affinity.yaml pod-with-pod-anti-affinity.yaml
7c7
< podAffinity:
---
> podAntiAffinity:
$k apply -f pod-with-pod-affinity.yaml
pod/with-pod-affinity created
$k get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
static-web 1/1 Running 0 35m 192.168.60.7 ip-192-168-48-33.ap-northeast-1.compute.internal <none> <none>
with-pod-affinity 1/1 Running 0 3m31s 192.168.71.173 ip-192-168-74-169.ap-northeast-1.compute.internal <none> <none>
別 AZ で動作するノード上に Pod が起動する事が確認出来た。