ArgoWorkflow教程(二)---快速構建流水線:Workflow & Template 概念

探索云原生發表於2024-08-20

argoworkflow-2-model-analyze.png

上一篇我們部署了 ArgoWorkflow,並建立了一個簡單的流水線做了個 Demo。本篇主要分析 ArgoWorkflow 中流水線相關的概念,瞭解概念後才能更好使用 ArgoWorkflow。

本文主要分析以下問題:

  • 1)如何建立流水線? Workflow 中各引數含義
  • 2)WorkflowTemplate 流水線模版如何使用,
  • 3)Workflow、WorkflowTemplate、template 之間的引用關係
  • 4)ArgoWorkflow 流水線最佳實踐

1.基本概念

ArgoWorkflow 中包括以下幾個概念:

  • Workflow:流水線,真正執行的流水線例項,類似於 Tekton 中的 pipelinerun
  • WorkflowTemplate:流水線模板,可以基於模板建立流水線,類似於 Tekton 中的 pipeline
    • ClusterWorkflowTemplate:叢集級別的流水線模板,和 WorkflowTemplate 的關係類似於 K8s 中的 Role 和 ClusterRole
  • templates:Workflow 或者 WorkflowTemplate/ClusterWorkflowTemplate 的最小組成單位,流水線由多個 template 組成,可以理解為流水線中的某一個步驟。

WorkflowTemplate 和 ClusterWorkflowTemplate 暫時統稱為 Template。

Workflow、Template(大寫)、template(小寫)之間的關係如下:

arg-workflow-template-ref.png

三者間關係比較複雜,官方也有提到這塊因為一些歷史遺留問題導致命名上比較混亂

個人感覺下面這種方式比較好理解:

  • template(小寫):為 Template(大寫)的基本組成單位,可以理解為流水線中的步驟
  • Template(大寫):一條完整的流水線,一般由多個 template(小寫) 組成
  • Workflow:真正執行的流水線例項,一般由 Template 直接建立,類似於流水線執行記錄,每一條記錄就是一個 Workflow

理清基本概念之後,接下來就看下看具體物件的分析。

2.Workflow

Workflow 是Argo中最重要的資源,具有兩個重要功能:

  • 1)工作流定義
  • 2)工作流狀態儲存

先看下 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 物件核心內容分為以下三部分:

  • templates:模板列表,此處定義了流水線中的所有步驟以及步驟之間的先後順序。
  • entrypoint: 流水線入口,類似於程式碼中的 main 方法,此處一般引用某一個 template invocators 即可。
  • parameters:流水線中用到的引數,包括 arguments 塊中的全域性引數和 inputs 塊中的區域性引數兩種

entrypoint

Workflow 中必須要指定 entrypoint,entrypoint 作為任務的執行起點,類似於程式中的 main 方法。

templates

ArgoWorkflow 當前支援 6 種 template,接下來挨個分析一下。

container

Kubernetes container spec 是一致的,這個型別的 template 就是啟動一個 container,使用者可以指定image、command、args 等資訊來控制具體執行的動作。

  - name: whalesay
    container:
      image: docker/whalesay
      command: [cowsay]
      args: ["hello world"]

script

script 實際上是 container 的封裝,spec 和 container 一致,同時增加了 source 欄位,用於定義一個指令碼,指令碼的執行結果會記錄到{{tasks.<NAME>.outputs.result}} or {{steps.<NAME>.outputs.result}}

script 可以理解為簡化了使用 container 來執行指令碼的配置

  - name: gen-random-int
    script:
      image: python:alpine3.6
      command: [python]
      source: |
        import random
        i = random.randint(1, 100)
        print(i)

resource

Resource 型別的 template 用於操作叢集中的資源,action 參數列示具體的動作,支援 get, create, apply, delete, replace, patch。

  - name: k8s-owner-reference
    resource:
      action: create
      manifest: |
        apiVersion: v1
        kind: ConfigMap
        metadata:
          generateName: owned-eg-
        data:
          some: value

suspend

Suspend 型別的 template 比較簡單,就是用於暫停流水線執行。

預設會一直阻塞直到使用者透過argo resume命令手動恢復,或者透過duration 引數指定暫停時間,到時間後會自動恢復。

  - name: delay
    suspend:
      duration: "20s"

steps

Steps 用於處理模版之間的關係,具體包含兩方面:

  • 1)哪些任務需要執行
  • 2)這些任務按照什麼先後順序執行

