はじめに
Kubernetesではノードにラベルを付与することができ、例えばテスト環境や本番環境のノードを明示的に分離することでPodのデプロイ先を明示的にスケジューリングすることができます。
本記事ではPodにtolerationsを設定することで明示的にノードに載せた後、ノードのラベルを変更した際の動きを実践してみました。
pod(test/prod) +------------+ | | +---v---+ +---v---+ Node(test) Node(prod) | | | | +-------+ +-------+
環境情報
$ kubectl get nodes NAME STATUS ROLES AGE VERSION test1 Ready master 4m29s v1.15.7 test2 Ready worker 4m6s v1.15.7 test3 Ready worker 4m8s v1.15.7
Node及びyamlファイルの準備
二つのDeploymentのyamlファイルを用意します。イメージは任意ですがspec.template.tolerations
に以下を記載したものと
tolerations: - key: node-type operator: Equal value: test effect: NoSchedule
以下を記載します。
tolerations: - key: node-type operator: Equal value: prod effect: NoSchedule
つまり一つ目のyamlファイルはNodeのタイプが「test」となっているもの、二つ目のyamlファイルはNodeのタイプが「prod」となっているものに配置されます。
ノードにはkubectl taint NODENAME node-type=HOGE:NoSchedule
と記載すれば設定でき
$ kubectl taint node test2 node-type=prod:NoSchedule node/test2 tainted $ kubectl taint node test3 node-type=test:NoSchedule node/test3 tainted
以下コマンドで設定値を確認できます。
$ kubectl describe nodes test2 | grep Taints Taints: node-type=prod:NoSchedule $ kubectl describe nodes test3 | grep Taints Taints: node-type=test:NoSchedule
実際にデプロイする
kubectl apply -f
にてyamlを適用すると以下のように想定のノードに対してデプロイされます。
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES prod-7654d444bc-m2rxm 1/1 Running 0 17s 10.244.1.2 test2 <none> <none> test-84cf5d57bf-wwtlh 1/1 Running 0 23s 10.244.2.2 test3 <none> <none>
ここでprodと設定したNodeをtestに変更します。
デプロイ済のノードのラベルを変更
以下コマンドで強制的にラベルを上書きします。
$ kubectl taint node test2 node-type=test:NoSchedule --overwrite node/test2 modified
既に設定済だからかoverwriteが無ければ以下のエラーとなります。
error: Node test2 already has node-type taint(s) with same effect(s) and --overwrite is false
一方でPodの状況を確認しますが本来はprodと指定したノードでしか動かないprod-7654d444bc-m2rxmは動いたままとなっています。
明示的にdeleteを行った後に再度applyをすると以下のようにPendingとなります。
prod-7654d444bc-vwj26 0/1 Pending 0 6s <none> <none> <none> <none>
Pending状態でノードのラベルを変更
prod-7654d444bc-vwj26はprodに配置するよう指定しているので「Warning FailedScheduling 26s (x4 over 52s) default-scheduler 0/3 nodes are available: 3 node(s) had taints that the pod didn't tolerate.」という状態で止まっています。
この状態で以下のように再度prodにノードを戻すと
$ kubectl taint node test2 node-type=prod:NoSchedule --overwrite node/test2 modified
Pendingが解消されてPodがprodのノードに配置されました。
終わりに
以下記事でもあったように明示的に再配置を行わないと瞬時にはPodはPendingにならないようです。
ただし、Pendingの解消はリトライ処理の中でクイックに配置可能ノードが検出できるのだと思います。
以上、ご参考になれば幸いです。