はじめに
TektonでCloud Native Buildpacksを使ってビルドするときに、-cache-dir
を使ってキャッシュを利用してみたいと思います。
TektonでCloud Native Buildpacksを使ってビルドする方法については下記を参照してください。

-cache-dirオプション
Cloud Native Buildpacksの/cnb/lifecycle/creator
コマンドを使う場合、-cache-dir
でキャッシュを格納するディレクトリを指定することができます。
いつ使うデータがキャッシュされているか
この-cache-dir
に格納されているデータがいつ使われているかですが、BuildpacksのドキュメントやTektonのcatalogには下記のように記載されています。
Directory where cache is stored (OPTIONAL)

Directory where cache is stored (when no cache image is provided).
ここを読む限りcreator
で使うデータをキャッシュしているように読み取れます。しかし、creator
が実行するanalyzer
、detector
、restorer
、builder
、exporter
のオプションを見ると、-cache-dir
オプションはrestorer
とexporter
にしかありません。

つまり、buildpacksでビルドしているときに使う依存関係をキャッシュしているわけではなさそうです。
このあと、実際に動かして確認してみますが、動かしてみた感じ構築したlayerをキャッシュしているようです。
Gradleアプリをビルドしてみる
Paketo Buildpacksが用意しているGradleのサンプルアプリで、実際に-cache-dir
を使ってビルドしてみます。
用意するファイルは下記の通りです。
.
├── buildpacks.yaml
├── git-clone.yaml
├── pipeline.yaml
├── pipelinerun1.yaml
├── pipelinerun2.yaml
├── pod.yaml
├── serviceaccount.yaml
└── volume.yaml
Secretの作成
Docker Hubにプッシュするときに必要な認証情報を持つSecretを作成します。
kubectl create secret docker-registry docker-registry \
--docker-server=https://index.docker.io/v1/ \
--docker-username=<DockerHubのアカウント名> \
--docker-password=<DockerHubのパスワード> \
--docker-email=<DockerHubのメールアドレス>
ServiceAccontの作成
先ほどのSecretを利用するServiceAccountを作成します(serviceaccount.yaml
)。
apiVersion: v1
kind: ServiceAccount
metadata:
name: buildpacks-service-account
secrets:
- name: docker-user-pass
kubectl apply -f serviceaccount.yaml
PVとPVCの作成
キャッシュとアプリのソースコードを配置するworkspaceのためのPersistentVolumeを作成します(volume.yaml
)。
apiVersion: v1
kind: PersistentVolume
metadata:
name: buildpacks-source-pv
spec:
capacity:
storage: 500Mi
accessModes:
- ReadWriteOnce
hostPath:
path: /tmp
type: Directory
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: buildpacks-source-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
kubectl apply -f volume.yaml
git-clone Taskの作成
git-clone TaskはCatalogから下記を利用します。
kubectl apply -f git-clone.yaml
buildpacks Taskの作成
buildpacks TaskはCatalogから下記を利用します。
kubectl apply -f buildpacks.yaml
Pipelineの作成
Pipelineを作成します(pipeline.yaml
)。
git-clone Taskでソースコードをクローンし、buildpacks Taskでビルドし、最後に結果を表示するPipelineになります。
buildpacks Taskにcache
というworkspaceをわたすことで-cache-dir
が使えます。
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: buildpacks-pipeline
spec:
params:
- name: image
type: string
description: image URL to push
workspaces:
- name: source-workspace
- name: cache-workspace # -cache-dir用のworkspace
tasks:
- name: fetch-repository
taskRef:
name: git-clone
workspaces:
- name: output
workspace: source-workspace
params:
- name: url
value: https://github.com/paketo-buildpacks/samples
- name: build
taskRef:
name: buildpacks
runAfter:
- fetch-repository
workspaces:
- name: source
workspace: source-workspace
- name: cache # -cache-dir用のworkspace
workspace: cache-workspace
params:
- name: APP_IMAGE
value: "$(params.image)"
- name: SOURCE_SUBPATH
value: "java/gradle"
- name: BUILDER_IMAGE
value: paketobuildpacks/builder:base
- name: SKIP_RESTORE
value: "false"
- name: display-results
runAfter:
- build
taskSpec:
steps:
- name: print
image: docker.io/library/bash:5.1.4@sha256:b208215a4655538be652b2769d82e576bc4d0a2bb132144c060efc5be8c3f5d6
script: |
#!/usr/bin/env bash
set -e
echo "Digest of created app image: $(params.DIGEST)"
params:
- name: DIGEST
params:
- name: DIGEST
value: $(tasks.build.results.APP_IMAGE_DIGEST)
kubectl apply -f pipeline.yaml
初回のビルド
PipelineRun(pipelinerun1.yaml
)で初回のビルドをします。
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: buildpacks-pipeline-run1
spec:
serviceAccountName: buildpacks-service-account
pipelineRef:
name: buildpacks-pipeline
workspaces:
- name: source-workspace
subPath: source
persistentVolumeClaim:
claimName: buildpacks-source-pvc
- name: cache-workspace # -cache-dir用のworkspace
subPath: cache
persistentVolumeClaim:
claimName: buildpacks-source-pvc
params:
- name: image
value: monda00/sample-gradle:v1
kubectl apply -f pipelinerun1.yaml
ログを見てみると、JDKやJREなどビルドに必要な依存関係をダウンロードしていることがわかります。
Contributing to layer
となっているので、それぞれでlayerを作成しているのが確認できます。
❯ tkn pr logs buildpacks-pipeline-run1
...
[build : create] ===> ANALYZING
[build : create] Previous image with name "monda00/sample-gradle:v1" not found
[build : create] ===> RESTORING
[build : create] ===> BUILDING
[build : create]
[build : create] Paketo CA Certificates Buildpack 3.2.5
[build : create] https://github.com/paketo-buildpacks/ca-certificates
[build : create] Launch Helper: Contributing to layer
[build : create] Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper
[build : create]
[build : create] Paketo BellSoft Liberica Buildpack 9.4.1
[build : create] https://github.com/paketo-buildpacks/bellsoft-liberica
[build : create] Build Configuration:
[build : create] $BP_JVM_JLINK_ARGS --no-man-pages --no-header-files --strip-debug --compress=1 configure custom link arguments (--output must be omitted)
[build : create] $BP_JVM_JLINK_ENABLED false enables running jlink tool to generate custom JRE
[build : create] $BP_JVM_TYPE JRE the JVM type - JDK or JRE
[build : create] $BP_JVM_VERSION 11 the Java version
[build : create] Launch Configuration:
[build : create] $BPL_DEBUG_ENABLED false enables Java remote debugging support
[build : create] $BPL_DEBUG_PORT 8000 configure the remote debugging port
[build : create] $BPL_DEBUG_SUSPEND false configure whether to suspend execution until a debugger has attached
[build : create] $BPL_HEAP_DUMP_PATH write heap dumps on error to this path
[build : create] $BPL_JAVA_NMT_ENABLED true enables Java Native Memory Tracking (NMT)
[build : create] $BPL_JAVA_NMT_LEVEL summary configure level of NMT, summary or detail
[build : create] $BPL_JFR_ARGS configure custom Java Flight Recording (JFR) arguments
[build : create] $BPL_JFR_ENABLED false enables Java Flight Recording (JFR)
[build : create] $BPL_JMX_ENABLED false enables Java Management Extensions (JMX)
[build : create] $BPL_JMX_PORT 5000 configure the JMX port
[build : create] $BPL_JVM_HEAD_ROOM 0 the headroom in memory calculation
[build : create] $BPL_JVM_LOADED_CLASS_COUNT 35% of classes the number of loaded classes in memory calculation
[build : create] $BPL_JVM_THREAD_COUNT 250 the number of threads in memory calculation
[build : create] $JAVA_TOOL_OPTIONS the JVM launch flags
[build : create] Using buildpack default Java version 11
[build : create] BellSoft Liberica JDK 11.0.16: Contributing to layer
[build : create] Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.16+8/bellsoft-jdk11.0.16+8-linux-amd64.tar.gz
[build : create] Verifying checksum
[build : create] Expanding to /layers/paketo-buildpacks_bellsoft-liberica/jdk
[build : create] Adding 127 container CA certificates to JVM truststore
[build : create] Writing env.build/JAVA_HOME.override
[build : create] Writing env.build/JDK_HOME.override
[build : create] BellSoft Liberica JRE 11.0.16: Contributing to layer
[build : create] Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.16+8/bellsoft-jre11.0.16+8-linux-amd64.tar.gz
[build : create] Verifying checksum
...
[build : create] ===> EXPORTING
[build : create] Adding layer 'paketo-buildpacks/ca-certificates:helper'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:helper'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:jre'
[build : create] Adding layer 'paketo-buildpacks/executable-jar:classpath'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:helper'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:web-application-type'
[build : create] Adding 5/5 app layer(s)
[build : create] Adding layer 'launcher'
[build : create] Adding layer 'config'
[build : create] Adding layer 'process-types'
[build : create] Adding label 'io.buildpacks.lifecycle.metadata'
[build : create] Adding label 'io.buildpacks.build.metadata'
[build : create] Adding label 'io.buildpacks.project.metadata'
[build : create] Adding label 'org.springframework.boot.version'
[build : create] Setting default process type 'web'
[build : create] Saving monda00/sample-gradle:v1...
[build : create] *** Images (sha256:80e142c664cbde7c1567cd61d91230870dc651488b091d797b85aad564533251):
[build : create] monda00/sample-gradle:v1
[build : create] Adding cache layer 'paketo-buildpacks/bellsoft-liberica:jdk'
[build : create] Adding cache layer 'paketo-buildpacks/syft:syft'
[build : create] Adding cache layer 'paketo-buildpacks/gradle:application'
[build : create] Adding cache layer 'paketo-buildpacks/gradle:cache'
...
2回目のビルド
タグを更新して、もう一度PipelineRun(pipelinerun2.yaml
)でビルドしてみます。
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: buildpacks-pipeline-run2
spec:
serviceAccountName: buildpacks-service-account
pipelineRef:
name: buildpacks-pipeline
workspaces:
- name: source-workspace
subPath: source
persistentVolumeClaim:
claimName: buildpacks-source-pvc
- name: cache-workspace # -cache-dir用のworkspace
subPath: cache
persistentVolumeClaim:
claimName: buildpacks-source-pvc
params:
- name: image
value: monda00/sample-gradle:v2 # タグを更新
kubectl apply -f pipelinerun2.yaml
ログを見てみると、restorer
で復元したcache layerを使っている部分(Reusing cached layer
)もありますが、先ほどもダウンロードしていたhttps://github.com/bell-sw/Liberica/releases/download/11.0.16+8/bellsoft-jre11.0.16+8-linux-amd64.tar.gz
をもう一度ダウンロードしているのも確認できます。
❯ tkn pr logs buildpacks-pipeline-run2
...
[build : create] ===> ANALYZING
[build : create] Previous image with name "monda00/sample-gradle:v2" not found
[build : create] Restoring metadata for "paketo-buildpacks/bellsoft-liberica:jdk" from cache
[build : create] Restoring metadata for "paketo-buildpacks/syft:syft" from cache
[build : create] Restoring metadata for "paketo-buildpacks/gradle:application" from cache
[build : create] Restoring metadata for "paketo-buildpacks/gradle:cache" from cache
[build : create] ===> RESTORING
[build : create] Restoring data for "paketo-buildpacks/bellsoft-liberica:jdk" from cache
[build : create] Restoring data for "paketo-buildpacks/syft:syft" from cache
[build : create] Restoring data for "paketo-buildpacks/gradle:application" from cache
[build : create] Restoring data for "paketo-buildpacks/gradle:cache" from cache
[build : create] ===> BUILDING
[build : create]
[build : create] Paketo CA Certificates Buildpack 3.2.5
[build : create] https://github.com/paketo-buildpacks/ca-certificates
[build : create] Launch Helper: Contributing to layer
[build : create] Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper
[build : create]
[build : create] Paketo BellSoft Liberica Buildpack 9.4.1
[build : create] https://github.com/paketo-buildpacks/bellsoft-liberica
[build : create] Build Configuration:
[build : create] $BP_JVM_JLINK_ARGS --no-man-pages --no-header-files --strip-debug --compress=1 configure custom link arguments (--output must be omitted)
[build : create] $BP_JVM_JLINK_ENABLED false enables running jlink tool to generate custom JRE
[build : create] $BP_JVM_TYPE JRE the JVM type - JDK or JRE
[build : create] $BP_JVM_VERSION 11 the Java version
[build : create] Launch Configuration:
[build : create] $BPL_DEBUG_ENABLED false enables Java remote debugging support
[build : create] $BPL_DEBUG_PORT 8000 configure the remote debugging port
[build : create] $BPL_DEBUG_SUSPEND false configure whether to suspend execution until a debugger has attached
[build : create] $BPL_HEAP_DUMP_PATH write heap dumps on error to this path
[build : create] $BPL_JAVA_NMT_ENABLED true enables Java Native Memory Tracking (NMT)
[build : create] $BPL_JAVA_NMT_LEVEL summary configure level of NMT, summary or detail
[build : create] $BPL_JFR_ARGS configure custom Java Flight Recording (JFR) arguments
[build : create] $BPL_JFR_ENABLED false enables Java Flight Recording (JFR)
[build : create] $BPL_JMX_ENABLED false enables Java Management Extensions (JMX)
[build : create] $BPL_JMX_PORT 5000 configure the JMX port
[build : create] $BPL_JVM_HEAD_ROOM 0 the headroom in memory calculation
[build : create] $BPL_JVM_LOADED_CLASS_COUNT 35% of classes the number of loaded classes in memory calculation
[build : create] $BPL_JVM_THREAD_COUNT 250 the number of threads in memory calculation
[build : create] $JAVA_TOOL_OPTIONS the JVM launch flags
[build : create] Using buildpack default Java version 11
[build : create] BellSoft Liberica JDK 11.0.16: Reusing cached layer
[build : create] BellSoft Liberica JRE 11.0.16: Contributing to layer
[build : create] Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.16+8/bellsoft-jre11.0.16+8-linux-amd64.tar.gz
[build : create] Verifying checksum
...
[build : create] ===> EXPORTING
[build : create] Adding layer 'paketo-buildpacks/ca-certificates:helper'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:helper'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:jre'
[build : create] Adding layer 'paketo-buildpacks/executable-jar:classpath'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:helper'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:web-application-type'
[build : create] Adding 5/5 app layer(s)
[build : create] Adding layer 'launcher'
[build : create] Adding layer 'config'
[build : create] Adding layer 'process-types'
[build : create] Adding label 'io.buildpacks.lifecycle.metadata'
[build : create] Adding label 'io.buildpacks.build.metadata'
[build : create] Adding label 'io.buildpacks.project.metadata'
[build : create] Adding label 'org.springframework.boot.version'
[build : create] Setting default process type 'web'
[build : create] Saving monda00/sample-gradle:v2...
[build : create] *** Images (sha256:80e142c664cbde7c1567cd61d91230870dc651488b091d797b85aad564533251):
[build : create] monda00/sample-gradle:v2
[build : create] Reusing cache layer 'paketo-buildpacks/bellsoft-liberica:jdk'
[build : create] Reusing cache layer 'paketo-buildpacks/syft:syft'
[build : create] Reusing cache layer 'paketo-buildpacks/gradle:application'
[build : create] Reusing cache layer 'paketo-buildpacks/gradle:cache'
キャッシュされたデータを確認する
PersistentVolumeに格納されたキャッシュデータを確認してみます。
下記のpod.yaml
でPodにキャッシュ用に使ったPVCをマウントして中身を確認します。
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- name: busybox
image: busybox:latest
args:
- sleep
- "999"
volumeMounts:
- mountPath: /tmp
name: volume-pvc
volumes:
- name: volume-pvc
persistentVolumeClaim:
claimName: buildpacks-source-pvc
kubectl apply -f pod.yaml
コンテナに入り、マウントしたディレクトリを確認してみると、layers
ディレクトリがキャッシュされており、これがrestorer
とexporter
で使われているようです。
❯ kubectl exec -it busybox -- /bin/sh
/ # cd tmp/cache/
/tmp/cache # ls
committed
/tmp/cache/committed # tar -xvf sha256\:5596f3f49be533ca6384724815f85b3f46ce300fe5ba70cc176de61d0982f497.tar
tar: removing leading '/' from member names
layers
layers/paketo-buildpacks_gradle
layers/paketo-buildpacks_gradle/application
layers/paketo-buildpacks_gradle/application/application.zip
試しにskip-restoreしてみる
restorer
をスキップしてみると-cache-dir
はどう動くか試してみます。
まずは、pipeline.yaml
のSKI_RESTORE
をtrueにします。
- name: SKIP_RESTORE
value: "true"
kubectl apply -f pipeline.yaml
PipelineRun(pipelinerun3.yaml
)でビルドしてみます。
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: buildpacks-pipeline-run3
spec:
serviceAccountName: buildpacks-service-account
pipelineRef:
name: buildpacks-pipeline
workspaces:
- name: source-workspace
subPath: source
persistentVolumeClaim:
claimName: buildpacks-source-pvc
- name: cache-workspace # -cache-dir用のworkspace
subPath: cache
persistentVolumeClaim:
claimName: buildpacks-source-pvc
params:
- name: image
value: monda00/sample-gradle:v3 # タグを更新
kubectl apply -f pipelinerun3.yaml
ログをみると、restorer
がスキップされ、builder
の中でReusing cached layer
されている箇所がなくなっています。
つまり、リストア(復元)されたlayerがなく、依存関係のダウンロードからビルドを実行しています。
❯ tkn pr logs buildpacks-pipeline-run3
...
[build : create] ===> ANALYZING
[build : create] Previous image with name "monda00/sample-gradle:v3" not found
[build : create] Skipping buildpack layer analysis
[build : create] ===> BUILDING
[build : create]
[build : create] Paketo CA Certificates Buildpack 3.2.5
[build : create] https://github.com/paketo-buildpacks/ca-certificates
[build : create] Launch Helper: Contributing to layer
[build : create] Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper
[build : create]
[build : create] Paketo BellSoft Liberica Buildpack 9.4.1
[build : create] https://github.com/paketo-buildpacks/bellsoft-liberica
[build : create] Build Configuration:
[build : create] $BP_JVM_JLINK_ARGS --no-man-pages --no-header-files --strip-debug --compress=1 configure custom link arguments (--output must be omitted)
[build : create] $BP_JVM_JLINK_ENABLED false enables running jlink tool to generate custom JRE
[build : create] $BP_JVM_TYPE JRE the JVM type - JDK or JRE
[build : create] $BP_JVM_VERSION 11 the Java version
[build : create] Launch Configuration:
[build : create] $BPL_DEBUG_ENABLED false enables Java remote debugging support
[build : create] $BPL_DEBUG_PORT 8000 configure the remote debugging port
[build : create] $BPL_DEBUG_SUSPEND false configure whether to suspend execution until a debugger has attached
[build : create] $BPL_HEAP_DUMP_PATH write heap dumps on error to this path
[build : create] $BPL_JAVA_NMT_ENABLED true enables Java Native Memory Tracking (NMT)
[build : create] $BPL_JAVA_NMT_LEVEL summary configure level of NMT, summary or detail
[build : create] $BPL_JFR_ARGS configure custom Java Flight Recording (JFR) arguments
[build : create] $BPL_JFR_ENABLED false enables Java Flight Recording (JFR)
[build : create] $BPL_JMX_ENABLED false enables Java Management Extensions (JMX)
[build : create] $BPL_JMX_PORT 5000 configure the JMX port
[build : create] $BPL_JVM_HEAD_ROOM 0 the headroom in memory calculation
[build : create] $BPL_JVM_LOADED_CLASS_COUNT 35% of classes the number of loaded classes in memory calculation
[build : create] $BPL_JVM_THREAD_COUNT 250 the number of threads in memory calculation
[build : create] $JAVA_TOOL_OPTIONS the JVM launch flags
[build : create] Using buildpack default Java version 11
[build : create] BellSoft Liberica JDK 11.0.16: Contributing to layer
[build : create] Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.16+8/bellsoft-jdk11.0.16+8-linux-amd64.tar.gz
[build : create] Verifying checksum
...
[build : create] ===> EXPORTING
[build : create] Adding layer 'paketo-buildpacks/ca-certificates:helper'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:helper'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
[build : create] Adding layer 'paketo-buildpacks/bellsoft-liberica:jre'
[build : create] Adding layer 'paketo-buildpacks/executable-jar:classpath'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:helper'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
[build : create] Adding layer 'paketo-buildpacks/spring-boot:web-application-type'
[build : create] Adding 5/5 app layer(s)
[build : create] Adding layer 'launcher'
[build : create] Adding layer 'config'
[build : create] Adding layer 'process-types'
[build : create] Adding label 'io.buildpacks.lifecycle.metadata'
[build : create] Adding label 'io.buildpacks.build.metadata'
[build : create] Adding label 'io.buildpacks.project.metadata'
[build : create] Adding label 'org.springframework.boot.version'
[build : create] Setting default process type 'web'
[build : create] Saving monda00/sample-gradle:v3...
[build : create] *** Images (sha256:80e142c664cbde7c1567cd61d91230870dc651488b091d797b85aad564533251):
[build : create] monda00/sample-gradle:v3
[build : create] Reusing cache layer 'paketo-buildpacks/bellsoft-liberica:jdk'
[build : create] Reusing cache layer 'paketo-buildpacks/syft:syft'
[build : create] Adding cache layer 'paketo-buildpacks/gradle:application'
[build : create] Adding cache layer 'paketo-buildpacks/gradle:cache'
まとめ
-cache-dir
を使うと指定したディレクトリにlayerがキャッシュされる- キャッシュされたlayerは
restorer
とexporter
で利用される restorer
で復元されたcache layerがbuilder
で使われる
ビルド時の依存関係などはキャッシュされないみたいです。