IK.AM

@making's tech note


Tanzu Application Platform 1.1 (Full Profile) をminikubeにLocal Registryを使ってインストールして"Source Test Scan to URL"を試すメモ

🗃 {Dev/CaaS/Kubernetes/TAP}
🏷 Cartographer 🏷 Knative 🏷 Kubernetes 🏷 TAP 🏷 Tanzu 🏷 Tekton 🏷 minukube 
🗓 Updated at 2022-06-30T02:07:00+09:00  🗓 Created at 2022-06-23T21:35:49+09:00 {✒️️ Edit  ⏰ History  🗑 Delete}

Tanzu Application Platform 1.1 をminikubeにインストールします。

本記事ではTAPのFulll ProfileをminikubeにLocal Registryを使ってInstallし、"Hello World"なアプリケーションをソースコードからテストとスキャンを経てデプロイする機能("Source Test Scan to URL")を試します。 。

なお、Iterate Profileをインストールするメモはこちら

目次

minikubeクラスタの作成

CPUは8、メモリは16GBでminikubeクラスタを作成します。

minikube start --memory=16384 --cpus=8 --disk-size=70GB  --kubernetes-version='1.22.10' --driver='hyperkit'

Local Registryのインストール

minikubeのregistry addonだとPersistent Volumeがattachされておらず、minikube stopするとデータが失われるので、 カスタマイズした次のマニフェストを使います。

cat <<EOF | kubectl apply -f-
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: kube-registry
  namespace: kube-system
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 30Gi 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    kubernetes.io/minikube-addons: registry
  name: registry
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      actual-registry: "true"
  strategy:
    type: Recreate
  template:    
    metadata:
      labels:
        actual-registry: "true"
        kubernetes.io/minikube-addons: registry
    spec:
      containers:
      - image: registry:2.7.1@sha256:d5459fcb27aecc752520df4b492b08358a1912fcdfa454f7d2101d4b09991daa
        imagePullPolicy: IfNotPresent
        name: registry
        ports:
        - containerPort: 5000
          protocol: TCP
        env:
        - name: REGISTRY_STORAGE_DELETE_ENABLED
          value: "true"
        - name: REGISTRY_VALIDATION_DISABLED
          value: "true"
        - name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
          value: /var/lib/registry
        volumeMounts:
        - name: image-store
          mountPath: /var/lib/registry        
      volumes:
      - name: image-store
        persistentVolumeClaim:
          claimName: kube-registry      
---
apiVersion: v1
kind: Service
metadata:
  labels:
    kubernetes.io/minikube-addons: registry
  name: registry
  namespace: kube-system
spec:
  type: ClusterIP
  ports:
  - port: 80
    name: http
    targetPort: 5000
  - port: 443
    name: https
    targetPort: 443
  selector:
    actual-registry: "true"
    kubernetes.io/minikube-addons: registry
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: registry-proxy
  namespace: kube-system
spec:
  selector:
    matchLabels:
      registry-proxy: "true"
  template:
    metadata:
      labels:
        registry-proxy: "true"
        kubernetes.io/minikube-addons: registry
    spec:
      containers:
      - image: gcr.io/google_containers/kube-registry-proxy:0.4@sha256:1040f25a5273de0d72c54865a8efd47e3292de9fb8e5353e3fa76736b854f2da
        imagePullPolicy: IfNotPresent
        name: registry-proxy
        ports:
        - name: registry
          containerPort: 80
          hostPort: 5000
        env:
        - name: REGISTRY_HOST
          value: registry.kube-system.svc.cluster.local
        - name: REGISTRY_PORT
          value: "80"
EOF

minikubeのdockerがregistry serviceのDNS名を解決できるように、Node上の/etc/hostsにregistry serviceのClusterIPを明示します。

echo "$(kubectl get svc -n kube-system registry -ojsonpath='{.spec.clusterIP}')\tregistry.kube-system.svc.cluster.local" | minikube ssh --native-ssh=false "sudo tee -a /etc/hosts"

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

TAPのインストールに必要なKapp ControllerとSecretgen Controllerをデプロイするために Cluster Essentials for VMware Tanzu をインストールします。

# Mac
pivnet download-product-files --product-slug='tanzu-cluster-essentials' --release-version='1.1.0' --product-file-id=1191985
# Linux
pivnet download-product-files --product-slug='tanzu-cluster-essentials' --release-version='1.1.0' --product-file-id=1191987
# Windows
pivnet download-product-files --product-slug='tanzu-cluster-essentials' --release-version='1.1.0' --product-file-id=1191983

Cluster Essentialsのimgpkg bundleをlocal registryにrelocateします。

まずはTanzuNet Registryにログインします。

TANZUNET_USERNAME=...
TANZUNET_PASSWORD=...

docker login registry.tanzu.vmware.com -u ${TANZUNET_USERNAME} -p ${TANZUNET_PASSWORD}

Cluster Essentialsのimgpkg bundleをtarファイルに保存します。

imgpkg copy -b registry.tanzu.vmware.com/tanzu-cluster-essentials/cluster-essentials-bundle:1.1.0 --to-tar ~/cluster-essentials-bundle-1.1.0.tar

localhost:5000でregistryにアクセスできるようにport-forwardします。

kubectl port-forward --namespace kube-system service/registry 5000:80

tarファイルのimgpkg bundleをlocalhost:5000にrelocateします。

imgpkg copy --tar ~/cluster-essentials-bundle-1.1.0.tar --to-repo localhost:5000/tanzu-cluster-essentials/cluster-essentials-bundle

relocateしたimgpkg bundleを使ってCluster Essentialsをインストールします。

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

cd tanzu-cluster-essentials

export INSTALL_REGISTRY_HOSTNAME=localhost:5000
export INSTALL_REGISTRY_USERNAME=admin
export INSTALL_REGISTRY_PASSWORD=admin
export INSTALL_BUNDLE=${INSTALL_REGISTRY_HOSTNAME}/tanzu-cluster-essentials/cluster-essentials-bundle:1.1.0

./install.sh --yes
cd ..

Tanzu Application Platformのインストール

