IK.AM

@making's tech note


Tanzu Application Platform 1.1で1つのnamespaceに複数のTekton Pipelineを使えるようにする

🗃 {Dev/CaaS/Kubernetes/TAP}
🏷 Kubernetes 🏷 Cartographer 🏷 kind 🏷 Tanzu 🏷 TAP 🏷 Tekton 
🗓 Updated at 2022-08-17T20:04:34+09:00  🗓 Created at 2022-06-30T17:57:42+09:00 {✒️️ Edit  ⏰ History  🗑 Delete}

こちらの記事でTAP 1.1のOut of the Box Supply Chain with Testingを試しました。
OOTBのSupply ChainではTektonのPipelineがnamespaceにつき一つしか設定できません。 つまり、同一namespaceのWorkloadに対して同じテストスクリプトを共用しないとけいません。これは同じnamespaceで多言語や異なるビルドツール(MavenとGradleなど)を扱う場合に不便です。

ドキュメントに複数パイプラインを使う方法のポイントが記載されています。

今回はSupply Chainをカスタマイズし、1つのnamespaceに複数のTekton Pipelineを使えるようにしてみます。

目次

ClusterSourceTemplateの更新

testing-pipelineという名前のClusterSourceTemplateをyttのoverlayでカスタマイズする必要があります。

次のoverlayファイルを作成します。

cat <<'EOF' > ootb-templates-multiple-pipelines.yml 
#@ load("@ytt:overlay", "overlay")
#@overlay/match by=overlay.subset({"metadata":{"name":"testing-pipeline"}, "kind": "ClusterSourceTemplate"})
---
spec:
  #! https://docs.vmware.com/en/Tanzu-Application-Platform/1.1/tap//GUID-scc-ootb-supply-chain-testing.html#multiple-pl
  #@overlay/replace via=lambda a, b: a.replace("apps.tanzu.vmware.com/pipeline: test", "apps.tanzu.vmware.com/pipeline: test\n      apps.tanzu.vmware.com/language: #@ data.values.workload.metadata.labels[\"apps.tanzu.vmware.com/language\"]")
  ytt:
EOF

overlayをSecretとして登録します。

kubectl -n tap-install create secret generic ootb-templates-multiple-pipelines \
  -o yaml \
  --dry-run=client \
  --from-file=ootb-templates-multiple-pipelines.yml \
  | kubectl apply -f-

作成したoverlayのSecret名をtap-values.ymlpackage_overlaysへ次のように設定します。

package_overlays:
# ...
- name: ootb-templates
  secrets:
  - name: ootb-templates-multiple-pipelines
  # ...

変更したtap-values.ymlを次のコマンドで反映します。

tanzu package installed update -n tap-install tap -f tap-values.yml -v 1.1.1

更新が完了したら次のコマンドを実行して、ClusterSourceTemplateが変更されていることを確認してください。

