常见的 CICD 引擎并不适合直接提供给业务方使用。主要原因在于用户学习成本高、缺乏必要的鉴权、维护升级难度大。
我们通常会基于流程引擎,针对业务进行适配提高易用性,针对场景进行封装收敛复杂度,那么一个 CICD 平台需要具备哪些基本的功能呢?
Tekton 作为云原生下的 CICD 引擎,用来构建面向 Kubernetes 基础设施的 CICD 平台,非常适用。本篇主要想和大家分享的是 Tekton 流程控制,特别是审批的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | - name: test-app taskRef: name: make-test resources: inputs: - name: workspace resource: my-repo - name: build-app taskRef: name: kaniko-build runAfter: - test-app resources: inputs: - name: workspace resource: my-repo |
---|
通过 runAfter 关键字可以控制任务的执行顺序,上面的示例中 build-app 会在 test-app 执行完成之后执行。使用 runAfter 可以实现对流程的编排。
这里首先创建一个 Condition 对象,检查代码仓库中是否存在指定文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 | apiVersion: tekton.dev/v1alpha1 kind: Condition metadata: name: file-exists spec: params: - name: "path" resources: - name: workspace type: git check: image: alpine script: 'test -f $(resources.workspace.path)/$(params.path)' |
---|
在创建 Pipeline 时,只需要在 Task 中引用这个 Condition,提供必要的参数即可。下面这个例子中,仅当代码仓库中存在 README.md
文件时,my-task 任务才会执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: conditional-pipeline spec: resources: - name: source-repo type: git params: - name: "path" default: "README.md" tasks: - name: if-condition-then-run conditions: - conditionRef: "file-exists" params: - name: "path" value: "$(params.path)" resources: - name: workspace resource: source-repo taskRef: name: my-task |
---|
当 PipelineRun Spec 中的状态处于 PipelineRunCancelled 时,Reconciler 会提前取消全部 Task 并更新状态。
1 2 3 4 | kubectl get pipelineruns.tekton.dev NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME cancel-pipelinerun-r-67qsr Unknown Running 51m |
---|
1 | kubectl patch PipelineRun cancel-pipelinerun-r-67qsr --type=merge -p '{"spec":{"status":"PipelineRunCancelled"}}' |
---|
1 2 3 4 | kubectl get pipelineruns.tekton.dev NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME cancel-pipelinerun-r-67qsr False PipelineRunCancelled 52m 3s |
---|
除了上面的 PipelineRunCancelled 状态,pipelinerun 还有一个状态,PipelineRunPending。PipelineRunPending 实现的效果是,创建 PipelineRun 但不立即运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | --- apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: pending-pipelinerun spec: params: - name: pl-param-x value: "100" - name: pl-param-y value: "500" pipelineRef: name: pending-pipeline status: "PipelineRunPending" |
---|
1 2 3 4 | kubectl get pipelineruns.tekton.dev NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME pending-pipelinerun Unknown PipelineRunPending |
---|
这条流水线没有执行时间,因为它一直处于等待状态。
1 | kubectl patch PipelineRun pending-pipelinerun --type=merge -p '{"spec":{"status":""}}' |
---|
这条流水线开始执行。
1 2 3 4 | kubectl get pipelineruns.tekton.dev NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME pending-pipelinerun Unknown Running 4s |
---|
在 Tekton v0.24.1 中无法修改状态为 PipelineRunPending,如果运行将可以实现暂停的效果。
1 2 3 4 | kubectl get pipelineruns.tekton.dev NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME cancel-pipelinerun Unknown Running 9s |
---|
1 2 3 | kubectl patch PipelineRun cancel-pipelinerun --type=merge -p '{"spec":{"status":"PipelineRunPending"}}' Error from server (BadRequest): admission webhook "validation.webhook.pipeline.tekton.dev" denied the request: validation failed: invalid value: PipelineRun cannot be Pending after it is started: spec.status |
---|
validation 限制了这次修改操作。
上面提到了 Tekton 中的几个流程控制方法,但是社区并没有提供、也不准备提供审批的功能。因此,在对 Tekton 进行二次开发时,需要 CICD 平台自行实现审批和权限的控制。下面是两种实现方案,以供参考:
如上图,可以将用户的一条流水线拆解为两条流水线,pipeline-1/2 和 pipeline-2/2。两条流水线之间引入一个 trigger。
Tekton 社区提供了一个 triggers 组件,用来自动化触发流水线。如下图:
开发 Task 是 Tekton 的主要扩展方式,同时开发 Task 只需要掌握基本的 Shell 和 Yaml 知识即可。这里提供另外一个思路就是开发一个审批 Task。
如上图,在一条流水线中,插入一个用于审批控制的 Task-Approve。
下面是一个示例:
首先创建一个 ConfigMap 用于保存审批状态。
1 2 3 4 5 6 | apiVersion: v1 kind: ConfigMap metadata: name: approve-cm data: status: init |
---|
编写一个审批的 Task,默认等待 24 小时审批,否则超时。如果将状态修改为 success 则审批通过,如果将状态修改为 refused 则表示拒绝。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: approve-task spec: workspaces: - name: data params: - name: timeout description: The max seconds to approve type: string default: "86400" steps: - name: sleep-a-while image: bash:latest script: | #!/usr/bin/env bash end=$((SECONDS+$(params.timeout))) while [ $SECONDS -lt $end ]; do name=$(cat "$(workspaces.data.path)"/status) if [ "$name" = "success" ] then echo "approved!" exit 0 elif [ "$name" = "refused" ] then echo "refused!" exit 1 fi sleep 2 echo "waiting" done echo "too long not to approve" exit 1 |
---|
然后,创建一个测试用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | apiVersion: tekton.dev/v1beta1 kind: Task metadata: name: something annotations: description: | A simple task that do something spec: steps: - name: do-something image: bash:latest script: | #!/usr/bin/env bash uname -a --- apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: approve-pipeline spec: workspaces: - name: workspace tasks: - name: wait-for-approve workspaces: - name: data workspace: workspace taskRef: name: approve-task - name: do-something taskRef: name: something runAfter: - wait-for-approve --- apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: name: approve-pipelinerun spec: workspaces: - name: workspace configmap: name: approve-cm pipelineRef: name: approve-pipeline |
---|
日志中会一直输出 waiting。
1 | kubectl patch ConfigMap approve-cm --type=merge -p '{"data":{"status":"success"}}' |
---|
在进行 Tekton 二次开发时,审批是很难绕开的功能,但社区并没有提供相关的特性。本文首先介绍了 Tekton 中流程控制方法,然后提供了两种实现审批功能的方案。下面对方案进行简单的对比和总结:
优点
缺点
优点
缺点
原文:https://www.chenshaowen.com/blog/how-to-implement-approval-function-in-tekton.html
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。