看下面這個例子:

  - name: hello-hello-hello
    steps:
    - - name: step1
        template: prepare-data
    - - name: step2a
        template: run-data-first-half
      - name: step2b
        template: run-data-second-half

哪些任務需要執行?

該 steps 則定義了要執行 step1、step2a、step2b 3 個 template。

這些任務按照什麼先後順序執行?

steps 中元素定義的先後順序就是各個任務的執行先後順序,在這裡就是 step1 先執行,然後 step2a、step2b 並行執行。

注意:仔細看 yaml 中 step2a 和 step2b 是同一個元素中的,steps 是一個二維陣列, 定義如下:

type Template struct {
    Steps []ParallelSteps `json:"steps,omitempty" protobuf:"bytes,11,opt,name=steps"`
}
type ParallelSteps struct {
    Steps []WorkflowStep `json:"-" protobuf:"bytes,1,rep,name=steps"`
}

轉換為 json 形式就像這樣:

{
    "steps": [
        ["step1"],
        ["step2a", "step2b"]
    ]
}

這樣應該比較清晰了,先後順序一目瞭然

dag

Dag template 的作用和 steps 是一樣的。

這裡的 DAG 就是 Directed Acyclic Graph 這個 DAG。

DAG 和 Steps 區別在於任務先後順序的定義上:

  • Steps 以定義先後順序作為 template 執行先後順序
  • DAG 則可以定義任務之間的依賴,由 argo 根據依賴自行生成最終的執行的先後順序

看下面這個例子:

  - name: diamond
    dag:
      tasks:
      - name: A
        template: echo
      - name: B
        dependencies: [A]
        template: echo
      - name: C
        dependencies: [A]
        template: echo
      - name: D
        dependencies: [B, C]
        template: echo

DAG 中新增了 dependencies 欄位,可以指定當前步驟依賴的的依賴。

哪些任務需要執行?

該 steps 則定義了要執行 A、B、C、D 4 個任務。

這些任務按照什麼先後順序執行?

不如 Steps 那麼直接,需要根據 dependencies 分析依賴關係。

A 沒有依賴,因此最先執行,B、C 都只依賴於 A,因此會再 A 後同時執行,D 則依賴於 B、C,因此會等B、C都完成後才執行。

轉換為 json 形式如下:

{
    "steps": [
        ["A"],
        ["B", "C"],
        ["D"]
    ]
}

ps:相比之下 steps 方式更為直接,任務先後順序一目瞭然。如果整個 Workflow 中所有任務先後順序理清楚了就推薦使用 steps,如果很複雜,只知道每個任務之間的依賴關係那就直接用 DAG,讓 ArgoWorkflow 計算。

template definitions & template invocators

大家可以發現,steps、dag 模板和另外 4 個不一樣,他們都是可以指定多個 template 的。

前面分別介紹了 ArgoWorkflow 中的 6 種 template,實際上可以按照具體作用將這 6 個 template 分為 template definitions(模板定義)以及 template invocators(模板呼叫器)兩種。

  • template definitions(模板定義):該型別 template 用於定義具體步驟要執行的內容,例子中的 whalesay 模板就是該型別
    • 包含 container, script, resource, suspend 等型別
  • template invocators(模板呼叫器):該型別 template 用於組合其他 template definitions(模版定義) ,定義步驟間的執行順序等,例子中的 hello 模板就是該型別。
  • 一般 entrypoint 指向的就是該型別的模板
  • 包含dagsteps 兩種型別,例子中的 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(模板呼叫器)

接下來就是 Workflow 中另一重要物件 entrypoit。

entrypoint

entrypoint 作為任務的執行起點,類似於程式中的 main 方法,每個 Workflow 中都必須要指定 entrypoint。

注意:只有被 entrypoint 指定的任務才會執行,因此,entrypoint 一般只會指定 Steps 和 DAG 型別的 template,也就是template invocators(模板呼叫器)。然後由 Steps 中的 steps 或者 DAG中的 tasks 來指定多個任務。

因此,並不是 Workflow 中寫了的 templates 都會執行。

看下面這個例子:

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}}"]

Entrypoint 指定 hello,然後 hello 是一個 steps 型別的 template,也就是template invocators。然後在 hello template 的 steps 中指定了 whalesay 這個 template,最終 whalesay template 為 container 型別,也就是 template definitions。這裡就是最終要執行的任務。

當然,entrypoint 也可以指定 template definitions(模板定義)型別的 template,不過這樣只能執行一個任務,就像這樣:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: steps-
spec:
  entrypoint: whalesay
  templates:
  - name: whalesay    
    container:
      image: docker/whalesay
      command: [cowsay]
      args: ["hello"]

