vm.gowatana.jp

NEOにほんごVMware(仮)

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

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

 

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

 

今回の内容です。

 

環境について

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

 

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

 

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 認証

これは、vSphere with Tanzu でもっとも一般的な方法ではないかと思います。

スーパーバイザー クラスタの制御プレーンに接続する際に、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`
$

 

ログインに成功すると、次の3つのコンテキストが作成されます。

  1. --server で指定したアドレスと同名のコンテキスト(192.168.70.97)
  2. TKC を作成したスーパーバイザー名前空間と同名のコンテキスト(lab-ns-03)
  3. TKC と同名のコンテキスト(tkg-cluster-41)

 

kubectl config get-contexts で確認すると、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 と同名のコンテキストを指定すると、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 の設定が必要になったりします。

 

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

この方法では、TKC を作成したスーパーバイザー名前空間に自動作成される Secret リソースに含まれている kubeconfig を使用して接続します。

 

kubernetes-admin の kubeconfig は、事前に kubectl vsphere login でスーパーバイザー クラスタか TKC に接続して、スーパーバイザー名前空間(この環境であれば lab-ns-03)から取得することになります。そして、取得した 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

 

Secret には、JSON Path での「.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 で、管理ユーザー(kubernetes-admin)として TKC に接続できます。コンテキストは、「kubernetes-admin@<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 ユーザー権限割り当て

スーパーバイザー名前空間ではなく、TKC に直接、vCenter SSO ユーザーの権限を割り当ててみます。 

あらかじめ、方法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 に(スーパーバイザー クラスタにも)接続することができます。

 

ためしに、スーパーバイザー制御プレーンからダウンロードしたものではなく、vSphere のプラグインもない kubectl で、TKC に接続してみます。kubeconfig は、ここまでに生成したものを利用します。

 

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

$ 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
Client Version: v1.17.4-2+a00aae1e6a4a69
$ ./kubectl version --short --client
Client Version: v1.17.8

 

kubeconfig が用意できていれば、どちらの 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 クラスタへ接続してみる話でした。