Skip navigation
2020

vSphere with Kubernetes のスーパーバイザー クラスタ上に作成した

「Tanzu Kubernetse Cluster」に、kubectl を使用していくつかの方法で接続してみます。

 

ドキュメントでは、下記のあたりが参考になります。

Tanzu Kubernetesクラスタ環境への接続

 

環境について。

今回の接続元の環境は Linux です。

スーパーバイザー クラスタの管理プレーンから、kubectl と vSphere プラグインはダウンロードしてあります。

$ cat /etc/system-release

Oracle Linux Server release 7.8

$ kubectl version --short --client

Client Version: v1.17.4-2+a00aae1e6a4a69

$ kubectl vsphere version

kubectl-vsphere: version 0.0.2, build 16232217, change 8039971

 

Tanzu Kubernetse Cluster のラボは、下記のように構築しています。

vSphere with Kubernetes ラボ環境構築。(まとめ)

 

kubectl は、スーパーバイザー クラスタの制御プレーンからダウンロードしたものを利用しています。

vSphere with Kubernetes ラボ環境構築。Part-11: kubectl で vSphere Pod 起動編

 

vCenter Server 7.0b で、3ノードの ESXi で スーパーバイザー クラスタを構成しています。

スーパーバイザークラスタ「wcp-cluster-41」の、制御プレーンの IP アドレスは「192.168.70.97」です。

tkc-access-00.png

 

Tanzu Kubernetes Cluster(TKC)は、スーパーバイザークラスタの名前空間「lab-ns-03」に作成ずみです。

TKC の名前は「tkg-cluster-41」で、制御プレーンの IP アドレスは「192.168.70.99」です。

tkc-access-01.png

 

あらかじめ、vCenter Single Sign-On には、ID ソースとして LDAP サーバを登録ずみです。

tkc-access-02.png

 

ID ソースのドメイン「go-lab.jp」からユーザ情報を取得できています。

tkc-access-03.png

 

方法1: vCenter Single Sign-On 認証で接続する。

ここでは、「k8s-infra-user @ go-lab.jp」という vCenter Single Sigh-On のユーザーで接続してみます。

 

まず、対象のユーザーには、スーパーバイザー クラスタの名前空間で「権限の追加」が必要です。

そして、kubectl で TKC に接続する際は、スーパーバイザー制御プレーン宛となります。

ちなみに、vCenter の管理者ユーザ(administrator@vsphere.local)であれば、

デフォルトでスーパーバイザー クラスタや TKC にアクセス可能です。

tkc-access-case-01.PNG

 

1-1: スーパーバイザー名前空間での権限の追加。

スーパーバイザー クラスタの名前空間「lab-ns-03」の、

「サマリ」→「権限」にある「権限の追加」をクリックします。

tkc-access-04.png

 

ID ソース、ユーザー(またはグループ)、ロールを選択して、「OK」をクリックします。

今回は、ユーザー(k8s-infra-user)を指定していますが、一般的にはグループを指定するはずです。

ロールでは、「編集可能」(edit) または、「表示可能」(view)が選択できます。

tkc-access-05.png

 

権限が追加されました。

tkc-access-06.png

 

1-2: kubectl での接続。

kubectl vsphere login でログインすると、kubeconfig のファイルが生成されます。

デフォルトでは、$HOME/.kube/config というファイル名で作成されますが、

環境変数 KUBECONFIG を設定しておくと、そのパスに生成されます。

$ export KUBECONFIG=$(pwd)/kubeconfig_tkc

 

kubectl vsphere login では、次のようなオプションを指定します。

  • --server: Tanzu Kubernetes Cluster の制御プレーンではなく、
    スーパーバイザー クラスタの、制御プレーンが持つ IP アドレス(この環境では 192.168.70.97)を指定します。
  • --tanzu-kubernetes-cluster-namespace: TKC を作成したスーパーバイザー名前空間
  • --tanzu-kubernetes-cluster-name: TKC の名前

$ kubectl vsphere login --insecure-skip-tls-verify --server=192.168.70.97 --tanzu-kubernetes-cluster-namespace=lab-ns-03 --tanzu-kubernetes-cluster-name=tkg-cluster-41

 

Username: k8s-infra-user@go-lab.jp

Password: ★パスワードを入力。

Logged in successfully.

 

You have access to the following contexts:

   192.168.70.97

   lab-ns-03

   tkg-cluster-41

 