TAP用Package Repositoryの登録

TAPのimgpkg bundleをtarファイルに保存します。 約16GBあるのでかなり時間がかかります。

👆 tarファイルを経由せずに直接registryにcopyすることもできますが、
失敗したときにダウンロードからやり直しになってしまうので、
試行錯誤を見越してtarでダウンロードしておいた方が効率的です。

TAP_VERSION=1.1.1
imgpkg copy -b registry.tanzu.vmware.com/tanzu-application-platform/tap-packages:${TAP_VERSION} --to-tar ~/tap-${TAP_VERSION}.tar

tarファイルのimgpkg bundleをlocalhost:5000にrelocateします。

imgpkg copy --tar ~/tap-${TAP_VERSION}.tar --to-repo localhost:5000/tanzu-application-platform/tap-packages

Package Repositoryの設定をします。kapp controllerがlocalhost:5000にアクセスできなかったので、ホスト名にはregistry.kube-system.svc.cluster.localを使用します。

kubectl create ns tap-install

tanzu secret registry add tap-registry \
  --username "${INSTALL_REGISTRY_USERNAME}" \
  --password "${INSTALL_REGISTRY_PASSWORD}" \
  --server registry.kube-system.svc.cluster.local \
  --export-to-all-namespaces \
  --yes \
  --namespace tap-install

tanzu package repository add tanzu-tap-repository \
  --url registry.kube-system.svc.cluster.local/tanzu-application-platform/tap-packages:${TAP_VERSION} \
  --namespace tap-install

Full Profileのインストール

TAPをインストールするためのtap-values.ymlを作成します。 cnrs.domain_nameには仮のドメインを指定します。あとでenvoyのExternal IPが設定されてから変更します。

ℹ️ grype packageはこのタイミングではインストールせず、excluded_packagesに加えて除外します。
TAP 1.1ではgrype packageはnamespaceごとに必要です。
profileのインストールでは、1つのnamespaceにしかgrype packageがインストールされず中途半端なので、それを除外して後に個別でインストールします。

cat <<EOF > tap-values.yml
profile: full

ceip_policy_disclosed: true

cnrs:
  domain_name: tap.example.com
  domain_template: "{{.Name}}-{{.Namespace}}.{{.Domain}}"
  default_tls_secret: tanzu-system-ingress/cnrs-default-tls
  provider: local

buildservice:
  kp_default_repository: registry.kube-system.svc.cluster.local/build-service
  kp_default_repository_username: admin
  kp_default_repository_password: admin
  tanzunet_username: ${TANZUNET_USERNAME}
  tanzunet_password: ${TANZUNET_PASSWORD}
  enable_automatic_dependency_updates: true

supply_chain: testing_scanning

ootb_supply_chain_testing_scanning:
  registry:
    server: registry.kube-system.svc.cluster.local
    repository: supplychain

contour:
  envoy:
    service:
      type: LoadBalancer
      externalTrafficPolicy: Local

learningcenter:
  ingressDomain: learningcenter.tap.example.com
  ingressSecret:
    secretName: learningcenter-tls

tap_gui:
  ingressEnabled: true
  ingressDomain: tap.example.com
  service_type: ClusterIP
  tls:
    secretName: cnrs-default-tls
    namespace: tanzu-system-ingress
  app_config:
    app:
      baseUrl: https://tap-gui.tap.example.com
    backend:
      baseUrl: https://tap-gui.tap.example.com
      cors:
        origin: https://tap-gui.tap.example.com
    catalog:
      locations:
      - type: url
        target: https://github.com/sample-accelerators/tanzu-java-web-app/blob/main/catalog/catalog-info.yaml
      - type: url
        target: https://github.com/sample-accelerators/spring-petclinic/blob/accelerator/catalog/catalog-info.yaml
      - type: url
        target: https://github.com/tanzu-japan/spring-music/blob/tanzu/catalog/catalog-info.yaml

accelerator:
  domain: tap.example.com
  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.example.com

package_overlays:
- name: cnrs
  secrets:
  - name: cnrs-default-tls
- name: learningcenter
  secrets:
  - name: learningcenter-certificate
- name: metadata-store
  secrets:
  - name: metadata-store-ingress-tls
excluded_packages:
- grype.scanning.apps.tanzu.vmware.com    
EOF

Cloud Native Runtimesで使用するデフォルトのTLS証明書を用意するための次の定義をoverlayで作成します。以下のドキュメントを参考にしました。

cat <<EOF > cnrs-default-tls.yml
#@ load("@ytt:data", "data")
#@ load("@ytt:overlay", "overlay")
#@ namespace = data.values.ingress.external.namespace
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: cnrs-selfsigned-issuer
  namespace: #@ namespace
spec:
  selfSigned: { }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cnrs-ca
  namespace: #@ namespace
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: #@ namespace
spec:
  ca:
    secretName: cnrs-ca
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cnrs-default-tls
  namespace: #@ namespace
spec:
  dnsNames:
  - #@ "*.{}".format(data.values.domain_name)
  issuerRef:
    kind: Issuer
    name: cnrs-ca-issuer
  secretName: cnrs-default-tls
---
apiVersion: projectcontour.io/v1
kind: TLSCertificateDelegation
metadata:
  name: contour-delegation
  namespace: #@ namespace
spec:
  delegations:
  - secretName: cnrs-default-tls
    targetNamespaces:
    - "*"
#@overlay/match by=overlay.subset({"metadata":{"name":"config-network"}, "kind": "ConfigMap"})
---
data:
  #@overlay/match missing_ok=True
  default-external-scheme: https
EOF

Cloud Native RuntimesからKnative Serving以外のリソースを削除するoverlayを作成します。 Learning CenterにTLS証明書の

cat <<EOF > learningcenter-certificate.yml
#@ load("@ytt:data", "data")
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: learningcenter-selfsigned-issuer
  namespace: #@ data.values.namespace
spec:
  selfSigned: { }
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: learningcenter-ca
  namespace: #@ data.values.namespace
