news 2026/9/23 2:43:51

Argo Workflows Workflow Spec 结构解析:从 Kubernetes 头部到模板编排

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Argo Workflows Workflow Spec 结构解析:从 Kubernetes 头部到模板编排

Argo Workflows Workflow Spec 结构解析:从 Kubernetes 头部到模板编排

【免费下载链接】argo-workflowsWorkflow Engine for Kubernetes项目地址: https://gitcode.com/gh_mirrors/ar/argo-workflows

导读

本文基于 Argo Workflows 官方 Walk-through 系列中《The Structure of Workflow Specs》一文,系统拆解 Workflow 清单(Manifest)的两层结构:Kubernetes 标准头部与spec主体,并深入每一个模板(Template)内部的输入、输出与执行体组织方式。读完本文,你将能够读懂任意一个 Workflow YAML 的骨架,理解 entrypoint 如何驱动模板调用链,掌握 container 与 steps 两类模板的编写方法,以及 Workflow 的 container 段为何能直接复用 Pod Spec 的全部能力。

从整体看 Workflow Spec:一个清单,两层结构

在 Argo Workflows 中,Workflow 是运行在 Kubernetes 之上的自定义资源(CRD)。因此,一份 Workflow 清单天然由两部分构成——Kubernetes 标准头部Argo 特有的 spec 主体。官方文档将其概括为:

  • Kubernetes 头部(header),包含apiVersionkind与元数据(meta-data);
  • Spec 主体(spec body),包含:
    • Entrypoint 调用(可携带可选参数);
    • 一组模板(template)定义列表。

逐层向下,每个模板定义又由以下部分组成:

  • 模板名称(name);
  • 可选的输入(inputs)列表;
  • 可选的输出(outputs)列表;
  • 一个容器调用(container,即叶子模板)或一个步骤列表(steps),其中每个步骤都会调用另一个模板。

这一结构在仓库中的 Go 类型定义里有着完全对应的实现:WorkflowSpecTemplate两个结构体定义在 pkg/apis/workflow/v1alpha1/workflow_types.go 中,WorkflowSpec从 第 299 行 开始,Template从 第 706 行 开始。CRD 的完整字段说明可以查阅 docs/fields.md 中的 WorkflowSpec 与 Template 两节。可以说,"Kubernetes 头部 + spec 主体"这种分层,正是 Argo Workflows 能原生融入 Kubernetes 生态(kubectl、RBAC、Secret、Volume)的根本原因。

第一层:Kubernetes 头部与元数据

任何 Workflow 清单的第一层都是标准 Kubernetes 头部。以仓库中最基础的示例 examples/hello-world.yaml 为例:

apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: hello-world- labels: workflows.argoproj.io/archive-strategy: "false" annotations: workflows.argoproj.io/description: | This is a simple hello world example. spec: entrypoint: hello-world templates: - name: hello-world container: image: busybox command: [echo] args: ["hello world"]

这里的关键信息:

  • apiVersion: argoproj.io/v1alpha1表明这是 Argo Workflows 定义的 API 组与版本;
  • kind: Workflow是 Argo 新增的一种 Kubernetes 资源类型(而非 Pod 或 Job),这一点在 docs/walk-through/hello-world.md 中有明确说明;
  • metadata中既可以使用generateName(如上例,让控制器自动生成带随机后缀的名字),也可以使用name固定资源名;labelsannotations与普通 Kubernetes 资源一致。

由于 Workflow 是标准 CRD,metadata段的写法与普通 Kubernetes 对象完全相同,这意味着你可以用kubectl直接创建、查看和删除 Workflow,也可以借助 label/annotation 实现归档策略、描述信息等扩展能力。

第二层:Spec 主体 —— Entrypoint 与 Templates

头部之下是spec主体,它只做两件事:声明从哪个模板开始执行定义可被引用的模板集合。这在WorkflowSpec结构体中体现得极为直白:

// Entrypoint is a template reference to the starting point of the workflow. Entrypoint string `json:"entrypoint,omitempty"` // Arguments contain the parameters and artifacts sent to the workflow entrypoint Arguments Arguments `json:"arguments,omitempty"` // Templates is a list of workflow templates used in a workflow Templates []Template `json:"templates,omitempty"`

(见 workflow_types.go)

Entrypoint:工作流的起点

entrypoint是对某个模板的引用,它指定 Workflow 执行时第一个被调用的模板。官方文档特别指出:当 Workflow 中定义了多个模板时,指定 entrypoint 就尤为重要——因为执行器需要明确知道从哪里开始。

仓库 examples/arguments-parameters.yaml 演示了 entrypoint 与 spec 级参数(arguments)配合的写法:

apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: arguments-parameters- spec: entrypoint: print-message # Parameters can be passed/overridden via the argo CLI. # To override the printed message, run `argo submit` with the -p option: # $ argo submit examples/arguments-parameters.yaml -p message="goodbye world" arguments: parameters: - name: message value: hello world templates: - name: print-message inputs: parameters: - name: message container: image: busybox command: [echo] args: ["{{inputs.parameters.message}}"]

这里的spec.arguments.parameters会作为入口参数传给 entrypoint 模板,而argo submit -p message="goodbye world"可以在命令行覆盖默认值。由源码注释可见,Workflow 级参数还可以通过workflow.parameters.myparam这样的变量前缀在工作流内全局引用(见 workflow_types.go)。

Templates:模板定义列表

templatesTemplate结构体的列表。需要注意两个来自 CRD 校验规则的约束:

  • 单个 Workflow 中模板数量上限为 200(MaxItems=200),这是为了避免过高的 CEL 校验成本;
  • 每个模板只能拥有一种执行体类型——container、script、dag、steps、resource、suspend、containerSet、data、http、plugin 中至多出现一个(template must have at most one template type)。

这两条规则都写在 workflow_types.go 的校验注解中,是理解模板定义边界的第一手依据。

第三层:单个模板的内部结构

回到官方文档给出的模板四要素:名称、可选输入、可选输出、执行体Template结构体原样反映了这一设计:

// Name is the name of the template Name string `json:"name,omitempty"` // Inputs describe what inputs parameters and artifacts are supplied to this template Inputs Inputs `json:"inputs,omitempty"` // Outputs describe the parameters and artifacts that this template produces Outputs Outputs `json:"outputs,omitempty"` // Steps define a series of sequential/parallel workflow steps Steps []ParallelSteps `json:"steps,omitempty"` // Container is the main container image to run in the pod Container *apiv1.Container `json:"container,omitempty"`

(见 workflow_types.go)

  • name:模板名称,受正则^[a-zA-Z0-9][-a-zA-Z0-9]*$约束且长度不超过 128,是模板被 entrypoint、steps、dag 任务引用的唯一标识;
  • inputs:可选,声明该模板需要接收的参数(parameters)与工件(artifacts);
  • outputs:可选,声明该模板产出并对外暴露的参数与工件;
  • 执行体:二选一(或多选一,见上文"至多一种执行体类型"的校验)——要么是container叶子执行体,要么是steps(或dag等)复合编排体。

叶子模板:Container 调用

当模板直接运行一个容器时,它就是"叶子模板"(leaf template)。container字段的类型是*apiv1.Container——直接复用了 Kubernetes 标准core/v1.Container类型,这一点意义重大,详见下文"与 Pod Spec 的兼容性"一节。

Hello World 示例中的hello-world模板就是最典型的叶子模板:image: busyboxcommand: [echo]args: ["hello world"],执行完毕即结束,不再派生子任务。

复合模板:Steps 列表与模板调用链

当模板需要编排多个任务时,它使用steps字段。官方文档对 steps 的定性是:每个步骤都调用另一个模板。仓库 examples/steps.yaml 给出了标准写法:

apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: steps- spec: entrypoint: hello-hello-hello templates: - name: hello-hello-hello steps: - - name: hello1 template: print-message arguments: parameters: [{name: message, value: "hello1"}] - - name: hello2a template: print-message arguments: parameters: [{name: message, value: "hello2a"}] - name: hello2b template: print-message arguments: parameters: [{name: message, value: "hello2b"}] - name: print-message inputs: parameters: - name: message container: image: busybox command: [echo] args: ["{{inputs.parameters.message}}"]

这个例子同时揭示了 steps 的两条关键语义:

  1. 模板即步骤hello-hello-hello模板本身不运行容器,它通过steps引用了三次print-message模板;而print-message才是真正执行echo的叶子模板。
  2. 列表的嵌套即编排顺序steps是"列表的列表"([]ParallelSteps,见 workflow_types.go)。外层每个子列表代表一个"阶段"(stage),阶段之间串行;同一阶段内的步骤并行。因此该示例中hello1先执行完毕,之后hello2ahello2b并行执行。

同时,步骤通过arguments.parameters把参数message传入被调用模板,而print-message模板通过inputs.parameters声明入参,并在容器命令中用{{inputs.parameters.message}}占位符完成替换——这就是"每个步骤调用另一个模板"这一链式结构的完整闭环。更多关于 steps 编排的细节可继续阅读 docs/walk-through/steps.md,参数机制见 docs/walk-through/parameters.md。

与 Pod Spec 的兼容性:Container 段的完整能力

官方文档特别强调了一条容易忽略但极为重要的设计:Workflow spec 中的 container 段接受与 Pod spec 的 container 段完全相同的选项,包括但不限于:

  • 环境变量(environment variables)
  • Secrets
  • 卷挂载(volume mounts)

同理,Workflow 级也支持卷声明(volume claims)与卷(volumes)。

这一保证的根源在于类型定义:Template.Container直接使用 Kubernetes 的*apiv1.Container类型(见 workflow_types.go),而不是 Argo 自造的简化类型。因此你在 Pod 里能给容器配置的一切——envenvFromvolumeMountsresourcesimagePullPolicyportssecurityContextlivenessProbe等——都可以原样写进模板的container段。

与之配套,WorkflowSpec还提供了与 Pod 对等的编排能力:

  • volumes:Workflow 级卷列表,可被各容器挂载(workflow_types.go);
  • volumeClaimTemplates:PVC 模板列表,控制器会在 Workflow 开始时创建 PVC、在 Workflow 结束时删除(workflow_types.go);
  • 模板级同样可以声明volumesinitContainerssidecars(见 workflow_types.go)。

这意味着你在编写 Workflow 时,可以把已有的 Pod/Deployment 容器配置几乎原样搬入模板,Secrets、ConfigMap、PVC 的接入方式与原生 Kubernetes 完全一致,学习与迁移成本极低。

从"二选一"到"多选一":执行体类型的现代扩展

官方文档撰写时所描述的是"container 或 steps"两类执行体;而从当前仓库的Template结构体(workflow_types.go)可以看出,Argo Workflows 已将该模型扩展为多种执行体类型,且它们遵循同样的"一个模板一种执行体"规则:

执行体字段作用文档参考
container运行单个容器(叶子模板)docs/walk-through/hello-world.md
steps串行/并行步骤编排examples/steps.yaml、docs/walk-through/steps.md
dag基于依赖关系的有向无环图编排examples/dag-diamond.yaml
script在解释器容器中运行脚本片段examples/scripts-bash.yaml
resource直接创建/管理 Kubernetes 资源examples/k8s-jobs.yaml
suspend挂起流程等待人工批准examples/suspend-template.yaml
containerSet在单个 Pod 内运行多个容器examples/container-set-template/parallel-workflow.yaml
data数据转换模板examples/data-transformations.yaml
http发起 HTTP 请求examples/http-hello-world.yaml
plugin使用自定义插件模板(自由格式结构)examples/workflow-level-executor-plugin.yaml