If the context you wish to use is not in this list, you may need to try

logging in again later, or contact your cluster administrator.

 

To change context, use `kubectl config use-context <workload name>`

$

 

TKC「tkg-cluster-41」と、TKC のスーパーバイザー名前空間「lab-ns-03」と同名のコンテキストが作成されます。

ここでも、TKC  の制御プレーン アドレス「192.168.70.99」がわかります。

$ kubectl config get-contexts tkg-cluster-41

CURRENT   NAME             CLUSTER         AUTHINFO                                     NAMESPACE

*         tkg-cluster-41   192.168.70.99   wcp:192.168.70.99:k8s-infra-user@go-lab.jp

 

TKC のノードが表示できました。

$ kubectl --context tkg-cluster-41 get nodes

NAME                                            STATUS   ROLES    AGE    VERSION

tkg-cluster-41-control-plane-vcdpg              Ready    master   153m   v1.17.8+vmware.1

tkg-cluster-41-workers-c72df-5979f6ffcf-lgsx2   Ready    <none>   131m   v1.17.8+vmware.1

tkg-cluster-41-workers-c72df-5979f6ffcf-qvv92   Ready    <none>   127m   v1.17.8+vmware.1

tkg-cluster-41-workers-c72df-5979f6ffcf-vdrpn   Ready    <none>   131m   v1.17.8+vmware.1

 

ちなみに権限を追加していなかったり、ロールが「表示可能」の場合はエラーになります。

$ kubectl --context tkg-cluster-41 get nodes

Error from server (Forbidden): nodes is forbidden: User "sso:k8s-infra-user@go-lab.jp" cannot list resource "nodes" in API group "" at the cluster scope

 

なお、TKC で Deployment リソースなどで Pod を作成するには、PodSecurityPolicy の設定が必要になったりします。

(これは、この後の方法でも同様です)

vSphere with Kubernetes ラボ環境構築。Part-15: Tanzu Kubernetes Cluster での PSP 使用 / Deployment 作成編

 

方法2: Kubernetes の管理ユーザ(kubernetes-admin)として接続する。

この方法では、TKC を作成してあるスーパーバイザー名前空間「lab-ns-03」に自動作成されている Secret リソースから、kubeconfig の情報を取得します。

これは、あらかじめ kubectl vsphere login でスーパーバイザー クラスタか TKC に接続したうえで取得することになります。

 

kubernetes-admin の kubeconfig での接続は、直接 TKC の管理プレーン宛を指定します。

tkc-access-case-02.PNG

 

2-1: kubernetes-admin ユーザーの kubeconfig の取得。

Secret リソースは、「<Tanzu Kubernetes Cluster の名前>-kubeconfig」となっており、

この環境では「tkg-cluster-41-kubeconfig」です。

$ kubectl --context lab-ns-03 get secrets tkg-cluster-41-kubeconfig

NAME                        TYPE     DATA   AGE

tkg-cluster-41-kubeconfig   Opaque   1      167m

 

JSON パスでの「{.data.value}」に、base64 エンコーディングされた kubeconfig が格納されています。

この内容を、「base64 -d」コマンドでデコードして、ファイルに保存します。

$ kubectl --context lab-ns-03 get secret tkg-cluster-41-kubeconfig -o jsonpath='{.data.value}' | base64 -d > ./kubeconfig_tkg-cluster-41

 

2-2: 生成した kubeconfig での kubectl 接続。

保存した kubeconfig で、管理ユーザーのコンテキストで TKC に接続できます。

これは、vCenter Single Sign-On の認証とは関係なく接続できるものです。

$ kubectl --kubeconfig=./kubeconfig_tkg-cluster-41 config current-context

kubernetes-admin@tkg-cluster-41

$ kubectl --kubeconfig=./kubeconfig_tkg-cluster-41 get nodes

NAME                                            STATUS   ROLES    AGE    VERSION

tkg-cluster-41-control-plane-vcdpg              Ready    master   155m   v1.17.8+vmware.1

tkg-cluster-41-workers-c72df-5979f6ffcf-lgsx2   Ready    <none>   133m   v1.17.8+vmware.1

tkg-cluster-41-workers-c72df-5979f6ffcf-qvv92   Ready    <none>   129m   v1.17.8+vmware.1