spec:
  commonName: learningcenter-ca
  isCA: true
  issuerRef:
    kind: Issuer
    name: learningcenter-selfsigned-issuer
  secretName: learningcenter-ca
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: learningcenter-ca-issuer
  namespace: #@ data.values.namespace
spec:
  ca:
    secretName: learningcenter-ca
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: learningcenter-tls
  namespace: #@ data.values.namespace
spec:
  dnsNames:
  - #@ data.values.ingressDomain
  - #@ "*.{}".format(data.values.ingressDomain)    
  issuerRef:
    kind: Issuer
    name: learningcenter-ca-issuer
  secretName: learningcenter-tls
EOF

Metadata StoreにCloud Native RuntimesのデフォルトのTLS証明書を使うoverlayを作成します。

ℹ️ Learning Centerと違ってMetadata StoreはContourのHTTPProxyを使用しているため、
TLSCertificateDelegationでCloud Native Runtimes用のTLS証明書を使えます。
Learning CenterはIngressを使っているため、TAP 1.1に含まれるContour 1.18.2ではTLSCertificateDelegationは使えません。
Contour 1.20からIngresでもTLSCertificateDelegationが使えるようになります。

cat <<EOF > metadata-store-ingress-tls.yml
#@ load("@ytt:overlay", "overlay")
#@overlay/match by=overlay.subset({"metadata":{"name":"metadata-store-ingress"}, "kind": "HTTPProxy"})
---
spec:
  virtualhost:
    tls:
      secretName: tanzu-system-ingress/cnrs-default-tls
#@overlay/match by=overlay.subset({"metadata":{"name":"ingress-cert"}, "kind": "Certificate"})
#@overlay/remove
---
EOF

overlayファイルをSecretとして作成します。

kubectl -n tap-install create secret generic cnrs-default-tls \
  -o yaml \
  --dry-run=client \
  --from-file=cnrs-default-tls.yml \
  | kubectl apply -f-

kubectl -n tap-install create secret generic learningcenter-certificate \
  -o yaml \
  --dry-run=client \
  --from-file=learningcenter-certificate.yml \
  | kubectl apply -f-

kubectl -n tap-install create secret generic metadata-store-ingress-tls \
  -o yaml \
  --dry-run=client \
  --from-file=metadata-store-ingress-tls.yml \
  | kubectl apply -f-

LoadBalancer Serviceを作成できるように別のコンソールでminikube tunnelを実行しておきます。

minikube tunnel

TAPをインストールします。

tanzu package install tap -p tap.tanzu.vmware.com -v ${TAP_VERSION} --values-file tap-values.yml -n tap-install

インストールの進捗は次のコマンドで確認します。

watch kubectl get app -n tap-install

全てのappが Reconcile succeeded になるまで待ちます。

$ kubectl get app -n tap-install 
NAME                       DESCRIPTION           SINCE-DEPLOY   AGE
appliveview-conventions    Reconcile succeeded   10m            11m
buildservice               Reconcile succeeded   17m            17m
cartographer               Reconcile succeeded   19s            12m
cert-manager               Reconcile succeeded   68s            17m
cnrs                       Reconcile succeeded   10m            11m
contour                    Reconcile succeeded   3m9s           12m
conventions-controller     Reconcile succeeded   12m            12m
developer-conventions      Reconcile succeeded   10m            11m
fluxcd-source-controller   Reconcile succeeded   18s            17m
ootb-delivery-basic        Reconcile succeeded   4s             10m
ootb-supply-chain-basic    Reconcile succeeded   2s             10m
ootb-templates             Reconcile succeeded   18s            11m
service-bindings           Reconcile succeeded   10m            17m
services-toolkit           Reconcile succeeded   19s            17m
source-controller          Reconcile succeeded   28s            17m
spring-boot-conventions    Reconcile succeeded   10m            11m
tap                        Reconcile succeeded   3m3s           18m
tap-auth                   Reconcile succeeded   7m50s          17m
tap-telemetry              Reconcile succeeded   25s            17m
tekton-pipelines           Reconcile succeeded   25s            17m

インストールされたパッケージは次の通りです。

$ kubectl get packageinstall -n tap-install 
NAME                                 PACKAGE NAME                                          PACKAGE VERSION   DESCRIPTION           AGE
accelerator                          accelerator.apps.tanzu.vmware.com                     1.1.2             Reconcile succeeded   15m
api-portal                           api-portal.tanzu.vmware.com                           1.0.15            Reconcile succeeded   17m
appliveview                          backend.appliveview.tanzu.vmware.com                  1.1.1             Reconcile succeeded   15m
appliveview-connector                connector.appliveview.tanzu.vmware.com                1.1.1             Reconcile succeeded   17m
appliveview-conventions              conventions.appliveview.tanzu.vmware.com              1.1.1             Reconcile succeeded   15m
buildservice                         buildservice.tanzu.vmware.com                         1.5.1             Reconcile succeeded   17m
cartographer                         cartographer.tanzu.vmware.com                         0.3.0             Reconcile succeeded   16m
cert-manager                         cert-manager.tanzu.vmware.com                         1.5.3+tap.2       Reconcile succeeded   17m
cnrs                                 cnrs.tanzu.vmware.com                                 1.2.0             Reconcile succeeded   15m
contour                              contour.tanzu.vmware.com                              1.18.2+tap.2      Reconcile succeeded   16m
conventions-controller               controller.conventions.apps.tanzu.vmware.com          0.6.3             Reconcile succeeded   16m
developer-conventions                developer-conventions.tanzu.vmware.com                0.6.0             Reconcile succeeded   15m
fluxcd-source-controller             fluxcd.source.controller.tanzu.vmware.com             0.16.4            Reconcile succeeded   17m
image-policy-webhook                 image-policy-webhook.signing.apps.tanzu.vmware.com    1.1.2             Reconcile succeeded   16m
learningcenter                       learningcenter.tanzu.vmware.com                       0.2.0             Reconcile succeeded   15m
learningcenter-workshops             workshops.learningcenter.tanzu.vmware.com             0.2.0             Reconcile succeeded   12m
metadata-store                       metadata-store.apps.tanzu.vmware.com                  1.1.3             Reconcile succeeded   16m
ootb-delivery-basic                  ootb-delivery-basic.tanzu.vmware.com                  0.7.1             Reconcile succeeded   15m
ootb-supply-chain-testing-scanning   ootb-supply-chain-testing-scanning.tanzu.vmware.com   0.7.1             Reconcile succeeded   15m
ootb-templates                       ootb-templates.tanzu.vmware.com                       0.7.1             Reconcile succeeded   15m
scanning                             scanning.apps.tanzu.vmware.com                        1.1.1             Reconcile succeeded   17m
service-bindings                     service-bindings.labs.vmware.com                      0.7.1             Reconcile succeeded   17m
services-toolkit                     services-toolkit.tanzu.vmware.com                     0.6.0             Reconcile succeeded   17m
source-controller                    controller.source.apps.tanzu.vmware.com               0.3.3             Reconcile succeeded   17m
spring-boot-conventions              spring-boot-conventions.tanzu.vmware.com              0.4.0             Reconcile succeeded   15m
tap                                  tap.tanzu.vmware.com                                  1.1.1             Reconcile succeeded   17m
tap-auth                             tap-auth.tanzu.vmware.com                             1.0.1             Reconcile succeeded   17m
tap-gui                              tap-gui.tanzu.vmware.com                              1.1.1             Reconcile succeeded   15m
tap-telemetry                        tap-telemetry.tanzu.vmware.com                        0.1.4             Reconcile succeeded   17m
tekton-pipelines                     tekton.tanzu.vmware.com                               0.33.5            Reconcile succeeded   17m

