前回デプロイと動作確認をしたので続きです。
順次実行 (コードはリンク先に)。
- -
で先行ステップを表現するのはややわかりづらい気がします。
でも DAG っていう GitHub Actions とかでもお馴染みの記法もサポートされてます。
後続のステップに成果物を受け渡せます。サンプルでは [MinIO] のストレージをマウントしてますが、S3 とか色々サポートされてます。
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}}"]
繰り返し。パラメータとかに 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]
実行結果。並列で動いてます。
条件分岐は when
タグで書きます。Coin flip のサンプルです。実行されたステップとされなかったステップが識別できます。
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)"]
ワークフローが成功しても失敗しても実行したいステップ(結果を通知するなど) を記述するときは Exit handler を使います。
suspend
タグで停止のステップを入れることが可能です。duration
で時間も指定できます。Argo CLI の resume サブコマンドで外部からレジュームすることも可能です。
$ argo resume WORKFLOW
template
のスコープで、指定したコンテナを Daemon として起動、破棄できます。そのスコープでは常に使用できるので、コンテナ化した Web アプリのテストをするとか、一時的に Docker レジストリとか NPM のパッケージレジストリを建ててテスト中だけ使うなどの用途が考えられます。
メインのコンテナと同一 Pod で起動するサイドカーコンテナを指定することもできます。
サイドカーを使って DinD な処理も書けます。
Docker-in-Docker Using Sidecars
Kubernetes のマニフェストを直接 workflowに記述して適用することも可能です。
以上のように Kubernetes ネイティブでかつ CI パイプラインの記述でお馴染みの書き方でワークフローを作れる Argo Workflow なかなかイイですね。色々なコンテナでコードもぱぱっとかけちゃうし。
CI にも使いたいぜって思いますが、今のところ git push で trigger できないです。でも、
but we plan to do so in the near future.
と近い将来対応されるようなので、それまでは cron ジョブとかで起動してねとのことです。