tkg-cluster-41-workers-c72df-5979f6ffcf-vdrpn   Ready    <none>   133m   v1.17.8+vmware.1

 

方法3: Kubernetes の ServiceAccount を作成して接続する。

方法1か、方法2の、いずれかで TKC に接続したうえで、TKC の名前空間に ServiceAccount を作成して接続します。

ServiceAccount での TKC への接続も、スーパーバイザー制御プレーンではなく、TKC 制御プレーン宛となります。

tkc-access-case-03.PNG

 

3-1: ServiceAccount の作成。

ここからは、ちょうど直前の 方法2 で作成した kubeconfig を利用します。

$ export KUBECONFIG=$(pwd)/kubeconfig_tkg-cluster-41

$ kubectl config current-context

kubernetes-admin@tkg-cluster-41

 

この時点では TKC の「default」名前空間を使用していますが、

あらたに「tkg-ns-01」という名前空間を作成して、そこに ServiceAccount で接続できるようにします。

$ kubectl create namespace tkg-ns-01

namespace/tkg-ns-01 created

 

この時点 tkg-ns-01 名前空間に存在するのは、ServiceAccount(sa) は default のみです。

$ kubectl -n tkg-ns-01 get sa

NAME      SECRETS   AGE

default   1         43s

 

ServiceAccount「sa-01」を作成します。

$ kubectl -n tkg-ns-01 create sa sa-01

serviceaccount/sa-01 created

$ kubectl -n tkg-ns-01 get sa

NAME      SECRETS   AGE

default   1         47s

sa-01     1         12s

 

この ServiceAccount のトークンが格納されている、Secret リソースの名前を確認します。

$ SA_SECRET_NAME=$(kubectl -n tkg-ns-01 get sa sa-01 -o jsonpath='{.secrets[0].name}')

$ echo $SA_SECRET_NAME

sa-01-token-zc74c

 

Secret リソースから、トークンを取得します。

$ SA_TOKEN=$(kubectl -n tkg-ns-01 get secrets $SA_SECRET_NAME -o jsonpath='{.data.token}' | base64 -d)

 

確認したトークンをもとに、Credential、コンテキストを作成します。

$ kubectl config set-credentials sa-01 --token=$SA_TOKEN

User "sa-01" set.

$ kubectl config set-context ctx-sa-01 --user=sa-01 --cluster=tkg-cluster-41 --namespace=tkg-ns-01

Context "ctx-sa-01" created.

 

コンテキストを kubeconfig ファイルとして保存しておきます。

$ kubectl config view --minify --context=ctx-sa-01 --raw > ./kubeconfig_ctx-sa-01

$ kubectl config delete-context ctx-sa-01

 

ServiceAccount で接続する kubeconifg が生成されました。

$ kubectl --kubeconfig=./kubeconfig_ctx-sa-01 config get-contexts

CURRENT   NAME        CLUSTER          AUTHINFO   NAMESPACE

*         ctx-sa-01   tkg-cluster-41   sa-01      tkg-ns-01

 

3-2: ServiceAccount の権限設定。

作成した ServiceAccount「sa-01」が Kubernetes のリソースを操作できるように、

ClusterRole「edit」を割り当てる RoleBinding を作成しておきます。

 

role-binding-edit.yml

---

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: rb-edit-sa-01

roleRef:

  kind: ClusterRole

  name: edit

  apiGroup: rbac.authorization.k8s.io

subjects:

- kind: ServiceAccount

  name: sa-01

 

RoleBinding を、TKC の tkg-ns-01 名前空間に作成します。

$ kubectl -n tkg-ns-01 apply -f role-binding-edit.yml

rolebinding.rbac.authorization.k8s.io/rb-edit-sa-01 created

 

TKC で Pod を起動できるように、PodSecurityPolicy を割り当てる RoleBinding も作成しておきます。

こちらは、すべての ServiceAccount を指定しています。

 

role-binding-psp.yml

---

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: rb-vmware-system-privileged

roleRef:

  kind: ClusterRole

  name: psp:vmware-system-privileged

  apiGroup: rbac.authorization.k8s.io

subjects:

- kind: Group

  name: system:serviceaccounts

  apiGroup: rbac.authorization.k8s.io

 

TKC の名前空間に RoleBinding を作成します。

$ kubectl -n tkg-ns-01 apply -f role-binding-psp.yml

rolebinding.rbac.authorization.k8s.io/rb-vmware-system-privileged created

 