Envoyに設定されたExternal IPを使って、cnrs.domain_nameを変更します。ドメイン名にはsslip.ioを使用します。 例えば、External IPが10.105.146.158の場合に、cnrs.domain_nameに*.10-105-146-158.sslip.ioを指定します。

次のコマンドでtap-values.ymlを更新します。

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

TAPを更新します。

tanzu package installed update tap -n tap-install -v ${TAP_VERSION} -f tap-values.yml 

Default TLSのCertificateのDNS名が更新されたことを確認してください。

$ kubectl get certificate -n tanzu-system-ingress cnrs-default-tls -ojsonpath='{.spec.dnsNames[0]}'
*.10-105-146-158.sslip.io

$ kubectl get certificate -n learningcenter learningcenter-tls -ojsonpath='{.spec.dnsNames[0]}'
learningcenter.10-105-146-158.sslip.io

👆 sslip.ioにアクセスできない環境の場合は、
ラップトップ上の/etc/hostsに今後使用する127.0.0.1 <...>.tap.example.comを一つずつ設定してください。

Workloadのデプロイ

Workloadを作成するための事前準備

RBACの設定

https://docs.vmware.com/en/Tanzu-Application-Platform/1.1/tap/GUID-install-components.html#setup (一部変更しています)

kubectl create ns demo
tanzu secret registry add registry-credentials --server registry.kube-system.svc.cluster.local --username admin --password admin --namespace demo
cat <<EOF | kubectl -n demo apply -f -
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: Secret
metadata:
  name: git-ssh
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
secrets:
  - name: registry-credentials
  - name: git-ssh
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
Tekton Pipelineの作成

https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.1/tap/GUID-scc-ootb-supply-chain-testing.html

今回はテストは空実装にします。

cat <<'EOF' | kubectl -n demo apply -f -
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: developer-defined-tekton-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: alpine
          script: |-
            echo "Skip Test :)"
EOF
ScanTemplateのインストール

https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.1/tap/GUID-scc-ootb-supply-chain-testing-scanning.html#updates-to-the-developer-namespace-2

ScanTemplateをdemo namespaceに作成するために、grype packageをここでインストールします。

cat <<EOF > grype-demo.yaml
namespace: demo
targetImagePullSecret: registry-credentials
EOF
tanzu package install grype-demo -p grype.scanning.apps.tanzu.vmware.com -v 1.1.1 -n tap-install -f grype-demo.yaml
$ kubectl get scantemplate -n demo
NAME                          AGE
blob-source-scan-template     27s
private-image-scan-template   27s
public-image-scan-template    27s
public-source-scan-template   27s
ScanPolicyの作成

https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.1/tap/GUID-scc-ootb-supply-chain-testing-scanning.html#updates-to-the-developer-namespace-2

ScanPolicyはサンプルと同じものを使用します。

cat <<'EOF' | kubectl -n demo apply -f -
apiVersion: scanning.apps.tanzu.vmware.com/v1beta1
kind: ScanPolicy
metadata:
  name: scan-policy
spec:
  regoFile: |
    package policies

    default isCompliant = false

    # Accepted Values: "Critical", "High", "Medium", "Low", "Negligible", "UnknownSeverity"
    violatingSeverities := ["Critical","High","UnknownSeverity"]
    ignoreCVEs := []

    contains(array, elem) = true {
      array[_] = elem
    } else = false { true }

    isSafe(match) {
      fails := contains(violatingSeverities, match.Ratings.Rating[_].Severity)
      not fails
    }

    isSafe(match) {
      ignore := contains(ignoreCVEs, match.Id)
      ignore
    }

    isCompliant = isSafe(input.currentVulnerability)
EOF

ここまでnamespace単位で行う必要のある設定でした。

Node.jsアプリのデプロイ

https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.1/tap/GUID-scc-ootb-supply-chain-testing-scanning.html#developer-workload-3

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

作成されるリソースを確認したければ次のコマンドをwatchしてください。

watch kubectl get pod,gitrepo,pipelinerun,sourcescan,imgs,build,imagescan,podintent,taskrun,imagerepository,app,ksvc,certificate,httpproxy -n demo -owide

ソースコードの脆弱性スキャンで"Failed"になります。

$ kubectl get sourcescans -n demo hello                  
NAME    PHASE    SCANNEDREVISION                            SCANNEDREPOSITORY                                                                                                                  AGE     CRITICAL   HIGH   MEDIUM   LOW   UNKNOWN   CVETOTAL
hello   Failed   19610d1789fb30d571e0b27a65ed03a7bdec2922   http://source-controller.flux-system.svc.cluster.local./gitrepository/demo/hello/19610d1789fb30d571e0b27a65ed03a7bdec2922.tar.gz   3m15s   0          1      0        1     0         2

