大家好!今天我们将深入探讨 Argo Workflows 的核心设计理念:DAG 和 Steps,以及在工作流之间传递数据的关键手段 Artifact。🚀
读完本文后,您将完全理解如何设计复杂的管道结构,以及如何安全地将前一阶段的结果传递给下一阶段。
在 Argo Workflows 中,安排任务主要有两种方式:Steps(顺序执行)和 DAG(基于依赖)。它们看起来相似,但在使用场景和数据引用方式上存在显著差异。

1. Steps: 顺序分步执行 🪜
Steps,顾名思义,是一种“分步”列出任务的方式。
✅ 何时使用?
- 当工作流清晰地从上到下流动时。
- 当需要同时执行多个任务(并行),或者在特定组完成后才能进入下一组时。
- 当设计结构简单直观的管道时。
📝 代码示例及说明 (Steps)
YAML
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: steps-example-
spec:
entrypoint: main
templates:
- name: main
steps:
- - name: step1 # 第一个步骤 (并行组 1)
template: echo
arguments: {parameters: [{name: message, value: "Step 1"}]}
- - name: step2-a # 第二个步骤 (并行执行 A)
template: echo
arguments: {parameters: [{name: message, value: "Step 2-A"}]}
- name: step2-b # 第二个步骤 (并行执行 B)
template: echo
arguments: {parameters: [{name: message, value: "Step 2-B"}]}
- name: echo
inputs:
parameters: [{name: message}]
container:
image: alpine:latest
command: [echo, "{{inputs.parameters.message}}"]
2. DAG: 复杂的基于依赖的执行 🕸️
DAG (Directed Acyclic Graph) 明确定义了任务之间的
“依赖关系”
。
✅ 何时使用?
- 当任务复杂交织,难以按顺序排列时。
- 当特定任务依赖于多个前置任务的结果时。
- 当高效的并行处理极其重要时(没有依赖的任务会立即执行)。
📝 代码示例及说明 (DAG)
YAML
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: dag-example-
spec:
entrypoint: main
templates:
- name: main
dag:
tasks:
- name: A
template: echo
- name: B
depends: "A" # 仅当 A 成功时执行
template: echo
- name: C
depends: "A" # 仅当 A 成功时执行 (与 B 并行)
template: echo
- name: D
depends: "B && C" # 仅当 B 和 C 都成功时执行
template: echo
- name: echo
container:
image: alpine:latest
command: [echo, "Running task"]
3. 获取前一结果(Output)方式的差异 🔄
这两种方式在变量引用语法(Variable Scope)上有所不同。请注意,如果此处出错,工作流将无法执行!
① 在 Steps 中引用
使用 steps.
- 示例: {{steps.generate-id.outputs.parameters.id}}
② 在 DAG 中引用
使用 tasks.
- 示例: {{tasks.generate-id.outputs.parameters.id}}
💡 核心区别: 引用前缀是 steps 还是 tasks。必须使用与结构相符的正确关键字。
4. Artifact: 大数据传输的核心 📦
如果 Parameter 用于传递短字符串或数字,那么 Artifact 则用于传递文件、目录和大数据。 (需要 S3、GCS、Minio 等外部存储。)
✅ Artifact 的特点
- 输入/输出: 一个阶段生成文件 (outputs.artifacts),下一个阶段将其作为输入 (inputs.artifacts) 接收。
- 持久性: 即使 Pod 被删除,数据仍保留在外部存储中,以便后续查看结果。
📝 实践代码: 传递 Artifact
YAML
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: artifact-passing-
spec:
entrypoint: main
templates:
- name: main
dag:
tasks:
- name: generate-file
template: producer
- name: consume-file
depends: "generate-file"
template: consumer
arguments:
artifacts:
# 将前一个任务的输出连接为输入
- name: input-file
from: "{{tasks.generate-file.outputs.artifacts.result-file}}"
- name: producer # 创建文件的模板
container:
image: alpine:latest
command: [sh, -c]
args: ["echo 'important data' > /tmp/out.txt"]
outputs:
artifacts:
- name: result-file # 以此名称创建 Artifact
path: /tmp/out.txt # 容器内的实际路径
- name: consumer # 接收文件的模板
inputs:
artifacts:
- name: input-file # 定义输入 Artifact
path: /tmp/in.txt # 在容器内放置的位置
container:
image: alpine:latest
command: [cat, /tmp/in.txt]
5. 总结与选择指南 📊
| 类别 | Steps | DAG |
| — | — | — |
| 理念 | 顺序流 (Sequential) | 依赖网络 (Dependency) |
| 可读性 | 有利于简单流程 | 有利于理解复杂关系 |
| 变量引用 | {{steps.NAME.outputs…}} | {{tasks.NAME.outputs…}} |
| 并行处理 | 定义为列表的列表 ([ [A, B] ]) | 如果没有 ‘depends’ 则自动并行执行 |
应该选择哪种方式?
- 如果流程简单,选择 Steps 以提高直观性。
- 如果任务间的先后关系复杂,且管道是非线性的,那么 DAG 是正确的选择。
- 如果数据是文件形式,请毫不犹豫地配置 Artifact。
Argo Workflows 的强大之处在于其结构灵活性。尝试为您的业务逻辑设计最合适的结构吧! 🛠️
发表回复