3-3: 生成した kubeconifg での kubectl 接続。

生成した kubeconfig で、Pod の起動ができました。

$ kubectl --kubeconfig=./kubeconfig_ctx-sa-01 run pod-01 --image=gowatana/centos7:httpd --restart=Never

pod/pod-01 created

$ kubectl --kubeconfig=./kubeconfig_ctx-sa-01 get pods

NAME     READY   STATUS              RESTARTS   AGE

pod-01   1/1     Running             0          44s

 

Pod は削除しておきます。

$ kubectl --kubeconfig=./kubeconfig_ctx-sa-01.txt delete pod pod-01

pod "pod-01" deleted

 

方法4: TKC 側で vCenter Single Sign-On ユーザーの権限を割り当てる。

あらかじめ、方法1、または方法2の、いずれかの方法で TKC に接続しておきます。

そして方法1 とは異なり、TKC で作成した名前空間に vCenter Single Sigh-On ユーザーの権限を割り当てます。

そのあとの TKC への接続はスーパーバイザー制御プレーン宛となります。

tkc-access-case-04a.png

 

方法4-1: TKC の名前空間への権限の追加。

ここでは、方法2 で生成した kubeconfig を利用して、TKC を操作します。

(方法1 の接続でも同様に操作できます)

$ export KUBECONFIG=$(pwd)/kubeconfig_tkg-cluster-41

$ kubectl config current-context

kubernetes-admin@tkg-cluster-41

 

TKC の名前空間「tkg-ns-02」を追加作成します。

あわせて、PSP の RoleBinding(YAML は方法3のものと同様)も作成しておきます。

$ kubectl create namespace tkg-ns-02

namespace/tkg-ns-02 created

$ kubectl -n tkg-ns-02 apply -f role-binding-psp.yml

rolebinding.rbac.authorization.k8s.io/rb-vmware-system-privileged created

 

RoleBinding の YAML を用意します。

リソースを操作できるように、ClusterRole「edit」を割り当てます。

subjects では vCenter Single Sign-On ユーザー(sso:k8s-dev-user@go-lab.jp)を指定しています。

ちなみに、グループを指定する場合は、「kind: User」を「kind: Group」にします。

 

role-binding-vcsso.yml

---

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

  name: rb-edit-k8s-dev-user

roleRef:

  kind: ClusterRole

  name: edit

  apiGroup: rbac.authorization.k8s.io

subjects:

- kind: User

  name: sso:k8s-dev-user@go-lab.jp #sso:<username>@<domain>

  apiGroup: rbac.authorization.k8s.io

 

作成した TKC の名前空間「tkg-ns-02」に、RoleBinding を作成します。

$ kubectl -n tkg-ns-02 apply -f role-binding-vcsso.yml

rolebinding.rbac.authorization.k8s.io/rb-edit-k8s-dev-user created

 

方法4-2: kubectl での接続。

既存の kubeconfig を上書きしないように、環境変数 KUBECONFIG に、新しい kubeconfig ファイルのパスを指定します。

この時点では「kubeconfig_k8s-dev-user」ファイルは存在しません。

$ export KUBECONFIG=$(pwd)/kubeconfig_k8s-dev-user

 

kubectl vsphere login で、スーパーバイザー制御プレーンと TKC に接続します。

$ kubectl vsphere login --insecure-skip-tls-verify --server=192.168.70.97 --tanzu-kubernetes-cluster-namespace=lab-ns-03 --tanzu-kubernetes-cluster-name=tkg-cluster-41

 

Username: k8s-dev-user@go-lab.jp

Password: ★パスワードを入力。

Logged in successfully.

 

You have access to the following contexts:

   192.168.70.97

   tkg-cluster-41

 

If the context you wish to use is not in this list, you may need to try

logging in again later, or contact your cluster administrator.

 

To change context, use `kubectl config use-context <workload name>`

$

 

コンテキストが生成されました。

$ kubectl config get-contexts tkg-cluster-41

CURRENT   NAME             CLUSTER         AUTHINFO                                   NAMESPACE

*         tkg-cluster-41   192.168.70.99   wcp:192.168.70.99:k8s-dev-user@go-lab.jp

 

コンテキストを TKC の「tkg-cluster-41」に切り替えて、

デフォルトの名前空間として「tkg-ns-02」を設定します。