スキャン結果を確認するためにtanzu insightコマンドを使用します。 このコマンドを使用するための設定を行います。

https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.1/tap/GUID-scst-store-create-service-account-access-token.html (一部変更しています)

read-onlyなアクセストークンを作成するために次のSecretを作成します。

cat <<EOF | kubectl apply -f-
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: metadata-store-ready-only
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: metadata-store-read-only
subjects:
- kind: ServiceAccount
  name: metadata-store-read-client
  namespace: metadata-store
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metadata-store-read-client
  namespace: metadata-store
automountServiceAccountToken: false
---
apiVersion: v1
kind: Secret
metadata:
  name: metadata-store-read-only-token
  namespace: metadata-store  
  annotations:
    kubernetes.io/service-account.name: metadata-store-read-client
type: kubernetes.io/service-account-token
EOF

アクセストークンを取得して、Metadata Storeのエンドポイントを設定します。 https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.1/tap/GUID-scst-store-using-encryption-and-connection.html

kubectl get secret -n tanzu-system-ingress cnrs-default-tls -otemplate='{{(index .data "ca.crt") | base64decode}}' > cnrs-default-tls.ca
METADATA_STORE_DOMAIN=$(kubectl get httpproxy -n metadata-store metadata-store-ingress -ojsonpath='{.spec.virtualhost.fqdn}')
AUTH_TOKEN=$(kubectl get secret -n metadata-store metadata-store-read-only-token -otemplate='{{.data.token | base64decode}}')
tanzu insight config set-target https://${METADATA_STORE_DOMAIN} --ca-cert cnrs-default-tls.ca --access-token=${AUTH_TOKEN}

以下のログが出力されます。

ℹ  Using config file: /Users/toshiaki/.config/tanzu/insight/config.yaml 
ℹ  Setting trustedcacert in config 
ℹ  Setting accesstoken in config 
ℹ  Setting endpoint in config to: https://metadata-store.10-105-146-158.sslip.io 
✔  Success: Set Metadata Store endpoint 

次のコマンドで疎通チェックします。

$ tanzu insight health
Success: Reached Metadata Store!

tanzu insightコマンドが使えるようになりました。 tanzu insight sourceでソースコードスキャンの結果を確認します。

$ tanzu insight source get --org making --repo hello-nodejs --commit 19610d1789fb30d571e0b27a65ed03a7bdec2922 
1. 	ID:       	1
    Repository:  	hello-nodejs
    Commit:      	19610d1789fb30d571e0b27a65ed03a7bdec2922
    Organization:	making
    Packages:
    1. accepts@1.3.8
    ...
    8. cookie@0.5.0
    CVEs:
        1. CVE-2017-18589 (High)
        1. CVE-2017-18589 (Unknown)
        1. CVE-2017-18589 (Unknown)
    9. cookie-signature@1.0.6
    ...
    20. fresh@0.5.2
    CVEs:
        1. CVE-2013-1779 (Low)
        1. CVE-2013-1779 (Unknown)
    21. function-bind@1.1.1
    ...
    56. vary@1.1.2

CVE-2017-18589がHigh Severityで報告されています。

ℹ️ SBOMの出力結果はscanしたPodのログで確認できます。

$ kubectl logs -n demo scan-hello-<...>

<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.2" xmlns:v="http://cyclonedx.org/schema/ext/vulnerability/1.0" version="1" serialNumber="urn:uuid:916fdfd5-2c29-4bc4-9dbf-a11c9731c5f1">
  <metadata>
    <timestamp>2022-06-21T17:07:18Z</timestamp>
    <tools>
      <tool>
        <vendor>anchore</vendor>
        <name>grype</name>
        <version>v0.33.1</version>
      </tool>
    </tools>
    <component type="file">
      <name>https://github.com/making/hello-nodejs</name>
      <version>19610d1789fb30d571e0b27a65ed03a7bdec2922</version>
    </component>
  </metadata>
  <components>
    <component type="library">
      <name>accepts</name>
      <version>1.3.8</version>
    </component>
    <!-- ... -->
    <component type="library">
      <name>content-type</name>
      <version>1.0.4</version>
    </component>
    <component type="library">
      <name>cookie</name>
      <version>0.5.0</version>
      <v:vulnerabilities>
        <v:vulnerability ref="urn:uuid:a13b50a9-6348-4f67-b703-87fa33b7017d">
          <v:id>CVE-2017-18589</v:id>
          <v:source name="nvd">
            <v:url>http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-18589</v:url>
          </v:source>
          <v:ratings>
            <v:rating>
              <v:severity>High</v:severity>
            </v:rating>
            <v:rating>
              <v:score>
                <v:base>5</v:base>
                <v:impact>2.9</v:impact>
                <v:exploitability>10</v:exploitability>
              </v:score>
              <v:method>CVSSv2</v:method>
              <v:vector>AV:N/AC:L/Au:N/C:N/I:N/A:P</v:vector>
            </v:rating>
            <v:rating>
              <v:score>
                <v:base>7.5</v:base>
                <v:impact>3.6</v:impact>
                <v:exploitability>3.9</v:exploitability>
              </v:score>
              <v:method>CVSSv3</v:method>
              <v:vector>CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H</v:vector>
            </v:rating>
          </v:ratings>
          <v:description>An issue was discovered in the cookie crate before 0.7.6 for Rust. Large integers in the Max-Age of a cookie cause a panic.</v:description>
          <v:advisories>
            <v:advisory>https://rustsec.org/advisories/RUSTSEC-2017-0005.html</v:advisory>
          </v:advisories>
        </v:vulnerability>
      </v:vulnerabilities>
    </component>
    <component type="library">
      <name>cookie-signature</name>
      <version>1.0.6</version>
    </component>
    <!-- ... -->
    <component type="library">
      <name>forwarded</name>
      <version>0.2.0</version>
    </component>
    <component type="library">
      <name>fresh</name>
      <version>0.5.2</version>
      <v:vulnerabilities>
        <v:vulnerability ref="urn:uuid:17c0acd2-cb25-4dce-af74-3a15c416c3fd">
          <v:id>CVE-2013-1779</v:id>
          <v:source name="nvd">
            <v:url>http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1779</v:url>
          </v:source>
          <v:ratings>
            <v:rating>
              <v:severity>Low</v:severity>
            </v:rating>
            <v:rating>
              <v:score>
                <v:base>2.1</v:base>
                <v:impact>2.9</v:impact>
                <v:exploitability>3.9</v:exploitability>
              </v:score>
              <v:method>CVSSv2</v:method>
              <v:vector>AV:N/AC:H/Au:S/C:N/I:P/A:N</v:vector>
            </v:rating>
          </v:ratings>
          <v:description>Cross-site scripting (XSS) vulnerability in the 3 slide gallery in the Fresh theme before 7.x-1.4 for Drupal allows remote authenticated users with the administer themes permission to inject arbitrary web script or HTML via unspecified vectors.</v:description>
          <v:advisories>
            <v:advisory>http://drupalcode.org/project/fresh.git/commitdiff/08a3ccb</v:advisory>
            <v:advisory>http://www.openwall.com/lists/oss-security/2013/02/28/3</v:advisory>
            <v:advisory>http://drupal.org/node/1929482</v:advisory>
            <v:advisory>http://drupal.org/node/1723316</v:advisory>
          </v:advisories>
        </v:vulnerability>
      </v:vulnerabilities>
    </component>
    <component type="library">
      <name>function-bind</name>
      <version>1.1.1</version>
    </component>
    <!-- ... -->
    <component type="library">
      <name>vary</name>
      <version>1.1.2</version>
    </component>
  </components>