至此,我們應該基本搞清楚了 Workflow 物件(引數部分除外)。接下來就看一下最後一部分,parameters。

Demo

列出幾個複雜一點點的 Workflow,看一下是不是真的搞懂 Workflow 了。

下面是一個包含 4個任務的 Workflow:

  • 1)首先列印 hello
  • 2)然後執行一段 python 指令碼,生成隨機數
  • 3)sleep 20s
  • 4)建立一個 Configmap

提供了 steps 和 dag 兩種寫法,可以對比下

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: steps-
spec:
  entrypoint: hello
  templates:
  - name: hello              
    steps:          
    - - name: hello
        template: whalesay
        arguments:
          parameters: [{name: message, value: "hello"}]
    - - name: runscript
        template: gen-random-int
    - - name: sleep
        template: delay
    - - name: create-cm
        template: k8s-owner-reference
  # - name: diamond
  #   dag:
  #     tasks:
  #     - name: hello
  #       template: whalesay
  #       arguments:
  #         parameters: [{name: message, value: "hello"}]
  #     - name: runscript
  #       dependencies: [hello]
  #       template: gen-random-int
  #     - name: sleep
  #       template: delay
  #       dependencies: [runscript]
  #     - name: create-cm
  #       template: k8s-owner-reference
  #       dependencies: [sleep]
  - name: whalesay
    inputs:
      parameters:
      - name: message
    container:
      image: docker/whalesay
      command: [cowsay]
      args: ["{{inputs.parameters.message}}"]
  - name: gen-random-int
    script:
      image: python:alpine3.6
      command: [python]
      source: |
        import random
        i = random.randint(1, 100)
        print(i)
  - name: k8s-owner-reference
    resource:
      action: create
      manifest: |
        apiVersion: v1
        kind: ConfigMap
        metadata:
          generateName: owned-eg-
        data:
          host: lixueduan.com
          wx: 探索雲原生
  - name: delay
    suspend:
      duration: "20s"

parameters

Workflow 中的引數可以分為以下兩種:

  • 形參:在 template(template definitions) 中透過 inputs 欄位定義需要哪些引數,可以指定預設值
  • 實參:在 template(template invocators) 中透過 arguments 欄位為引數賦值,覆蓋 inputs 中的預設值

以上僅為個人理解

inputs 形式引數

template 中可以使用 spec.templates[*].inputs 欄位來指定形式引數,在 template 中可以透過{{inputs.parameters.$name}} 語法來引用引數。

下面這個例子則是宣告瞭 template 需要一個名為 message 的引數,這樣呼叫方在使用該 template 時就知道需要傳哪些引數過來。

  templates:
    - name: whalesay-template
      inputs:
        parameters:
          - name: message
      container:
        image: docker/whalesay
        command: [cowsay]
        args: ["{{inputs.parameters.message}}"]

當然也可以指定預設值

  templates:
    - name: whalesay-template
      inputs:
        parameters:
          - name: message
            value: "default message"
      container:
        image: docker/whalesay
        command: [cowsay]
        args: ["{{inputs.parameters.message}}"]

注意:如果未指定預設值,則呼叫該 template 時必須指定該引數,有預設值則可以不指定。

arguments 實際引數

spec.arguments用於定義要傳遞的實際引數,這部分引數在當前 Workflow 下的所有 Template 中都可以使用,可以使用 {{workflow.parameters.$name}} 語法來引用。

例如下面這個例子中指定了一個名為 message 的引數,並賦值為 hello world。

  arguments:
    parameters:
      - name: message
        value: hello world

引數複用

除了在 steps/dag 中指定 arguments,甚至可以直接在 Workflow 中指定,然後 steps/dag 中透過{{workflow.parameters.$name}} 語法進行引用。這樣即可實現引數複用,Workflow 中定義一次,steps/dag 中可以多次引用。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: example-
spec:
  entrypoint: main
  arguments:
    parameters:
    - name: workflow-param-1
  templates:
  - name: main
    dag:
      tasks:
      - name: step-A 
        template: step-template-A
        arguments:
          parameters:
          - name: template-param-1
            value: "{{workflow.parameters.workflow-param-1}}"

  - name: step-template-A
    inputs:
      parameters:
        - name: template-param-1
    script:
      image: alpine
      command: [/bin/sh]
      source: |
          echo "{{inputs.parameters.template-param-1}}"

Demo