$ kubectl config use-context tkg-cluster-41

Switched to context "tkg-cluster-41".

$ kubectl config set-context --current --namespace=tkg-ns-02

Context "tkg-cluster-41" modified.

$ kubectl config get-contexts tkg-cluster-41

CURRENT   NAME             CLUSTER         AUTHINFO                                   NAMESPACE

*         tkg-cluster-41   192.168.70.99   wcp:192.168.70.99:k8s-dev-user@go-lab.jp   tkg-ns-02

 

Pod が起動できました。

$ kubectl run pod-01 --image=gowatana/centos7:httpd --restart=Never

pod/pod-01 created

$ kubectl get pods -n tkg-ns-02

NAME     READY   STATUS    RESTARTS   AGE

pod-01   1/1     Running   0          10s

 

スーパーバイザー名前空間「lab-ns-03」では「k8s-dev-user」ユーザーへの権限は追加していませんが、

vCenter Single Sigh-On ユーザーでリソース作成ができました。

vSphere Client で確認すると、方法1 で使用した「k8s-infra-user」ユーザーのみが追加されています。

tkc-access-09.png

 

vCenter 同梱ではない kubectl の接続。

ちなみに、ここまでの方法に関わらず、kubeconfig が生成できていれば

一般的な Kubernetes 操作ツールでも TKC に(スーパーバイザー クラスタにも)接続することができます。

 

Kubernetes のドキュメントでおなじみの URL から kubectl をダウンロードします。

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.8/bin/linux/amd64/kubectl

$ chmod +x ./kubectl

 

vCenter 同梱の kubectl と、あらたにダウンロードした kubectl(./kubectl でカレント ディレクトリのものを実行)です。

$ kubectl version --short

Client Version: v1.17.4-2+a00aae1e6a4a69

Server Version: v1.17.8+vmware.1

$ ./kubectl version --short

Client Version: v1.17.8

Server Version: v1.17.8+vmware.1

 

どちらの kubectl でも、普通に TKC を操作できます。

$ ./kubectl --kubeconfig=./kubeconfig_k8s-dev-user run pod-01 --image=gowatana/centos7:httpd --restart=Never

pod/pod-01 created

$ ./kubectl --kubeconfig=./kubeconfig_k8s-dev-user get pods

NAME     READY   STATUS    RESTARTS   AGE

pod-01   1/1     Running   0          15s

 

Tanzu Kubernetes Cluster は、kubectl + vSphere プラグインによる vCenter Single Sign-On の認証だけでなく、

一般的な kubernetes と同様なクラスターへの接続ができます。

いくつか接続方法を試しましたが、もっとよい方法もあるかもしれません。

 

以上、いろいろと Tanzu Kubernetes Cluster への接続を試してみる話でした。

vSphere with Kubernetes のスーパーバイザー クラスタで、

Pod をノードに分散して起動する「アンチ アフィニティ」を試してみます。

 

vSphere で VM を起動する場合でも、複数台の VM を ESXi に分散して配置しようとするケースが多くあります。

たとえば「Web サーバ VM の 1号機と2号機は別の ESXi で起動する」といったものです。

 

vSphere Pod の実体は VM なのですが、特殊な VM なので、

ユーザが手動で vMotion できなかったり、DRS + アンチ アフィニティルールが利用できなかったりします。

 

そこで、Kubernetes の持つ affinity の仕組みを利用できそうか様子を見てみます。

 

今回の環境。

vCenter Server 7.0b / ESXi 7.0 を利用しています。

スーパーバイザー クラスタ(wcp-cluster-41)には、3台のワーカー ノードとなる ESXi があります。

vsphere-pod-aa-01.png

 

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 Kubernetes ラボ環境構築。(まとめ)

 

vSphere Pod の起動。

まず、Kubernetes の Deployment リソースで、vSphere Pod を2つ起動します。

Deployment の定義は下記のようにしています。

 

httpd.yml · GitHub

---

kind: Service

apiVersion: v1

metadata:

  name: web-svc

spec:

  type: LoadBalancer

  ports:

  - port: 80

    protocol: TCP

    targetPort: 80

  selector:

    app: demo-httpd

 

---

kind: Deployment

apiVersion: apps/v1

metadata:

  name: demo-httpd

  labels:

    app: web