$ kubectl get clustersourcetemplate testing-pipeline -oyaml
apiVersion: carto.run/v1alpha1
kind: ClusterSourceTemplate
metadata:
  annotations:
    kapp.k14s.io/identity: v1;/carto.run/ClusterSourceTemplate/testing-pipeline;carto.run/v1alpha1
    kapp.k14s.io/original: '{"apiVersion":"carto.run/v1alpha1","kind":"ClusterSourceTemplate","metadata":{"labels":{"kapp.k14s.io/app":"1656510239955370900","kapp.k14s.io/association":"v1.50024c093435d6c798ab4a6429d20dc7"},"name":"testing-pipeline"},"spec":{"revisionPath":".status.outputs.revision","urlPath":".status.outputs.url","ytt":"#@
      load(\"@ytt:data\", \"data\")\n\n#@ def merge_labels(fixed_values):\n#@   labels
      = {}\n#@   if hasattr(data.values.workload.metadata, \"labels\"):\n#@     labels.update(data.values.workload.metadata.labels)\n#@   end\n#@   labels.update(fixed_values)\n#@   return
      labels\n#@ end\n\napiVersion: carto.run/v1alpha1\nkind: Runnable\nmetadata:\n  name:
      #@ data.values.workload.metadata.name\n  labels: #@ merge_labels({ \"app.kubernetes.io/component\":
      \"test\" })\nspec:\n  #@ if/end hasattr(data.values.workload.spec, \"serviceAccountName\"):\n  serviceAccountName:
      #@ data.values.workload.spec.serviceAccountName\n\n  runTemplateRef:\n    name:
      tekton-source-pipelinerun\n    kind: ClusterRunTemplate\n\n  selector:\n    resource:\n      apiVersion:
      tekton.dev/v1beta1\n      kind: Pipeline\n    matchingLabels:\n      apps.tanzu.vmware.com/pipeline:
      test\n      apps.tanzu.vmware.com/language: #@ data.values.workload.metadata.labels[\"apps.tanzu.vmware.com/language\"]\n\n  inputs:\n    source-url:
      #@ data.values.source.url\n    source-revision: #@ data.values.source.revision\n"}}'
    kapp.k14s.io/original-diff-md5: c6e94dc94aed3401b5d0f26ed6c0bff3
  creationTimestamp: "2022-06-29T13:44:00Z"
  generation: 2
  labels:
    kapp.k14s.io/app: "1656510239955370900"
    kapp.k14s.io/association: v1.50024c093435d6c798ab4a6429d20dc7
  name: testing-pipeline
  resourceVersion: "1080279"
  uid: 67f284d6-bff8-4468-a174-16d2c7cfa19e
spec:
  revisionPath: .status.outputs.revision
  urlPath: .status.outputs.url
  ytt: |
    #@ load("@ytt:data", "data")

    #@ def merge_labels(fixed_values):
    #@   labels = {}
    #@   if hasattr(data.values.workload.metadata, "labels"):
    #@     labels.update(data.values.workload.metadata.labels)
    #@   end
    #@   labels.update(fixed_values)
    #@   return labels
    #@ end

    apiVersion: carto.run/v1alpha1
    kind: Runnable
    metadata:
      name: #@ data.values.workload.metadata.name
      labels: #@ merge_labels({ "app.kubernetes.io/component": "test" })
    spec:
      #@ if/end hasattr(data.values.workload.spec, "serviceAccountName"):
      serviceAccountName: #@ data.values.workload.spec.serviceAccountName

      runTemplateRef:
        name: tekton-source-pipelinerun
        kind: ClusterRunTemplate

      selector:
        resource:
          apiVersion: tekton.dev/v1beta1
          kind: Pipeline
        matchingLabels:
          apps.tanzu.vmware.com/pipeline: test
          apps.tanzu.vmware.com/language: #@ data.values.workload.metadata.labels["apps.tanzu.vmware.com/language"] # <---------------------- Added

      inputs:
        source-url: #@ data.values.source.url
        source-revision: #@ data.values.source.revision

apps.tanzu.vmware.com/languageラベルを使用することでPipelineを特定できるようになりました。

Pipelineは自身で好きなように作成できます。いくつかの使用例を示します。

Mavenを使用したテスト

次のパイプラインを作成してください。

cat <<'EOF' > pipeline-maven.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: maven-test-pipeline
  labels:
    apps.tanzu.vmware.com/pipeline: test
    apps.tanzu.vmware.com/language: maven-jdk-17
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 pipeline-maven.yaml -n demo

Workloadは次のように作成してください。

tanzu apps workload apply hello-servlet \
  --app hello-servlet \
  --git-repo https://github.com/making/hello-servlet \
  --git-branch master \
  --type web \
  --label apps.tanzu.vmware.com/has-tests=true \
  --label apps.tanzu.vmware.com/language=maven-jdk-17 \
  -n demo -y

tanzu apps workload tail hello-servlet -n demo

テストが成功して、イメージがビルドされればOK

$ kubectl get workload,pod,gitrepo,pipelinerun,build -n demo -l app.kubernetes.io/part-of=hello-servlet
NAME                               SOURCE                                    SUPPLYCHAIN          READY   REASON   AGE
workload.carto.run/hello-servlet   https://github.com/making/hello-servlet   source-test-to-url   True    Ready    4m54s

NAME                                                  READY   STATUS      RESTARTS   AGE
pod/hello-servlet-00001-deployment-7cd478cbf9-lcpfr   2/2     Running     0          41s
pod/hello-servlet-build-1-build-pod                   0/1     Completed   0          3m36s
pod/hello-servlet-config-writer-569vq-pod             0/1     Completed   0          90s
pod/hello-servlet-jm458-test-pod                      0/1     Completed   0          4m44s

NAME                                                   URL                                       READY   STATUS                                                              AGE
gitrepository.source.toolkit.fluxcd.io/hello-servlet   https://github.com/making/hello-servlet   True    Fetched revision: master/52d3ce0ebf10deab0495845fd36027c5da39efc9   4m52s

NAME                                         SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/hello-servlet-jm458   True        Succeeded   4m44s       3m46s

NAME                                   IMAGE                                                                                                       SUCCEEDED
build.kpack.io/hello-servlet-build-1   ghcr.io/making/hello-servlet-demo@sha256:232a034df0f53519304c4fac62882a3a5f5af27479e1deabd41af5ac669d4d73   True

確認が終わったら不要なWorkloadを削除してください。

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

Gradleを使用したテスト

次のパイプラインを作成してください。

cat <<'EOF' > pipeline-gradle.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: gradle-test-pipeline
  labels:
    apps.tanzu.vmware.com/pipeline: test
    apps.tanzu.vmware.com/language: gradle-jdk-17
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 -
          ./gradlew --no-daemon test
EOF
kubectl apply -f pipeline-gradle.yaml -n demo

Workloadは次のように作成してください。

tanzu apps workload apply spring-music \
  --app spring-music \
  --git-repo https://github.com/tanzu-japan/spring-music \
  --git-branch tanzu \
  --type web \
  --label apps.tanzu.vmware.com/has-tests=true \
  --label apps.tanzu.vmware.com/language=gradle-jdk-17 \
  -n demo -y

tanzu apps workload tail spring-music -n demo

テストが成功して、イメージがビルドされればOK

$ kubectl get workload,pod,gitrepo,pipelinerun,build -n demo -l app.kubernetes.io/part-of=spring-music 
NAME                              SOURCE                                        SUPPLYCHAIN          READY   REASON   AGE
workload.carto.run/spring-music   https://github.com/tanzu-japan/spring-music   source-test-to-url   True    Ready    7m49s

NAME                                                 READY   STATUS      RESTARTS   AGE
pod/spring-music-00001-deployment-79dc6b6666-hgt4p   2/2     Running     0          34s
pod/spring-music-8cpp2-test-pod                      0/1     Completed   0          7m39s
pod/spring-music-build-1-build-pod                   0/1     Completed   0          4m37s
pod/spring-music-config-writer-gf4t9-pod             0/1     Completed   0          96s

NAME                                                  URL                                           READY   STATUS                                                             AGE
gitrepository.source.toolkit.fluxcd.io/spring-music   https://github.com/tanzu-japan/spring-music   True    Fetched revision: tanzu/7a7641687498e837a34a3e07964bab589285084d   7m47s

NAME                                        SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/spring-music-8cpp2   True        Succeeded   7m39s       4m46s

NAME                                  IMAGE                                                                                                      SUCCEEDED
build.kpack.io/spring-music-build-1   ghcr.io/making/spring-music-demo@sha256:0073c1ee433cfa478f2eba3b2c2a56d78244fc7357e24fc38128f18006b9f970   True

確認が終わったら不要なWorkloadを削除してください。

tanzu apps workload delete spring-music -n demo -y

キャッシュを使用したい場合は、合わせてこちらの記事の内容を設定してください。