</bom>

https://github.com/anchore/anchore-engine/issues/304 を見る限り、この脆弱性はRustのライブラリに関するものであり、 今回使用しているのはNode.jsのライブラリなので、これは誤検出です。 ignoreCVEsにCVE-2017-18589を追加して、ScanPolicyを更新します。

cat <<'EOF' | kubectl -n demo apply -f -
apiVersion: scanning.apps.tanzu.vmware.com/v1beta1
kind: ScanPolicy
metadata:
  name: scan-policy
spec:
  regoFile: |
    package policies

    default isCompliant = false

    # Accepted Values: "Critical", "High", "Medium", "Low", "Negligible", "UnknownSeverity"
    violatingSeverities := ["Critical","High","UnknownSeverity"]
    # https://github.com/anchore/anchore-engine/issues/304
    ignoreCVEs := ["CVE-2017-18589"]

    contains(array, elem) = true {
      array[_] = elem
    } else = false { true }

    isSafe(match) {
      fails := contains(violatingSeverities, match.Ratings.Rating[_].Severity)
      not fails
    }

    isSafe(match) {
      ignore := contains(ignoreCVEs, match.Id)
      ignore
    }

    isCompliant = isSafe(input.currentVulnerability)
EOF

Scanが再度走ります。今度は"Completed"になります。

$ kubectl get sourcescans -n demo hello
NAME    PHASE       SCANNEDREVISION                            SCANNEDREPOSITORY                                                                                                                  AGE   CRITICAL   HIGH   MEDIUM   LOW   UNKNOWN   CVETOTAL
hello   Completed   19610d1789fb30d571e0b27a65ed03a7bdec2922   http://source-controller.flux-system.svc.cluster.local./gitrepository/demo/hello/19610d1789fb30d571e0b27a65ed03a7bdec2922.tar.gz   13m   0          1      0        1     0         2

ちなみにIgnoreしたCVEもMetaData Storeに残り、CVE情報でソースを検索するとhello-nodejsがヒットします。

$ tanzu insight vulnerabilities sources --cveid CVE-2017-18589
1. 	ID:       	1
    Repository:  	hello-nodejs
    Commit:      	19610d1789fb30d571e0b27a65ed03a7bdec2922
    Organization:	making
    Packages:
    1. cookie@0.5.0
    CVEs:
        1. CVE-2017-18589 (High)
        1. CVE-2017-18589 (Unknown)
        1. CVE-2017-18589 (Unknown)

さて、ソースコードスキャンが成功した後、イメージのビルドが行われ、次のイメージの脆弱性をスキャンします。

イメージの脆弱性スキャンで"Failed"になります。

$ kubectl get imagescan -n demo hello 
NAME    PHASE    SCANNEDIMAGE                                                                                                                            AGE   CRITICAL   HIGH   MEDIUM   LOW   UNKNOWN   CVETOTAL
hello   Failed   registry.kube-system.svc.cluster.local/supplychain/hello-demo@sha256:a1a401c25e787cb380eec4433b9ba1de4b7742352e8c80ce57c60110d6e69b5b   79s   0          7      3        12    0         22

tanzu insight imageでイメージスキャンの結果を確認します。

