この記事では、VMware Tanzu Application Platform (以降TAP)1.4 から提供している Namespace Provisioner 機能について紹介します。
TAP が目指しているのは、開発者の皆様にとっての面倒な作業を減らし、プラットフォームチームにとっての運用周りの手間を減らすことにあります。
手間を減らす機能としてはこれまでに Service Bindings などの機能を紹介していますが、今回は TAP 1.4 から提供している Namespace Provisioner 機能について紹介します。
(ちなみに、そもそも TAP をインストールできず TAP の Namespace Provisioner 機能も含め試せない場合は、こちらのブログを参考に TAP をインストールしてみてください。)
Namespace Provisioner は、プラットフォームチームがアプリの Workload が意図通りに機能するために必要なリソースと適切な権限を備えた Namespace を安全かつ自動化された方法でプロビジョニングするための機能です。TAP 1.4 からデフォルトで利用できるようになっており、この機能を使うことで Kubernetes (K8s) に詳しくないプラットフォームエンジニアでも共有 K8s クラスター内の複数の開発者用 Namespace の払い出しを簡単に実現できます。
まず、TAP 1.4 前のバージョンではどのような手順で開発者用 Namespace を払い出しているかをみてみましょう。
今回は demo という名前の Namespace に Java アプリの Workload をデプロイするとします。
参考ドキュメントは下記となります。
https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.3/tap/GUID-set-up-namespaces.html
下記の Step1 ~ Step3 の作業はプラットフォームチーム側の作業になります。
Step1. demo という名前の Namespace を作成します。
$kubectl create ns demo
Step2. この namespace 上で Workload を作成時にコンテナイメージを <Container Repository> から pullしたり、pushできるように Secret を作成します。
(今回は Azure ACR サーバーにアクセスすることを例にしています)
tanzu secret registry add registry-credentials --server ${ACR_SERVER} --username ${ACR_USERNAME} --password ${ACR_PASSWORD} --namespace demo
Step3. demo Namespace 上に RBAC の設定を行います。
下記のように rbac.yaml を作成し、kubectl apply コマンドで実行します。
$ cat <<EOF > ${HOME}/workspace/tap-install/rbac.yaml apiVersion: v1 kind: Secret metadata: name: tap-registry annotations: secretgen.carvel.dev/image-pull-secret: "" type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: e30K --- apiVersion: v1 kind: ServiceAccount metadata: name: default secrets: - name: registry-credentials imagePullSecrets: - name: registry-credentials - name: tap-registry --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: default-permit-deliverable roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: deliverable subjects: - kind: ServiceAccount name: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: default-permit-workload roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: workload subjects: - kind: ServiceAccount name: default EOF kubectl apply -f ${HOME}/workspace/tap-install/rbac.yaml -n demo
(ここは開発者の作業範囲になります)
tanzu apps workload apply tanzu-java-web-app \ --app tanzu-java-web-app \ --git-repo https://github.com/gordon-jin/tanzu-java-web-app \ --git-branch main \ --type web \ --annotation autoscaling.knative.dev/minScale=1 \ -n demo \ -y
(Knative Services が Ready になれば、問題なくアプリにアクセスできます。)
$ tanzu apps wld get tanzu-java-web-app -n demo ? Overview name: tanzu-java-web-app type: web ? Source type: git url: https://github.com/gordon-jin/tanzu-java-web-app branch: main ? Supply Chain name: source-to-url RESOURCE READY HEALTHY TIME OUTPUT source-provider True True 7d1h GitRepository/tanzu-java-web-app image-provider True True 7d1h Image/tanzu-java-web-app config-provider True True 7d1h PodIntent/tanzu-java-web-app app-config True True 7d1h ConfigMap/tanzu-java-web-app service-bindings True True 7d1h ConfigMap/tanzu-java-web-app-with-claims api-descriptors True True 7d1h ConfigMap/tanzu-java-web-app-with-api-descriptors config-writer True True 7d1h Runnable/tanzu-java-web-app-config-writer ? Delivery name: delivery-basic RESOURCE READY HEALTHY TIME OUTPUT source-provider True True 7d1h ImageRepository/tanzu-java-web-app-delivery deployer True True 7d1h App/tanzu-java-web-app ? Messages No messages found. ? Pods NAME READY STATUS RESTARTS AGE tanzu-java-web-app-00001-deployment-db6bd4497-hjtmn 2/2 Running 0 7d1h tanzu-java-web-app-build-1-build-pod 0/1 Completed 0 7d1h tanzu-java-web-app-config-writer-pgkzb-pod 0/1 Completed 0 7d1h ? Knative Services NAME READY URL tanzu-java-web-app Ready https://tanzu-java-web-app.demo.172.17.203.60.sslip.io To see logs: "tanzu apps workload tail tanzu-java-web-app --namespace demo"
開発者が利用する 1 個の Namespace を払い出すたびにプラットフォームチームは Step1 ~ Step3 の面倒なことを繰り返しながら実行する必要があります。
特に Step3 のような長い Yaml ファイルを Namespace を払い出すたびに使う必要があります。
では、TAP 1.4 でこの作業がどのように楽になるかをみてみましょう。
Step1. demo namespace を作成します。
$kubectl create ns demo
Step2. Secret を作成
(こちらの Step は最初の一回のみ実行する必要があります )
tanzu secret registry add registry-credentials --server ${ACR_SERVER} --username ${ACR_USERNAME} --password ${ACR_PASSWORD} --namespace tap-install --export-to-all-namespaces -y
Step3. 払い出す Namespace にラベルを設定します。
kubectl label namespaces demo apps.tanzu.vmware.com/tap-ns=""
「Step1. namespace を作成」、「Step2. 払い出す Namespace にラベルを設定する」だけで新しい Namespace を簡単に払い出すことができます。
具体例でみる Namespace Provisioner 機能
さて、上の説明だけではイメージがつかないと思うので、実際の TAP 1.4 を使い Namespace の払い出しと払い出された Namespace 上にアプリの Workload をデプロイしてみたいと思います。
(下記の Step1 と Step2 はプラットフォームチーム側の作業になります)
Step1. dev01 という名前の Namespace を作成します。
$ kubectl create ns dev01 namespace/dev01 created
Step2. dev01 Namespace にラベルを設定します。
(今回は、二回目以降の Namespace 払い出しの作業になるため 「Secret 作成」の作業は省きます)
$ kubectl label namespaces dev01 apps.tanzu.vmware.com/tap-ns="" namespace/dev01 labeled
ここからは開発者の作業になります。
tanzu apps workload apply tanzu-java-web-app \ --app tanzu-java-web-app \ --git-repo https://github.com/gordon-jin/tanzu-java-web-app \ --git-branch main \ --type web \ --annotation autoscaling.knative.dev/minScale=1 \ -n dev01 \ -y
しばらく経つと TAP GUI から tanzu-java-web-app という workload が dev01 Namespace 上にデプロイされているのを確認できます。
該当 workload の URL を確認し、アプリにアクセスしてみます。
$ kubectl get ksvc -n dev01 NAME URL LATESTCREATED LATESTREADY READY REASON tanzu-java-web-app https://tanzu-java-web-app.dev01.172.17.203.60.sslip.io tanzu-java-web-app-00001 tanzu-java-web-app-00001 True
$ curl -sk https://tanzu-java-web-app.dev01.172.17.203.60.sslip.io welcome tanzu and TAP
いかがでしょうか?
Namespace の払い出し作業がかなりシンプルになってるのを確認できると思います。
Namespace Provisioner 機能の仕組み
では、Namespace Provisioner 機能の仕組みについて少し説明します。
実際、apps.tanzu.vmware.com/tap-ns=”” というラベルを新しく作成した Namespace に設定すると裏でなにが起きているかをみてみましょう。
$ kubectl get secrets,serviceaccount,rolebinding,configmap -n dev01 NAME TYPE DATA AGE secret/default-token-xm7pt kubernetes.io/service-account-token 3 38s secret/registries-credentials kubernetes.io/dockerconfigjson 1 14s NAME SECRETS AGE serviceaccount/default 2 38s NAME ROLE AGE rolebinding.rbac.authorization.k8s.io/default-permit-deliverable ClusterRole/deliverable 14s rolebinding.rbac.authorization.k8s.io/default-permit-workload ClusterRole/workload 14s NAME DATA AGE configmap/kube-root-ca.crt 1 38s
上記のように一覧のリソースが自動的に作成されているのを確認できます。
Namespace Provisioner のアーキテクチャについてもみてみましょう。
Namespace Provisioner のアーキテクチャ図:
Namespace Provisioner は、tap-namespace-provisioning という Namespace にインストールされる Carvelアプリケーションで構成されています。
$ kubectl get pods -n tap-namespace-provisioning NAME READY STATUS RESTARTS AGE controller-manager-6dc566c644-mbnlf 1/1 Running 0 2d5h
Provisioner アプリケーションは ytt を使用してリソースのセットを複数の Namespace にインストールするようにテンプレート化しています。
tap-namespace-provisioning の Namespace にある desired-namespaces という ConfigMap は
どの Namespace にリソースを配置するかを示す宣言的な方法を提供します。
$ kubectl get configmap -n tap-namespace-provisioning NAME DATA AGE controller-config 1 2d5h desired-namespaces 1 2d5h expansion-template 1 2d5h kube-root-ca.crt 1 2d5h ns-selector-config 1 2d5h provisioner-ctrl 1 2d5h provisioner-ctrl-change-5jdlp 1 3m58s provisioner-ctrl-change-7gcv2 1 24m provisioner-ctrl-change-f7vnv 1 14m provisioner-ctrl-change-nr6ph 1 90s provisioner-ctrl-change-tchjz 1 34m
$ kubectl describe configmap desired-namespaces -n tap-namespace-provisioning Name: desired-namespaces Namespace: tap-namespace-provisioning Labels: kapp.k14s.io/app=1678235192605669950 kapp.k14s.io/association=v1.5c8b25dcf919f5c82c8b6da7f53b1c32 Annotations: doc: This resources has been created for you as part of the necessary resources for running your cluster supply chain. You are free to make cha... kapp.k14s.io/change-group: namespace-provisioner.apps.tanzu.vmware.com/delete-after-app kapp.k14s.io/create-strategy: fallback-on-update kapp.k14s.io/identity: v1;tap-namespace-provisioning//ConfigMap/desired-namespaces;v1 kapp.k14s.io/original: {"apiVersion":"v1","data":{"namespaces.yaml":"#@data/values\n---\nnamespaces:\n"},"kind":"ConfigMap","metadata":{"annotations":{"doc":"Thi... kapp.k14s.io/original-diff-md5: 58e0494c51d30eb3494f7c9198986bb9 namespace-provisioner.apps.tanzu.vmware.com/no-overwrite: Data ==== namespaces.yaml: ---- #@data/values --- namespaces: - name: demo - name: dev01 BinaryData ==== Events: <none>
先程、ラベルを設定した dev01 の Namespace も確認できます。
最後に kapp CLI を使って Namespace Provisioner によって作成されたリソースを確認します。
$ kapp inspect -n tap-namespace-provisioning -a provisioner-ctrl Target cluster 'https://172.17.203.54:6443' (nodes: tkg-gj1-full2-control-plane-vrxmx, 3+) Resources in app 'provisioner-ctrl' Namespace Name Kind Owner Rs Ri Age demo default ServiceAccount kapp ok - 2d ^ default-permit-deliverable RoleBinding kapp ok - 2d ^ default-permit-workload RoleBinding kapp ok - 2d ^ registries-credentials Secret kapp ok - 2d dev01 default ServiceAccount kapp ok - 57m ^ default-permit-deliverable RoleBinding kapp ok - 57m ^ default-permit-workload RoleBinding kapp ok - 57m ^ registries-credentials Secret kapp ok - 57m Rs: Reconcile state Ri: Reconcile information 8 resources Succeeded
まとめ
ここまで TAP 1.4 で提供している Namespace Provisioner 機能について紹介しました。
この機能を利用することで、プラットフォームチームは必要なリソースと適切な権限を備えた Namespace をかなりシンプルに払い出すことができ、開発者はその Namespace を使ってアプリの Workload を K8s へデプロイできます。
VMware ブログでは、引き続き TAP の新機能を続々と紹介させていただきます。