透過下面這個 Demo 來理解引數傳遞:

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 的引數,同時在 steps template 中引用 whalesay 時透過 arguments 指定了引數 message 的值為 hello。因此最終會列印出 hello。

3.WorkflowTemplate

官方原文:

A WorkflowTemplate is a definition of a Workflow that lives in your cluster.

WorkflowTemplate 就是 Workflow 的定義,WorkflowTemplate 描述了這個流水線的詳細資訊,包括有哪些任務,任務之間的先後順序等等。

根據前面對 Workflow 的描述可知,我們能直接建立 Workflow 物件來執行流水線,不過這種方式存在的一些問題:

  • 1)如果 template 比較多的話,Workflow 物件就會特別大,修改起來比較麻煩
  • 2)模板無法共享,不同 Workflow 都需要寫一樣的 template,或者同一個 template 會出現在不同的 Workflow yaml 中。

因此,關於 Workflow 和 WorkflowTemplate 的最佳實踐:將 template 存到 WorkflowTemplate,Workflow 中只引用 Template 並提供引數即可。

而 ArgoWorkflow 中的工作流模板根據範圍不同分為 WorkflowTemplateClusterWorkflowTemplate 兩種。

  • 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 引數是一模一樣,這裡就不在贅述了。

只需要將 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 即可。

4.TemplateRef

建立好 WorkflowTemplate 之後就可以在 Workflow 中使用 TemplateRef 直接引用對應模板了,這樣 Workflow 物件就會比較乾淨。

對於 WorkflowTemplate 的引用也有兩種方式:

  • 1)workflowTemplateRef:引用完整的 WorkflowTemplate,Workflow 中只需要指定全域性引數即可
  • 2)templateRef:只引用某一個 template,Workflow 中還可以指定其他的 template、entrypoint 等資訊。

workflowTemplateRef

可以透過workflowTemplateRef欄位直接引用 WorkflowTemplate。

注意📢:這裡需要 Workflow 和 WorkflowTemplate 在同一個名稱空間

就像這樣:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: workflow-template-hello-world-
spec:
  arguments:
    parameters:
      - name: message
        value: "from workflow"
  workflowTemplateRef:
    name: workflow-template-submittable

workflowTemplateRef 指定要引用的 Template 名字即可,這一句就相當於把對應 Template 中 spec 欄位下的所有內容都搬過來了,包括 entrypoint、template 等。

Workflow 中一般只需要透過 argument 欄位來實現引數覆蓋,當然也可以不指定,若 Workflow 中不指定引數則會使用 Template 中提供的預設值

一個最精簡的 Workflow 如下:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: workflow-template-hello-world-
spec:
  workflowTemplateRef:
    name: workflow-template-submittable

只有 workflowTemplateRef 欄位,未提供 argument 引數。

和前面的 Workflow 對比起來,內容就更少了,因為大部分都寫在 WorkflowTemplate 裡了,Workflow 中一般只需要指定引數就行。

clusterWorkflowTemplateRef

和 workflowTemplateRef 類似,只需要增加 clusterScope: true 配置即可。

預設為 false,即 WorkflowTemplate

就像這樣:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: workflow-template-hello-world-
spec:
  entrypoint: whalesay
  templates:
  - name: whalesay
    steps:                              # You should only reference external "templates" in a "steps" or "dag" "template".
      - - name: call-whalesay-template
          templateRef:                  # You can reference a "template" from another "WorkflowTemplate or ClusterWorkflowTemplate" using this field
            name: cluster-workflow-template-whalesay-template   # This is the name of the "WorkflowTemplate or ClusterWorkflowTemplate" CRD that contains the "template" you want
            template: whalesay-template # This is the name of the "template" you want to reference
            clusterScope: true          # This field indicates this templateRef is pointing ClusterWorkflowTemplate
          arguments:                    # You can pass in arguments as normal
            parameters:
            - name: message
              value: "hello world"

核心部分:

  workflowTemplateRef:
    name: cluster-workflow-template-submittable
    clusterScope: true

當指定為叢集範圍時,ArgoWorkflow 會去搜尋 ClusterWorkflowTemplate 物件,否則會在當前名稱空間搜尋 WorkflowTemplate。

templateRef

