LinuCエヴァンジェリスト・Open Source Summit Japan 2022ボランティアリーダーの鯨井貴博@opensourcetechです。
はじめに
今回はkubernetesのPod(コンテナ)を特定のノードに配置しないようにTaintとTolerationを使ってみます。
TaintとTolerationsとは
Taintは特定のノードにマーキング(Taintは汚れという意味)をして、
それを許容(Tolerarion)するPodのみ配置(スケジューリング)出来るようにするものです。
Taintをノードに付ける
早速、特定ノードにTaintを付けてみます。
まず、現在のノード状態を確認。
kubeuser@master01:~$ kubectl get nodes NAME STATUS ROLES AGE VERSION master01 Ready control-plane 151d v1.27.0 worker01 Ready <none> 151d v1.27.0 worker02 Ready <none> 151d v1.27.0 kubeuser@master01:~$ kubectl describe nodes master01 | grep Taint Taints: node-role.kubernetes.io/control-plane:NoSchedule kubeuser@master01:~$ kubectl describe nodes worker01 | grep Taint Taints: <none> kubeuser@master01:~$ kubectl describe nodes worker02 | grep Taint Taints: <none>
MasterノードのみTaintが付与(デフォルト)されており、
Workerノードの2台はTaintがありません。
この場合、worker01/worker02いずれのノードもPodが配置できる状態です。
では、worker01にTaint(env=production:NoSchedule)を付与します。
Taintは、Key=Value:Effectという形式で付与します。
- Key:任意名
- Value:任意値
- Effect:NoSchedule(Podを配置しない)・NoExecute(Podの実行を許可しない、既存Podは停止される)・PreferNoSchedule(可能な限り配置しない)
kubeuser@master01:~$ kubectl taint node worker01 env=production:NoSchedule node/worker01 tainted kubeuser@master01:~$ kubectl describe nodes worker01 | grep Taint Taints: env=production:NoSchedule
Taintを考慮せず、Podを起動してみる
まずは、Taintの事を気にせずに通常通りPodを起動します。
想定では、Taintが付与されていないノード(worker02)で起動するはずです。
kubeuser@master01:~/taint$ kubectl run taint01 --image=nginx:latest --dry-run=client -o yaml > taint01.yaml kubeuser@master01:~/taint$ vi taint01.yaml kubeuser@master01:~/taint$ cat taint01.yaml apiVersion: v1 kind: Pod metadata: labels: status: notaint run: taint01 name: taint01 spec: containers: - image: nginx:latest name: taint01 dnsPolicy: ClusterFirst restartPolicy: Always kubeuser@master01:~/taint$ kubectl apply -f taint01.yaml pod/taint01 created kubeuser@master01:~/taint$ kubectl get pods -w NAME READY STATUS RESTARTS AGE hpa-nginx-668b69fd79-k7d2q 1/1 Running 1 (91d ago) 129d nginx-6cbc9bb4f5-jm8mr 1/1 Running 0 142d nginx-6cbc9bb4f5-pfhfz 1/1 Running 0 142d nginx2-f96cfc57b-vnsfm 1/1 Running 0 142d taint01 0/1 ContainerCreating 0 22s test-webserver 1/1 Running 2 (91d ago) 126d webserver-master01 1/1 Running 0 93d taint01 0/1 ContainerCreating 0 52s taint01 1/1 Running 0 97s kubeuser@master01:~/taint$ kubectl get pods taint01 -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES taint01 1/1 Running 0 113s 10.0.30.77 worker02 <none> <none>
想定通りですね!
Taintを考慮して、Podを起動してみる
では続いて、Taintを考慮してPodを起動します。
Toleration(許容)を設定したyamlファイルからPodを起動するので、想定ではworker01で起動するはずです。
この例では、operator: Equalを使っており、
Key・Value・Effectが一致する場合にそのノードでPodが起動されます。
kubeuser@master01:~/taint$ cp -p taint01.yaml taint02.yaml kubeuser@master01:~/taint$ vi taint02.yaml kubeuser@master01:~/taint$ cat taint02.yaml apiVersion: v1 kind: Pod metadata: labels: status: taint run: taint02 name: taint02 spec: containers: - image: nginx:latest name: taint02 tolerations: - key: env operator: Equal value: "production" effect: "NoSchedule" dnsPolicy: ClusterFirst restartPolicy: Always kubeuser@master01:~/taint$ kubectl apply -f taint02.yaml pod/taint02 created kubeuser@master01:~/taint$ kubectl get pods -w NAME READY STATUS RESTARTS AGE hpa-nginx-668b69fd79-k7d2q 1/1 Running 1 (91d ago) 129d nginx-6cbc9bb4f5-jm8mr 1/1 Running 0 142d nginx-6cbc9bb4f5-pfhfz 1/1 Running 0 142d nginx2-f96cfc57b-vnsfm 1/1 Running 0 142d taint01 1/1 Running 0 7m15s taint02 0/1 ContainerCreating 0 9s test-webserver 1/1 Running 2 (91d ago) 126d webserver-master01 1/1 Running 0 93d taint02 0/1 ContainerCreating 0 42s taint02 1/1 Running 0 92s kubeuser@master01:~/taintkubectl get pods taint02 -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES taint02 1/1 Running 0 2m 10.0.5.51 worker01 <none> <none>
想定通り、worker01上でPodが起動しました。
Taintを考慮して、Podを起動してみる2
そして、もう一つ。
operator: Existsを使ってみます。
この例では、operator: Existsを使っており、
Keyが一致する場合にそのノードでPodが起動されます。
kubeuser@master01:~/taint$ cp -p taint02.yaml taint03.yaml kubeuser@master01:~/taint$ vi taint03.yaml kubeuser@master01:~/taint$ cat taint03.yaml apiVersion: v1 kind: Pod metadata: labels: status: taint run: taint03 name: taint03 spec: containers: - image: nginx:latest name: taint03 tolerations: - key: env operator: Exists dnsPolicy: ClusterFirst restartPolicy: Always kubeuser@master01:~/taint$ kubectl apply -f taint03.yaml pod/taint03 created kubeuser@master01:~/taint$ kubectl get pods taint03 -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES taint03 1/1 Running 0 10s 10.0.5.52 worker01 <none> <none>
こちらも想定通り、"worker01"上でPodが起動されました。
Taintの削除
Taintを付与したときのコマンドの最後に "-"を付ければOKです。
kubeuser@master01:~/taint$ kubectl get nodes worker01 | grep Taint kubeuser@master01:~/taint$ kubectl describe nodes worker01 | grep Taint Taints: env=production:NoSchedule kubeuser@master01:~/taint$ kubectl taint node worker01 env=production:NoSchedule- node/worker01 untainted kubeuser@master01:~/taint$ kubectl describe nodes worker01 | grep Taint Taints: <none>
TaintとTolerationの詳細
詳細については、以下の本家サイトで確認できます。
Taints and Tolerations
Taints and Tolerations日本語ページ
ノードの状態などによって自動的に付与されるものがあるというのも、興味深いですね。