流水线的 K8S API

独立运行的流水线功能相较于 KubeVela 本身具备的应用级工作流,具有以下特性:

  1. 它可以管理多个 KubeVela 应用,跨多个环境创建。
  2. 不绑定应用,可以独立使用,如针对一组资源做扩缩容,针对一个应用做面向流程的灰度发布,批量执行一组运维操作。
  3. 它是一次性的,不对资源做管理,即使删除流水线也不会删除创建出来的资源。
  4. 它与应用流水线的执行引擎是同源的,这也完全继承了 KubeVela 轻量级工作流的特性,相较于传统的基于容器的 CI 流水线,KubeVela 的流水线在执行各类资源操作时不依赖容器、无需额外的计算资源。

流水线的 K8S API - 图1提示

为了更好地复用已有的能力及保证技术一致性,我们将原本应用工作流中的工作流引擎部分进行了拆分。 应用内工作流和应用间流水线都使用了这个 工作流引擎 作为底层的技术实现。应用工作流体现为应用中的 Workflow 字段,而流水线则体现为 WorkflowRun 资源。

这意味着绝大部分工作流步骤在二者间都是通用的,如:暂停,通知,发送 HTTP 请求,读取配置等。

但 WorkflowRun 中只有步骤的配置,没有组件、运维特征、策略的配置。因此,与组件等相关的步骤只能在应用内工作流中使用,如:部署/更新组件、运维特征等。

确保你已经开启了独立的 workflow 插件。

  1. vela addon enable vela-workflow

WorkflowRun 为流水线执行的 K8S API。你可以选择在 WorkflowRun 里执行一个外部的 Workflow 模板或者执行直接在里面配置要执行的步骤(如果你同时声明了二者,WorkflowRun 里的步骤配置会覆盖模板中的内容)。一个 WorkflowRun 的组成如下:

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: <名称>
  5. namespace: <命名空间>
  6. spec:
  7. mode: <可选项,WorkflowRun 的执行模式,默认步骤的执行模式是 StepByStep,子步骤为 DAG>
  8. steps: <DAG 或者 StepByStep>
  9. subSteps: <DAG 或者 StepByStep>
  10. context:
  11. <可选项,自定义上下文参数>
  12. workflowRef: <可选项,用于运行的外部 Workflow 模板>
  13. workflowSpec: <可选项,用于运行的配置>
  14. steps:
  15. - name: <名称>
  16. type: <类型>
  17. dependsOn:
  18. <可选项,该步骤需要依赖的步骤名称数组>
  19. meta: <可选项,该步骤的额外信息>
  20. alias: <可选项,该步骤的别名>
  21. properties:
  22. <步骤参数值>
  23. if: <可选项,用于判断该步骤是否要被执行>
  24. timeout: <可选项,该步骤的超时时间>
  25. outputs: <可选项,该步骤的输出>
  26. - name: <输出名>
  27. valueFrom: <输出来源>
  28. inputs: <可选项,该步骤的输入>
  29. - name: <输入来源名>
  30. parameterKey: <可选项,该输入要被设置为步骤的某个参数名>
  31. subSteps:
  32. <可选项,如果步骤类型为 step-group,可在这里声明子步骤>

WorkflowRun 拥有以下几种状态:

WorkflowRun 状态说明
executing当 WorkflowRun 中的步骤正在执行时,其状态为 executing
suspending当 WorkflowRun 被暂停时,其状态为 suspending
terminated当 WorkflowRun 被终止时,其状态为 terminated
failed当 WorkflowRun 执行完成,且有步骤失败时,其状态为 failed
succeeded当 WorkflowRun 执行完成,且所有步骤的状态均为成功或者跳过时,其状态为 succeeded

WorkflowRun 步骤拥有以下几种状态:

步骤状态说明
running该步骤正在执行
succeeded该步骤执行完成,且状态为成功
failed该步骤执行失败
skipped该步骤被跳过,没有被执行
pending步骤等待某些条件来执行,如:等待 inputs 的输入

对于执行失败的步骤,步骤状态的 Message 中会显示报错信息,步骤状态的 Reason 会显示失败原因,分为以下几种:

步骤失败原因说明
Execute步骤执行出错
Terminate步骤被终止
Output步骤在输出 Output 时出错
FailedAfterRetries步骤执行失败达到重试上限
Timeout步骤因超时出错
Action步骤定义中执行了 op.#Fail

你可以在 WorkflowRun 或者 Workflow 模板中定义执行模式:

  1. mode:
  2. steps: <DAG or StepByStep>
  3. subSteps: <DAG or StepByStep>