无论是哪种执行体,它们都遵守本文所讲的外层骨架:模板有名字、可选输入、可选输出,而 steps/dag 等复合模板内部引用的仍是其他模板——整套"模板调用模板"的递归模型保持不变。这也正是"Workflow spec 由一组 Argo 模板构成,每个模板包含可选输入、可选输出,以及容器调用或步骤列表"这一官方总结在今日依然成立的深层原因。

小结:一张图读懂 Workflow Spec 的骨架

把官方文档的层次结构整理成如下骨架,可作为阅读任意 Workflow YAML 的速查表:

Workflow 清单 ├── Kubernetes 头部 │ ├── apiVersion: argoproj.io/v1alpha1 │ ├── kind: Workflow │ └── metadata(generateName/name、labels、annotations) └── spec 主体 ├── entrypoint:指定起始模板(可携带 arguments 参数) ├── arguments(可选):传给 entrypoint 的参数与工件 └── templates:模板定义列表 └── 每个模板 ├── name:模板唯一标识 ├── inputs(可选):入参 parameters / artifacts ├── outputs(可选):出参 parameters / artifacts └── 执行体(至多一种) ├── container:叶子模板,直接运行容器 └── steps / dag 等复合模板:内部步骤再调用其他模板

实践中,读者可以对照 examples/hello-world.yaml(单模板、纯 container 叶子)、examples/arguments-parameters.yaml(entrypoint + arguments + inputs 参数链路)与 examples/steps.yaml(复合 steps 编排 + 模板调用链)三个示例,逐层验证本文总结的结构。如果想继续系统学习,官方 Walk-through 系列建议按顺序阅读 docs/walk-through/argo-cli.md 起步,随后进入参数、工件、步骤、DAG 等专题;完整字段级说明则以 docs/fields.md 中的WorkflowSpecTemplate两节为最终权威参考。

【免费下载链接】argo-workflowsWorkflow Engine for Kubernetes项目地址: https://gitcode.com/gh_mirrors/ar/argo-workflows

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 2:40:08

Python考试系统实战:自动组卷遗传算法与自动评卷全解析

简介:Python实现自动组卷评卷考试系统源码及配套文档,适合教育领域开发者、Python Web学习者及高校课程设计使用。系统涵盖题库管理、组卷算法、在线答题、自动评卷和成绩管理五大功能模块,基于Flask/Django与SQLAlchemy等主流技术构建&#…

作者头像 李华
网站建设 2026/9/23 2:36:37

分布式事务从原理到落地:五大方案对比与选型指南

上周有个同事跑来问我:订单服务和库存服务拆开之后,用户下单成功,订单状态显示已支付,库存却扣了两次,数据库事务到底还能不能保证一致性?这个问题背后牵扯出来的东西,恰恰就是分布式事务的核心…

作者头像 李华
网站建设 2026/9/23 2:36:05

趋势与季节性时间序列预测:从STL分解到SARIMA建模实战

简介:面向有一定Python基础、希望掌握气候数据预测的时间序列分析初学者,这套实战内容围绕趋势与季节性两个核心维度,结合Pandas、statsmodels、Matplotlib等常用库,系统演示了移动平均提取趋势、STL季节分解、ARIMA/SARIMA建模、…

作者头像 李华
网站建设 2026/9/23 2:34:51

多功能记事本小程序开发:数据模型、同步与防乱码实践

简介:这是一套面向高校计算机相关专业毕业设计场景的多功能记事本系统项目资料,集成记事、分类管理、记录检索等常见功能模块,采用Java技术栈实现前后台分离,适合需要快速完成系统设计、源码阅读或二次开发的学生使用。资源包整体…

作者头像 李华