これは何
NodeSelectorの動きの検証
検証リストと結果
- NodeSelectorでPodを特定のNodeに配置した後でNodeのラベルを消す
- ⇒何も起こらない
- NodeSelectorでPodを特定のNodeに配置した後でPodのNodeSelectorを更新する
- ⇒Podが再作成されて反映される
- NodeSelectorで同時に満たすことが可能な複数のラベルを設定する
- ⇒ちゃんと複数のラベルの条件にマッチしたNodeにスケジューリングされる
- NodeSelectorで同時に満たすことが不可能な複数のラベルを設定する
- ⇒条件にマッチするNodeが無いとしてPendingになる
tl;dr
-
Node側のラベルについては、恐らくkube-shcedulerはスケジューリング時にしか見ていない
- そのため、スケジューリング後にNodeのラベルを変更しても何も起こらない
- 他のNodeにラベルを貼っても、そっちに移動したりはしない
- この問題の解決はdeschedulerが必要
-
DeploymentやPod側のラベルが更新されれば、即時反映される
- これは恐らく、厳密にはPodが再作成されるので再度スケジューリングのプロセスを通過するため
以下、具体的な検証内容
NodeSelectorでPodを特定のNodeに配置してからNodeのラベルを消す
普通にNodeSelectorでNodeを指定するようにして配置する。
PS C:\dev\temp\20191209> kubectl get node
NAME STATUS ROLES AGE VERSION
ip-10-0-1-174.us-east-2.compute.internal Ready <none> 31h v1.14.7-eks-1861c5
ip-10-0-54-134.us-east-2.compute.internal Ready <none> 31h v1.14.7-eks-1861c5
ip-10-0-91-149.us-east-2.compute.internal Ready <none> 31h v1.14.7-eks-1861c5
PS C:\dev\temp\20191209> kubectl get node -l NoScheduleTest
NAME STATUS ROLES AGE VERSION
ip-10-0-1-174.us-east-2.compute.internal Ready <none> 31h v1.14.7-eks-1861c5
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy: {}
template:
metadata:
labels:
app: test
spec:
containers:
- image: nginx
name: nginx
nodeSelector:
NoScheduleTest: "True"
PS C:\dev\temp\20191209> kubectl apply -f .\test.yaml
deployment.apps/test created
PS C:\dev\temp\20191209> kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-84c94bbd8f-s5zbh 1/1 Running 0 20s 10.0.16.103 ip-10-0-1-174.us-east-2.compute.internal <none> <none>
ここで、Podが配置された後にNodeのラベルを剥がしても何も起こらない。
PS C:\dev\temp\20191209> kubectl label node ip-10-0-1-174.us-east-2.compute.internal NoScheduleTest-
node/ip-10-0-1-174.us-east-2.compute.internal labeled
PS C:\dev\temp\20191209> kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-84c94bbd8f-s5zbh 1/1 Running 0 3m7s 10.0.16.103 ip-10-0-1-174.us-east-2.compute.internal <none> <none>
ついでに、他のNodeに該当のラベルを貼ってみても何も起こらない。
PS C:\dev\temp\20191209> kubectl label node ip-10-0-91-149.us-east-2.compute.internal NoScheduleTest=True
node/ip-10-0-91-149.us-east-2.compute.internal labeled
PS C:\dev\temp\20191209> kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-84c94bbd8f-s5zbh 1/1 Running 0 4m35s 10.0.16.103 ip-10-0-1-174.us-east-2.compute.internal <none> <none>
NodeSelectorでPodを特定のNodeに配置した後でPodのNodeSelectorを更新する
普通にNodeSelectorでNodeを指定するようにして配置する。
PS C:\dev\temp\20191209> kubectl get node -l Test=True
NAME STATUS ROLES AGE VERSION
ip-10-0-91-149.us-east-2.compute.internal Ready <none> 3d5h v1.14.7-eks-1861c5
PS C:\dev\temp\20191209> kubectl get node -l Test=False
NAME STATUS ROLES AGE VERSION
ip-10-0-1-174.us-east-2.compute.internal Ready <none> 3d6h v1.14.7-eks-1861c5
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy: {}
template:
metadata:
labels:
app: test
spec:
containers:
- image: nginx
name: nginx
nodeSelector:
Test: "True"
PS C:\dev\temp\20191209> kubectl apply -f .\test.yaml
deployment.apps/test created
PS C:\dev\temp\20191209> kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-5b89bbf9f-g4wbq 1/1 Running 0 11s 10.0.95.169 ip-10-0-91-149.us-east-2.compute.internal <none> <none>
PS C:\dev\temp\20191209>
NodeSelectorの値をTrue
からFalse
に変えてDeploymentをデプロイ。
nodeSelector:
Test: "False"
PS C:\dev\temp\20191209> kubectl apply -f .\test.yaml
deployment.apps/test configured
ちゃんとPodが再作成され、NodeSelectorで指定した条件を満たすNodeに配置された。
PS C:\dev\temp\20191209> kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-cf8d65d84-rb9ct 1/1 Running 0 14s 10.0.16.103 ip-10-0-1-174.us-east-2.compute.internal <none> <none>
NodeSelectorで同時に満たすことが不可能な複数のラベルを設定する
False
だけのNodeと、False
とTrue
が両方貼ってあるNodeの2つを用意する。
C:\dev\temp\20191209> kubectl get node -L NodeAffinityTest -L NodeSelectorTest
NAME STATUS ROLES AGE VERSION NODEAFFINITYTEST NODESELECTORTEST
ip-10-0-1-174.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5 False true
ip-10-0-54-134.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5 False
ip-10-0-91-149.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5
PS C:\dev\temp\20191209>
NodeSelectorに2つを指定してデプロイ。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy: {}
template:
metadata:
labels:
app: test
spec:
containers:
- image: nginx
name: nginx
nodeSelector:
NodeAffinityTest: "False"
NodeSelectorTest: "true"
PS C:\dev\temp\20191209> kubectl apply -f .\test.yaml
deployment.apps/test created
PS C:\dev\temp\20191209> kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-64cc7fddf7-46ln8 1/1 Running 0 9s 10.0.19.186 ip-10-0-1-174.us-east-2.compute.internal <none> <none>
ちゃんと、両方を満たすNodeにスケジューリングされた。
NodeSelectorで同時に満たせない複数のラベルを設定。
False
、True
のNodeをそれぞれ1つずつ用意する。
両方が貼られているNodeは存在しない状態。
PS C:\dev\temp\20191209> kubectl get node -L NodeAffinityTest
NAME STATUS ROLES AGE VERSION NODEAFFINITYTEST
ip-10-0-1-174.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5
ip-10-0-54-134.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5 False
ip-10-0-91-149.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5
PS C:\dev\temp\20191209> kubectl get node -L NodeSelectorTest
NAME STATUS ROLES AGE VERSION NODESELECTORTEST
ip-10-0-1-174.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5 true
ip-10-0-54-134.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5
ip-10-0-91-149.us-east-2.compute.internal Ready <none> 4d v1.14.7-eks-1861c5
PS C:\dev\temp\20191209>
先ほど同様、両方を指定するDeploymentをデプロイ。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: test
name: test
spec:
replicas: 1
selector:
matchLabels:
app: test
strategy: {}
template:
metadata:
labels:
app: test
spec:
containers:
- image: nginx
name: nginx
nodeSelector:
NodeAffinityTest: "False"
NodeSelectorTest: "true"
Pending
になる。
PS C:\dev\temp\20191209> kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-64cc7fddf7-ksx8q 0/1 Pending 0 9s <none> <none> <none> <none>
kubectl describe pod
してみると、条件にマッチするNodeが無いと出力されている。
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 21s (x2 over 21s) default-scheduler 0/3 nodes are available: 3 node(s) didn't match node selector.
NodeSelectorは強制力があるが同時に満たせないので、やっぱりスケジューリングできない。
同じような動きだが、条件にマッチするNodeが無かったら妥協して別のNodeにスケジューリングするという動きはNodeAffinity
であれば可能(preferredDuringSchedulingIgnoredDuringExecution
)のようだ。