如果没有显示指定,默认 WorkflowRun 会以顺序(StepByStep)执行步骤,并行(DAG)执行子步骤的模式来执行。

流水线的 K8S API - 图2警告

如果你同时在 WorkflowRun 和 Workflow 中指定了执行模式,那么 WorkflowRun 中的模式会覆盖 Workflow 模板中的执行模式。

你可以在 WorkflowRun 中使用不带有label: custom.definition.oam.dev/scope: Application 的 KubeVela 内置步骤

你可以参考 自定义步骤文档 来自定义你的步骤。

流水线的 K8S API - 图3警告

在自定义 WorkflowRun 的步骤过程中,你无法使用对当前应用的操作

流水线的 K8S API - 图4提示

vela workflow 命令可以操作应用内的工作流,也可以操作 WorkflowRun。 它默认会先去找同名的应用,如果找不到则会去找 WorkflowRun。 你也可以在使用时通过 --type=workflow 来表明操作对象为 WorkflowRun。

如果你有一个正在执行中的 WorkflowRun,那么,你可以用 suspend 命令来暂停这个工作流。

  1. vela workflow suspend <name>

流水线的 K8S API - 图5提示

如果工作流已经执行完毕,使用 vela workflow suspend 命令不会产生任何效果。

当 WorkflowRun 进入暂停状态后,你可以使用 vela workflow resume 命令来手动继续工作流。workflow resume 命令会把 WorkflowRun 从暂停状态恢复到执行状态。

  1. vela workflow resume <name>

当 WorkflowRun 正在执行时,如果你想终止它,你可以使用 vela workflow terminate 命令来终止 WorkflowRun。

  1. vela workflow terminate <name>

如果你想查看 WorkflowRun 的日志,你可以使用 vela workflow logs 命令来查看日志。

流水线的 K8S API - 图6提示

只有配置了 op.#Log 的步骤才会有日志输出。

  1. vela workflow logs <name>

参考 操作 WorkflowRun

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: suspend
  5. namespace: default
  6. spec:
  7. workflowSpec:
  8. steps:
  9. - name: step1
  10. type: apply-deployment
  11. properties:
  12. image: nginx
  13. - name: step2-suspend
  14. type: suspend
  15. - name: step2
  16. type: apply-deployment
  17. properties:
  18. image: nginx

WorkflowRun 将在执行完第一个步骤后自动暂停,直至你继续了这个 WorkflowRun,第三个步骤才会被执行。

参考 操作 WorkflowRun

suspend 类型的步骤中配置 duration: <duration>,当 duration 时间超过后,WorkflowRun 将自动继续执行。

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: suspend
  5. namespace: default
  6. spec:
  7. workflowSpec:
  8. steps:
  9. - name: step1
  10. type: apply-deployment
  11. properties:
  12. image: nginx
  13. - name: step2-suspend
  14. type: suspend
  15. properties:
  16. duration: 10s
  17. - name: step2
  18. type: apply-deployment
  19. properties:
  20. image: nginx

当第一个步骤执行完成后,WorkflowRun 将进入暂停状态,十秒过后,WorkflowRun 将自动继续执行第三个步骤。

步骤中有一个特殊的步骤类型:step-group。在使用步骤组类型的步骤时,你可以在其中声明子步骤。

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: group
  5. namespace: default
  6. spec:
  7. workflowSpec:
  8. steps:
  9. - name: my-group
  10. type: step-group
  11. subSteps:
  12. - name: sub1
  13. type: apply-deployment
  14. properties:
  15. image: nginx
  16. - name: sub2
  17. type: apply-deployment
  18. properties:
  19. image: nginx

你可以通过 dependsOn 来指定步骤之间的依赖关系。

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: dependency
  5. namespace: default
  6. spec:
  7. mode:
  8. steps: DAG
  9. workflowSpec:
  10. steps:
  11. - name: step1
  12. type: apply-deployment
  13. dependsOn:
  14. - step2
  15. - step3
  16. properties:
  17. image: nginx
  18. - name: step2
  19. type: apply-deployment
  20. properties:
  21. image: nginx
  22. - name: step3
  23. type: apply-deployment
  24. properties:
  25. image: nginx

step1 将在 step2 和 step3 执行完成后执行。

你可以通过 inputsoutputs 完成步骤间的数据传递,具体介绍请参考 步骤间的输入输出

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: request-http
  5. namespace: default
  6. spec:
  7. workflowSpec:
  8. steps:
  9. - name: request
  10. type: request
  11. properties:
  12. url: https://api.github.com/repos/kubevela/workflow
  13. outputs:
  14. - name: stars
  15. valueFrom: |
  16. import "strconv"
  17. "Current star count: " + strconv.FormatInt(response["stargazers_count"], 10)
  18. - name: notification
  19. type: notification
  20. inputs:
  21. - from: stars
  22. parameterKey: slack.message.text
  23. properties:
  24. slack:
  25. url:
  26. value: <your slack url>

