DAGパイプラインとJobの距離を測る
目標
Argo WorkflowsのDAG・アーティファクト・テンプレートの再利用を、マニフェストで表現し、同じことをKubernetesのJobとCronJobでも実際に載せて、2つのモデルの表現力の違いを、目で確認します。
なぜ重要なのか
Workflowsを導入するかどうかを判断するには、Jobでどこまでできるかを知る必要があります。Jobは、リトライ(backoffLimit)と並列(parallelism)までは表現できますが、作業の間の依存関係とファイルの受け渡しは表現できません。そのため、Jobだけを使う組織は、結局、コンテナ1つにシェルスクリプトを詰め込むか、クラスター外のオーケストレーターに順序を任せることになり、どちらの方法も、失敗した地点を見失います。このラボで、2つのマニフェストを並べて作ってみると、その境界線がどこかが、手に残ります。
ステップ
/root/capa-wf/ディレクトリを作成し、workflow.yamlに、apiVersionがargoproj.io/v1alpha1、kindがWorkflow、metadata.nameがcapa-build、spec.entrypointがmainのリソースを書いてください。spec.templatesには、nameがmainのテンプレートがある必要があります。mainテンプレートにdag.tasksを作成し、checkout、build、testの3つのタスクを入れてください。buildはcheckoutに、testはbuildに依存させ、checkoutにはdependenciesを付けないでください。spec.templatesに、nameがbuildのテンプレートを置き、inputs.parametersに名前がrevisionのパラメーターを、outputs.artifactsに、名前がbinaryで、pathが/out/appのアーティファクトを宣言してください。/root/capa-wf/cronworkflow.yamlに、kindがCronWorkflow、metadata.nameがcapa-nightly、spec.scheduleが0 3 * * *、spec.concurrencyPolicyがForbid、spec.workflowSpec.entrypointがmainのリソースを書いてください。/root/capa-wf/workflowtemplate.yamlに、kindがWorkflowTemplate、metadata.nameがcapa-commonのリソースを書き、その中に、nameがnotifyのテンプレートを置いてください。そして、workflow.yamlのmainのdagにnotifyタスクを追加し、templateRef.nameはcapa-common、templateRef.templateはnotify、dependenciesはtestにしてください。- クラスターに、ネームスペース
capa-wfを作成し、その中にJobcapa-build-jobを実際に作成してください。spec.backoffLimitは2、PodのrestartPolicyはNever、コンテナイメージはbusybox:1.36です。 - 同じネームスペースに、CronJob
capa-nightly-jobを実際に作成してください。spec.scheduleは0 3 * * *、spec.concurrencyPolicyはForbid、spec.successfulJobsHistoryLimitは1です。 - 同じネームスペースに、ConfigMap
capa-wf-summaryを実際に作成してください。キーdag-tasksにはworkflow.yamlのmainのdagのタスクの個数を、キーcron-scheduleにはcronworkflow.yamlのscheduleの値を、キーjob-nameにはcapa-build-jobを入れてください。
参考
kubectl create job capa-build-job --image=busybox:1.36 -n capa-wf --dry-run=client -o yamlで骨組みを出力してから、backoffLimitを埋めると早いです。- dagのタスクの個数は、
yq '.spec.templates[] | select(.name == "main") | .dag.tasks | length' /root/capa-wf/workflow.yamlで数えられます。 - よくある間違い1: CronWorkflowの中に、Workflowのspecのフィールドを直接書くことです。1段階包むフィールドがあります。
- よくある間違い2: cron式で、空白を含む文字列を、引用符なしで書くことです。YAMLでは引用符で囲んでください。
Workflowの骨格とentrypoint
/root/capa-wf/ディレクトリを作成し、workflow.yamlに、apiVersionがargoproj.io/v1alpha1、kindがWorkflow、metadata.nameがcapa-build、spec.entrypointがmainのリソースを書いてください。spec.templatesには、nameがmainのテンプレートがある必要があります。
entrypointは、templates配列の中にあるテンプレートのnameを指します。指す名前が実際に存在しないと、ワークフローは開始すらできません。
依存関係のグラフを描く
mainテンプレートにdag.tasksを作成し、checkout、build、testの3つのタスクを入れてください。buildはcheckoutに、testはbuildに依存させ、checkoutにはdependenciesを付けないでください。
dag.tasksの各項目は、nameとtemplate(またはtemplateRef)、そしてdependenciesを持ちます。グラフの開始ノードには、dependenciesを付けません。
パラメーターとアーティファクト
spec.templatesに、nameがbuildのテンプレートを置き、inputs.parametersに名前がrevisionのパラメーターを、outputs.artifactsに、名前がbinaryで、pathが/out/appのアーティファクトを宣言してください。
parametersは文字列、artifactsはファイルです。出力アーティファクトには、名前とコンテナ内のパスが両方必要です。
CronWorkflowで定期実行する
/root/capa-wf/cronworkflow.yamlに、kindがCronWorkflow、metadata.nameがcapa-nightly、spec.scheduleが0 3 * * *、spec.concurrencyPolicyがForbid、spec.workflowSpec.entrypointがmainのリソースを書いてください。
CronWorkflowは、Workflowのspecをそっくり、1つのフィールドの下に抱えます。そのフィールド名を見つけることが、このステップの半分です。
WorkflowTemplateの再利用
/root/capa-wf/workflowtemplate.yamlに、kindがWorkflowTemplate、metadata.nameがcapa-commonのリソースを書き、その中に、nameがnotifyのテンプレートを置いてください。そして、workflow.yamlのmainのdagにnotifyタスクを追加し、templateRef.nameはcapa-common、templateRef.templateはnotify、dependenciesはtestにしてください。
templateRefは、どのオブジェクトの(name)どのテンプレートを(template)使うかの、2つの値の両方が必要です。このタスクもグラフの一部なので、先行条件を設定する必要があります。
同じことを行うJobを実際に載せる
クラスターに、ネームスペースcapa-wfを作成し、その中にJobcapa-build-jobを実際に作成してください。spec.backoffLimitは2、PodのrestartPolicyはNever、コンテナイメージはbusybox:1.36です。
JobのPodのrestartPolicyには、Alwaysを使えません。リトライ回数は、Podではなく、Jobのspecのフィールド1つで決めます。
CronJobで同じ周期を表現する
同じネームスペースに、CronJobcapa-nightly-jobを実際に作成してください。spec.scheduleは0 3 * * *、spec.concurrencyPolicyはForbid、spec.successfulJobsHistoryLimitは1です。
CronJobにも、同時実行ポリシーがあります。履歴の保持個数を決めるフィールドが、成功と失敗でそれぞれ別にある点も確認してください。
ファイルとクラスターをつなぐサマリー
同じネームスペースに、ConfigMapcapa-wf-summaryを実際に作成してください。キーdag-tasksにはworkflow.yamlのmainのdagのタスクの個数を、キーcron-scheduleにはcronworkflow.yamlのscheduleの値を、キーjob-nameにはcapa-build-jobを入れてください。
前のステップで作成したファイルから、値を取り出す必要があります。yqで取り出した結果を、そのままConfigMapの値として入れればよく、手で数えてもかまいません。