spec:

  replicas: 2

  selector:

    matchLabels:

      app: demo-httpd

  template:

    metadata:

      labels:

        app: demo-httpd

    spec:

      containers:

      - name: httpd

        image: gowatana/centos7:httpd

        ports:

        - containerPort: 80

          protocol: TCP

 

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

vsphere-pod-aa-02.png

 

2つめの vSphere Pod です。

vsphere-pod-aa-03.png

 

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

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

 

アフィニティとアンチアフィニティ(日本語)

https://kubernetes.io/ja/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity

 

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

httpd_anti-affinity.yml · GitHub

 

Deployment を作成した YAML との差分です。

今回は、わかりやすく動きを見たいので、必須要件となるように

「requiredDuringSchedulingIgnoredDuringExecution」を指定しています。

$ diff httpd.yml httpd_anti-affinity.yml

37a38,47

>       affinity:

>         podAntiAffinity:

>           requiredDuringSchedulingIgnoredDuringExecution:

>           - labelSelector:

>               matchExpressions:

>               - key: app

>                 operator: In

>                 values:

>                 - demo-httpd

>             topologyKey: "kubernetes.io/hostname"

 

それでは、定義を変更(YAML を適用)します。

※今回は既存の Deployment の定義を変更していますが、新規作成でもアンチ アフィニティ配置になります。

$ kubectl apply -f httpd_anti-affinity.yml

service/web-svc unchanged

deployment.apps/demo-httpd configured

 

kubectl get pods で様子を見ていると、

Kubernetes による Pod の追加 / 削除が実施されます。

既存の Pod(~-c26jc、~-sjxpp)は停止され、あらたに Pod(~-rdz6l、~-wb774)が起動されています。

特に、スーパーバイザー クラスタだからといって、vSphere DRS で vMotion されたりはしていません。

ちなみに内部的には、ReplicaSet リソースが作成されて Pod が追加されています。

$ 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-aa-05.png

 

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

1つめの vSphere Pod です。

vsphere-pod-aa-07.png

 

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

vsphere-pod-aa-08.png

 

vSphere Pod 起動時の配置決定では DRS が利用されています。

しかし、vCenter 7.0b 時点では、vSphere Pod の配置制御を工夫したい場合には

アフィニティ ルールや DRS ではなく、Kubernetes 側の仕組みを利用するとよさそうです。

 

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

通常の Kubernetes では、名前空間(Namespace)を分ければ、同名の Pod を作成できます。

今回は、ためしに vSphere with Kubernetes の 2つのスーパーバイザー名前空間でも、

あえて同名の vSphere Pod を起動してみました。

 

ちなみに、今回の環境は vCenter Server 7.0b です。

ソフトウェア バージョンやホスト名などは異なりますが、下記のようにラボを用意しています。

vSphere with Kubernetes ラボ環境構築。(まとめ)

 

それではまず、

1つめのスーパーバイザー名前空間「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

 

Pod を「pod-01」という名前で起動します。

$ kubectl run pod-01 --image=gowatana/centos7:httpd --generator=run-pod/v1 --context=lab-ns-01

pod/pod-01 created

$ kubectl get pods --context=lab-ns-01

NAME     READY   STATUS    RESTARTS   AGE

pod-01   1/1     Running   0          102s

 

vSphere Pod として起動された様子が、vSphere Client でも確認できます。

vsphere-pod-02.png

 

2つめのスーパーバイザー名前空間は「lab-ns-02」です。

$ kubectl config get-contexts lab-ns-02

CURRENT   NAME        CLUSTER         AUTHINFO                                        NAMESPACE

          lab-ns-02   192.168.70.97   wcp:192.168.70.97:administrator@vsphere.local   lab-ns-02

 

この名前空間でも、Pod をあえて「pod-01」という名前で起動してみます。

(当然ながら起動できます)

$ kubectl run pod-01 --image=gowatana/centos7:httpd --generator=run-pod/v1 --context=lab-ns-02

pod/pod-01 created

$ kubectl get pods --context=lab-ns-02

NAME     READY   STATUS              RESTARTS   AGE

pod-01   1/1     Running             0          2m53s

 

vSphere Client でも、vSphere Pod が起動できたことが確認できます。

vsphere-pod-04.png

 

vSphere Pod の実体は VM です。

vSphere では、フォルダ内では同名の VM は作成できませんが・・・

vsphere-pod-06.png

 

一方で、リソースプール内では、もともと同名の VM が作成可能でした。