除了使用 workflowTemplateRef / clusterWorkflowTemplateRef 引用整個 WorkflowTemplate 之外,還可以使用 templateRef 引數來實現引用 WorkflowTemplate 中的某一個 template。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: workflow-template-hello-world-
spec:
  entrypoint: whalesay
  templates:
  - name: whalesay
    steps:                              # You should only reference external "templates" in a "steps" or "dag" "template".
      - - name: call-whalesay-template
          templateRef:                  # You can reference a "template" from another "WorkflowTemplate" using this field
            name: workflow-template-1   # This is the name of the "WorkflowTemplate" CRD that contains the "template" you want
            template: whalesay-template # This is the name of the "template" you want to reference
          arguments:                    # You can pass in arguments as normal
            parameters:
            - name: message
              value: "hello world"

核心為:

          templateRef:
            name: workflow-template-1
            template: whalesay-template

引數分析:

  • name 指的是 WorkflowTemplate 名稱,即 workflow-template-1 這個 WorkflowTemplat
  • template 指的就是 template 的名稱 ,即 workflow-template-1 這個 WorkflowTemplat 中的名為 whalesay-template 的 template

注意📢:根據官方文件,最好不要在 stepsdag 這兩個template invocators(模板呼叫器)之外使用 templateRef 。

原文如下:

You should never reference another template directly on a template object (outside of a steps or dag template). This behavior is deprecated, no longer supported, and will be removed in a future version.

Parameters

WorkflowTemplate 中使用引數和 Workflow 基本一致,沒有太大區別。

  • template definitions 中透過 inputs 欄位定義需要的引數
  • template invocators 中透過 arguments 欄位為引數複製

Workflow 中引用 WorkflowTemplate 時可以再次定義 arguments 以覆蓋 WorkflowTemplate 中的預設引數。

最佳實踐

根據 workflowTemplateRef 和 templateRef 描述可以得出以下最佳實踐:

  • 1)workflowTemplateRef 使用:WorkflowTemplate 中定義完整流水線內容,包括 entrypoint、template,Workflow 中透過 workflowTemplateRef 引用並透過 argument 指定引數覆蓋預設值。
  • 2)templateRef 使用:WorkflowTemplate 中不定義完整流水線內容,只定義常用 template,Workflow 中需要使用該型別 template 時,透過 templateRef 引用,而不是在 Workflow 中再定義一次該 template。

第一種情況 WorkflowTemplate 可以稱為流水線模板,第二種情況下 WorkflowTemplate 充當 template-utils 角色。


【ArgoWorkflow 系列】持續更新中,搜尋公眾號【探索雲原生】訂閱,閱讀更多文章。


5.小結

本文主要分析了 ArgoWorkflow 中的 Workflow、WorkflowTemplate、template 物件及其之間的聯絡。

1)Workflow 物件:由 templates、entrypoint 組成。

  • templates:按照作用分為 template definitions(模板定義)以及 template invocators(模板呼叫器)
    • template definitions:用於定義具體步驟要執行的內容,包括 container、script、resource、suspend
    • template invocators:用於組合其他模板,控制任務先後順序,包括 steps、dag
  • entrypoint:任務執行起點

2)WorkflowTemplate/ClusterWorkflowTemplate 物件:和 Workflow 物件一致,但只用於定義流水線,不可執行

  • Workflow 中可以透過 WorkflowTemplateRef/clusterWorkflowTemplateRef 引用整個 WorkflowTemplate
  • 或者透過 templateRef 引用某個 template

3)Parameters:分為形參和實參

  • inputs:形參,申明該 template 需要使用哪些引數,可指定預設值
  • arguments:實參,為對應 template 中的引數賦值,會覆蓋 inputs 提供的預設值

4)引數優先順序:

  • Workflow arguments > WorkflowTemplate arguments > WorkflowTemplate inputs

最後則是Workflow、WorkflowTemplate、template 這三者之間的關係

arg-workflow-template-ref.png

5)一些最佳實踐:

WorkflowTemplate

  • 1)可以用作流水線模版:WorkflowTemplate 中定義全部的 entrypoint 和 templates,Workflow 中透過 WorkflowTemplateRef 引入即可使用
  • 2)用作 template-utils:WorkflowTemplate 中僅包含常用的 template,Workflow 中要使用時透過 templateRef 引入,避免重複定義 template

steps 和 dag 選擇

  • steps 方式更為直接,任務先後順序一目瞭然,但是需要理清所有任務的先後順序
  • dag 則不夠直觀,但是填寫時只需要知道某個任務的依賴關係就可以新增新任務

建議:如果整個 Workflow 中所有任務先後順序理清楚了就推薦使用 steps,如果很複雜,只知道每個任務之間的依賴關係那就直接用 DAG,讓 ArgoWorkflow 計算。

相關文章