该 WorkflowRun 中,第一步会去请求 GitHub API,拿到 workflow 仓库的 star 数作为 Output,再在下一步中使用这个 Output 作为 Input,从而将 star 数的信息发送到 Slack。

你可以为步骤指定 timeout 来表示该步骤的超时时间。

timeout 遵循 duration 格式,例如 30s, 1m 等。你可以参考 Golang 的 parseDuration

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: timeout
  5. namespace: default
  6. spec:
  7. workflowSpec:
  8. steps:
  9. - name: suspend
  10. type: suspend
  11. timeout: 3s

如果上述 WorkflowRun 没有在三秒内被继续执行,那么 suspend 步骤将因超时而失败。

你可以在步骤中使用 if 来判断是否执行该步骤。

在步骤不指定 if 的情况下,如果步骤之前的步骤执行失败,那么该步骤将被跳过,不会被执行。

在步骤中指定 if: always 的情况下,无论步骤之前的步骤是否执行成功,该步骤都会被执行。

你也可以编写自己的判断逻辑来确定是否应该执行该步骤。注意: if 里的值将作为 CUE 代码执行。WorkflowRun 在 if 中提供了一些内置变量,它们是:

  • status:status 中包含了所有 WorkflowRun 步骤的状态信息。你可以使用 status.<step-name>.phase == "succeeded" 来判断步骤的状态,也可以使用简化方式status.<step-name>.succeeded 来进行判断。
  • inputs:inputs 中包含了该步骤的所有 inputs 参数。你可以使用 inputs.<input-name> == "value" 来获取判断步骤的输入。
  • context:context 中包含了 WorkflowRun 的所有 context 参数。你可以使用 context.<context-name> == "value" 来获取判断 WorkflowRun 的 context。

流水线的 K8S API - 图7提示

注意,如果你的步骤名、inputs 名或者 context 名并不是一个有效的 CUE 变量名(如:包含 -,或者以数字开头等),你可以用如下方式引用:status["invalid-name"].failed

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: if-condition
  5. namespace: default
  6. spec:
  7. workflowSpec:
  8. steps:
  9. - name: suspend
  10. type: suspend
  11. timeout: 3s
  12. - name: my-step
  13. type: apply-deployment
  14. if: status.suspend.failed
  15. properties:
  16. image: nginx
  17. - name: my-step2
  18. type: apply-deployment
  19. if: status.suspend.succecceed
  20. properties:
  21. image: busybox

上述 WorkflowRun 中,如果 suspend 步骤因超时而失败,那么 my-step 步骤将会被执行,否则 my-step2 步骤将会被执行。

WorkflowRun 中的步骤拥有一些内置的上下文参数,你也可以在 context 中声明你自己的上下文参数。

流水线的 K8S API - 图8提示

如果你的自定义上下文参数与内置上下文参数重名,那么内置上下文参数将会被自定义参数覆盖。

你可以通过条件判断和自定义参数的结合,来控制 WorkflowRun 在不同情况下的执行。

  1. apiVersion: core.oam.dev/v1alpha1
  2. kind: WorkflowRun
  3. metadata:
  4. name: deploy-run
  5. namespace: default
  6. spec:
  7. context:
  8. env: test
  9. workflowRef: deploy-template
  10. ---
  11. apiVersion: core.oam.dev/v1alpha1
  12. kind: Workflow
  13. metadata:
  14. name: deploy-template
  15. namespace: default
  16. steps:
  17. - name: apply
  18. type: apply-deployment
  19. if: context.env == "dev"
  20. properties:
  21. image: nginx
  22. - name: apply-test
  23. type: apply-deployment
  24. if: context.env == "test"
  25. properties:
  26. image: crccheck/hello-world

上述 WorkflowRun 将引用 deploy-template Workflow 作为执行模板,如果 context 中的 env 参数为 dev,那么 apply 步骤将会被执行,否则 apply-test 步骤将会被执行。

WorkflowRun 中的内置上下文参数如下:

Context VariableDescriptionType
context.nameWorkflowRun 的名称string
context.namespaceWorkflowRun 的命名空间string
context.stepName当前步骤的名称string
context.stepSessionID当前步骤的 IDstring
context.spanID当前步骤此次执行的 Trace IDstring

Last updated on 2023年8月4日 by Daniel Higuero