$ tanzu insight image get --digest sha256:a1a401c25e787cb380eec4433b9ba1de4b7742352e8c80ce57c60110d6e69b5b
ID:       	1
Registry:  	registry.kube-system.svc.cluster.local
Image Name:	supplychain/hello-demo
Digest:    	sha256:a1a401c25e787cb380eec4433b9ba1de4b7742352e8c80ce57c60110d6e69b5b
Packages:
    1. accepts@1.3.8
    ...
    8. cookie@0.5.0
    CVEs:
        1. CVE-2017-18589 (High)
        1. CVE-2017-18589 (Unknown)
        1. CVE-2017-18589 (Unknown)
    9. cookie-signature@1.0.6
    ...
    20. fresh@0.5.2
    CVEs:
        1. CVE-2013-1779 (Low)
        1. CVE-2013-1779 (Unknown)
    21. function-bind@1.1.1
    ...
    67. coreutils@8.28-1ubuntu1
    CVEs:
        1. CVE-2016-2781 (Low)
    68. dash@0.5.8-2.10
    ...
    76. gcc-8-base@8.4.0-1ubuntu1~18.04
    CVEs:
        1. CVE-2020-13844 (Medium)
    77. gpgv@2.2.4-1ubuntu1.5
    ...
    89. libc-bin@2.27-3ubuntu1.6
    CVEs:
        1. CVE-2009-5155 (Low)
        2. CVE-2015-8985 (Low)
        3. CVE-2016-20013 (Low)
    90. libc6@2.27-3ubuntu1.6
    CVEs:
        1. CVE-2009-5155 (Low)
        2. CVE-2015-8985 (Low)
        3. CVE-2016-20013 (Low)
    91. libcap-ng0@0.7.7-3.1
    ...
    98. libgcc1@1:8.4.0-1ubuntu1~18.04
    CVEs:
        1. CVE-2020-13844 (Medium)
    99. libgcrypt20@1.8.1-4ubuntu1.3
    100. libgmp10@2:6.1.2+dfsg-2
    101. libgnutls30@3.5.18-1ubuntu1.5
    CVEs:
        1. CVE-2018-16868 (Low)
    102. libgpg-error0@1.27-6
    ...
    108. libncurses5@6.1-1ubuntu1.18.04
    CVEs:
        1. CVE-2019-17594 (Low)
        2. CVE-2019-17595 (Low)
        3. CVE-2021-39537 (Low)
        4. CVE-2022-29458 (Low)
    109. libncursesw5@6.1-1ubuntu1.18.04
    CVEs:
        1. CVE-2019-17594 (Low)
        2. CVE-2019-17595 (Low)
        3. CVE-2021-39537 (Low)
        4. CVE-2022-29458 (Low)
    110. libnettle6@3.4.1-0ubuntu0.18.04.1
    ...
    116. libpcre3@2:8.39-9ubuntu0.1
    CVEs:
        1. CVE-2017-11164 (Low)
    117. libprocps6@2:3.3.12-3ubuntu1.2
    ...
    126. libstdc++6@8.4.0-1ubuntu1~18.04
    CVEs:
        1. CVE-2020-13844 (Medium)
    127. libsystemd0@237-3ubuntu10.53
    128. libtasn1-6@4.13-2
    129. libtinfo5@6.1-1ubuntu1.18.04
    CVEs:
        1. CVE-2019-17594 (Low)
        2. CVE-2019-17595 (Low)
        3. CVE-2021-39537 (Low)
        4. CVE-2022-29458 (Low)
    130. libudev1@237-3ubuntu10.53
    ...
    135. locales@2.27-3ubuntu1.6
    CVEs:
        1. CVE-2009-5155 (Low)
        2. CVE-2015-8985 (Low)
        3. CVE-2016-20013 (Low)
    136. login@1:4.5-1ubuntu2.2
    CVEs:
        1. CVE-2013-4235 (Low)
    137. lsb-base@9.20170808ubuntu1
    ...
    140. ncurses-base@6.1-1ubuntu1.18.04
    CVEs:
        1. CVE-2019-17594 (Low)
        2. CVE-2019-17595 (Low)
        3. CVE-2021-39537 (Low)
        4. CVE-2022-29458 (Low)
    141. ncurses-bin@6.1-1ubuntu1.18.04
    CVEs:
        1. CVE-2019-17594 (Low)
        2. CVE-2019-17595 (Low)
        3. CVE-2021-39537 (Low)
        4. CVE-2022-29458 (Low)
    142. netbase@5.4
    143. openssl@1.1.1-1ubuntu2.1~18.04.17
    144. passwd@1:4.5-1ubuntu2.2
    CVEs:
        1. CVE-2013-4235 (Low)
    145. perl-base@5.26.1-6ubuntu0.5
    CVEs:
        1. CVE-2020-16156 (Medium)
    146. procps@2:3.3.12-3ubuntu1.2
    ...
    179. ansi-regex@3.0.0
    CVEs:
        1. CVE-2021-3807 (High)
        1. CVE-2021-3807 (Unknown)
        1. CVE-2021-3807 (Unknown)
        2. GHSA-93q8-gq69-wqmw (High)
    180. ansi-regex@5.0.0
    CVEs:
        1. CVE-2021-3807 (High)
        1. CVE-2021-3807 (Unknown)
        1. CVE-2021-3807 (Unknown)
        2. GHSA-93q8-gq69-wqmw (High)
    181. ansi-regex@5.0.1
    ...
    324. once@1.4.0
    325. opener@1.5.2
    CVEs:
        1. CVE-2021-27478 (High)
        1. CVE-2021-27478 (Unknown)
        1. CVE-2021-27478 (Unknown)
        2. CVE-2021-27482 (High)
        2. CVE-2021-27482 (Unknown)
        2. CVE-2021-27482 (Unknown)
        3. CVE-2021-27498 (High)
        3. CVE-2021-27498 (Unknown)
        3. CVE-2021-27498 (Unknown)
        4. CVE-2021-27500 (High)
        4. CVE-2021-27500 (Unknown)
        4. CVE-2021-27500 (Unknown)
    326. p-map@4.0.0
    ...
    382. yallist@4.0.0

たくさん検出されました。

Metadata StoreにはSBOMの情報が保存されますが、CVEとSeverityの情報しかわからないので、 grype CLIを直接使ってFixedされたCVEの情報を取得します。

SCAN_IMAGE=$(kubectl get scantemplate -n demo private-image-scan-template -ojsonpath='{.spec.template.containers[0].image}')
TARGET_IMAGE=$(kubectl get imgs -n demo hello -ojsonpath='{.status.latestImage}')
kubectl run grype -n demo --restart=Never -ti --image=${SCAN_IMAGE} --timeout=10m --rm --command -- grype -v ${TARGET_IMAGE} --only-fixed
If you don't see a command prompt, try pressing enter.
[0000]  INFO New version of grype is available: 0.40.0
[0001]  INFO downloading new vulnerability DB
[0015]  INFO identified distro: Ubuntu 18.04.6 LTS from-lib=syft
[0015]  INFO cataloging image from-lib=syft
[0119]  INFO updated vulnerability DB to version=3 built="2022-06-23 08:15:59 +0000 UTC"
[0120]  INFO ignoring 46 matches due to user-provided ignore rules
NAME        INSTALLED  FIXED-IN  VULNERABILITY        SEVERITY 
ansi-regex  3.0.0      3.0.1     GHSA-93q8-gq69-wqmw  High      
ansi-regex  5.0.0      5.0.1     GHSA-93q8-gq69-wqmw  High      
npm         8.5.0      8.11.0    GHSA-hj9c-8jmm-8c52  Medium       