vsphere-pod-07.png

 

そして「Namespaces」リソースプールの配下の「名前空間」でも、ちゃんと同名の Pod は起動できます。

従来からの vSphere の仕組みを、うまく利用しているのだなと思いました。

 

以上、重複する名前の vSphere Pod を起動してみる話でした。

vSphere 7.0 では、コンテンツ ライブラリに登録した「仮想マシン テンプレート」で、

バージョン管理をしやすくなりました。

vSphere Client での操作で、コンテンツ ライブラリに登録したテンプレートの

「チェックアウト」、「チェックイン」といった更新管理ができるようになっています。

 

ドキュメントでは下記のあたりです。

仮想マシン テンプレートの管理

 

今回の環境。

今回の環境は、vCenter Server 7.0b(Build 16386335)を利用しています。

 

コンテンツ ライブラリには「仮想マシン テンプレート」と「OVF & OVA テンプレート」が登録できますが、

ここでの対象は「仮想マシン テンプレート」の方です。

コンテンツ ライブラリ「lib-os-02」には、「ol78-min-01」という名前で、Linux VM を登録してあります。

テンプレートの実体となる仮想マシン(最新のもものは「ol78-min-01 (3)」)や、

「このテンプレートから仮想マシンをチェックアウト」ボタンが表示されています。

lib-vm-template-00.png

 

OVF とは異なり、「仮想マシン テンプレート」では

サブスクライブしたライブラリでのコンテンツ同期はできませんが、

今回紹介するようなバージョン管理ができるようになっています。

 

「仮想マシンおよびテンプレート」のインベントリでも、

テンプレートに紐づく仮想マシン テンプレートの「サマリ」や「バージョン管理」タブから

同様の UI でチェックアウトができるようになっています。

lib-vm-template-02.png

 

古いバージョンのテンプレートには、新バージョンへのリンクがあります。

lib-vm-template-01.png

 

1. 仮想マシン テンプレートのチェックアウト。

ためしに、仮想マシン テンプレートを更新してみます。

テンプレートを選択して、「このテンプレートから仮想マシンをチェックアウト」をクリックします。

lib-vm-template-11.png

 

仮想マシン名を入力し、場所(仮想マシン フォルダ)を選択して「次へ」をクリックします。

lib-vm-template-12.png

 

クラスタ / リソースプール を選択して「次へ」をクリックします。

lib-vm-template-13.png

 

「チェックアウト後に仮想マシンをパワーオン」のチェックを入れて「完了」をクリックします。

lib-vm-template-14.png

 

仮想マシンが作成され「チェックアウト」された状態になりました。

パワーオン状態なので、この時点ではまだ「チェックイン」できません。

lib-vm-template-17.png

 

2. 仮想マシン(ゲスト OS)の更新。

起動された仮想マシンにアクセスして、ゲスト OS で何らかの更新をしておきます。

lib-vm-template-22.png

 

そして、仮想マシンを停止(ゲスト OS をシャットダウン)します。

※ゲスト OS 内部からのシャットダウンでも大丈夫です。

lib-vm-template-23.png

 

3. 仮想マシン テンプレートへのチェックイン。

チェックアウトで作成された仮想マシンには、水色の丸印がついています。

仮想マシンを停止した状態で、「テンプレートに仮想マシンをチェックイン」をクリックます。

lib-vm-template-31.png

 

「仮想マシンのチェックイン」画面で、チェックイン メモを何か入力して「チェックイン」をクリックします。

lib-vm-template-32.png

 

仮想マシンがテンプレートに変換(仮想マシン名も変更)され、

2世代前のテンプレート(元から存在していた、前バージョンのもの)は自動削除されます。

lib-vm-template-34.png

 

新しく作成された仮想マシン テンプレート「ol78-min-01 (4)」でも、

「サマリ」や「バージョン管理」タブの表示が更新されています。

lib-vm-template-35.png

 

これで、コンテンツ ライブラリの UI (でのテンプレートの右クリック)などから、

更新されたテンプレートから、仮想マシンが新規作成できるようになります。

lib-vm-template-36.png

 

参考: 仮想マシン テンプレートのバージョンを戻す。

仮想マシン テンプレートを、ひとつ前のバージョンに戻すことができます。

「・・・」→「このバージョンに戻す」から実行します。

lib-vm-template-41.png

 

