vSphere with Tanzu のスーパーバイザー クラスタで、vSphere Pod を ESXi ホストに分散して起動する「アンチ アフィニティ」を試してみます。
vSphere で VM を起動する場合でも、複数台の VM を ESXi に分散して配置しようとするケースが多くあります。たとえば「Web サーバ VM の 1号機と2号機は別の ESXi で起動する」といったものです。
vSphere Pod の実体は VM なのですが、特殊な VM なので、ユーザが手動で vMotion できなかったり、DRS + アンチ アフィニティ ルールが利用できなかったりします。
そこで、Kubernetes の持つアフィニティの仕組みを利用できそうか様子を見てみます。
今回の環境
スーパーバイザー クラスタ(wcp-cluster-41)には、3台のワーカー ノードとなる ESXi があります。今回は vCenter Server 7.0b / ESXi 7.0 を利用していますが、7.0 U1 でも同様に動作します。
kubectl でも、スーパーバイザー クラスタに ESXi が 3台あることが確認できます。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION 42113326156c17e10192d03d69cfc933 Ready master 25d v1.17.4-2+a00aae1e6a4a69 4211b5cba366a26db4debeca422d75ca Ready master 25d v1.17.4-2+a00aae1e6a4a69 4211b7998322f27779a8a0af22dbf35d Ready master 25d v1.17.4-2+a00aae1e6a4a69 lab-wcp-esxi-41.go-lab.jp Ready agent 25d v1.17.4-sph-c4c19c8 lab-wcp-esxi-42.go-lab.jp Ready agent 25d v1.17.4-sph-c4c19c8 lab-wcp-esxi-43.go-lab.jp Ready agent 25d v1.17.4-sph-c4c19c8
ホスト名やソフトウェア バージョンは若干異なりますが、このラボは下記のように環境構築しています。
vSphere with Tanzu ラボ環境構築。まとめ - vm.gowatana.jp
vSphere Pod の起動
まず、Kubernetes の Deployment リソースで、vSphere Pod を2つ起動します。Deployment の定義は下記のようにしています。
Pod を作成するのは、すでに用意してあるスーパーバイザー名前空間「lab-ns-01」です。
$ kubectl config current-context
lab-ns-01
$ kubectl config get-contexts lab-ns-01
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* lab-ns-01 192.168.70.97 wcp:192.168.70.97:administrator@vsphere.local lab-ns-01
Deployment を作成します。
$ kubectl apply -f httpd.yml service/web-svc created deployment.apps/demo-httpd created
特に Pod 配置にかかわる定義はなく、1つのホストに Pod が2つとも起動しています。
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo-httpd-6b58f9f454-kqld5 1/1 Running 0 70s 10.244.0.227 lab-wcp-esxi-41.go-lab.jp <none> <none> demo-httpd-6b58f9f454-t8bwj 1/1 Running 0 70s 10.244.0.226 lab-wcp-esxi-41.go-lab.jp <none> <none>
vSphere Client でも、vSphere Pod として、Pod が 2つとも「lab-wcp-esxi-41.go-lab.jp」で起動されたことが確認できます。
1つめの vSphere Pod です。
2つめの vSphere Pod です。
アンチ アフィニティへの定義変更
アンチ アフィニティの方法については、下記の Kubernetes ドキュメントが参考になります。
Node上へのPodのスケジューリング | Kubernetes
podAntiAffinity を定義した、下記のような YAML を用意しました。
httpd_anti-affinity.yml · GitHub
Deployment を作成した YAML との差分です。 今回は、わかりやすく動きを見たいので、必須要件となるように「requiredDuringSchedulingIgnoredDuringExecution」を指定しています。
それでは、定義を変更(YAML を適用)します。今回は既存の Deployment の定義を変更していますが、新規作成でもアンチ アフィニティ配置になります。
$ kubectl apply -f httpd_anti-affinity.yml service/web-svc unchanged deployment.apps/demo-httpd configured
kubectl get pods で様子を見ていると、Kubernetes による Pod の追加 / 削除が実施されます。特に、スーパーバイザー クラスタだからといって、vSphere DRS で vMotion されたりはしていません。ちなみに内部的には、ReplicaSet リソースが作成されて Pod が追加されています。
既存の Pod(~-c26jc、~-sjxpp)は停止され、あらたに Pod(~-rdz6l、~-wb774)が起動されています。
$ kubectl get pods --watch NAME READY STATUS RESTARTS AGE demo-httpd-68979c6d58-rdz6l 0/1 Pending 0 9s demo-httpd-6b58f9f454-c26jc 1/1 Running 0 70m demo-httpd-6b58f9f454-sjxpp 1/1 Running 0 71m demo-httpd-68979c6d58-rdz6l 1/1 Running 0 9s demo-httpd-6b58f9f454-c26jc 1/1 Terminating 0 70m demo-httpd-68979c6d58-wb774 0/1 Pending 0 0s demo-httpd-68979c6d58-wb774 0/1 Pending 0 0s demo-httpd-68979c6d58-wb774 0/1 Pending 0 1s demo-httpd-6b58f9f454-c26jc 1/1 Terminating 0 70m demo-httpd-68979c6d58-wb774 0/1 Pending 0 3s demo-httpd-68979c6d58-wb774 0/1 Pending 0 4s demo-httpd-6b58f9f454-c26jc 1/1 Terminating 0 70m demo-httpd-68979c6d58-wb774 1/1 Running 0 9s demo-httpd-6b58f9f454-sjxpp 1/1 Terminating 0 71m demo-httpd-6b58f9f454-sjxpp 1/1 Terminating 0 71m demo-httpd-6b58f9f454-sjxpp 1/1 Terminating 0 71m
別のワーカー ノードで、Pod が起動された状態になりました。
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo-httpd-68979c6d58-bvlgx 1/1 Running 0 119s 10.244.0.228 lab-wcp-esxi-43.go-lab.jp <none> <none> demo-httpd-68979c6d58-dhrpc 1/1 Running 0 106s 10.244.0.229 lab-wcp-esxi-42.go-lab.jp <none> <none>
vSphere Client でも、vSphere Pod が順次追加 → 削除される様子が見られます。
最終的に vSphere Pod は 2つとなり、別の ESXi で起動されたことが確認できます。
1つめの vSphere Pod です。
もうひとつの vSphere Pod も、別の ESXi で起動されています。
vSphere Pod 起動時の配置決定では DRS が利用されています。しかし具体的に配置制御するには、DRS のアフィニティ ルールではなく、Kubernetes 側の持つアフィニティの仕組みを利用するとよさそうです。
以上、vSphere Pod をアンチ アフィニティ配置してみる話でした。