FixedでSeverityがHigh以上なものだけを見るとGHSA-93q8-gq69-wqmwが該当します。 どこで使われているのかを確認するために、次のコマンドでイメージを展開し、ansi-regexを検索します。

$ imgpkg pull -i $(kubectl get imgs -n demo hello -ojsonpath='{.status.latestImage}' | sed 's/registry.kube-system.svc.cluster.local/localhost:5000/g') -o /tmp/hello
$ cd /tmp/hello
$ grep -irI ansi-regex  ./
./layers/tanzu-buildpacks_node-engine-lite/node/lib/node_modules/npm/docs/content/commands/npm-install.md:    npm install ansi-regex --save-bundle
...
./layers/tanzu-buildpacks_node-engine-lite/node/lib/node_modules/npm/node_modules/ansi-regex/package.json:  "repository": "chalk/ansi-regex",

どうやら、node自身にバンドルされているライブラリのようです。この脆弱性をFixするにはnode-engine buildpackが更新される必要があります。 とはいえ、脆弱性のPoCを見るとアプリがansi-regexを使ってるansiRegex().test(...)で悪意のある文字列を受け取らない問題なさそう。 アプリではansi-regexは使用していないのでこれはignoreします。(buildpack teamに確認中です) UnfixedなCVEもいったんignoreします。

というわけで

  • CVE-2021-3807
  • GHSA-93q8-gq69-wqmw
  • CVE-2021-27478
  • CVE-2021-27482
  • CVE-2021-27498
  • CVE-2021-27500 をignoreCVEsに追加して、ScanPolicyを更新します。
cat <<'EOF' | kubectl -n demo apply -f -
apiVersion: scanning.apps.tanzu.vmware.com/v1beta1
kind: ScanPolicy
metadata:
  name: scan-policy
spec:
  regoFile: |
    package policies

    default isCompliant = false

    # Accepted Values: "Critical", "High", "Medium", "Low", "Negligible", "UnknownSeverity"
    violatingSeverities := ["Critical","High","UnknownSeverity"]
    # https://github.com/anchore/anchore-engine/issues/304
    ignoreCVEs := ["CVE-2017-18589", "CVE-2021-3807", "GHSA-93q8-gq69-wqmw", "CVE-2021-27478", "CVE-2021-27482", "CVE-2021-27498", "CVE-2021-27500"]

    contains(array, elem) = true {
      array[_] = elem
    } else = false { true }

    isSafe(match) {
      fails := contains(violatingSeverities, match.Ratings.Rating[_].Severity)
      not fails
    }

    isSafe(match) {
      ignore := contains(ignoreCVEs, match.Id)
      ignore
    }

    isCompliant = isSafe(input.currentVulnerability)
EOF

Scanが再度走ります。今度は"Completed"になります。

$ kubectl get imagescan -n demo hello
NAME    PHASE       SCANNEDIMAGE                                                                                                                            AGE     CRITICAL   HIGH   MEDIUM   LOW   UNKNOWN   CVETOTAL
hello   Completed   registry.kube-system.svc.cluster.local/supplychain/hello-demo@sha256:a1a401c25e787cb380eec4433b9ba1de4b7742352e8c80ce57c60110d6e69b5b   7m55s   0          7      3        12    0         22

無視したCVEもMetaData Storeに規則され、次のように指定した脆弱性を持つイメージの検索結果に含まれます。

$ tanzu insight vulnerabilities images --cveid CVE-2021-3807
1. 	ID:       	1
    Registry:  	registry.kube-system.svc.cluster.local
    Image Name:	supplychain/hello-demo
    Digest:    	sha256:a1a401c25e787cb380eec4433b9ba1de4b7742352e8c80ce57c60110d6e69b5b
    Packages:
    1. ansi-regex@3.0.0
    CVEs:
        1. CVE-2021-3807 (High)
        1. CVE-2021-3807 (Unknown)
        1. CVE-2021-3807 (Unknown)
        2. GHSA-93q8-gq69-wqmw (High)
    2. ansi-regex@5.0.0
    CVEs:
        1. CVE-2021-3807 (High)
        1. CVE-2021-3807 (Unknown)
        1. CVE-2021-3807 (Unknown)
        2. GHSA-93q8-gq69-wqmw (High)

Scanをパスしたので、ようやくアプリのデプロイが行われます。

$ tanzu apps workload get -n demo hello
# hello: Ready
---
lastTransitionTime: "2022-06-22T18:07:27Z"
message: ""
reason: Ready
status: "True"
type: Ready

Pods
NAME                                     STATUS      RESTARTS   AGE
hello-00001-deployment-994f5755f-f2rjc   Running     0          37s
hello-build-1-build-pod                  Succeeded   0          9m52s
hello-config-writer-v4v9w-pod            Succeeded   0          96s
hello-sq9wx-test-pod                     Succeeded   0          13m
scan-hello-24ggg-8wp7h                   Succeeded   0          10m
scan-hello-72g2f-hmf2g                   Succeeded   0          9m16s
scan-hello-j5pfr-pm4hj                   Succeeded   0          13m
scan-hello-q9ctb-hqbfg                   Succeeded   0          2m45s
scan-hello-w8svx-m7tx5                   Succeeded   0          2m45s

Knative Services
NAME    READY   URL
hello   Ready   https://hello-demo.10-105-146-158.sslip.io
$ curl -k https://hello-demo.10-105-146-158.sslip.io
Hello Tanzu!!

確認が終わればWorkloadを削除します。

tanzu apps workload delete -n demo hello -y