IK.AM

@making's tech note


Tanzu Application Platform 1.2 on Azure ハンズオン


⚠️ 本記事の内容はVMwareによってサポートされていません。 記事の内容で生じた問題については自己責任で対応し、 VMwareサポート窓口には問い合わせないでください

Tanzu Application Platform (TAP)をインストールし、様々な機能を試すハンズオンです。

TAPの大まかな構成要素を次の図で表すと、

alt_text

本ハンズオンでカバーするのは次の黄色の部分のみです。

alt_text

本ハンズオンではAzure Kubernetes Service (AKS)にTAP 1.2をインストールします。

以降、[O] がつく節はPlatform Operatorが担当する作業です。[D] がつく節はApp Developerが担当する作業です。

ハンズオン参加者は事前に与えられたハンズオン作業環境 (VS Code Server) にアクセスしてください。

ℹ️ ハンズオン環境をAKS上に作成する方法はこちらを参照してください。

ハンズオン環境をローカルで実行したい場合は、以下で実行できます(未検証)。

docker run \
  --name code-server \
  --rm \
  -p 3000:3000 \
  -e PASSWORD=password  \
  -e PORT=3000 \
  -e NAMESPACE=handson-00 \
  ghcr.io/making/code-server@sha256:3b671ae5a4e991e72eda10253b6edc945d52ec49b4a246f3034d4ab93457cee2

次のようなダイアログが表示されたら"Yes, I trust the authors"をクリックしてください。

alt_text


目次

Tanzu Application Platformのインストール (Iterate Profile)

まずはイテレーション開発用のiterate profileをインストールします。Iterate ProfileはTAPの全構成要素のうち、次の図の部分のみをインストールします。

alt_text

[O] リソースグループの作成

TAPをインストールするためのAzureリソースグループを作成します。

alt_text

VS Codeのメニューから”Terminal” -> “New Terminal”を選択し、作業用のターミナルを開いてください。

まずはAzureにログインします。次のコマンドを実行してください。

az login --allow-no-subscriptions

ログインのURLとコードが出力されるので、ブラウザで開いてコードを入力し、

alt_text

リソースグループ名は”tap-${NAMESPACE}”とします。次のコマンドを実行し、リソースグループを作成してください。

環境変数NAMESPACEに値が入っていない場合は任意の値を設定してください。

az group create --name tap-${NAMESPACE} --location japaneast

[O] Azure Container Registryインスタンスの作成

次にAzure Container Registry (ACR)のインスタンスを作成します。このRegistryにはTAPにデプロイするアプリの

  • コンテナイメージ
  • マニフェスト
  • ソースコード

が格納されます。

次のコマンドを実行してください。

ACR_NAME=tap${RANDOM}
az acr create --resource-group tap-${NAMESPACE} \
  --location japaneast \
  --name ${ACR_NAME} --sku standard \
  --admin-enabled true

ACRへの接続情報を変数に設定します。次のコマンドを実行してください。これらの変数はTAPインストール時に使用します。

ACR_SERVER=${ACR_NAME}.azurecr.io
ACR_USERNAME=${ACR_NAME}
ACR_PASSWORD=$(az acr credential show --name ${ACR_NAME} --resource-group tap-${NAMESPACE} --query 'passwords[0].value' --output tsv)

次のコマンドで、接続情報が正しいことを試します。試した後は生成されたconfigファイルを削除します。

docker login ${ACR_SERVER} -u ${ACR_USERNAME} -p ${ACR_PASSWORD}
rm -rf ${HOME}/.docker/config.json

TODO 今回はadminユーザーを使用しているが、本来は使用すべきでない。要検討。

[O] Azure Kubernetes Serviceクラスタの作成

次にAzure Kubernetes Service (AKS)のK8sクラスタを作成します。このK8sクラスタにTAPをインストールします。

次のコマンドを実行してください。

az aks create \
  --resource-group tap-${NAMESPACE} \
  --location japaneast \
  --name tap-sandbox \
  --node-count 2 \
  --enable-cluster-autoscaler \
  --min-count 1 \
  --max-count 10 \
  --node-vm-size standard_f4s_v2 \
  --load-balancer-sku standard \
  --network-plugin kubenet \
  --network-policy calico \
  --zones 1 2 3 \
  --generate-ssh-keys \
  --enable-aad

次のコマンドでK8sクラスタへの接続情報を取得してください。

az aks get-credentials --resource-group tap-${NAMESPACE} --name tap-sandbox --admin --overwrite-existing

次のコマンドでK8sクラスタへ接続できることを確認してください。

kubectl cluster-info

alt_text

[O + D] EULAのAgree

Tanzu Network のアカウントがない場合は作成してください。

Tanzu Networkにログインして、次のプロダクトのELUAをAgreeしてください。

Agreeしていない場合は、 "Click here to sign the EULA" をクリックしてください。

[O + D] Tanzu CLIのインストール

TAPをインストールしたり、TAPにアプリをデプロイするために使用するTanzu CLIをインストールします。Tanzu CLIはTanzu Networkからダウンロードできます。

CLIからTanzu CLIなどをダウンロードするために、API TOKENを取得します。

https://network.tanzu.vmware.com/users/dashboard/edit-profile (要ログイン)

下の図の"REQUEST NEW REFRESH TOKEN"をクリックし、API TOKENを取得してください。

alt_text

取得したAPI TOKENを使用して、次のコマンドを実行してください。

API_TOKEN=......
pivnet login --api-token=${API_TOKEN}

次のコマンドを実行して、Tanzu CLIをダウンロードし、インストールしてください。

