---
title: Tanzu Application Platformで特定のBuildpackだけ更新するメモ
tags: ["Kubernetes", "Tanzu Build Service", "Tanzu", "TAP", "kpack"]
categories: ["Dev", "CaaS", "Kubernetes", "TAP"]
date: 2023-12-02T16:26:09Z
updated: 2023-12-02T17:02:31Z
---

Tanzu Application Platform 1.6から、`ClusterBuildpack` CRが追加されました。
それ以前は `ClusterBuilder` は `ClusterStore` (OSのベースイメージ) と `ClusterStack` (Buildpack集) から構成されていました。
1.6からは `ClusterBuilder` は `ClusterStore` (OSのベースイメージ) と複数の `ClusterBuildpack` で構成されます。
これにより、個別のBuildpackのアップデートが行いやすくなりました。

更新方法は
https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.7/tap/tanzu-build-service-dependencies.html#update-dependencies-7
に記載されています。

実例を挙げます。TAP 1.7.0ではNode.jsのBuildpackとして[tanzu nodejs buildpack 2.3.1](https://network.tanzu.vmware.com/products/tanzu-nodejs-buildpack#/releases/1370858)がインストールされています。
しかし、このBuildpackに含まれるNode.jsには [CVE-2023-39332](https://nvd.nist.gov/vuln/detail/CVE-2023-39332) (Critical) が存在します。

実際に、TAP 1.7.0でNode.jsのWorkloadをsource-test-scan-to-urlのSupply Chainでビルドすると、次のように脆弱性が検出されます。

<img width="1579" alt="image" src="https://github.com/making/blog.ik.am/assets/106908/ec4f6dfd-7f09-4347-b618-b20ac06eb9a7">

TAP 1.7.0のままではCVE-2023-39332を無視するか、この脆弱性がFixされたbuildpackを含む新しいTAPのバージョンがリリースされるまでSupply Chainをストップさせるしかありません。
しかし、`ClusterBuildpack` が導入されたことにより、新しいbuildpackさえリリースされていれば、TAPのリリースを待たずにClusterBuilderを更新できます。

実際に、CVE-2023-39332は [tanzu nodejs buildpack 2.3.2](https://network.tanzu.vmware.com/products/tanzu-nodejs-buildpack#/releases/1399626) でFixされました。

<img width="1241" alt="image" src="https://github.com/making/blog.ik.am/assets/106908/c03ded69-d46b-422a-a5b3-c6a9f62f53b3">


TAPのリリースを待たずに、このtanzu nodejs buildpack 2.3.2を適用してみます。

> ℹ️ 本記事執筆時点のTAPの最新バージョンである1.7.1ではtanzu nodejs buildpack 2.3.2が含まれています。

まずはbuildpackのDockerイメージを `imgpkg` コマンドでrelocateします。元となるイメージ名はTanzu Netから確認可能です。
lite dependenciesを使用している場合は末尾に`-lite`がつくものを、full dependenciesを使用している場合は`-lite`がつかないものを使用します。

<img width="1377" alt="image" src="https://github.com/making/blog.ik.am/assets/106908/6533daaa-2b5e-45ce-b8ba-841036d34fd8">

ここでは `ghcr.io/making` 配下にrelocateします。

```
imgpkg copy -i registry.tanzu.vmware.com/tanzu-nodejs-buildpack/nodejs:2.3.2 --to-repo ghcr.io/making/tanzu-nodejs-buildpack/nodejs
```

relocateしたイメージを `ClusterBuildpack` の `.spec.image` に指定します。
`.spec.serviceAccountRef`に指定するService Accountは、relocateしたイメージをpullできる`imagePullSecrets`が設定されている必要があります。
わからない場合は`kubectl get clusterbuildpack -ojsonpath='{.items[0].spec.serviceAccountRef}'`で既存の`ClusterBuildpack`が使用しているService Accountを確認できます。

以下はfull dependenciesを使用している場合に、tanzu nodejs buildpackを2.3.2に更新する例です。
名前の形式は、TAPに同梱されるものと被らないようにする方が良いでしょう。ここではドキュメント同様に `out-of-band-` をprefixとして使用しています。

```yaml
kubectl apply -f - << 'EOF'
---
apiVersion: kpack.io/v1alpha2
kind: ClusterBuildpack
metadata:
  name: out-of-band-nodejs-2.3.2
spec:
  image: ghcr.io/making/tanzu-nodejs-buildpack/nodejs:2.3.2
  serviceAccountRef:
    name: dependencies-pull-serviceaccount
    namespace: tbs-full-deps
---
EOF
```

同じIDを持つbuildpackが複数ある場合、`ClusterBuilder` はより新しいものを選びます。
これにより、TAP 1.7.0同梱のtanzu nodejs buildpack 2.3.1ではなく、2.3.2を使って `ClusterBuilder` が更新されます。

`ClusterBuilder` が更新されると、それを使用しているWorkloadのイメージは自動で再ビルドが行われます。これにより、Supply Chainの脆弱性チェックもパスできます。

<img width="1574" alt="image" src="https://github.com/making/blog.ik.am/assets/106908/37b740c9-03b6-42db-970e-ee4788a4ef58">


この手法で、TAPをアップデートすることなくBuildpackを更新することができましたが、BuildpackのAPIバージョンやSBoMのバージョンの依存関係があるため、TAPのバージョンによっては最新のBuildpackだとエラーが起きる可能性がある点に注意してください。
