vm.gowatana.jp

NEOにほんごVMware(仮)

Tanzu Kubernetes クラスタへのさまざまな接続方法を試してみる。

vSphere with Tanzu のスーパーバイザー クラスタ上に作成した「Tanzu Kubernetes クラスタ」に、kubectl を使用していくつかの方法で接続してみます。

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

vSphere with Tanzu クラスタへの接続

今回の目次です。

環境について

今回の接続元の環境は 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 Kubernetes クラスタのラボは、下記のように構築しています。

vSphere with Tanzu ラボ環境構築。まとめ - vm.gowatana.jp

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

vSphere with Tanzu ラボ環境構築。Part-11: kubectl のダウンロード - vm.gowatana.jp

vCenter Server 7.0b で、3ノードの ESXi で スーパーバイザー クラスタを構成しています。スーパーバイザー クラスタ「wcp-cluster-41」の、制御プレーンの IP アドレスは「192.168.70.97」です。

f:id:gowatana:20201124080744p:plain

Tanzu Kubernetes クラスタ(TKC)は、スーパーバイザー クラスタの名前空間「lab-ns-03」に作成ずみです。TKC の名前は「tkg-cluster-41」で、制御プレーンの IP アドレスは「192.168.70.99」です。

f:id:gowatana:20201124080854p:plain

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

f:id:gowatana:20201124080924p:plain

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

f:id:gowatana:20201124080956p:plain

方法1: スーパーバイザー クラスタ制御プレーンでの vCenter Single Sign-On 認証

これはおそらくもっとも知られた方法ではないかと思います。

スーパーバイザー クラスタの制御プレーンに接続する際に、TKC を作成したスーパーバイザー 名前空間と、TKC の名前を追加で指定します。ここでは、「k8s-infra-user@go-lab.jp」という vCenter Single Sigh-On のユーザーで接続してみます。

まず、対象のユーザーには、スーパーバイザー クラスタの名前空間で「権限の追加」が必要です。そして、kubectl で TKC に接続する際は、スーパーバイザー制御プレーン宛となります。ちなみに、vCenter の管理者ユーザ(administrator@vsphere.local)であれば、デフォルトでスーパーバイザー クラスタや TKC にアクセス可能です。

f:id:gowatana:20201124081101p:plain

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

スーパーバイザー クラスタの名前空間「lab-ns-03」の、「サマリ」→「権限」にある「権限の追加」をクリックします。

f:id:gowatana:20201124081155p:plain

ID ソース、ユーザー(またはグループ)、ロールを選択して、「OK」をクリックします。今回は、ユーザー(k8s-infra-user)を指定していますが、一般的にはグループを指定するはずです。

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

f:id:gowatana:20201124081231p:plain

権限が追加されました。

f:id:gowatana:20201124081256p:plain

1-2: kubectl での接続

kubectl vsphere login でログインすると、kubeconfig のファイルが生成されます。デフォルトでは、$HOME/.kube/config というファイル名で作成されますが、環境変数 KUBECONFIG を設定しておくと、そのパスに生成されます。

$ export KUBECONFIG=$(pwd)/kubeconfig_tkc

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

  • --server: Tanzu Kubernetes クラスタの制御プレーンではなく、スーパーバイザー クラスタの、制御プレーンが持つ 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`
$

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 Tanzu ラボ環境構築。Part-16: Tanzu Kubernetes クラスタでの PSP 使用 / Deployment 作成編 - vm.gowatana.jp

方法2: Kubernetes の管理ユーザ(kubernetes-admin)での接続

この方法では、TKC を作成してあるスーパーバイザー名前空間「lab-ns-03」に自動作成されている Secret リソースから、kubeconfig の情報を取得します。これは、あらかじめ kubectl vsphere login でスーパーバイザー クラスタか TKC に接続したうえで取得することになります。

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

f:id:gowatana:20201124081907p:plain

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

Secret リソースは、「<Tanzu Kubernetes クラスタの名前>-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 制御プレーン宛となります。

f:id:gowatana:20201124082109p:plain

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 を作成しておきます。

gist.github.com

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(system:serviceaccounts)を指定しています。

gist.github.com

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 への接続はスーパーバイザー制御プレーン宛となります。

f:id:gowatana:20201124082450p:plain

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」にします。

gist.github.com

作成した 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 の「権限」画面を確認すると k8s-dev-user は存在せず、方法1 で使用した k8s-infra-user ユーザーのみが追加されています。

f:id:gowatana:20201124082745p:plain

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 クラスタは、kubectl + vSphere プラグインによる vCenter Single Sign-On の認証だけでなく、一般的な kubernetes と同様なクラスタへの接続ができます。いくつか接続方法を試しましたがもっとよい方法もあるかもしれません。

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