「バージョンを戻す」画面で、「メモを元に戻す」に何か入力して「元に戻す」をクリックします。

lib-vm-template-42.png

 

ひとつ前のバージョンの仮想マシン テンプレート「ol78-min-01 (3)」から、あらたに「ol78-min-01 (5)」が作成されます。

このように、コンテンツ ライブラリで管理される「仮想マシン テンプレート」では、

同時に 2つまでの、実体となる仮想マシンが存在することになります。

lib-vm-template-43.png

 

ちなみに、前バージョンのテンプレート(の仮想マシン)は、

不要になったら「バージョンの削除」メニューから削除することもできます。

この例では「ol78-min-01 (5)」ではなく、古い「ol78-min-01 (4)」の方が削除されます。

lib-vm-template-45.png

 

仮想マシン テンプレート更新にかかわる手順を一般化するときに便利かなと思います。

 

以上、コンテンツ ライブラリで仮想マシンをチェックアウト / チェックインしてみる話でした。

vSphere with Kubernetes によるスーパーバイザー クラスタで、vSphere Pod が削除できなくなることがあります。

そもそも vSphere Pod は右クリックメニューなどから削除できず、わりと悩ましい状態になります。

そこで、なぜか残ってしまった Pod を削除する方法を紹介してみます。

 

削除ずみの vSphere Pod が残った状態。

kubectl(kubectl delete pod ~ など)で vSphere Pod を削除すると、

下記のような状態で Pod が残ってしまうことがあります。

通常は少し待つと自動的に削除されますが、たまに 1日待っても vCenter を再起動しても削除されないことがあります。

 

停止された Pod が残っている様子です。

vsphere-pod-del-01.png

 

ごく稀に、起動中の Pod が残ったりもします。

vsphere-pod-del-02.png

 

kubectl では、すでに Pod が削除された状態で、

対象の名前空間では、Pod がみつかりません。

$ 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

$ kubectl get pods -n lab-ns-01

No resources found in lab-ns-01 namespace.

$

 

スーパーバイザー クラスタの名前空間を削除すれば一緒に削除できますが、

Pod 単位での削除を試みます。

 

vCenter インベントリに残った vSphere Pod の削除。

まず、Pod が残った名前空間に、あえて同名の Pod「demo-centos7-httpd-6b58f9f454-2jddf」を作成します。

コンテナ イメージは何でもよいので、サイズが小さそうな busybox を利用しました。

$ kubectl run demo-centos7-httpd-6b58f9f454-2jddf --image=busybox --restart=Never

pod/demo-centos7-httpd-6b58f9f454-2jddf created

 

このとき、名前空間にはすでに同名 Pod があるため、Pod の作成は失敗します。

$ kubectl get pod

NAME                                  READY   STATUS                RESTARTS   AGE

demo-centos7-httpd-6b58f9f454-2jddf   0/1     PodVMCreationFailed   0          5s

 

vSphere Client でも、Pod の作成が失敗します。

vsphere-pod-del-03.png

 

ここから、あらためて Pod を削除します。

$ kubectl delete pod demo-centos7-httpd-6b58f9f454-2jddf

pod "demo-centos7-httpd-6b58f9f454-2jddf" deleted

$ kubectl get pod

No resources found in lab-ns-01 namespace.

 

これで Pod「demo-centos7-httpd-6b58f9f454-2jddf」は削除されました。

vsphere-pod-del-05.png

 

同様に、もう一つの vSphere Pod「demo-centos7-httpd-68979c6d58-4l47n」も削除します。

$ kubectl run demo-centos7-httpd-68979c6d58-4l47n --image=busybox --restart=Never

pod/demo-centos7-httpd-68979c6d58-4l47n created

$ kubectl get pods

NAME                                  READY   STATUS                RESTARTS   AGE

demo-centos7-httpd-68979c6d58-4l47n   0/1     PodVMCreationFailed   0          22s

$ kubectl delete pod demo-centos7-httpd-68979c6d58-4l47n

pod "demo-centos7-httpd-68979c6d58-4l47n" deleted

$ kubectl get pods

No resources found in lab-ns-01 namespace.

 

vSphere Client でも、削除が確認できました。

vsphere-pod-del-08.png

 

このように vSphere Pod が削除できますが、他にいい方法がないかは気になっています・・・

 

以上、kubectl で削除できなかった vSphere Pod を削除してみる話でした。