🏗️ Argo Workflows 设计指南: DAG vs Steps 以及数据流 (Artifact)

大家好!今天我们将深入探讨 Argo Workflows 的核心设计理念:DAGSteps,以及在工作流之间传递数据的关键手段 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..outputs.parameters. 格式。

  • 示例: {{steps.generate-id.outputs.parameters.id}}

② 在 DAG 中引用

使用 tasks..outputs.parameters. 格式。

  • 示例: {{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’ 则自动并行执行

应该选择哪种方式?

  1. 如果流程简单,选择 Steps 以提高直观性。
  2. 如果任务间的先后关系复杂,且管道是非线性的,那么 DAG 是正确的选择。
  3. 如果数据是文件形式,请毫不犹豫地配置 Artifact

Argo Workflows 的强大之处在于其结构灵活性。尝试为您的业务逻辑设计最合适的结构吧! 🛠️


Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注