需求場景
Tekton是從Knative的Build獨立出來的一個開源項目,它能夠以Kubernetes原生的方式創建在任何Kubernetes上運行的CI/CD Pipeline。Tekton通過引入一系列CRD(自定義資源定義),如Pipeline、Task和ClusterTask等。
在運行Tekton Pipeline的時候,如果能在任務之間共享工件就能縮短運行耗時。本位將在Java構建中使用工作空間來緩存Maven依賴項,以消除每次構建時下載依賴項的需求。
什麼是Workspaces
Tekton Pipeline中的Workspace指的是Pipeline在運行時需要的共享卷的聲明。它們類似於卷,只是不提供實際的卷,而只是聲明意圖。在Pipeline定義中,Workspaces可以作爲共享卷傳遞給相關Task。當同一個Workspaces提供給多個Task時,這些Task可以從完全相同的卷中讀寫,並根據需要共享文件和工件。儘管以上的“卷”指的是用於緩存Maven依賴關係的持久化卷,但它也可以是ConfigMap,或者是傳遞給Pipeline運行的Secret,這些資源都可以在Task之間共享。
Tekton的Workspace可用於以下目的:
- 輸入和/或輸出的儲存。
- 在任務之間共享數據。
- 在Secret中安全憑證的裝載點。
- 在ConfigMaps中保存的配置的掛載點。
- 一個組織共享的通用工具的裝載點。
- 緩存構建工件,加快Pipeline作業的執行速度。
在Task中可以爲多個Steps指定Workspace使用的存儲。在運行時,TaskRun會提供針對性的“卷”並將其掛在到Workspace。在Pipeline中可以用Workspace爲多個Tasks指定共享的存儲。 例如,Task A將一個源碼庫克隆到一個Workspace上,而Task B編譯在該Workspace中找到的代碼。Pipeline的工作是確保這兩個Task所使用的Workspace是相同的,更重要的是確保他們訪問Workspace的順序是正確的。
使用Workspace
在Maven Task中使用Workspace
- 首先在OpenShift中創建名爲tekton-maven的項目。
- 然後根據以下YAML創建Task對象。這個Task中定義了一個名爲maven-repo的Workspace。這個Workspace規定,每當這個Task要運行時需要掛載一個卷,用來作爲本地的Maven倉庫。然後將這個Workspace的路徑傳遞給 Maven 命令,以便作爲本地 Maven 倉庫。
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: mvn
spec:
workspaces:
- name: maven-repo
inputs:
params:
- name: GOALS
description: The Maven goals to run
type: array
default: ["package"]
resources:
- name: source
type: git
steps:
- name: mvn
image: gcr.io/cloud-builders/mvn
workingDir: /workspace/source
command: ["/usr/bin/mvn"]
args:
- -Dmaven.repo.local=$(workspaces.maven-repo.path)
- "$(inputs.params.GOALS)"
定義Pipeline對象
- 在OpenShift中創建以下Pipeline對象,其中使用了名爲local-maven-repo的workspace。
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: maven-build
spec:
workspaces:
- name: local-maven-repo
resources:
- name: app-git
type: git
tasks:
- name: build
taskRef:
name: mvn
resources:
inputs:
- name: source
resource: app-git
params:
- name: GOALS
value: ["package"]
workspaces:
- name: maven-repo
workspace: local-maven-repo
- name: int-test
taskRef:
name: mvn
runAfter: ["build"]
resources:
inputs:
- name: source
resource: app-git
params:
- name: GOALS
value: ["verify"]
workspaces:
- name: maven-repo
workspace: local-maven-repo
- name: gen-report
taskRef:
name: mvn
runAfter: ["build"]
resources:
inputs:
- name: source
resource: app-git
params:
- name: GOALS
value: ["site"]
workspaces:
- name: maven-repo
workspace: local-maven-repo
定義PVC對象
- 在OpenShift中創建以下PVC對象。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: maven-repo-pvc
spec:
resources:
requests:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
運行Pipeline
- 創建以下PipelineRun對象,運行Pipeline。其中爲名爲local-maven-repo的workspace使用了名爲maven-repo-pvc的PVC。
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
generateName: petclinic-run-
spec:
pipelineRef:
name: maven-build
resources:
-- name: app-git
resourceSpec:
type: git
params:
- name: url
value: https://github.com/spring-projects/spring-petclinic
workspaces:
-- name: local-maven-repo
persistentVolumeClaim:
claimName: maven-repo-pvc
- 記錄其運行完成後的時間,34分31秒。
- 再次執行本步驟的(1)操作,再次運行Pipeline。這次Pipeline只用了4分44秒就完成了。
參考
https://developers.redhat.com/blog/2020/02/26/speed-up-maven-builds-in-tekton-pipelines/
https://github.com/tektoncd/pipeline/blob/master/docs/workspaces.md