为容器模板动态提供图像名称

Dynamically provide an image name for the container template

有没有办法根据输入参数为容器模板动态提供图像名称?

我们有 30 多个不同的任务,每个任务都有自己的图像,应该在工作流中以相同的方式调用它们。根据上一个任务的输出,每个 运行 的数字可能会有所不同。所以我们不想甚至不能将它们硬编码到工作流 YAML 中。

一个简单的解决方案是根据输入参数为容器提供图像字段,并为每个任务使用相同的模板。但看起来这是不可能的。此工作流程不起作用:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: hello-world-
spec:
  entrypoint: whalesay

  templates:
  - name: whalesay
    inputs:
      parameters:
        - name: image
          default: whalesay:latest
    container:
      image: "docker/{{image}}"
      command: [cowsay]
      args: ["hello world"]

对于这种特殊情况是否有一些解决方法?

另外,是否有文档描述了可以在哪些字段中使用工作流变量? Documentation page 只说:

Some fields in a workflow specification allow for variable references which are automatically substituted by Argo.

这是一个可能的解决方法:使用任务的 when 和条件 运行。我们需要列出所有可能的任务及其容器镜像:

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: test-dynamic-image-
spec:
  entrypoint: main

  templates:
  - name: main
    steps:
    - - name: fanout-step
        template: fanout
    - - name: loop-step
        template: options
        arguments:
          parameters:
          - name: code
            value: "{{item}}"
        withParam: "{{steps.code-step.outputs.parameters.codes}}"

  - name: fanout
    script:
      image: python:alpine3.6
      command: [python]
      source: |
        import json
        with open("/tmp/codes.json", 'w') as wf:
          json.dump(["foo", "bar", "buz"], wf)
    outputs:
      parameters:
        - name: codes
          valueFrom:
            path: /tmp/codes.json

  - name: foo-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("foo-code")

  - name: bar-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("bar-code")

  - name: buz-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("buz-code")

  - name: missed-code
    script:
      image: python:alpine3.6
      command: [ python ]
      source: |
        print("THIS SHOULD NOT BE PRINTED")

  - name: options
    inputs:
      parameters:
        - name: code
    steps:
    - - name: foo-code-option
        template: foo-code
        when: "{{inputs.parameters.code}} == foo"
      - name: bar-code-option
        template: bar-code
        when: "{{inputs.parameters.code}} == bar"
      - name: buz-code-option
        template: buz-code
        when: "{{inputs.parameters.code}} == buz"
      - name: missed-code-option
        template: missed-code
        when: "{{inputs.parameters.code}} == missed"

绝对支持您尝试做的事情。只需将 {{image}} 更改为完全限定的变量名称 {{inputs.parameters.image}}.

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: hello-world-
spec:
  entrypoint: whalesay
  templates:
  - name: whalesay
    inputs:
      parameters:
        - name: image
          default: whalesay:latest
    container:
      image: "docker/{{inputs.parameters.image}}"
      command: [cowsay]
      args: ["hello world"]

目前没有列出可模板字段的文档。但是有一个 open issue 用于添加该文档。