ℹ️ 2022-10-30 TAP 1.3でも同じです。
ℹ️ 2022-08-15 TAP 1.2でも同じです。
こちらの記事でTAP 1.1のOut of the Box Supply Chain with Testingを試しました。
OOTBのSupply ChainではTektonのテスト時にキャッシュがないため、毎回依存ライブラリをダウンロードすることにより、テストに時間がかかってしまいます。
今回はSupply Chainをカスタマイズし、TektonのPipelineでキャッシュを使えるようにします。
Tektonでキャッシュを使用する方法は次の記事が参考になります。
https://developers.redhat.com/blog/2020/02/26/speed-up-maven-builds-in-tekton-pipelines#run_a_maven_pipeline
目次
ClusterRunTemplateの更新
キャッシュを使用するにはTektonのPipeline、PipelineRunリソースそれぞれにworkspaceの設定が必要です。
PipelineRunはootb-templateのtekton-source-pipelinerunという名前のClusterRunTemplateでtemplate化されています。
ここをカスタマイズするにはyttのoverlayを作成する必要があります。
次のoverlayファイルを作成します。1 Workloadにつき、1 PVを使用する想定です。PVCの名前は<workload name>-pipeline-cache
に固定します。
cat <<'EOF' > ootb-templates-cache-workspace.yml
#@ load("@ytt:overlay", "overlay")
#@overlay/match by=overlay.subset({"metadata":{"name":"tekton-source-pipelinerun"}, "kind": "ClusterRunTemplate"})
---
spec:
template:
spec:
#@overlay/match missing_ok=True
workspaces:
- name: cache
persistentVolumeClaim:
claimName: $(runnable.metadata.name)$-pipeline-cache
EOF
📝 Namespaceにつき1 PVを作りたい場合は
claimName
を$(runnable.metadata.namespace)$-pipeline-cache
にすれば良いです。
ただし、この場合はReadWriteManyに対応したPVを作成する必要があります。
kindはデフォルトでReadWriteManyのPVをサポートしていません。
overlayをSecretとして登録します。
kubectl -n tap-install create secret generic ootb-templates-cache-workspace \
-o yaml \
--dry-run=client \
--from-file=ootb-templates-cache-workspace.yml \
| kubectl apply -f-
作成したoverlayのSecret名をtap-values.yml
のpackage_overlays
へ次のように設定します。
package_overlays:
# ...
- name: ootb-templates
secrets:
- name: ootb-templates-cache-workspace
# ...
変更したtap-values.yml
を次のコマンドで反映します。
tanzu package installed update -n tap-install tap -f tap-values.yml
更新が完了したら次のコマンドを実行して、ClusterRunTemplateが変更されていることを確認してください。
$ kubectl get clusterruntemplate tekton-source-pipelinerun -oyaml
apiVersion: carto.run/v1alpha1
kind: ClusterRunTemplate
metadata:
annotations:
kapp.k14s.io/identity: v1;/carto.run/ClusterRunTemplate/tekton-source-pipelinerun;carto.run/v1alpha1
kapp.k14s.io/original: '{"apiVersion":"carto.run/v1alpha1","kind":"ClusterRunTemplate","metadata":{"labels":{"kapp.k14s.io/app":"1656510239955370900","kapp.k14s.io/association":"v1.72b4cf08dac7ed1e3cac533f6a62ff76"},"name":"tekton-source-pipelinerun"},"spec":{"outputs":{"revision":"spec.params[?(@.name==\"source-revision\")].value","url":"spec.params[?(@.name==\"source-url\")].value"},"template":{"apiVersion":"tekton.dev/v1beta1","kind":"PipelineRun","metadata":{"generateName":"$(runnable.metadata.name)$-","labels":"$(runnable.metadata.labels)$"},"spec":{"params":[{"name":"source-url","value":"$(runnable.spec.inputs.source-url)$"},{"name":"source-revision","value":"$(runnable.spec.inputs.source-revision)$"}],"pipelineRef":{"name":"$(selected.metadata.name)$"},"workspaces":[{"name":"cache","persistentVolumeClaim":{"claimName":"$(runnable.metadata.name)$-pipeline-cache"}}]}}}}'
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.72b4cf08dac7ed1e3cac533f6a62ff76
name: tekton-source-pipelinerun
resourceVersion: "329502"
uid: 54c10f86-3d28-463f-a310-f9262d2825b0
spec:
outputs:
revision: spec.params[?(@.name=="source-revision")].value
url: spec.params[?(@.name=="source-url")].value
template:
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: $(runnable.metadata.name)$-
labels: $(runnable.metadata.labels)$
spec:
params:
- name: source-url
value: $(runnable.spec.inputs.source-url)$
- name: source-revision
value: $(runnable.spec.inputs.source-revision)$
pipelineRef:
name: $(selected.metadata.name)$
workspaces: # <---------------------- Added
- name: cache
persistentVolumeClaim:
claimName: $(runnable.metadata.name)$-pipeline-cache
PipelineRunが更新されると、テストが自動で再実行されます。 まだPipelineはキャッシュを使用するように設定されていないので、この段階ではキャッシュを使用しないテストが再び実施されます。
Pipelineの更新
次に前の記事で作成したhello-servlet workloadのテストにキャッシュを追加します。
次のコマンドでキャッシュ用のPVCを作成します。PVCの名前はhello-servlet-pipeline-cache
にする必要があります。
cat <<EOF > hello-servlet-pipeline-cache-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hello-servlet-pipeline-cache
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1Gi"
EOF
kubectl apply -f hello-servlet-pipeline-cache-pvc.yaml -n demo
次のコマンドで、Pipelineでキャッシュを使用するように変更します。
cat <<'EOF' > 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
workspaces:
- name: cache
tasks:
- name: test
params:
- name: source-url
value: $(params.source-url)
- name: source-revision
value: $(params.source-revision)
workspaces:
- name: cache
workspace: cache
taskSpec:
params:
- name: source-url
- name: source-revision
workspaces:
- name: cache
steps:
- name: test
image: eclipse-temurin:17
script: |-
set -ex
rm -rf ~/.m2
mkdir -p $(workspaces.cache.path)/.m2
ln -fs $(workspaces.cache.path)/.m2 ~/.m2
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
Pipelineリソースを更新してもテストは再実行されません。テストを強制再実行するには、Pipelineリソースを削除すれば良いです。
kubectl delete pipelinerun -l app.kubernetes.io/part-of=hello-servlet -n demo
キャッシュを設定した直後のテストではキャッシュにデータがないため、ビルドに要する時間はキャッシュなしの場合と同じです。 次の例ではビルドに51sかかっています。
$ kubectl logs -n demo -l app.kubernetes.io/component=test,app.kubernetes.io/part-of=hello-servlet --tail=-1
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.example.hello.HelloServletTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.108 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 51.056 s
[INFO] Finished at: 2022-06-29T17:26:21Z
[INFO] ------------------------------------------------------------------------
もう一度Pipelineリソースを削除し、テストを再実行します。
kubectl delete pipelinerun -l app.kubernetes.io/part-of=hello-servlet -n demo
今度はキャッシュ上にデータが残っているため、ビルドは速いです。 次の例ではビルドに3.6sしかかかっていません。
$ kubectl logs -n demo -l app.kubernetes.io/component=test,app.kubernetes.io/part-of=hello-servlet --tail=-1
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.example.hello.HelloServletTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.144 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.652 s
[INFO] Finished at: 2022-06-29T17:27:45Z
[INFO] ------------------------------------------------------------------------
Gradleの場合は次のPipelineを使用してください。
cat <<'EOF' > pipeline-gradle.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: gradle-test-pipeline
labels:
apps.tanzu.vmware.com/pipeline: test
spec:
params:
- name: source-url
- name: source-revision
workspaces:
- name: cache
tasks:
- name: test
params:
- name: source-url
value: $(params.source-url)
- name: source-revision
value: $(params.source-revision)
workspaces:
- name: cache
workspace: cache
taskSpec:
params:
- name: source-url
- name: source-revision
workspaces:
- name: cache
steps:
- name: test
image: eclipse-temurin:17
script: |-
set -ex
rm -rf ~/.gradle
mkdir -p $(workspaces.cache.path)/.gradle
ln -fs $(workspaces.cache.path)/.gradle ~/.gradle
cd `mktemp -d`
curl -s $(params.source-url) | tar -m -xzvf -
./gradlew --no-daemon test
EOF
TAP 1.1のOut of the Box Supply Chain with Testingでキャッシュを使用する方法を説明しました。この設定はworkspaceなしでPVを使わずにテストを実行することもできるので、キャッシュが必要なテストにのみPVを用意すれば良いです。 カスタマイズが必要ですが、テストを快適に実行するには必要ではないでしょうか。