Argo Workflow の機能と記法

前回デプロイと動作確認をしたので続きです。

blog.kondoumh.com

Steps

順次実行 (コードはリンク先に)。

f:id:kondoumh:20210611131108p:plain

- - で先行ステップを表現するのはややわかりづらい気がします。

でも DAG っていう GitHub Actions とかでもお馴染みの記法もサポートされてます。

DAG

f:id:kondoumh:20210611131224p:plain

Artifacts

後続のステップに成果物を受け渡せます。サンプルでは [MinIO] のストレージをマウントしてますが、S3 とか色々サポートされてます。

Scripts & Results

source タグに直接コード書けます。Node.js とか Python のイメージ持ってくれば、ベタっとスクリプト書けて便利そうです。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: scripts-bash-
spec:
  entrypoint: bash-script-example
  templates:
  - name: bash-script-example
    steps:
    - - name: generate
        template: gen-random-int-bash
    - - name: print
        template: print-message
        arguments:
          parameters:
          - name: message
            value: "{{steps.generate.outputs.result}}"  # The result of the here-script

  - name: gen-random-int-bash
    script:
      image: debian:9.4
      command: [bash]
      source: |                                         # Contents of the here-script
        cat /dev/urandom | od -N2 -An -i | awk -v f=1 -v r=100 '{printf "%i\n", f + r * $1 / 65536}'

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

  - name: gen-random-int-javascript
    script:
      image: node:9.1-alpine
      command: [node]
      source: |
        var rand = Math.floor(Math.random() * 100);
        console.log(rand);

  - name: print-message
     inputs:
      parameters:
      - name: message
    container:
      image: alpine:latest
      command: [sh, -c]
      args: ["echo result was: {{inputs.parameters.message}}"]

Loops

繰り返し。パラメータとかに List や Map を書いて Matrix build 的なこともできます。いろんな環境で並列にテストするとかが簡単です。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: loops-maps-
spec:
  entrypoint: loop-map-example
  templates:
  - name: loop-map-example
    steps:
    - - name: test-linux
        template: cat-os-release
        arguments:
          parameters:
          - name: image
            value: "{{item.image}}"
          - name: tag
            value: "{{item.tag}}"
        withItems:
        - { image: 'debian', tag: '9.1' }       #item set 1
        - { image: 'debian', tag: '8.9' }       #item set 2
        - { image: 'alpine', tag: '3.6' }       #item set 3
        - { image: 'ubuntu', tag: '17.10' }     #item set 4

  - name: cat-os-release
    inputs:
      parameters:
      - name: image
      - name: tag
    container:
      image: "{{inputs.parameters.image}}:{{inputs.parameters.tag}}"
      command: [cat]
      args: [/etc/os-release]

実行結果。並列で動いてます。

f:id:kondoumh:20210611131255p:plain

Conditional

条件分岐は when タグで書きます。Coin flip のサンプルです。実行されたステップとされなかったステップが識別できます。

f:id:kondoumh:20210611131313p:plain

Retrying Failed or Errord Steps

エラーのリトライも指定できます。特徴的なのは、nodeAntiAffinity の設定で、失敗した時とは別のワーカーノードで実行されることで環境要因のエラーが切り分けられる可能性があります。Kubernetes の特性を活かしてる感があります。

retry-backoff.yaml

 apiVersion: argoproj.io/v1alpha1
 kind: Workflow
 metadata:
   generateName: retry-backoff-
 spec:
   entrypoint: retry-backoff
   templates:
   - name: retry-backoff
     retryStrategy:
       limit: 10
       retryPolicy: "Always"
       backoff:
         duration: "1" # Must be a string. Default unit is seconds. Could also be a Duration, e.g.: "2m", "6h", "1d"
         factor: 2
         maxDuration: "1m" # Must be a string. Default unit is seconds. Could also be a Duration, e.g.: "2m", "6h", "1d"
       affinity:
         nodeAntiAffinity: {}
     container:
       image: python:alpine3.6
       command: ["python", -c]
       # fail with a 66% probability
       args: ["import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code)"]

f:id:kondoumh:20210611131331p:plain

Exit handlers

ワークフローが成功しても失敗しても実行したいステップ(結果を通知するなど) を記述するときは Exit handler を使います。

f:id:kondoumh:20210611131346p:plain

Suspending

suspend タグで停止のステップを入れることが可能です。duration で時間も指定できます。Argo CLI の resume サブコマンドで外部からレジュームすることも可能です。

 $ argo resume WORKFLOW

Daemon Containers

template のスコープで、指定したコンテナを Daemon として起動、破棄できます。そのスコープでは常に使用できるので、コンテナ化した Web アプリのテストをするとか、一時的に Docker レジストリとか NPM のパッケージレジストリを建ててテスト中だけ使うなどの用途が考えられます。

Sidecars

メインのコンテナと同一 Pod で起動するサイドカーコンテナを指定することもできます。

サイドカーを使って DinD な処理も書けます。

Docker-in-Docker Using Sidecars

Kubernetes Resources

Kubernetes のマニフェストを直接 workflowに記述して適用することも可能です。

以上のように Kubernetes ネイティブでかつ CI パイプラインの記述でお馴染みの書き方でワークフローを作れる Argo Workflow なかなかイイですね。色々なコンテナでコードもぱぱっとかけちゃうし。

CI にも使いたいぜって思いますが、今のところ git push で trigger できないです。でも、

but we plan to do so in the near future.

と近い将来対応されるようなので、それまでは cron ジョブとかで起動してねとのことです。