Tanzu Application PlatformのProfileを使ってTanzu Build Serviceをインストールする

Tanzu Build Service(TBS) 1.10ではTanzu Application Platform(TAP)のインストール用Profileを使ってインストールするのが推奨となっている。
これを試した時のメモ。
基本的には[公式手順](https://docs.vmware.com/en/Tanzu-Build-Service/1.10/vmware-tanzu-build-service/installing-tap-profile.html)をなぞっただけなので大したものではないが、設定ファイルの書式とかは公式には記載例がない箇所もあるので、参考になれば幸いです。

## 前提
- イメージレジストリとしてHarborは構築済み、かつ証明書も作業端末に導入済み
- Harborの空きは20Gくらいはあること（tapのイメージコピー等でPrerequisitesより多く必要）
- クラスタのノードにもHarborの証明書を設定済み（参考：[こちら](https://docs.vmware.com/jp/VMware-Tanzu-Kubernetes-Grid/2.2/using-tkg-22/workload-clusters-secret.html#--8)）
- kapp-controllerにもHarborの証明書を設定済み
- [Carvelツール](https://carvel.dev/)はインストール済み
- tanzuコマンドはインストール済み
- [kpack-cli](https://github.com/buildpacks-community/kpack-cli)はインストール済み

## TBSのインストール準備
最初に配布されているTAPのイメージを自前のイメージレジストリにpushし直す。
利用可能なTAPのバージョンを取得する（省略可）。
```sh
imgpkg tag list -i registry.tanzu.vmware.com/tanzu-application-platform/tap-packages | grep -v sha | sort -V
```
環境変数の定義ファイルを作成する。
```sh
cat << EOF > ./env.sh
# イメージをPushするImage Registryのユーザ名
export INSTALL_REGISTRY_USERNAME=admin
# イメージをPushするImage Registryのパスワード
export INSTALL_REGISTRY_PASSWORD='xxxxxx'
# イメージをPushするImage Registryのホスト名
export INSTALL_REGISTRY_HOSTNAME=harbor.10.41.79.209.sslip.io
# イメージをPushするImage Registry内のリポジトリ名
export INSTALL_REPO=library
# TAPのバージョン
export TAP_VERSION=1.5.3
EOF
```
作った環境変数のファイルを使ってPush先レジストリとTAPのイメージの配布元である`registry.tanzu.vmware.com`にログインする。
```sh
. env.sh
echo $INSTALL_REGISTRY_PASSWORD | docker login -u $INSTALL_REGISTRY_USERNAME --password-stdin $INSTALL_REGISTRY_HOSTNAME
docker login registry.tanzu.vmware.com
```

自前のイメージレジストリにTAP Packageをコピーする。イメージレジストリに自己証明書を利用しているため、`--registry-ca-cert-path`で証明書のパスを指定する。
```sh
imgpkg copy -b registry.tanzu.vmware.com/tanzu-application-platform/tap-packages:${TAP_VERSION} --to-repo ${INSTALL_REGISTRY_HOSTNAME}/${INSTALL_REPO}/tap-packages --registry-ca-cert-path /tmp/harbor.crt
```
転送が始まると以下のような画面になる。TAPのイメージは8.59Gと結構大きいので時間がかかる点に注意。
```
copy | will export registry.tanzu.vmware.com/tanzu-application-platform/tap-packages@sha256:fe8d3bde3d58c066c2ad2132357457cf2f0c62984a9ba162d11fc391e4089652
copy | exported 252 images
copy | importing 252 images...

2.52 GiB / 8.59 GiB [---------------------------------------------->________________________________________________________________________________________________________________] 29.38% 32.79 MiB p/s
```

イメージの転送が終わったら、`tanzu package`コマンドでインストールを行うために、TAPの`kind: PackageRepository`を作成する。

```sh
kubectl create ns tap-install
tanzu secret registry add tap-registry \
  --username ${INSTALL_REGISTRY_USERNAME} \
  --password ${INSTALL_REGISTRY_PASSWORD} \
  --server ${INSTALL_REGISTRY_HOSTNAME} \
  --export-to-all-namespaces --yes --namespace tap-install
tanzu package repository add tanzu-tap-repository \
  --url ${INSTALL_REGISTRY_HOSTNAME}/${INSTALL_REPO}/tap-packages:$TAP_VERSION \
  --namespace tap-install
```
なお、ここでエラーが出る場合は`imgpkg pull`に失敗しているか、kapp-controllerにHarborの証明書が入れられていない可能性が高いので、その辺りを見直すと良さそう。
問題なければ`tanzu package repository list`を実行すると以下のように表示される。
```sh
$ tanzu package repository list

  NAME                  SOURCE                                                            STATUS
  tanzu-tap-repository  (imgpkg) harbor.10.41.79.209.sslip.io/library/tap-packages:1.5.3  Reconcile succeeded
```


## TBSのインストール
次にTBSで利用するリポジトリの認証情報をSecretとして作成する。
先程と同じリポジトリを使い回すので、環境変数は変えずにそのまま作成する。
```sh
tanzu secret registry add kp-default-repository \
  --username ${INSTALL_REGISTRY_USERNAME} \
  --password ${INSTALL_REGISTRY_PASSWORD} \
  --server ${INSTALL_REGISTRY_HOSTNAME} \
  --yes --namespace tap-install
```
次に新しいベースイメージがリリースされた時などに自動更新するためにVMware Tanzu Networkの認証情報をSecretとして作成する。
```sh
export TANZUNET_USERNAME=xxxx
export TANZUNET_PASSWORD=xxxx
tanzu secret registry add tanzunet-registry \
  --username ${TANZUNET_USERNAME} \
  --password ${TANZUNET_PASSWORD} \
  --server "registry.tanzu.vmware.com" \
  --yes --namespace tap-install
```
次にTBSの設定ファイルを作成する。
```yaml
cat << EOF > ./tap-values.yaml
ceip_policy_disclosed: true
profile: buildservice
buildservice:
  kp_default_repository: ${INSTALL_REGISTRY_HOSTNAME}/${INSTALL_REPO}/tbs
  kp_default_repository_secret:
    name: kp-default-repository
    namespace: tap-install
  tanzunet_secret:
    name: tanzunet-registry
    namespace: tap-install
  enable_automatic_dependency_updates: true
  ca_cert_data: |
    -----BEGIN CERTIFICATE-----
    MIIDKDCCAhCgAwIBAgIQNE0hB9cxQZF4jRq2Ai95OzANBgkqhkiG9w0BAQsFADAU
     ：(省略)
    -----END CERTIFICATE-----
  descriptor_name: lite
EOF
```
設定した値の意味は以下。
- `ceip_policy_disclosed`: カスタマーエクスペリエンス向上のためのデータ提供の有無。falseにすると失敗する。。。
- `profile`: TAPのprofile。TBSのみ入れるので`buildservice`を指定。
- `kp_default_repository`: TBSが使うイメージを格納するリポジトリ
- `kp_default_repository_secret`: 先程作ったTBS用のSecretを指定
- `tanzunet_secret`: 先程作ったVMware Tanzu Network用のSecretを指定
- `enable_automatic_dependency_updates`: ベースイメージなどの自動アップデートの有効/無効
- `ca_cert_data`: TBSで使うイメージレジストリの証明書
- `descriptor_name`: 関連イメージを全てインストールするか(`full`)、都度インストールするか(`lite`)

設定後、以下のコマンドでインストールする。
```sh
tanzu package install tap -p tap.tanzu.vmware.com -v $TAP_VERSION --values-file tap-values.yaml -n tap-install
```
TAP packageのインストールとなっているが、TBSがTAPの1コンポーネントであるため、このようなインストールコマンドとなっている。
インストールが成功すると以下のようにtap, build-service, tap-telemetryが`kind: App`としてデプロイされる。
```sh
$ kubectl get app -n tap-install
NAME            DESCRIPTION           SINCE-DEPLOY   AGE
buildservice    Reconcile succeeded   41s            44m
tap             Reconcile succeeded   1s             44m
tap-telemetry   Reconcile succeeded   4m44s          44m
```

## 動作確認
動作確認として、Javaのコードからイメージを作成してみる。
対象はGitHubでPublicに公開されている[hello-tanzu](https://github.com/imurata/hello-tanzu)を使う。
先程使った環境変数を使いまわして認証情報を登録する。
```sh
export REGISTRY_PASSWORD=${INSTALL_REGISTRY_PASSWORD}
kp secret create my-registry-cred --registry ${INSTALL_REGISTRY_HOSTNAME} --registry-user ${INSTALL_REGISTRY_USERNAME}
```
イメージを作成する。
```sh
kp image save --git https://github.com/imurata/hello-tanzu --tag ${INSTALL_REGISTRY_HOSTNAME}/${INSTALL_REPO}/hello-tanzu hello-tanzu --wait
```
問題なく作成できたので、作成したイメージを使って起動してみる。
```sh
kubectl run --image ${INSTALL_REGISTRY_HOSTNAME}/${INSTALL_REPO}/hello-tanzu hello-tanzu
```
問題なく起動できた。
```sh
$ kubectl get pod
NAME                            READY   STATUS      RESTARTS   AGE
hello-tanzu                     1/1     Running     0          19m
```