はじめに
k8sにはNodeのメンテナンスなどの制御でCordon/Drainというものがあるらしい(勉強中)。しかしローカル検証環境であるminikubeは1Nodeなのでうまい検証ができない。これをクラスター環境を作れるkindで検証してみたい。(追記:minikubeも対応していた…)
何がしたいかというと、「Kubernetes道場」のこちらの記事をminikubeでなくkindでやってみたいということ。
追記
後日調べていたら・勉強していたら、既に2020年の時点でminikubeはマルチノードに対応してたことを知った…
次の方法で…
$ minikube start --nodes 3
$ kubectl get node
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 73s v1.32.0
minikube-m02 Ready <none> 58s v1.32.0
minikube-m03 Ready <none> 44s v1.32.0
kindによるクラスター環境の準備
インストール
私はmacOSなので、
brew install kind
クラスターの作成
とりあえず2Nodeとして次のファイルを作成し、
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
クラスターを作成
kind create cluster --config kind-example-config.yaml
Node確認
$ kubectl get node
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 62s v1.32.0
kind-worker Ready <none> 53s v1.32.0
kind-worker2 Ready <none> 53s v1.32.0
これでテストできる環境ができた。
検証
まずはnginxを動かしてみる
$ kubectl create deploy nginx --image nginx:alpine
deployment.apps/nginx created
NginxがどのNodeで動いているか確認すると、この時はkind-workerで動いている様子。
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6b66fbbd46-gbb4v 1/1 Running 0 42s 10.244.1.2 kind-worker <none> <none>
Drain
Nodeをメンテナンスする等を想定してこのkind-worker NodeをDrainする。
$ kubectl drain kind-worker --ignore-daemonsets
node/kind-worker cordoned
Warning: ignoring DaemonSet-managed Pods: kube-system/kindnet-pc2m7, kube-system/kube-proxy-gvxlr
evicting pod default/nginx-6b66fbbd46-gbb4v
pod/nginx-6b66fbbd46-gbb4v evicted
node/kind-worker drained
すると、別Nodeであるkind-worker2に移動しRunning状態になっていることがわかる。
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6b66fbbd46-c842z 1/1 Running 0 24s 10.244.2.2 kind-worker2 <none> <none>
また、kind-workerがSchedulingDisabledになっている
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 3m31s v1.32.0
kind-worker Ready,SchedulingDisabled <none> 3m21s v1.32.0
kind-worker2 Ready <none> 3m21s v1.32.0
次のコマンドで状態・イベントをみてみると該当NodeがTaintedになっていること、該当Podが別のNodeで起動したことがわかる。
$ kubectl describe nodes
略
$ kubectl describe pods
略
Uncordon
メンテナンス等が終わったものとしてUncordonさせる
$ kubectl uncordon kind-worker
node/kind-worker uncordoned
$ kubectl describe node/kind-worker
〜〜〜
Taints: <none>
Unschedulable: false
〜〜〜
Taintsが消えて、Readyになっている
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 8m33s v1.32.0
kind-worker Ready <none> 8m23s v1.32.0
kind-worker2 Ready <none> 8m23s v1.32.0
Cordon
今度はkind-worker,kind-worker2ともにCordonさせる。
$ kubectl cordon kind-worker
node/kind-worker cordoned
$ kubectl cordon kind-worker2
node/kind-worker2 cordoned
両方のWorker NodeともにSchedulingDisabledになっているが、
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 9m20s v1.32.0
kind-worker Ready,SchedulingDisabled <none> 9m10s v1.32.0
kind-worker2 Ready,SchedulingDisabled <none> 9m10s v1.32.0
すでに実行済みのPodはRunningのままになっている。
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-6b66fbbd46-c842z 1/1 Running 0 7m31s 10.244.2.2 kind-worker2 <none> <none>
この状態で新規にhttpdを起動させてみようとすると
$ kubectl create deploy httpd --image httpd:alpine
deployment.apps/httpd created
どちらのWorker NodeもCordonで起動中のものは動き続けるが新規のスケジュールは受け付けないのでPendingとなる。
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-798d447958-ftwsf 0/1 Pending 0 18s <none> <none> <none> <none>
nginx-6b66fbbd46-c842z 1/1 Running 0 8m30s 10.244.2.2 kind-worker2 <none> <none>
Uncordon
この状態でkind-worker NodeをUncordonさせるとPodが実行できる様になるので
$ kubectl uncordon kind-worker
node/kind-worker uncordoned
PendingになっていたものがRunning状態になる。
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
httpd-798d447958-ftwsf 1/1 Running 0 2m1s 10.244.1.3 kind-worker <none> <none>
nginx-6b66fbbd46-c842z 1/1 Running 0 10m 10.244.2.2 kind-worker2 <none> <none>
kind-worker2もUncordenすると
$ kubectl uncordon kind-worker2
node/kind-worker2 uncordoned
どちらのNodeもReadyになり今後動くPodはどちらのNodeでも実行可能になる。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 15m v1.32.0
kind-worker Ready <none> 15m v1.32.0
kind-worker2 Ready <none> 15m v1.32.0