vm.gowatana.jp

NEOにほんごVMware(仮)

vSphere Pod を Anti-Affinity で起動してみる。

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 でも同様に動作します。

f:id:gowatana:20201124001338p:plain

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 の定義は下記のようにしています。

gist.github.com

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 です。

f:id:gowatana:20201124001813p:plain

2つめの vSphere Pod です。

f:id:gowatana:20201124001848p:plain

アンチ アフィニティへの定義変更

アンチ アフィニティの方法については、下記の Kubernetes ドキュメントが参考になります。

Node上へのPodのスケジューリング | Kubernetes

podAntiAffinity を定義した、下記のような YAML を用意しました。

httpd_anti-affinity.yml · GitHub

Deployment を作成した YAML との差分です。 今回は、わかりやすく動きを見たいので、必須要件となるように「requiredDuringSchedulingIgnoredDuringExecution」を指定しています。

gist.github.com

それでは、定義を変更(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 が順次追加 → 削除される様子が見られます。

f:id:gowatana:20201124002414p:plain

最終的に vSphere Pod は 2つとなり、別の ESXi で起動されたことが確認できます。

1つめの vSphere Pod です。

f:id:gowatana:20201124002450p:plain

もうひとつの vSphere Pod も、別の ESXi で起動されています。

f:id:gowatana:20201124002520p:plain

vSphere Pod 起動時の配置決定では DRS が利用されています。しかし具体的に配置制御するには、DRS のアフィニティ ルールではなく、Kubernetes 側の持つアフィニティの仕組みを利用するとよさそうです。

以上、vSphere Pod をアンチ アフィニティ配置してみる話でした。