pivnet download-product-files --product-slug='tanzu-application-platform' --release-version='1.2.1' --glob='tanzu-framework-linux-amd64.tar'
tar xvf tanzu-framework-*-amd64.tar
mkdir -p ${HOME}/.local/bin
install cli/core/*/tanzu-core-*_amd64 ${HOME}/.local/bin/tanzu

次のコマンドを実行して、CLIのversionを確認してください。

tanzu version

alt_text

次のコマンドを実行してTAPで使用するプラグインをインストールしてください。

tanzu plugin install --local cli all

alt_text

不要なファイルは削除してください。

rm -f tanzu-framework-linux-amd64.tar
rm -rf cli

[O] Cluster Essentials for VMware Tanzuのインストール

TAPを管理するための主要なOSSコンポーネントとして、kapp controllersecretgen controllerがあります。

これらはGithub上のmanifestを使用してもインストールできますが、Cluster Essentials for VMware TanzuとしてTanzu Networkからも配布されているため、今回はCluster Essentials for VMware Tanzuをインストールします。

次のコマンドでCluster Essentials for VMware TanzuのInstallerをダウンロードします。

mkdir -p ${HOME}/workspace/tap-install
cd ${HOME}/workspace/tap-install
pivnet download-product-files --product-slug='tanzu-cluster-essentials' --release-version='1.2.0' --glob='tanzu-cluster-essentials-linux-amd64-*'

次のコマンドでCluster Essentials for VMware Tanzuをインストールします。TANZUNET_USERNAMEにはTanzu Networkのユーザー名(メールアドレス)を、TANZUNET_PASSWORDにはパスワードを設定してください。

TANZUNET_USERNAME=...
TANZUNET_PASSWORD=...

mkdir tanzu-cluster-essentials
tar xzvf tanzu-cluster-essentials-*-amd64-*.tgz -C tanzu-cluster-essentials

export INSTALL_BUNDLE=registry.tanzu.vmware.com/tanzu-cluster-essentials/cluster-essentials-bundle:1.2.0
export INSTALL_REGISTRY_HOSTNAME=registry.tanzu.vmware.com
export INSTALL_REGISTRY_USERNAME=${TANZUNET_USERNAME}
export INSTALL_REGISTRY_PASSWORD=${TANZUNET_PASSWORD}
cd tanzu-cluster-essentials
./install.sh --yes
cd ..

次のコマンドを実行して、Cluster Essentials for VMware Tanzuインストール後の全Pod一覧を確認してください。

kubectl get pod -A

alt_text

[O] Package Repositoryの登録

TAPはkapp controllerのPackage Repositoryという仕組みを使用して配布されています。

次のコマンドで、TAPのPackage Repositoryを"tap-install" namespaceに登録します。

TANZUNET_USERNAME=...
TANZUNET_PASSWORD=...

kubectl create ns tap-install

tanzu secret registry add tap-registry \
  --username "${TANZUNET_USERNAME}" \
  --password "${TANZUNET_PASSWORD}" \
  --server registry.tanzu.vmware.com \
  --kubeconfig ${HOME}/.kube/config \
  --export-to-all-namespaces \
  --yes \
  --namespace tap-install

tanzu package repository add tanzu-tap-repository \
  --url registry.tanzu.vmware.com/tanzu-application-platform/tap-packages:1.2.1 \
  --namespace tap-install \
  --kubeconfig ${HOME}/.kube/config

登録したPackage Repositoryから利用可能なPackage一覧を次のコマンドで確認できます。

tanzu package available list --namespace tap-install --kubeconfig ${HOME}/.kube/config

alt_text

[O] Iterate Profileのインストール

いよいよTAP (Iterate Profile)をインストールします。

次のコマンドでTAPをインストールするための設定ファイルを作成します。cnrs.domain_nameに設定したドメイン名は後に変更します。

cd ${HOME}/workspace/tap-install
cat <<EOF > tap-values.yml
profile: iterate

ceip_policy_disclosed: true

cnrs:
  domain_name: tap.example.com
  domain_template: "{{.Name}}-{{.Namespace}}.{{.Domain}}"

buildservice:
  kp_default_repository: ${ACR_SERVER}/build-service
  kp_default_repository_username: ${ACR_USERNAME}
  kp_default_repository_password: ${ACR_PASSWORD}

supply_chain: basic

ootb_supply_chain_basic:
  registry:
    server: ${ACR_SERVER}
    repository: supply-chain
  gitops:
    ssh_secret: ""

contour:
  infrastructure_provider: azure
  envoy:
    service:
      type: LoadBalancer
      annotations: {}
EOF

次のコマンドでTAPをインストールします。

tanzu package install tap \
  -p tap.tanzu.vmware.com \
  -v 1.2.1 \
  --values-file ${HOME}/workspace/tap-install/tap-values.yml \
  -n tap-install \
  --kubeconfig ${HOME}/.kube/config \
  --wait=false

インストールの進捗状況を次のコマンドで確認できます。12分くらいでインストールが完了します。

while [ "$(kubectl -n tap-install get app tap -o=jsonpath='{.status.friendlyDescription}')" != "Reconcile succeeded" ];do
  date
  kubectl get app -n tap-install
  echo "---------------------------------------------------------------------"
  sleep 30
done
echo "✅ Install succeeded"

alt_text

TAP上のアプリケーションへのリクエストは全て"tanzu-system-ingress" namespaceのenvoyを経由します。envoyにはLoad Balancerがアタッチされ、External IPが設定されます。このIPを使用して、ドメイン名を用意します。今回はsslip.ioを使用します。例えばdemo.8-8-8-8.sslip.ioは8.8.8.8に解決されます。

次のコマンドを実行して、tap-values.yml中のexample.comをa-b-c-d.sslip.ioに置換します。(a.b.c.dはEnvoyのExternal IP)

DOMAIN_NAME=$(kubectl get -n tanzu-system-ingress svc envoy -ojsonpath='{.status.loadBalancer.ingress[0].ip}' | sed 's/\./-/g').sslip.io
sed -i.bak "s|example.com|${DOMAIN_NAME}|g" tap-values.yml

次のコマンドを実行して、TAPに変更を適用します。

tanzu package installed update tap -f tap-values.yml -n tap-install --kubeconfig ${HOME}/.kube/config

設定されたことを次のコマンドで確認できます。

kubectl get cm -n knative-serving config-domain -ojsonpath='{.data}'

alt_text

以降、アプリへのリクエストのルーティングは次の図のようになります。

alt_text

Tanzu Application PlatformにWorkloadをデプロイ

インストールしたTAPにWorkloadをデプロイします。

[O] Workloadデプロイのための準備

"demo" namespaceにWorkloadをデプロイします。本節の作業はデプロイしたいnamespace毎に必要です。

kubectl create ns demo

このnamespace上でTAPで作成されるコンテナイメージをACRからpullしたり、ACRにpushできるようにSecretを作成します。次のコマンドを実行してください。

tanzu secret registry add registry-credentials --server ${ACR_SERVER} --username ${ACR_USERNAME} --password ${ACR_PASSWORD} --namespace demo --kubeconfig ${HOME}/.kube/config

TODO 今回はadminユーザーを使用しているが、本来は使用すべきでない。要検討。

このnamespace上にTAPがWorkloadをデプロイできるためのRBACの設定を行います。次のコマンドを実行してください。

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

次のコマンドを叩いて、Secetを確認してください。

kubectl get secret -n demo

alt_text

[D] Node.jsアプリをGit上のソースコードからデプロイ

"demo" namespaceに簡単なNode.jsのアプリをデプロイします。ソースコードはGitから取得します。

tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo https://github.com/making/hello-nodejs \
  --git-branch master \
  --type web \
  -n demo \
  -y

次のコマンドでログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=hello-nodejs

次のコマンドを実行し、"Knative Services"に Ready が表示されればアプリのデプロイが完了です。

tanzu apps workload get -n demo hello-nodejs

alt_text

このWorkloadから作成される主要なリソースは次のコマンドで確認できます。

kubectl get workload,pod,gitrepo,imgs,build,podintent,taskrun,deliverable,imagerepository,app,ksvc -n demo -owide -l app.kubernetes.io/part-of=hello-nodejs

alt_text

kubectl treeプラグインを使うと作成されたリソースが階層的にわかります。

kubectl tree -n demo workload hello-nodejs

alt_text

アプリにアクセスしましょう。

curl -sv $(kubectl get ksvc -n demo hello-nodejs  -ojsonpath='{.status.url}')

alt_text

ソースコードを変更し、Gitにpushするとアプリはローリングアップデートで再デプロイされます。

https://github.com/making/hello-nodejs を自分のレポジトリにフォークして、Workloadを更新し、ソースコードを更新してみてください。

FORKED_REPO=https://…
tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo ${FORKED_REPO} \
  --git-branch master \
  --type web \
  -n demo \
  -y

TAPではRuntimeに使用しているKnative Servingの仕様によりデフォルトで、1分間リクエストがないとインスタンス数が自動で0になります (Scale to Zero)。再度リクエストを受け付けた際にインスタンスが自動で再作成 されます。 最小インスタンス数を1以上に設定することで、"Scale to Zero"を無効にできます。

次のコマンドで最小インスタンス数を指定できます。

tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo https://github.com/making/hello-nodejs \
  --git-branch master \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  -n demo \
  -y

デプロイしたWorkloadを次のコマンドで削除します。

tanzu apps workload delete -n demo hello-nodejs -y

[D] JavaアプリをGit上のソースコードからデプロイ

"demo" namespaceに簡単なJavaのアプリをデプロイします。ソースコードはGitから取得します。

tanzu apps workload apply tanzu-java-web-app \
  --app tanzu-java-web-app \
  --git-repo https://github.com/sample-accelerators/tanzu-java-web-app \
  --git-branch main \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  -n demo \
  -y

次のコマンドでログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=tanzu-java-web-app

次のコマンドを実行し、"Knative Services"に Ready が表示されればアプリのデプロイが完了です。

tanzu apps workload get -n demo tanzu-java-web-app

alt_text

このWorkloadから作成される主要なリソースは次のコマンドで確認できます。

kubectl get workload,pod,gitrepo,imgs,build,podintent,taskrun,deliverable,imagerepository,app,ksvc -n demo -owide -l app.kubernetes.io/part-of=tanzu-java-web-app

alt_text

kubectl treeプラグインを使うと作成されたリソースが階層的にわかります。

kubectl tree -n demo workload tanzu-java-web-app

alt_text

アプリにアクセスしましょう。

curl -sv $(kubectl get ksvc -n demo tanzu-java-web-app  -ojsonpath='{.status.url}')

alt_text

デプロイしたWorkloadを次のコマンドで削除します。

tanzu apps workload delete -n demo tanzu-java-web-app -y

[D] Dockerfileでイメージビルド

TAPではデフォルトでKpackによりTanzu Buildpacksを使用してソースコードからコンテナイメージが自動で作成されます。Buildpackではなく、Dockerfileでコンテナイメージを作成することも可能です。内部的にはKanikoが使用されます。

先ほどデプロイしたNode.jsのアプリを今度はDockerfileを使用してデプロイしましょう。次のコマンドを実行してください。

tanzu apps workload apply hello-nodejs \
  --app hello-nodejs \
  --git-repo https://github.com/making/hello-nodejs \
  --git-branch master \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  --param dockerfile=./Dockerfile \
  -n demo \
  -y

次のコマンドでログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=hello-nodejs

次のコマンドを実行し、"Knative Services"に Ready が表示されればアプリのデプロイが完了です。

tanzu apps workload get -n demo hello-nodejs

alt_text

このWorkloadから作成される主要なリソースは次のコマンドで確認できます。

kubectl get workload,pod,gitrepo,imgs,build,podintent,taskrun,deliverable,imagerepository,app,ksvc -n demo -owide -l app.kubernetes.io/part-of=hello-nodejs

alt_text

kubectl treeプラグインを使うと作成されたリソースが階層的にわかります。Buildpackを使った場合と作成されるリソースに違いがあることを確認してください

kubectl tree -n demo workload hello-nodejs

alt_text

アプリにアクセスしましょう。

curl -sv $(kubectl get ksvc -n demo hello-nodejs  -ojsonpath='{.status.url}')

alt_text

デプロイしたWorkloadを次のコマンドで削除します。

tanzu apps workload delete -n demo hello-nodejs -y

[D] Docker Imageを直接デプロイ

ここまでTAPにソースコードからアプリをデプロイしてきましたが、ビルド済みのDocker Imageからアプリをデプロイすることもできます。この場合、これまでとは異なるSupply Chainを使用します。

利用可能なSupply Chain一覧を次のコマンドで確認できます。

tanzu apps cluster-supply-chain list

alt_text

これまでは"source-to-url" Supply Chainを使用してきました。今回は"basic-image-to-url" Supply Chainを使用します。

それぞれのSupply Chainを使用するためのWorkloadの条件は次のコマンドで確認できます。

tanzu apps cluster-supply-chain get source-to-url
tanzu apps cluster-supply-chain get basic-image-to-url

alt_text

Workloadのspec.imageに値が設定されている場合は"basic-image-to-url" Supply Chainが選択されます。

--imageオプションでデプロイしたいDocker Imageを指定します。ここではTAP 1.2のBuildpackではサポートされていないRubyのアプリケーションをデプロイします。次のコマンドを実行してください。

tanzu apps workload apply hello-ruby \
  --app hello-ruby \
  --image gcr.io/knative-samples/helloworld-ruby \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  --env TARGET="TAP" \
  -n demo \
  -y

次のコマンドでログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=hello-ruby

次のコマンドを実行し、"Knative Services"に Ready が表示されればアプリのデプロイが完了です。

tanzu apps workload get -n demo hello-ruby

alt_text

このWorkloadから作成される主要なリソースは次のコマンドで確認できます。

kubectl get workload,pod,gitrepo,imgs,build,podintent,taskrun,deliverable,imagerepository,app,ksvc -n demo -owide -l app.kubernetes.io/part-of=hello-ruby

alt_text

kubectl treeプラグインを使うと作成されたリソースが階層的にわかります。Buildpackソースコードからコンテナイメージをビルドする場合と作成されるリソースに違いがあることを確認してください

kubectl tree -n demo workload hello-ruby

alt_text

アプリにアクセスしましょう。

curl -sv $(kubectl get ksvc -n demo hello-ruby  -ojsonpath='{.status.url}')

alt_text

デプロイしたWorkloadを次のコマンドで削除します。

tanzu apps workload delete -n demo hello-ruby -y

[D] Javaアプリをローカルパスのソースコードからデプロイ

これまではGit上のソースコードからアプリをデプロイしていましたが、今回はローカルパスにあるソースコードからアプリをデプロイします。先にデプロイしたJavaアプリのソースコードをgit cloneします。

cd ${HOME}/workspace
git clone https://github.com/sample-accelerators/tanzu-java-web-app
cd tanzu-java-web-app

ローカルパスのソースコードをTAP上にデプロイするために、Tanzu CLIはいったんソースコードをコンテナレジストリにアップロードします。ACRにアップロードできるようにACRへログインします。ログインするためのスクリプトを次のコマンドで作成します。az acr loginコマンドでログインするにはDocker Deamonが必要です。Docker Daemonが起動していない環境ではスクリプトのようにログインできます。

cat << EOF > ${HOME}/acr-login.sh
###/bin/bash
set -e
ACR_NAME=$(az acr list --resource-group tap-${NAMESPACE} --query '[0].name' --output tsv)
az acr login -n ${ACR_NAME} --expose-token > ${HOME}/acr-token.json
ACR_SERVER=\$(cat ${HOME}/acr-token.json | jq -r .loginServer)
ACR_TOKEN=\$(cat ${HOME}/acr-token.json | jq -r .accessToken)
set -x
docker login${ACR_SERVER} -u 00000000-0000-0000-0000-000000000000 -p${ACR_TOKEN}
EOF
chmod +x ${HOME}/acr-login.sh

次のコマンドでACRへログインしてください。

${HOME}/acr-login.sh 

Tokenは約3時間で失効します。失効したら再度このスクリプトを実行してください。

次のコマンドでローカルパスのソースコードをTAPにデプロイします。

cd ${HOME}/workspace/tanzu-java-web-app

tanzu apps workload apply tanzu-java-web-app \
  --app tanzu-java-web-app \
  --local-path . \
  --source-image ${ACR_SERVER}/sources/demo/tanzu-java-web-app \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  -n demo \
  -y

次のコマンドでログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=tanzu-java-web-app

次のコマンドを実行し、"Knative Services"に Ready が表示されればアプリのデプロイが完了です。

tanzu apps workload get -n demo tanzu-java-web-app

alt_text

このWorkloadから作成される主要なリソースは次のコマンドで確認できます。

kubectl get workload,pod,gitrepo,imgs,build,podintent,taskrun,deliverable,imagerepository,app,ksvc -n demo -owide -l app.kubernetes.io/part-of=tanzu-java-web-app

alt_text

kubectl treeプラグインを使うと作成されたリソースが階層的にわかります。Git上のソースコードからデプロイする場合と作成されるリソースに違いがあることを確認してください

kubectl tree -n demo workload tanzu-java-web-app

alt_text

アプリにアクセスしましょう。

curl -sv $(kubectl get ksvc -n demo tanzu-java-web-app  -ojsonpath='{.status.url}')

alt_text

ブラウザからもアクセスしましょう。

alt_text

[D] Tanzu VS Code Extensionsのインストール

開発中、ローカルパスのソースコードを変更する際に効率よくTAPにデプロイするためにVS CodeのExtensionが用意されています。

次のコードでExtensionをダウンロードしてください。

pivnet download-product-files --product-slug='tanzu-application-platform' --release-version=1.2.1 --glob='*.vsix'

次のコマンドでExtensnionをVS Code Serverにインストールします。

for vsix in $(ls *.vsix);do
    /usr/lib/code-server/bin/code-server --install-extension ${vsix}
done
rm -f *.vsix

alt_text

VS Code ServerのExtension一覧に次の図のような"Tanzu …" Extensnionが表示されていることを確認してください。

alt_text

右下のポップアップの"Update Workspace Settings"ボタンをクリックし、 "Restart Now" ボタンをクリックしてリスタートしてください。

[D] Live Update

変更したソースコードが即時TAP上に反映される”Live Update”を試します。Live UpdateはTiltによって実現されます。

まずは、git cloneしたソースコードをVS Code Serverで開きます。メニューから”File” -> "Open Folder"を選択してください。

alt_text

"/home/coder/workspace/tanzu-java-web-app"を選択してください。

alt_text

次の図のように、Extensions一覧から”Tanzu Developer Tools”を右クリックして、”Extension Settings”を選択してください。

alt_text

次の図のように、Workspaceタブで"Namespace"に"demo"を"Source Image"に

echo $(cat ${HOME}/acr-token.json | jq -r .loginServer)/sources/demo/tanzu-java-web-app

の出力結果を設定してください。

alt_text

tanzu-java-web-appフォルダの"Tiltfile"を右クリックし、"Tanzu: Live Update Start" をクリックします。

alt_text

次の図のようなエラーが出るでしょう。デプロイ先のK8sクラスタを誤らないために予防されています。

alt_text

出力された allow_k8s_contexts('tap-sandbox-admin') を、次の図のようにTiltfileに追記してください。Tilefileを保存するとデプロイが始まります。

alt_text

初回のデプロイが完了したら、ブラウザからアクセスしましょう。

alt_text

次にソースコードを変更しましょう。 src/main/java/com/example/springboot/HelloController.java を開き、index()メソッドの返り値の文字列を変更してください。変更のあったファイルだけがコンテナに転送され、コンテナ内のアプリだけが再起動します。

alt_text

ブラウザをリロードし、変更が即時に反映されていることを確認してください。

alt_text

もう一度、コードを変更してください。

alt_text

ブラウザをリロードし、変更が即時に反映されていることを確認してください。

alt_text

Live Updateを止める場合は、Tiltfileを右クリックし、"Tanzu: Live Update Stop" をクリックします。

alt_text

次の図のようなログが出力されます。エンターキーを押すと、ターミナルが閉じます。この手順でLive Updateを止めないと、Tiltが起動し続け、次のStart時にポートが衝突するので、注意してください。

alt_text

[D] Live Debug

次にTAP上にデプロイされたアプリを直接Debugできる、"Live Debug"を試します。

次の図のように、tanzu-java-web-app/configフォルダの"workload.yaml"を右クリックし、"Tanzu: Java Debug Start" をクリックします。

alt_text

しばらくすると、次の図のように、"Port forwarding to tanzu-java-web-app-******" というメッセージが出力され、フッターのバーの色が代わります。

alt_text

ソースコードを開いて、止めたい行の左をクリックして、Break Pointを設定します。

alt_text

この状態で、アプリにアクセスすると、次の図のようにBreak Pointを通った場所で停止します。この状態の変数などを確認することができます。バーの ▶️ ボタンをクリックすると、処理が再開します。

alt_text

Live Debugを終了する場合は、バーからStopを選択してください。この方法で止めないとDebugモードやPort Forwardが残ったままになるので気をつけてください。

alt_text

[O] HTTPS対応

TAPをデフォルトでインストールした場合はHTTPのみ有効になっています。TLS証明書を作成し、tap-values.ymlに設定することでHTTPSに対応できます。

TLS証明書はcert-managerを用いて作成します。次のコマンドを実行してください。

DOMAIN_NAME=$(kubectl get -n tanzu-system-ingress svc envoy -ojsonpath='{.status.loadBalancer.ingress[0].ip}' | sed 's/\./-/g').sslip.io

cat <<EOF > ${HOME}/workspace/tap-install/default-tls.yaml
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: cnrs-selfsigned-issuer
  namespace: tanzu-system-ingress
spec:
  selfSigned: { }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cnrs-ca
  namespace: tanzu-system-ingress
spec:
  commonName: cnrs-ca
  isCA: true
  issuerRef:
    kind: Issuer
    name: cnrs-selfsigned-issuer
  secretName: cnrs-ca
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: cnrs-ca-issuer
  namespace: tanzu-system-ingress
spec:
  ca:
    secretName: cnrs-ca
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cnrs-default-tls
  namespace: tanzu-system-ingress
spec:
  dnsNames:
  - "*.tap.${DOMAIN_NAME}"
  issuerRef:
    kind: Issuer
    name: cnrs-ca-issuer
  secretName: cnrs-default-tls
---
apiVersion: projectcontour.io/v1
kind: TLSCertificateDelegation
metadata:
  name: contour-delegation
  namespace: tanzu-system-ingress
spec:
  delegations:
  - secretName: cnrs-default-tls
    targetNamespaces:
    - "*"
EOF

kubectl apply -f ${HOME}/workspace/tap-install/default-tls.yaml

次のコマンドで、作成されたSecretを確認します。

kubectl get secret -n tanzu-system-ingress

alt_text

ワイルドカード証明書である、 "cnrs-default-tls" をデフォルトのTLS証明書として使用します。 TLSCertificateDelegationが作成されていることで、この"cnrs-default-tls"が他のnamespaceでも利用可能になります。

次のように、tap-values.ymlのcnrs.default_tls_secretを設定してください。

### …

cnrs:
  # ...
  default_tls_secret: tanzu-system-ingress/cnrs-default-tls

### …

次のコマンドを実行して、TAPに変更を適用します。

tanzu package installed update tap -f ${HOME}/workspace/tap-install/tap-values.yml -n tap-install --kubeconfig ${HOME}/.kube/config

alt_text

TAPのRuntimeであるKnative ServiceがHTTPSをデフォルトで使用するように、次のコマンドで設定を変更します。

kubectl patch configmap config-network -n knative-serving --type merge --patch '{"data":{"default-external-scheme": "https"}}'

次のコマンドを実行してください。Knative ServicesのURLが"https"に変更されているのがわかります。

tanzu apps workload get -n demo tanzu-java-web-app

alt_text

アプリにアクセスしましょう。今回は自己署名証明書を使用しているため、curlのオプションに-kをつけてください。

curl -skv $(kubectl get ksvc -n demo tanzu-java-web-app  -ojsonpath='{.status.url}')

alt_text

ブラウザでもアクセスしましょう。Chromeの場合は、自己署名証明書を使用している場合、次の図のようなワーニングが表示されます。

alt_text

ワーニング画面で"THISISUNSAFE"を入力すると、画面へアクセスできます。

alt_text

Tanzu Application Platformのインストール (Full Profile)

次にfull profileをインストールします。full ProfileはTAPの全構成要素をインストールします。ただし、今回は使用しないLearning Centerはインストールから除外します。

alt_text

[O] Full Profileのインストール

まず、tap-values.ymlの"profile"を"iterate"から"full"に変更してください。

profile: full

### …

そして、次のコマンドを実行し、tap-value.ymlにfull profileのインストールに必要な設定項目を追記してください。

DOMAIN_NAME=$(kubectl get -n tanzu-system-ingress svc envoy -ojsonpath='{.status.loadBalancer.ingress[0].ip}' | sed 's/\./-/g').sslip.io

cat <<EOF >> ${HOME}/workspace/tap-install/tap-values.yml

tap_gui:
  ingressEnabled: true
  ingressDomain: tap.${DOMAIN_NAME} 
  service_type: ClusterIP
  tls:
    secretName: cnrs-default-tls
    namespace: tanzu-system-ingress
  app_config:
    app:
      baseUrl: https://tap-gui.tap.${DOMAIN_NAME}
    backend:
      baseUrl: https://tap-gui.tap.${DOMAIN_NAME}
      cors:
        origin: https://tap-gui.tap.${DOMAIN_NAME}

accelerator:
  domain: tap.${DOMAIN_NAME}  
  ingress:
    include: true
    enable_tls: true
  tls:
    secret_name: cnrs-default-tls
    namespace: tanzu-system-ingress
  server:
    service_type: ClusterIP

metadata_store:
  app_service_type: ClusterIP
  ingress_enabled: "true"
  ingress_domain: tap.${DOMAIN_NAME}
  ns_for_export_app_cert: "*"

scanning:
  metadataStore:
    url: ""

excluded_packages:
- grype.scanning.apps.tanzu.vmware.com
- learningcenter.tanzu.vmware.com
- workshops.learningcenter.tanzu.vmware.com
EOF

次のコマンドを実行して、TAPに変更を適用します。

tanzu package installed update tap -f ${HOME}/workspace/tap-install/tap-values.yml -n tap-install --kubeconfig ${HOME}/.kube/config

インストールの進捗状況を次のコマンドで確認できます。5分くらいでインストールが完了します。

while [ "$(kubectl -n tap-install get app tap -o=jsonpath='{.status.friendlyDescription}')" != "Reconcile succeeded" ];do
  date
  kubectl get app -n tap-install
  echo "---------------------------------------------------------------------"
  sleep 10
done
echo "✅ Update succeeded"

alt_text

[D] TAP GUIにアクセス

full profileではDeveloper向けのPortal UIとして、TAP GUIが用意されています。TAP GUIのFQDNは次のコマンドで確認できます。

kubectl get httpproxy -n tap-gui tap-gui

alt_text

このFQDNにブラウザでアクセスしてください。次の図のようなワーニングが表示されるので、"THISISUNSAFE"を入力してください。

alt_text

トップページが表示されます。TAP GUIの認証はK8sの認証と独立しており、デフォルトでは誰でもTAP GUIにアクセスできます。"Enter"ボタンをクリックしてください。

alt_text

次の図のような、Catalog一覧画面が表示されます。

alt_text

サイドバーの➕アイコンをクリックしてください。次の図のようにWorkload一覧が表示されます。

alt_text

Workload名をクリックしてください。このWorkloadに対するSupply Chainが視覚化されます。

alt_text

[D] Catalogの登録

TAP GUIにtanzu-java-web-appのCatalogを登録します。サイドメニューから🏠のアイコンをクリックしてください。 右上の"REGISTER ENTITY"ボタンをクリックします。

alt_text

Repository URLに https://github.com/sample-accelerators/tanzu-java-web-app/blob/main/catalog/catalog-info.yaml を入力してください。

alt_text

"ANALYZE" ボタンをクリックしてください。

alt_text

"IMPORT" ボタンをクリックしてください。

alt_text

再度、サイドメニューの🏠アイコンをクリックしてください。

alt_text

左下の"YOUR ORGANIZATION”が"All 1"になっていることを確認してください。"All" をクリックしてください。

alt_text

Component一覧に "tanzu-java-web-app" が表示されます。"tanzu-java-web-app" をクリックしてください。

alt_text

componentの詳細画面が表示されます。Runtime Resourcesタブをクリックしてください。

alt_text

tanzu-java-web-appに関するResource一覧が表示されます。 Resource Nameが"tanzu-java-web-app-000NN-deployment-XXXXX"で、Statusが"Running"でKindが"Pod"なResourceを選択してください。

alt_text

Podの詳細情報が表示されます。"VIEW POD LOGS"をクリックしてください。

alt_text

Podのログが表示されます。

alt_text

[D] App Live Viewの確認

"Overview"タブに戻ってください。 Spring Bootで作られたアプリでSpring Boot Actuatorが含まれている場合は、"Live View" が見られます。

⚠️ AdBlockをインストールしている場合は、TAP GUIでは無効化してください。

alt_text

Spring Boot Actuatorのエンドポイントを選択できます。

alt_text

"Memory"を選んだ場合

alt_text

"Threads"を選んだ場合

alt_text

"Log Levels" を選んだ場合

alt_text

[D] App Acceleratorから雛形プロジェクトを作成

サイドメニューから⨁アイコンをクリックしてください。 Accelerators一覧が表示されます。ここからプロジェクトを生成することができます。

"Tanzu Java Web App" の "Choose" を選択してください。

alt_text

雛形のプレースホルダーに埋める値を入力します。“Name”に”hello-tanzu”を、“Prefix for the container image repository” に

echo $(cat ${HOME}/acr-token.json | jq -r .loginServer)/sources/demo

の出力結果を設定してください。 "EXPLORE FILE" ボタンをクリックするとプレースホルダーを埋めた状態で生成されるプロジェクトを確認することができます。

alt_text

config/workload.yamlに "Name" で指定した値が設定されていることを確認してください。

alt_text

Tiltfileに "Prefix for the container image repository" で指定した値が設定されていることを確認してください。

確認できたらダイアログを閉じて、 "NEXT" ボタンをクリックしてください。

alt_text

"GENERATE ACCELERATOR" ボタンをクリックしてください。

alt_text

ZIPファイルが生成されるのでDownloadしてください。

alt_text

Downloadしたhello-tanzu.zipをworkspaceフォルダにDrag&Dropしてください。

alt_text

TerminalでZipを展開します。次のコマンドを実行してください。

cd ${HOME}/workspace
unzip hello-tanzu.zip
cd hello-tanzu

メニューから”File” -> "Open Folder"を選択してください。"/home/coder/workspace/hello-tanzu" を選択し、"OK" ボタンをクリックしてください。

alt_text

Extensions一覧から”Tanzu Developer Tools”を右クリックして、”Extension Settings”を選択し、”Source Image”に次のコマンドの出力結果を設定してください。

echo $(cat ${HOME}/acr-token.json | jq -r .loginServer)/sources/demo/hello-tanzu

alt_text

ACRに再ログインしてください。

${HOME}/acr-login.sh 

Tiltfileの末尾に次の内容を追記してください。

allow_k8s_contexts('tap-sandbox-admin')

Tiltfileを右クリックして "Tanzu: Live Update Start" を選択してください。

alt_text

ローカルパスのソースコードからWorkloadが作成されるのでしばらく待ってください。

alt_text

ログが出力され始めたらTAP GUIのサイドメニューの➕アイコンをクリックし、hello-tanzuのWorkloadを選択してください。Supply Chainでどこまで進んでいるかがわかります。

alt_text

次のようなアプリログが出力されたら、デプロイが完了です。

alt_text

TAP GUIでWorkloadを確認するとDeliveryに✅が入っていることが確認できます。

alt_text

次のコマンドを実行してアプリにアクセスしてください。

curl -skv $(kubectl get ksvc -n demo hello-tanzu  -ojsonpath='{.status.url}')

alt_text

HelloControllerのソースコードを変更してください。

alt_text

Live Updateでソースコードの変更が反映されたら、再度アプリにアクセスして、レスポンスが変わることを確認してください。

curl -skv $(kubectl get ksvc -n demo hello-tanzu  -ojsonpath='{.status.url}')

alt_text

確認できたらTiltfileを右クリックして、"Tanzu: Live Update Stop"をクリックし、Live Updateを終了してください。

alt_text

次のコマンドを実行してWorkloadを削除してください。

tanzu apps workload delete -n demo hello-tanzu --kubeconfig ${HOME}/.kube/config -y

[O] Acceleratorの追加

https://github.com/spring-socks/template を追加します。

tanzu accelerator create spring-socks --git-repository https://github.com/spring-socks/template --git-branch main

Accelerator一覧に "Spring Socks Template" が表示されることを確認してください。

alt_text

[O] TAP GUIのロゴのカスタマイズ

TAP GUIのロゴとタイトルを変更します。tap-values.ymlの次の箇所を変更します。

### ….
tap_gui:
  # ….
  app_config:
    customize:
      custom_name: "<Your Product Name> Developer Portal"
      custom_logo: "<base64 encoded logo data>"
    app:
      title: "<Your Product Name> Developer Portal"
      # ….
### ….

次のコマンドを実行して、TAPに変更を適用します。

tanzu package installed update tap -f ${HOME}/workspace/tap-install/tap-values.yml -n tap-install --kubeconfig ${HOME}/.kube/config

次のコマンドを実行し、TAP GUI のPod (server-xxxxx) が新規作成され、READYが "1/1" になるまで待ってください。

kubectl get pod -n tap-gui

alt_text

READYになったら、TAP GUIに再アクセスしてください。

ロゴやタイトルが変更されていることを確認してください。

Tanzu Application Platformのその他の機能

[O] "source-test-to-url" Supply Chainへの変更

ここまで "source-to-url" Supply Chainを使用してきましたが、今度はコンテナイメージを作る前にユニットテストを挟んだ"source-test-to-url" Supply Chainを使用します。

"source-test-to-url" Supply Chainはiterate profileでも利用可能です。

いったんここまで作ったWorkloadを次のコマンドで削除してください。

kubectl delete workload -A --all

現在のSupply Chainを次のコマンドで確認します。

tanzu apps cluster-supply-chain list

alt_text

次のように、tap-values.yml中の"basic"と設定されている箇所を"testing"に変更してください。

### …

supply_chain: testing

ootb_supply_chain_testing:
  # …

### …

次のコマンドを実行して、TAPに変更を適用します。

tanzu package installed update tap -f ${HOME}/workspace/tap-install/tap-values.yml -n tap-install --kubeconfig ${HOME}/.kube/config

更新後のSupply Chainを次のコマンドで確認します。"source-test-to-url"が表示されることを確認してください。

tanzu apps cluster-supply-chain list

alt_text

Supply Chainを使うためのSelectorを確認してください。

tanzu apps cluster-supply-chain get source-test-to-url
tanzu apps cluster-supply-chain get testing-image-to-url

alt_text

"source-test-to-url" を使うにはWorkloadに "apps.tanzu.vmware.com/hast-tests: true" というlabelがついている必要があります。

[O or D] Pipelineの作成

Supply Chainの中で使用されるテストスクリプトをTektonのPipelineとして定義します。次のコマンドでPipelineを作成してください。

cat <<'EOF' > ${HOME}/workspace/tap-install/pipeline-maven.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: maven-test-pipeline
  labels:
    apps.tanzu.vmware.com/pipeline: test
spec:
  params:
  - name: source-url
  - name: source-revision
  tasks:
  - name: test
    params:
    - name: source-url
      value: $(params.source-url)
    - name: source-revision
      value: $(params.source-revision)
    taskSpec:
      params:
      - name: source-url
      - name: source-revision
      steps:
      - name: test
        image: eclipse-temurin:17
        script: |-
          set -ex
          cd `mktemp -d`
          curl -s $(params.source-url) | tar -m -xzvf -
          ./mvnw clean test -V --no-transfer-progress
EOF

kubectl apply -f ${HOME}/workspace/tap-install/pipeline-maven.yaml -n demo

次のコマンドでWorkloadを作成してください。

tanzu apps workload apply tanzu-java-web-app \
  --app tanzu-java-web-app \
  --git-repo https://github.com/sample-accelerators/tanzu-java-web-app \
  --git-branch main \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  --label apps.tanzu.vmware.com/has-tests=true \
  -n demo \
  -y

次のコマンドでWorkloadの状態を確認してください。

tanzu apps workload get -n demo tanzu-java-web-app

Supply Chainに "source-tester" が追加されていることがわかります。

alt_text

次のコマンドを実行してログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=tanzu-java-web-app

テストの実行ログを確認できます。

alt_text

TAP GUIでSupply Chainを確認してください。"Source Tester"が追加されていることを確認できます。

alt_text

Source Testerをクリックするとテストの実行ログを確認することができます。

alt_text

テストがパスし、アプリがデプロイされてDeliveryに✅がつくまで待ってください。

alt_text

次のコマンドでアプリにアクセスしてください。

curl -skv $(kubectl get ksvc -n demo tanzu-java-web-app  -ojsonpath='{.status.url}')

alt_text

[D + O] Service Binding

次はデータベースアクセスのあるアプリ vehicle-api をデプロイします。TAPでは"Service Binding"の仕組みを使って、アプリにデータベースを"アタッチ"することができます。これによりアプリはデータベースの接続情報を意識することなく、データベースにアクセスできるようになります。

Service Bindingはiterate profileでも利用可能です

データベースとしてAzure PostgreSQLを使用します。

次のコマンドでAzure PostgreSQLのインスタンスを作成してください。

POSTGRESQL_USERNAME=vehicle
POSTGRESQL_PASSWORD=$(openssl rand -base64 32)

az postgres server create \
    --resource-group tap-${NAMESPACE} \
    --name vehicle-db-${NAMESPACE} \
    --location japaneast \
    --sku-name B_Gen5_1 \
    --storage-size 5120 \
    --admin-user ${POSTGRESQL_USERNAME} \
    --admin-password ${POSTGRESQL_PASSWORD} \
    --version 11 \
    --output tsv

次のコマンドでAKSから作成したインスタンスにアクセスを許可するためのFirewallの設定を行います。

ALLOWED_IP=...

az postgres server firewall-rule create \
    --resource-group tap-${NAMESPACE} \
    --name vehicle-db-${NAMESPACE}-allowed-ip \
    --server vehicle-db-${NAMESPACE} \
    --start-ip-address ${ALLOWED_IP} \
    --end-ip-address ${ALLOWED_IP} \
    --output tsv

ALLOWED_IPの値はAKSのoutbound用のIPを設定します。次のコマンドで確認できます。 何も出力されなかったら、もう一度同じコマンドを実行してください。

kubectl run -n default curl --timeout=5m --restart=Never --image=curlimages/curl --rm -it -- curl -s https://httpbin.org/ip

alt_text

作成したインスタンスにデータベースを作成します。

az postgres db create \
    --resource-group tap-${NAMESPACE} \
    --name vehicle \
    --server-name vehicle-db-${NAMESPACE} \
    --output tsv

PostgreSQLへの接続情報を次のコマンドで出力します。

az postgres server show --resource-group tap-${NAMESPACE} --name vehicle-db-${NAMESPACE}  > ${HOME}/vehicle-db.json

Service Bindingの仕様に合わせて、次のような形式のSecretを作成します。

apiVersion: v1
kind: Secret
metadata:
  name: <Service Instance Name>
type: servicebinding.io/<Type>
stringData:
  type: <Type>
  host: …
  port: …
  username: …
  password: …
  # …

実際にどのようなフィールドを設定すべきかは、このService Bindingに対応したクライアントライブラリに依存します。

TAPではSpring Bootのアプリのコンテナイメージにはspring-cloud-bindingsというライブラリをbuildpackで自動で埋め込みます。

このライブラリを使う場合はPostgreSQLにアクセスする際に、Secretのフィールドがアプリのプロパティへと次の表のようにマッピングされます。

alt_text

このマッピングに合うように、Azure PostgreSQLにアクセスするためのSecretを次のように作成します。

cat <<EOF > ${HOME}/vehicle-db.yaml
apiVersion: v1
kind: Secret
metadata:
  name: vehicle-db
type: servicebinding.io/postgresql
stringData:
  type: postgresql
  host: $(cat ${HOME}/vehicle-db.json  | jq -r .fullyQualifiedDomainName)
  port: "5432"
  username: ${POSTGRESQL_USERNAME}@vehicle-db-${NAMESPACE}
  password: "${POSTGRESQL_PASSWORD}"
  database: vehicle
  sslmode: require
EOF

kubectl apply -f ${HOME}/vehicle-db.yaml -n demo

このデータベースを使用したアプリをデプロイします。Service Bindingの設定は--service-refオプションで行います。

次のコマンドを実行してください。

tanzu apps workload apply vehicle-api \
  --app vehicle-api \
  --git-repo https://github.com/making/vehicle-api \
  --git-branch main \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  --label apps.tanzu.vmware.com/has-tests=true \
  --service-ref vehicle-db=v1:Secret:vehicle-db \
  -n demo \
  -y

次のコマンドでログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=vehicle-api

Known Issueですが、Service Bindingを使用してWorkloadをデプロイした場合、最初のrevision (00001) は接続情報のSecretが設定されていない状態でアプリがデプロイされてしまいます。その結果、デフォルトのlocalhostに接続しに行こうと試み、エラーが発生します。

alt_text

revision 00001ができたすぐ後にrevision 00002がデプロイされ、このrevisionではは接続情報のSecretが正しく設定されるため、Service Binidingから接続情報をプロパティが設定され、PostgreSQLに接続できます。

alt_text

次のコマンドでアプリにアクセスしてください。

curl -sk $(kubectl get ksvc -n demo vehicle-api -ojsonpath='{.status.url}')/vehicles | jq .

alt_text

次のコマンドでデータを追加してください。

curl -sk $(kubectl get ksvc -n demo vehicle-api -ojsonpath='{.status.url}')/vehicles -d "{\"name\":"Sienta\"}" -H "Content-Type: application/json" | jq .

alt_text

次のコマンドを再度実行し、追加したデータが表示されることを確認してください。

curl -sk $(kubectl get ksvc -n demo vehicle-api -ojsonpath='{.status.url}')/vehicles | jq .

alt_text

アプリのPodを次のコマンドで削除してください。しばらくすると自動で復旧します。

kubectl delete pod -n demo -l app.kubernetes.io/component=run,app.kubernetes.io/part-of=vehicle-api --force

復旧後に再度アプリにアクセスし、データが失われていないことを確認してください。

curl -sk $(kubectl get ksvc -n demo vehicle-api -ojsonpath='{.status.url}')/vehicles | jq .

TAP GUIにvehicle-apiのCatalogを登録します。次のURLを登録してください。

https://github.com/making/vehicle-api/blob/main/catalog/catalog-info.yaml

alt_text

vehicle-apiのApp Live Viewを確認してください。

alt_text

Healthを選択するとPostgreSQLとの接続状態の確認ができます。

alt_text

[D + O] Resource Claim

前節ではアプリに必要なデータベースの接続情報をSecretとして直接作成し、バインドしました。

今回はResource Claimという、プールされたリソースからサービスのインスタンスを確保する方法でService Bindingを行います。

Resource Claimはiterate profileでも利用可能です

demo namespaceに作成したSecretを次のコマンドで削除してください。

kubectl delete secret -n demo vehicle-db

次のコマンドでResource ClaimによってSecretを管理するためのRBACの設定を行います。

cat <<EOF > ${HOME}/workspace/tap-install/resourceclaim-role.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: resource-claims
  labels:
    servicebinding.io/controller: "true"
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]
EOF
kubectl apply -f ${HOME}/workspace/tap-install/resourceclaim-role.yaml

PostgreSQLのInstance Classを定義します。ここでは "type" fieldが "servicebinding.io/postgresql" であるSecretをPostgreSQLインスタンスと定義します。

cat <<EOF > ${HOME}/workspace/tap-install/clusterinstanceclass.yaml
---
apiVersion: services.apps.tanzu.vmware.com/v1alpha1
kind: ClusterInstanceClass
metadata:
  name: postgresql
spec:
  description:
    short: PostgreSQL
  pool:
    group: ""
    kind: Secret
    fieldSelector: type=servicebinding.io/postgresql
EOF

kubectl apply -f ${HOME}/workspace/tap-install/clusterinstanceclass.yaml

次のコマンドでこのクラスタ上で定義されているInstane Class一覧を表示します。

tanzu service classes list

alt_text

次のコマンドでdemo namespaceで利用可能なPostgreSQLインスタンス一覧を表示します。

tanzu service claimable list --class postgresql -n demo

まだ利用可能なインスタンスは用意されていません。

alt_text

サービスインスタンスを管理するnamespaceとしてservice-instancesを作成します。

kubectl create namespace service-instances

前説で作ったAzure PostgreSQLへの接続情報を持つSecretをservice-instances namespaceに作成します。

kubectl apply -f ${HOME}/vehicle-db.yaml -n service-instances

次のコマンドで再度demo namespaceで利用可能なPostgreSQLインスタンス一覧を表示します。

tanzu service claimable list --class postgresql -n demo

まだ利用可能なインスタンスはありません。vehicle-dbはdemo namespaceではなく、service-instances namespaceに作成されているからです。

alt_text

次のコマンドでservice-instances namespaceに作成されているSecretを他のnamespaceで参照できるようなポリシーを作成します。

cat <<EOF > ${HOME}/workspace/tap-install/resourceclaimpolicy.yaml
apiVersion: services.apps.tanzu.vmware.com/v1alpha1
kind: ResourceClaimPolicy
metadata:
  name: cross-namespace
  namespace: service-instances
spec:
  consumingNamespaces:
  - '*'
  subject:
    group: ""
    kind: Secret
EOF
kubectl apply -f ${HOME}/workspace/tap-install/resourceclaimpolicy.yaml

次のコマンドで再度demo namespaceで利用可能なPostgreSQLインスタンス一覧を表示します。

tanzu service claimable list --class postgresql -n demo

今度はservice-instances namespaceにvehicle-dbが利用可能になりました。

alt_text

次のコマンドでservice-instances namespaceのvehicle-dbをdemo namespaceで使うための確保を行います。

tanzu service claim create vehicle-db \
  --resource-name vehicle-db \
  --resource-namespace service-instances \
  --resource-kind Secret \
  --resource-api-version v1 \
  -n demo

alt_text

確保したサービスの情報を次のコマンドで確認できます。

tanzu services claims get vehicle-db -n demo

alt_text

service-instances namespaceからこのインスタンスに関するSecretがコピーされます。

kubectl get secret -n demo vehicle-db

alt_text

次のコマンドで再度demo namespaceで利用可能なPostgreSQLインスタンス一覧を表示します。

tanzu service claimable list --class postgresql -n demo

vehicle-dbは確保されたため、利用可能ではなくなりました。

alt_text

確保したリソースはResourceClaimリソースとして管理されます。次のコマンドでSecretの代わりにResourceClaimをバインドしてください。

tanzu apps workload apply vehicle-api \
  --app vehicle-api \
  --git-repo https://github.com/making/vehicle-api \
  --git-branch main \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  --label apps.tanzu.vmware.com/has-tests=true \
  --service-ref vehicle-db=services.apps.tanzu.vmware.com/v1alpha1:ResourceClaim:vehicle-db \
  -n demo \
  -y

次のコマンドでログを確認してください。

stern -n demo -l app.kubernetes.io/part-of=vehicle-api

生成されたmanifestがResourceClaimを使用していることが分かります。

alt_text

今回はResourceClaimの名前とSecretの名前が同じだったので変更点が分かりづらいですが、ResourceClaimとSecretの名前は必ずしも一致するわけではありません。また、適切なRBAC設定されている場合、DeveloperはSecretを参照することはできませんが、ResourceClaimは参照できます。したがって、Developer観点ではSecretをバインドするよりもResourceClaimを参照する方がより良いです。Operator観点でもResouce Claimを使用すると、リソースをプールして公開することにより、self-serviceのようにDeveloperにデータベースを利用してもらえるという運用的メリットがあります。

[O] DeveloperのRBAC

Azure AD上でグループを作成してください。

GROUP_ID=$(az ad group create --display-name tap-demo-developer-${NAMESPACE} --mail-nickname tap-demo-developer-${NAMESPACE} --query id -o tsv)

グループ内のメンバー一覧を確認します。この段階ではメンバーは空です。

az ad group member list --group tap-demo-developer-${NAMESPACE} 

ログインユーザーをグループに追加します。

az ad group member add --group tap-demo-developer-${NAMESPACE} --member-id $(az ad signed-in-user show --query id --output tsv)

グループ内のメンバー一覧を確認し、追加したユーザーが含まれていることを確認してください。

az ad group member list --group tap-demo-developer-${NAMESPACE} 

グループに対し、demo namepsaceへのapp-editor Roleと、app-editor-cluster-access CluserRoleをバインドします。

kubectl create rolebinding app-editor -n demo --clusterrole app-editor --group ${GROUP_ID}
kubectl create clusterrolebinding app-editor-${GROUP_ID} --clusterrole app-editor-cluster-access --group ${GROUP_ID}

demo namespaceのrolebiningを確認してください。

kubectl get rolebinding -n demo app-editor -owide

alt_text

clusterrolebiningを確認してください。

kubectl get clusterrolebinding app-editor-${GROUP_ID} -o wide

alt_text

adminではなく、一般ユーザーとしてAKSにアクセスするためのconfigを取得します。

az aks get-credentials --resource-group tap-${NAMESPACE} --name tap-sandbox --overwrite-existing

default namespaceのPod一覧の取得を試みてください。権限がなく、アクセスを拒否されます。

kubectl get pod -n default

alt_text

demo namespaceのPod一覧の取得を試みてください。権限があるためPod一覧を取得できます。

kubectl get pod -n demo

alt_text

demo namespaceのWorkload一覧を取得できることを確認してください。

tanzu apps workload list -n demo

alt_text

demo namespaceでもSecretは取得できません。

kubectl get secret -n demo

alt_text

一方、ResourceClaimであれば取得できます。

tanzu service claim list -n demo

alt_text

Workloadを削除できることを確認してください。

tanzu apps workload delete -n demo vehicle-api -y 

Workloadを作成できることを確認してください。

tanzu apps workload apply vehicle-api \
  --app vehicle-api \
  --git-repo https://github.com/making/vehicle-api \
  --git-branch main \
  --type web \
  --annotation autoscaling.knative.dev/minScale=1 \
  --label apps.tanzu.vmware.com/has-tests=true \
  --service-ref vehicle-db=services.apps.tanzu.vmware.com/v1alpha1:ResourceClaim:vehicle-db \
  -n demo \
  -y

[O] TAP GUIのAzure AD連携

TBD

https://ik.am/entries/708 を参照

[D + O] WorkloadのGitOps

TBD https://ik.am/entries/706 を参照

リソースの削除

ハンズオンが終わったら、次のコマンドを実行して作成したリソースを削除してください。

az group delete --name tap-${NAMESPACE} -y

✒️️ Edit  ⏰ History  🗑 Delete