本文主要记录了如何使用 ArgoWorkflow 构建流水线,以及 ArgoWorkflow 中 的 Workflow、Template 等概念模型。
本文主要分析以下问题:
- 1)如何创建流水线
- 2)Workflow、Template、template 自己的引用关系
- 3)Workflow 和 Template 之间的参数传递问题
- 4)ArgoWorkflow 流水线最佳实践
1.概念模型
接下来就是如何构建我们的流水线了,ArgoWorkflow 中流水线相关的概念如下:
- Workflow:流水线,真正运行的流水线实例,类似于 Tekton 中的 pipelinerun
- WorkflowTemplate:流水线模板,可以基于模板创建流水线,类似于 Tekton 中的 pipeline
- ClusterWorkflowTemplate:集群级别的流水线模板,和 WorkflowTemplate 的关系类似于 K8s 中的 Role 和 ClusterRole
- templates:Workflow 或者 Template 的最小组成单位,流水线由多个 template 组成。
WorkflowTemplate 和 ClusterWorkflowTemplate 暂时统称为 Template。
Workflow、Template(大写)、template(小写)之间的关系如下:
三者间关系比较复杂,官方也有提到这块因为一些历史遗留问题导致命名上比较混乱
个人理解:
- template(小写):为 Template(大写)的基本组成单位,可以理解为流水线中的步骤
- Template(大写):一条完整的流水线,一般由多个 template(小写) 组成
- Workflow:真正运行的流水线实例,一般由 Template 直接创建,类似于流水线运行记录,每一条记录都是一个 Workflow
理清基本概念之后,接下来就看下看具体使用。
2.Workflow
在 ArgoWorkflow 中 Workflow 为流水线运行实例,每创建一个 Workflow 对象,都会触发流水线运行一次。
以下是一个简单的 Workflow 例子:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: steps-
spec:
entrypoint: hello # We reference our first "template" here
templates:
- name: hello # The first "template" in this Workflow, it is referenced by "entrypoint"
steps: # The type of this "template" is "steps"
- - name: hello
template: whalesay # We reference our second "template" here
arguments:
parameters: [{name: message, value: "hello"}]
- name: whalesay # The second "template" in this Workflow, it is referenced by "hello"
inputs:
parameters:
- name: message
container: # The type of this "template" is "container"
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
整个 Workflow 对象核心内容分为以下三部分:
entrypoint
: 流水线入口,类似于代码中的 main 方法,此处一般引用某一个template invocators
即可。templates
:模板列表,此处定义了流水线中的所有步骤以及步骤之间的先后顺序。parameters
:流水线中用到的参数,包括 arguments 块中的全局参数和 inputs 块中的局部参数两种
entrypoint
Workflow 中必须要指定 entrypoint,entrypoint 作为任务的执行起点,类似于程序中的 main 方法。
templates
具体见官方文档:#template-types
模板分为多种类型,根据类型的不同分为 template definitions(模板定义)以及 template invocators(模板调用器)。
- template definitions(模板定义):该类型 template 用于定义具体步骤要执行的内容,例子中的 whalesay 模板就是该类型
- 包含
container
,script
,resource
,suspend
等类型
- 包含
- template invocators(模板调用器):该类型 template 用于组合其他 template definitions(模版定义) ,定义步骤间的执行顺序等,例子中的 hello 模板就是该类型。
- 一般 entrypoint 就是该类型的模板
- 包含
dag
和steps
两种类型,例子中的 hello 模板就是 steps 类型。
吐槽一下:template 这里有点绕,如果能将 模板定义 、模板调用器 拆分为两个不同的对象就比较清晰。
了解完 template 分类之后再回头看之前的 Workflow 例子就比较清晰了:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: steps-
spec:
entrypoint: hello # We reference our first "template" here
templates:
- name: hello # The first "template" in this Workflow, it is referenced by "entrypoint"
steps: # The type of this "template" is "steps"
- - name: hello
template: whalesay # We reference our second "template" here
arguments:
parameters: [{name: message, value: "hello"}]
- name: whalesay # The second "template" in this Workflow, it is referenced by "hello"
inputs:
parameters:
- name: message
container: # The type of this "template" is "container"
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
- 1)首先 whalesay 模板是一个
container
类型的 template,因此是 template definitions(模板定义) - 2)其次 hello 是一个
steps
类型的 template,因此是 template invocators(模板调用器)- 在该调用器中 steps 字段中定义了一个名为 hello 的步骤,该步骤引用的就是 whalesay template
- 3)entrypoint 指定的是 hello 这个 template invocators(模板调用器)
小结:entrypoint、template definitions、template invocators 这三个就是一个 Workflow 的必要组成。
parameters
Workflow 支持两种类型的参数:
- arguments:全局参数,Workflow 下所有 template 都可使用
- inputs:局部参数,仅当前 template 可使用
arguments 全局参数
spec.arguments
用于定义全局参数,这部分参数在当前 Workflow 下的所有 Template 中都可以使用,可以使用 {{workflow.parameters.$name}}
语法来引用。
例如下面这个例子中指定了一个名为 message 的参数,并赋值为 hello world。
arguments:
parameters:
- name: message
value: hello world
inputs 局部参数
Template 中可以使用 templates[*].inputs
字段来指定局部参数,这部分参数只有当前 Template 可以使用。可以通过{{inputs.parameters.$name}}
语法来引用参数。
下面这个例子则是声明了 template 需要一个名为 message 的参数,但是未提供具体值。
templates:
- name: whalesay-template
inputs:
parameters:
- name: message
container:
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
参数传递
Workflow 中的全局参数值由用户指定,而局部参数中的值一般是由全局参数覆盖。
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: steps-
spec:
entrypoint: hello # We reference our first "template" here
templates:
- name: hello # The first "template" in this Workflow, it is referenced by "entrypoint"
steps: # The type of this "template" is "steps"
- - name: hello
template: whalesay # We reference our second "template" here
arguments:
parameters: [{name: message, value: "hello"}]
- name: whalesay # The second "template" in this Workflow, it is referenced by "hello"
inputs:
parameters:
- name: message
container: # The type of this "template" is "container"
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
上述例子中,template whalesay 定义了一个名为 message 的局部参数,但是没有赋值,同时在 template 中又定义了一个名为 message 的参数,因此最终局部参数 message 会被全局参数 message 覆盖。
上述例子可以看成是这样的:
templates:
- name: hello # The first "template" in this Workflow, it is referenced by "entrypoint"
steps: # The type of this "template" is "steps"
- - name: hello
template: whalesay # We reference our second "template" here
arguments:
parameters: [{name: message, value: "hello"}]
- name: whalesay # The second "template" in this Workflow, it is referenced by "hello"
inputs:
parameters:
- name: message
value: "{{workflow.parameters.message}}"
container: # The type of this "template" is "container"
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
即:template 引用局部参数,局部参数来自全局参数,用户配置全局参数。
3.Template
根据前面描述可以指定,我们能直接创建 Workflow 对象来运行流水线,不过这种方式存在的一些问题:
- 1)如果 template 比较多的话,Workflow 对象就会特别大,修改起来比较麻烦
- 2)模板无法共享,不同 Workflow 都需要写一样的 template
因此,一般建议将 template 存到 WorkflowTemplate,Workflow 中只引用 Template 并提供参数即可。
而 ArgoWorkflow 中的工作流模板根据范围不同分为 WorkflowTemplate 和 ClusterWorkflowTemplate 两种。
- WorkflowTemplate:命名空间范围,只能在同一命名空间引用
- ClusterWorkflowTemplate:集群范围,任意命名空间都可以引用
WorkflowTemplate
下面是一个简单的 WorkflowTemplate 例子:
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: workflow-template-submittable
namespace: default
spec:
entrypoint: whalesay-template
arguments:
parameters:
- name: message
value: tpl-argument-default
templates:
- name: whalesay-template
inputs:
parameters:
- name: message
value: tpl-input-default
container:
image: docker/whalesay
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
可以看到 WorkflowTemplate 和 Workflow 参数是一模一样,只是将 yaml 中的 kind 由 Workflow 替换为 WorkflowTemplate 即可,这里就不在赘述了。
workflowMetadata
workflowMetadata 是 Template 中独有的一个字段,主要用于存储元数据,后续由这个 Template 创建出的 Workflow 都会自动携带上这些信息。
通过这些信息可以追踪到 Workflow 是由那个 Template 创建的。
使用方式就像下面这样,workflowMetadata 中指定了一个 label
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: workflow-template-submittable
spec:
workflowMetadata:
labels:
example-label: example-value
然后由该 Template 创建的 Workflow 对象都会携带这个 label:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
annotations:
workflows.argoproj.io/pod-name-format: v2
creationTimestamp: "2023-10-27T06:26:13Z"
generateName: workflow-template-hello-world-
generation: 2
labels:
example-label: example-value
name: workflow-template-hello-world-5w7ss
namespace: default
ClusterWorkflowTemplate
类似于 WorkflowTemplate,可以理解为 k8s 中的 Role 和 ClusterRole 的关系。
和 WorkflowTemplate 所有参数都一致,只是将 yaml 中的 kind 替换为 ClusterWorkflowTemplate 即可。
小结
Template 中最好将以下三部分内容都配置好:
- entrypoint:推荐,虽然可以在 Workflow 中指定,但是这样每次创建 Workflow 都需要先看一下 Template 中有哪些 template 了,比较麻烦,因此最好 Template 中直接填好
- templates:必须,Template 的作用就是写模板
- arguments:最好将默认值填上,这样 Workflow 在不指定任何参数时也能使用
当 Template 中将这三个核心内容都填好之后,Workflow 使用时就非常简单了。
4. TemplateRef
创建好 Template 之后就可以在 Workflow 中使用 TemplateRef 直接引用对应模板了,这样 Workflow 对象就会比较干净。
workflowTemplateRef
可以通过workflowTemplateRef
字段直接引用 WorkflowTemplate。
注意
标签:初体验,name,Workflow,--,CICD,WorkflowTemplate,template,Template,hello From: https://www.cnblogs.com/KubeExplorer/p/18344987