Slide 1

Slide 1 text

CloudNative Days Tokyo 2021 使いこなせ!Argo Workflows @makocchi

Slide 2

Slide 2 text

2 Makoto Hasegawa Working at // CIU, CyberAgent, Inc Currently // Develop and maintain private OpenStack cloud. Develop and maintain Kubernetes as a Service platform. Kubernetes organization member (sig-docs-ja) CKA / CKAD / CKS Job Title // Technical Lead Infrastructure Engineer WHO am I Twitter // @makocchi Facebook // makocchi0923 Hobby // Playing bass

Slide 3

Slide 3 text

CloudNative Days Tokyo 2021 | @makocchi 3 💪 本日のゴール💪 Argo Workflowsについて理解して使えるようになる! 既に使っている人は知識の復習に! タコが好きになる Argo Workflows について一緒に学んでいきましょう👌

Slide 4

Slide 4 text

CloudNative Days Tokyo 2021 | @makocchi 4 Argo Workflowsとは? https://github.com/argoproj/argo-workflows

Slide 5

Slide 5 text

CloudNative Days Tokyo 2021 | @makocchi 5 Argo Workflows is an open source container-native workflow engine for orchestrating parallel jobs on Kubernetes. Argo Workflows is implemented as a Kubernetes CRD (Custom Resource Definition). https://argoproj.github.io/argo-workflows/ Argo Workflows は Kubernetes 上で並列 Job を構成する オープンソースのコンテナネイティブなワークフローエンジンです。 Argo Workflows は Kubernetes の CRD で実装されています。 つまり ということ

Slide 6

Slide 6 text

CloudNative Days Tokyo 2021 | @makocchi 6 一つ一つの処理(Job)がパイプラインのようにつながってい るもの 例えばこんなもの アプリケーションのソースを GitHub から Pull する 🔽 アプリケーションをビルドする 🔽 アプリケーションのコンテナイメージを作成する 🔽 コンテナレジストリに Push する ワークフローとは?

Slide 7

Slide 7 text

CloudNative Days Tokyo 2021 | @makocchi 7 ワークフローをどうやって定義するの? このようなワークフローの定義を Kubernetes の CRD を 使って定義・実行することができる アプリケーションのソースを GitHub から Pull する 🔽 アプリケーションをビルドする 🔽 アプリケーションのコンテナイメージを作成する 🔽 コンテナレジストリに Push する apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: generateName: my-awesome-wf- spec: entrypoint: pull-from-github templates: - name: pull-from-github container: image: docker/my-image:1.0.0 command: [“git”, “clone”] …

Slide 8

Slide 8 text

CloudNative Days Tokyo 2021 | @makocchi 8 Argo Workflows では下記の CRD が使われています Kind Shotnames Namespaced ClusterWorkflowTemplate clusterwftmpl,cwft FALSE CronWorkflow cwf,cronwf TRUE WorkflowEventBinding wfeb TRUE Workflow wf TRUE WorkflowTaskSet wfts TRUE WorkflowTemplate wftmpl TRUE ※ WorkflowTaskSet は v3.2.0 から登場 参考までに CRD の情報

Slide 9

Slide 9 text

CloudNative Days Tokyo 2021 | @makocchi 9 Argo Workflowsを インストールしよう

Slide 10

Slide 10 text

CloudNative Days Tokyo 2021 | @makocchi 10 多くのケースでは下記のインストールの仕方で十分です $ kubectl create namespace argo $ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/vN.N.N/install.yaml 現時点での最新は v3.2.2 このケースではコントローラーには clusterrole が割当たり、クラスター全体(全ての namespace のリソース)を watch するパターンになります namespace に閉じた形でインストールしたい場合は install.yaml を namespace-install.yaml に変更してインストールして下さい Kubernetes クラスターに Argo Workflows をインストールする

Slide 11

Slide 11 text

CloudNative Days Tokyo 2021 | @makocchi 11 イマドキ kubectl なんかでインストールしてられっか!という人には・・ Helm Chart も用意されてます $ helm repo add argo https://argoproj.github.io/argo-helm $ helm install --create-namespace --namespace argo argo-workflows argo/argo-workflows 細かい設定の変更をしたい場合はこの方法がオススメです Chart は下記の GitHub リポジトリにあります https://github.com/argoproj/argo-helm/blob/master/charts/argo-workflows/ Kubernetes クラスターに Argo Workflows をインストールする

Slide 12

Slide 12 text

CloudNative Days Tokyo 2021 | @makocchi 12 時代はやっぱ kustomize でしょ!っていう人には・・・ もちろん kustomize でも可能です $ cat base/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - [email protected]:argoproj/argo-workflows.git/manifests/cluster-install?ref=vN.N.N namespace に閉じてインストールしたい場合は cluster-install の部分を namespace-install に変更してください Kubernetes クラスターに Argo Workflows をインストールする

Slide 13

Slide 13 text

CloudNative Days Tokyo 2021 | @makocchi 13 インストールが完了すると workflow-controller と argo-server の 2 つのコンポーネ ントが稼働している(deployment)状態になっていると思います 特に設定を変更しなかった場合は各 deployment は両方とも Pod が 1 つだけです 場合によっては冗長化して動かしておきたい場合もあると思いますが、workflow- controller は Leader Election に対応しているので、Pod の数を増やすだけで特に何も 考えずに冗長化することが可能です(v3.0.0以降) argo-server もそれ自体は状態を持たないので、特に何も考えずに Pod の数を増やすだ けで冗長化することが可能です(v2.6.0以降) HA構成もオススメ Kubernetes クラスターに Argo Workflows をインストールする

Slide 14

Slide 14 text

CloudNative Days Tokyo 2021 | @makocchi 14 各種ワークフローの操作は argo コマンドで行います なお、だいたいの操作は kubectl でも可能ですが、一部(ワークフローの resubmit とか)は argo コマンドじゃないと出来ない操作もあります インストールはバイナリが用意されているので配置するだけで完了します # Linux ͷ৔߹ (Mac ͷ৔߹͸ linux ͷ෦෼Λ darwin ʹมߋ͍ͯͩ͘͠͞) $ curl -sLO https://github.com/argoproj/argo-workflows/releases/download/vN.N.N/argo-linux-amd64.gz $ gunzip argo-linux-amd64.gz $ chmod +x argo-linux-amd64 $ mv ./argo-linux-amd64 /path/to/argo mac の方は brew でも可能です $ brew install argoproj/tap/argo コマンドラインツール argo をインストールする

Slide 15

Slide 15 text

CloudNative Days Tokyo 2021 | @makocchi 15 実は argo-server の Pod は argocli というイメージが使われています なので argo-server の Pod 内で argo コマンドを叩いてしまうという手もあります # ϕʔεΠϝʔδ͸ scratch ͳͷͰ͜ΕҎ֎͸΄΅Ͱ͖ͳ͍ɾɾ💦 $ kubectl exec -ti -n argo argo-server-68b9f8c695-h4nxp -- argo auth token Bearer eyJhbGciOiJSUzM... $ kubectl exec -ti -n argo argo-server-68b9f8c695-h4nxp -- argo list -n argo NAME STATUS AGE DURATION PRIORITY hello-world-b4n87 Succeeded 3m 31s 0 ※ ちなみに workflow-controller もベースイメージは scratch ちょっと触ってみるか、の場合はこれでいいかもしれません コマンドラインツール argo をインストールする (楽ちん編)

Slide 16

Slide 16 text

CloudNative Days Tokyo 2021 | @makocchi 16 GUIに アクセスしてみよう

Slide 17

Slide 17 text

CloudNative Days Tokyo 2021 | @makocchi 17 Hello-world の ワークフローを動かしたところ Argo Workflows には素敵な UI が用意されています

Slide 18

Slide 18 text

CloudNative Days Tokyo 2021 | @makocchi 18 UI にアクセスするために必要なこと (expose 編) UI は argo-server の port 2746 によって提供されています。 「kubectl port-forward」もしくは Service(NodePort や LoadBalancer) を作成するこ とでアクセスが可能になります。 # port-forward ͷྫ (port 2746 -> port 2746) # ϒϥ΢βͰΞΫηε͢Δ৔߹͸ https://localhost:2746 $ kubectl port-forward -n argo svc/argo-server 2746:2746 Forwarding from 127.0.0.1:2746 -> 2746 Forwarding from [::1]:2746 -> 2746

Slide 19

Slide 19 text

CloudNative Days Tokyo 2021 | @makocchi 19 UI にアクセスするために必要なこと (expose 編) v3.0.0 以降、argo-server はデフォルトで HTTPS で Listen するようになりました。 port-forward する時は特に気にすることはないんですが、LoadBalancer や Ingress 配下にぶら下 げたい場合に HTTP で Listen してほしいケースがあると思います その場合は argo-server の Pod 内の args に「--secure=false」を追加、もしくは ARGO_SECURE=false の環境変数を設定してください しかしこれだけだと readinessProbe が「scheme: HTTPS」になっている場合にいつまで経っても READY にならないので 「scheme: HTTP」に変更することも忘れずに! ちなみに Helm だと「--secure=false」がデフォルトになっているようです ちなみに自己証明書の期限は 1 年(今の所ハードコード)で自動的に作成されます (Pod を再作成する ことで証明書も再作成されます)

Slide 20

Slide 20 text

CloudNative Days Tokyo 2021 | @makocchi 20 UI にアクセスするために必要なこと (Auth mode 編) UI へアクセスすることができても、最初は何もできないと思います💦 なんらかの形で Login しないと先程のワークフロー一覧のような画面に辿り着くことがで きないようになっています。 こんな感じで Login が必要になります

Slide 21

Slide 21 text

CloudNative Days Tokyo 2021 | @makocchi 21 UI にアクセスするために必要なこと (Auth mode 編) argo-server では 3 つの認証方式をサポートしています。 server client sso v3.0.0 以前は server 方式がデフォルトで、v3.0.0 以降は client 方式がデフォルトです。 認証方式の設定は argo-server の起動時に「--auth-mode=server」のように指定します。 3 つの認証方式はそれぞれ独立しているので、認証方式は複数指定することが可能です 引数に渡す時に少し気をつけないといけないことがあります

Slide 22

Slide 22 text

CloudNative Days Tokyo 2021 | @makocchi 22 UI にアクセスするために必要なこと (Auth mode 編) 複数の認証方式を設定する時は・・・ 「--auth-mode=client --auth-mode=server --auth-mode=sso」のように「--auth- mode」を複数回指定しなければなりません 「--auth-mode=client,server,sso」のようにすることは出来ません・・! 理由としては内部で cobra の StringArrayVarP で処理されているからで、これが StringSliceVarP だったらカンマ区切りでいけるのにな・・・ ちなみにドキュメントには特に書かれていないんですが、hybrid というモードも指定するこ とができます (「--auth-mode=hybrid」にすると server と client が有効になる) ソース見て 初めて知った hybrid

Slide 23

Slide 23 text

CloudNative Days Tokyo 2021 | @makocchi 23 UI にアクセスするために必要なこと (Auth mode 編) それぞれの認証方式はどのようなものなのでしょうか? 1つずつ見ていきましょう!

Slide 24

Slide 24 text

CloudNative Days Tokyo 2021 | @makocchi 24 認証方式 server について

Slide 25

Slide 25 text

CloudNative Days Tokyo 2021 | @makocchi 25 認証方式 server について server による認証方式は UI の操作を argo-server 自体の 権限で行う方式になります おそらくみなさんの argo-server は「serviceAccount: argo-server」で動いていると思います。そして clusterrole として「argo-server-cluster-role」が割当 たっているんじゃないでしょうか。(cluster install の場合) 「argo-server-cluster-role」は結構強い権限で、UI から ワークフローを作成したり削除したりすることができます v3.0.0 より前はこれがデフォルトの認証方式でした

Slide 26

Slide 26 text

CloudNative Days Tokyo 2021 | @makocchi 26 認証方式 server について ちょっとログインが分かりにくいんですが、真ん中の token を使ってログインする場所で token を入れずに「LOGIN」をクリックすれば OK です。

Slide 27

Slide 27 text

CloudNative Days Tokyo 2021 | @makocchi 27 認証方式 client について

Slide 28

Slide 28 text

CloudNative Days Tokyo 2021 | @makocchi 28 認証方式 client について client による認証方式は UI の操作を特定のサービスアカウ ントの権限で行う方式です サービスアカウントの token を入力してログインします 「argo auth token」というコマンドを叩くと、自身の kubeconfig 内の token を抜き出して表示してくれます ただし token 方式で認証していない kubeconfig を指定 していると、「could not find a token」って怒られま す・・・ v3.0.0 以降はこちらの方式がデフォルト

Slide 29

Slide 29 text

CloudNative Days Tokyo 2021 | @makocchi 29 認証方式 client について client による認証方式は UI の操作を特定のサービスアカウ ントの権限で行う方式です サービスアカウントの token を入力してログインします 「argo auth token」というコマンドを叩くと、自身の kubeconfig 内の token を抜き出して表示してくれます ただし token 方式で認証していない kubeconfig を指定 していると、「could not find a token」って怒られま す・・・ v3.0.0 以降はこちらの方式がデフォルト # ͍͍ͪͪ token औಘ͢ΔͷΊΜͲ͍͘͞ͳ͊ɾɾͱ͍͏ਓ͸͜ΕͰ😝 $ kubectl exec -ti -n argo argo-server-68b9f8c695-h4nxp -- argo auth token Bearer eyJhbGciOiJSUzM...

Slide 30

Slide 30 text

CloudNative Days Tokyo 2021 | @makocchi 30 認証方式 client について ログインする場合は token の入力欄に「Bearer 」+「」を入力してログインします この「Bearer 」(スペース有り)が無いとうまく認証できませんので注意! 「argo auth token」で表示した場合は Bearer が付与されて表示されます 「Bearer 」忘れずに

Slide 31

Slide 31 text

CloudNative Days Tokyo 2021 | @makocchi 31 認証方式 sso について

Slide 32

Slide 32 text

CloudNative Days Tokyo 2021 | @makocchi 32 認証方式 sso について sso による認証方式は外部に認証を任せる方式です 例えば Google 認証と連携させたりすることが可能です ログイン後にルールに従って RBAC を適用(サービスア カウント権限を割り当てる)することが可能です ⏩ の例は [email protected] でログインしたら 「argo-read-only」のサービスアカウントの権限を与 えるという例です この RBAC 連携は v2.12.0 以降で実装されています 設定で RBAC 連携させるかさせないか選択が可能です

Slide 33

Slide 33 text

CloudNative Days Tokyo 2021 | @makocchi 33 認証方式 sso について sso + RBAC の設定はサービスアカウントに対して「workflows.argoproj.io/rbac- rule」の Annotation を付けることで制御します # ྫ͑͹ @makocchi.com ͰϩάΠϯͨ͠Β argo-read-only ͷݖݶΛ౉࣌͢ apiVersion: v1 kind: ServiceAccount metadata: name: argo-read-only annotations: workflows.argoproj.io/rbac-rule: "email endsWith ‘@makocchi.com'" workflows.argoproj.io/rbac-rule-precedence: "10" 内部のルールの書き方はこちらの記述方式で行います https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md

Slide 34

Slide 34 text

CloudNative Days Tokyo 2021 | @makocchi 34 認証方式 sso について 「workflows.argoproj.io/rbac-rule-precedence」の Annotation は適用順序を制御す る時に使います 省略した場合は 0 で扱われるので、何かしら数を割り当てておいたほうがよい デフォルトのルールを 0 で定義しておくと良い # rbac-rule ͸ true ʹ͓ͯ͘͠ apiVersion: v1 kind: ServiceAccount metadata: name: default-ui-account annotations: workflows.argoproj.io/rbac-rule: "true" workflows.argoproj.io/rbac-rule-precedence: "0"

Slide 35

Slide 35 text

CloudNative Days Tokyo 2021 | @makocchi 35 認証方式 sso について 「--auth-mode=sso」の場合、別途設定 が必要になります workflow-controller が参照する configMap で設定します また client-id や client-secret-key は 別途 secret に登録する必要があります RBAC 連携をしない (sso.rbac.enabled=false)の場合、UI は argo-server のサービスアカウント の権限が割当たります # configMap Ͱ͍Ζ͍Ζઃఆ͕ඞཁ kind: ConfigMap metadata: name: workflow-controller-configmap data: config: | sso: issuer: https://accounts.google.com clientId: name: client-id-secret key: client-id-key clientSecret: name: client-secret-secret key: client-secret-key redirectUrl: https://your-server/oauth2/callback scopes: - openid - email - profile rbac: enabled: true sessionExpiry: 10h

Slide 36

Slide 36 text

CloudNative Days Tokyo 2021 | @makocchi 36 認証方式 sso について いろいろ設定がめんどくさい部分がありますが、設定してしまえばかなり柔軟にアクセス制 御できるようになるので是非 sso + RBAC をオススメします Argo CD の Dex との連携もできるよ!

Slide 37

Slide 37 text

CloudNative Days Tokyo 2021 | @makocchi 37 ここまでのまとめ

Slide 38

Slide 38 text

CloudNative Days Tokyo 2021 | @makocchi 38 Argo Workflows とは、ワークフローの処理をカスタムリソース で管理することができるオープンソースのソフトウェア Kubernetes に対して様々なインストール方式に対応している kubectl apply / Helm / Kustomize HA 構成も手軽に組むことができる UI が用意されており、ワークフローの把握がしやすい UI は様々な認証方式に対応している server 方式 / client 方式 / sso 方式 ここまでのまとめ

Slide 39

Slide 39 text

CloudNative Days Tokyo 2021 | @makocchi 39 ワークフローを 書いてみよう

Slide 40

Slide 40 text

CloudNative Days Tokyo 2021 | @makocchi 40 用語の説明 UI の見た目と操作 シンプルな例 Dag の紹介 パラメーターの渡し方 withItems を使った loop ワークフローの自動削除 簡単なスクリプトの実行 ワークフローから Kubernetes のリソースを作成する リトライ処理の仕方 Kind: Workflow の書き方 - 目次 - 失敗しても無視して進む方法 条件によって処理を分岐させる Exit-handler の使い方 ワークフローの途中で承認をしないと進まないようにしたい 外部にあるリソースを簡単に取ってくる バックグラウンドでずっと起動させる Pod を作成する volumeClameTemplate を使ったファイルのやりとり artifacts を使ったファイルのやりとり ワークフロー全体で使える変数を定義する ワークフローの同時実行数の制御 組み込み関数、sprig を使ったパラメーターの操作

Slide 41

Slide 41 text

CloudNative Days Tokyo 2021 | @makocchi 41 Kind: Workflow の書き方 # ͘͢͝γϯϓϧͳྫ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: Name: hello-world spec: entrypoint: main templates: - name: main steps: - - name: step1 template: whalesay - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: [“step1”] とりあえずシンプルな例だとこちらです

Slide 42

Slide 42 text

CloudNative Days Tokyo 2021 | @makocchi 42 Kind: Workflow の書き方 Argo Workflows では一つ一つの処理を 「template」という概念で管理します spec.entrypoint は必須になっていて、これは ワークフローがどの処理(template)から開始す るかを指定するものです ワークフローの流れは steps として記述しま す(dag でも記述することが可能です) 実際の処理の詳細は「name: whalesay」に記 述します(今回は steps の内部から参照する方 式で記述しています) # ͘͢͝γϯϓϧͳྫ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: Name: hello-world spec: entrypoint: main templates: - name: main steps: - - name: step1 template: whalesay - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: [“step1”]

Slide 43

Slide 43 text

CloudNative Days Tokyo 2021 | @makocchi 43 Kind: Workflow の書き方 先程のサンプルを UI で見るとこんな感じになります

Slide 44

Slide 44 text

CloudNative Days Tokyo 2021 | @makocchi 44 Kind: Workflow の書き方 こんな感じで Pod のログも見ることができます

Slide 45

Slide 45 text

CloudNative Days Tokyo 2021 | @makocchi 45 Kind: Workflow の書き方 steps の中身は基本的には上から書いた順に実 行されていきます 先程のシンプルな例に単純に step2 を追加す るとこうなります # ͘͢͝γϯϓϧͳྫ2 ... spec: entrypoint: main templates: - name: main steps: - - name: step1 template: whalesay - - name: step2 template: whalesay - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: [“step1”]

Slide 46

Slide 46 text

CloudNative Days Tokyo 2021 | @makocchi 46 Kind: Workflow の書き方 # ͘͢͝γϯϓϧͳྫ2 ... spec: entrypoint: main templates: - name: main steps: - - name: step1 template: whalesay - - name: step2 template: whalesay - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: [“step1”] steps の中身は基本的には上から書いた 順に実行されていきます 先程のシンプルな例に単純に step2 を 追加するとこうなります UI 的にはこんな感じになります

Slide 47

Slide 47 text

CloudNative Days Tokyo 2021 | @makocchi 47 ちなみに UI もいろいろオプションがあるよ デフォルトだと上から下に流れるように表示されますが、 左から右に流れるように表示することも可能です ここで切り替えられるよ!

Slide 48

Slide 48 text

CloudNative Days Tokyo 2021 | @makocchi 48 ちなみに UI もいろいろオプションがあるよ その2 大きさも変えられますよ! ここで拡大縮小できる

Slide 49

Slide 49 text

CloudNative Days Tokyo 2021 | @makocchi 49 さらに言うと・・・実はボタンを増やすことができます 外部にログ基盤とかあるのであれば Pod の Status(startedAt とか)を url に埋め込めるので、 リンクさせておくとか便利かもしれません

Slide 50

Slide 50 text

CloudNative Days Tokyo 2021 | @makocchi 50 Kind: Workflow の書き方 # inline ΋Մೳ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: Name: hello-world-inline spec: entrypoint: main templates: - name: main steps: - - name: step1 inline: container: image: docker/whalesay:latest command: [cowsay] args: ["inline"] step 内の処理を template 内に別途書くのは ちょっと違和感があるなぁという方は、inline でワークフローを書くこともできます 少し直感的になるかもしれませんが、step が 多いような場合に可読性が下がるかもしれませ ん

Slide 51

Slide 51 text

CloudNative Days Tokyo 2021 | @makocchi 51 Kind: Workflow の書き方 ハマりがちポイント steps を記述する際に気をつけるポイントとし て、「- -」という風に配列をネストさせる必要 があります! 「Failed to parse workflow: json: cannot unmarshal object into Go struct field Template.spec.templates.steps of type []map[string]interface {}」が出たら要確認! # ΄Μͱؒҧ͑΍͍͢ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: Name: hello-world spec: entrypoint: main templates: - name: main steps: - - name: step1 template: whalesay - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: [“step1”] - が 2 個必要!

Slide 52

Slide 52 text

CloudNative Days Tokyo 2021 | @makocchi 52 Kind: Workflow の書き方 なぜ map の配列が必要なのかというと、step で並列で動かしたい処理があった場合に対応す るためです 例えばこのように記述すると 2-1 と 2-2 は並 列で動きます # ฒྻॲཧΛهड़͢Δ͜ͱ΋Մೳ ... - name: main steps: - - name: step1 template: argosay - - name: step2-1 template: argosay - name: step2-2 template: argosay - - name: step3 template: argosay - name: argosay container: image: argoproj/argosay:v2

Slide 53

Slide 53 text

CloudNative Days Tokyo 2021 | @makocchi 53 Kind: Workflow の書き方 なぜ map の配列が必要なのかというと、step で並列で動かしたい処理があった場合に対応す るためです 例えばこのように記述すると 2-1 と 2-2 は並 列で動きます UI で見るとこのようになります # ฒྻॲཧΛهड़͢Δ͜ͱ΋Մೳ ... - name: main steps: - - name: step1 template: argosay - - name: step2-1 template: argosay - name: step2-2 template: argosay - - name: step3 template: argosay - name: argosay container: image: argoproj/argosay:v2

Slide 54

Slide 54 text

CloudNative Days Tokyo 2021 | @makocchi 54 Kind: Workflow の書き方 「- -」のせいで steps 書くの嫌いになった人 がいるとかいないとか・・・ そんな人には steps の代わりに dag を使うこ ともできます # ฒྻॲཧΛهड़͢Δ͜ͱ΋Մೳ ... - name: main dag: tasks: - name: step1 template: argosay - name: step2-1 depends: "step1" template: argosay - name: step2-2 depends: "step1" template: argosay - name: step3 depends: "step2-1 && step2-2" template: argosay steps の代わりに dag を記述する

Slide 55

Slide 55 text

CloudNative Days Tokyo 2021 | @makocchi 55 Kind: Workflow の書き方 「- -」のせいで steps 書くの嫌いになった人 がいるとかいないとか・・・ そんな人には steps の代わりに dag を使うこ ともできます dag を使う場合は depends を使って順番を制 御してあげる必要があります # ฒྻॲཧΛهड़͢Δ͜ͱ΋Մೳ ... - name: main dag: tasks: - name: step1 template: argosay - name: step2-1 depends: "step1" template: argosay - name: step2-2 depends: "step1" template: argosay - name: step3 depends: "step2-1 && step2-2" template: argosay depends を書こう

Slide 56

Slide 56 text

CloudNative Days Tokyo 2021 | @makocchi 56 Kind: Workflow の書き方 「- -」のせいで steps 書くの嫌いになった人 がいるとかいないとか・・・ そんな人には steps の代わりに dag を使うこ ともできます dag を使う場合は depends を使って順番を制 御してあげる必要があります 「いっけーなーい。dag なのに depends 書き 忘れちゃった😝てへっ」になるとこうなります # ฒྻॲཧΛهड़͢Δ͜ͱ΋Մೳ ... - name: main dag: tasks: - name: step1 template: argosay - name: step2-1 depends: "step1" template: argosay - name: step2-2 depends: "step1" template: argosay - name: step3 depends: "step2-1 && step2-2" template: argosay depends を書こう

Slide 57

Slide 57 text

CloudNative Days Tokyo 2021 | @makocchi 57 Kind: Workflow の書き方 同じような処理を parameter を変えて処理さ せたいと言ったケースが多いと思います その場合は各処理は parameter を受け取るこ とができるので、それを使います inline で記載していると parameter の恩恵は 受けにくいと思いますので、inline じゃない書 き方に慣れておくほうがいいかなと思います # parameter Ͱॊೈʹॲཧͤ͞Δ ... - name: main steps: - - name: step1 template: whalesay arguments: parameters: - name: message value: hoge - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay:latest command: [cowsay] args: ["{{inputs.parameters.message"]

Slide 58

Slide 58 text

CloudNative Days Tokyo 2021 | @makocchi 58 Kind: Workflow の書き方 parameters の定義は step 内で template を 呼び出す時に定義するのと、呼び出される template 側の両方で定義してあげる必要があ ります 呼び出す側は「arguments」として定義し、呼 び出される側は「inputs」で定義します # parameter Ͱॊೈʹॲཧͤ͞Δ ... - name: main steps: - - name: step1 template: whalesay arguments: parameters: - name: message value: hoge - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay:latest command: [cowsay] args: ["{{inputs.parameters.message"]

Slide 59

Slide 59 text

CloudNative Days Tokyo 2021 | @makocchi 59 Kind: Workflow の書き方 Inputs.parameters の定義はデフォルトの値を 設定することが可能です その場合は steps の arguments は省略するこ とができます ⏩ の例の場合は cndt2021 が args として展 開されます # parameter Ͱॊೈʹॲཧͤ͞Δ ... - name: main steps: - - name: step1 template: whalesay - name: whalesay inputs: parameters: - name: message value: cndt2021 container: image: docker/whalesay:latest command: [cowsay] args: ["{{inputs.parameters.message}}"] Value を設定すると デフォルト値になる

Slide 60

Slide 60 text

CloudNative Days Tokyo 2021 | @makocchi 60 Kind: Workflow の書き方 当然ですが、呼び出す時に arguments で定義 すればデフォルト値は上書きされて渡されます ちなみにデフォルト値が設定されていない場合 に arguments でパラメーターを渡さなかった 場合は「inputs.parameters.xxxx was not supplied」という形でワークフロー登録時にエ ラーになります # parameter Ͱॊೈʹॲཧͤ͞Δ ... - name: main steps: - - name: step1 template: whalesay arguments: parameters: - name: message value: hoge - name: whalesay inputs: parameters: - name: message value: cndt2021 container: image: docker/whalesay:latest command: [cowsay] args: ["{{inputs.parameters.message}}"] hoge で上書きされる

Slide 61

Slide 61 text

CloudNative Days Tokyo 2021 | @makocchi 61 Kind: Workflow の書き方 同じような処理を arguments だけ変えて繰り 返し実行したい!というケースもあると思いま す 例えば ⏩ のように処理したいケースです # parameter Ͱॊೈʹॲཧͤ͞Δ ... - name: main steps: - - name: step1 template: whalesay arguments: parameters: - name: message value: "1111" - name: step2 template: whalesay arguments: parameters: - name: message value: "2222" - name: step3 template: whalesay arguments: parameters: - name: message value: "3333"

Slide 62

Slide 62 text

CloudNative Days Tokyo 2021 | @makocchi 62 Kind: Workflow の書き方 同じような処理を arguments だけ変えて繰り 返し実行したい!というケースもあると思いま す 例えば ⏩ のように処理したいケースです そのような場合は withItems でまとめること ができます 注意点としてはあくまで同じ階層で複数回実行 されるので、並列で処理されることになります # parameter Ͱॊೈʹॲཧͤ͞Δ ... - name: main steps: - - name: step1 template: whalesay arguments: parameters: - name: message value: "1111" - name: step2 template: whalesay arguments: parameters: - name: message value: "2222" - name: step3 template: whalesay arguments: parameters: - name: message value: "3333" # withItems Ͱϧʔϓͤ͞Δ ... - name: main steps: - - name: step1 template: whalesay arguments: parameters: - name: message value: "{{item}}" withItems: - "1111" - "2222" - "3333"

Slide 63

Slide 63 text

CloudNative Days Tokyo 2021 | @makocchi 63 Kind: Workflow の書き方 処理が成功した(もしくは失敗した)ワークフ ローは自動で削除したいケースがあると思いま す その場合は ttlStrategy を使います ttlStrategy が無いと Completed な Pod で 溢れることになりますので、設定しておくこと をオススメします いちいち Workflow に書くの面倒くさいよ ねっていう場合はコントローラーで TTL のデ フォルト値を設定しておくことも可能です # ttlStrategy ͸ઃఆ͓ͯ͜͠͏ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: hello-world-til spec: ttlStrategy: secondsAfterCompletion: 10 secondsAfterSuccess: 5 secondsAfterFailure: 5 entrypoint: main ... workflow-controller が参照する ConfigMap で設定しておく

Slide 64

Slide 64 text

CloudNative Days Tokyo 2021 | @makocchi 64 Kind: Workflow の書き方 ttlStrategy の設定項目の説明 ワークフローは内部的にステータスとして Phase という状態を持っています その Phase によってそれぞれ TTL を設定でき ます secondsAfterSuccess : Phase が Succeeded secondsAfterFailure : Phase が Failed secondsAfterCompletion : これがちょっと 特殊で、ワークフローの Phase に関係なく各 処理の状態が Running じゃないもの # ttlStrategy ͸ઃఆ͓ͯ͜͠͏ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: hello-world-til spec: ttlStrategy: secondsAfterCompletion: 10 secondsAfterSuccess: 5 secondsAfterFailure: 5 entrypoint: main ... 自分もちょっと自身が無いんですが ワークフローは Phase として Succeeded と Failed 以外に Error もあるので Succeeded と Failed 以外の 状態のものと考えていいかもしれません

Slide 65

Slide 65 text

CloudNative Days Tokyo 2021 | @makocchi 65 Kind: Workflow の書き方 ちょっとしたスクリプトを実行したい場合もあ ると思います その場合は script を使うことができます sh だけじゃなくて python とかでも OK # script Ͱ sh Λ࣮ߦ͢Δ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: sh-script spec: entrypoint: main templates: - name: main steps: - - name: sh template: sh-script - name: sh-script script: image: alpine:latest command: [sh] source: | apk -q update && apk -q upgrade apk -q add figlet echo cndt2021 | figlet conatiner の代わり

Slide 66

Slide 66 text

CloudNative Days Tokyo 2021 | @makocchi 66 Kind: Workflow の書き方 ワークフローの処理中に Kubernetes のリソー スを作成したい! そんな場合も resource を使って定義すること が可能です serviceAccountName が無い場合は namespace 内の default の権限で実行される ことになるので、大抵の場合は失敗することに なります serviceAccountName は適切に設定することを オススメします # ࣌ʹ͸௚઀ૢ࡞΋ඞཁʹͳΔ͔΋ʁ ... - name: main steps: - - name: k8s-create-cm template: k8s-create-cm - - name: k8s-get-cm template: k8s-get-cm - name: k8s-create-cm serviceAccountName: workflow-sa resource: action: create manifest: | apiVersion: v1 kind: ConfigMap metadata: name: test-cm data: key: value - name: k8s-get-cm serviceAccountName: workflow-sa container: image: argoproj/argoexec:latest command: [sh, -c] args: ["kubectl get cm test-cm"]

Slide 67

Slide 67 text

CloudNative Days Tokyo 2021 | @makocchi 67 Kind: Workflow の書き方 ワークフローの処理中に Kubernetes のリソー スを作成したい! そんな場合も resource を使って定義すること が可能です serviceAccountName が無い場合は namespace 内の default の権限で実行される ことになるので、大抵の場合は失敗することに なります serviceAccountName は適切に設定することを オススメします # ࣌ʹ͸௚઀ૢ࡞΋ඞཁʹͳΔ͔΋ʁ ... - name: main steps: - - name: k8s-create-cm template: k8s-create-cm - - name: k8s-get-cm template: k8s-get-cm - name: k8s-create-cm serviceAccountName: workflow-sa resource: action: create manifest: | apiVersion: v1 kind: ConfigMap metadata: name: test-cm data: key: value - name: k8s-get-cm serviceAccountName: workflow-sa container: image: argoproj/argoexec:latest command: [sh, -c] args: ["kubectl get cm test-cm"]

Slide 68

Slide 68 text

CloudNative Days Tokyo 2021 | @makocchi 68 Kind: Workflow の書き方 処理が失敗した時に自動でリトライしたい! そんな場合は retryStrategy を設定します リトライ回数は limit で指定します あくまでリトライの回数なので、⏩ の例だと本 実行とリトライの合計で 6 回まで処理が実行さ れる可能性があります(最初の実行は 0 番目の リトライとして表示されるみたいです) # ϦτϥΠॲཧͰສ͕Ұͷ࣌΋҆৺ ... - name: main steps: - - name: fail-with-retry template: fail-with-retry - - name: step-after-success template: whalesay arguments: parameters: - name: message value: "Success!" - name: fail-with-retry retryStrategy: limit: "5" script: image: python:alpine3.6 command: ["python"] source: | import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code) ...

Slide 69

Slide 69 text

CloudNative Days Tokyo 2021 | @makocchi 69 Kind: Workflow の書き方 処理が失敗した時に自動でリトライしたい! そんな場合は retryStrategy を設定します リトライ回数は limit で指定します あくまでリトライの回数なので、⏩ の例だと本 実行とリトライの合計で 6 回まで処理が実行さ れる可能性があります # ϦτϥΠॲཧͰສ͕Ұͷ࣌΋҆৺ ... - name: main steps: - - name: fail-with-retry template: fail-with-retry - - name: step-after-success template: whalesay arguments: parameters: - name: message value: "Success!" - name: fail-with-retry retryStrategy: limit: "5" script: image: python:alpine3.6 command: ["python"] source: | import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code) ...

Slide 70

Slide 70 text

CloudNative Days Tokyo 2021 | @makocchi 70 Kind: Workflow の書き方 少し高度な retryStrategy リトライの間隔や時間の設定を backoff を 使って細かく設定することが可能です いわゆる exponential backoff を実現するこ とが可能です ⏩ の例だとリトライは 10秒待つ⇒20秒待つ ⇒40秒待つ・・となります(factor は何倍する か) maxDuration が 1m(60秒) なので、リトライ としては 2 回で終わることになります # ϦτϥΠॲཧΛ΍͘͢͞͠Δ ... - name: main steps: - - name: fail-with-retry template: fail-with-retry - - name: step-after-success template: whalesay arguments: parameters: - name: message value: "Success!" - name: fail-with-retry retryStrategy: limit: “5" backoff: duration: "10s" factor: "2" maxDuration: "1m" script: image: python:alpine3.6 command: ["python"] ...

Slide 71

Slide 71 text

CloudNative Days Tokyo 2021 | @makocchi 71 Kind: Workflow の書き方 いやいや処理が失敗したらリトライしないでフ ローを進めてほしい そんな場合は失敗を無視したい step に対して continueOn を設定します 失敗したフローがあったとしてもワークフロー 全体としては成功扱いになります # ΤϥʔΛແࢹ͢Δஉؾ step ͸ͪ͜ΒͰ͢ ... - name: main steps: - - name: continue-on-fail template: always-fail continueOn: failed: true - - name: step-after-fail template: whalesay arguments: parameters: - name: message value: "I'm fine!" - name: always-fail script: image: python:alpine3.6 command: ["python"] source: | import sys; sys.exit(1) ...

Slide 72

Slide 72 text

CloudNative Days Tokyo 2021 | @makocchi 72 Kind: Workflow の書き方 いやいや処理が失敗したらリトライしないでフ ローを進めてほしい そんな場合は失敗を無視したい step に対して continueOn を設定します 失敗したフローがあったとしてもワークフロー 全体としては成功扱いになります # ΤϥʔΛແࢹ͢Δஉؾ step ͸ͪ͜ΒͰ͢ ... - name: main steps: - - name: continue-on-fail template: always-fail continueOn: failed: true - - name: step-after-fail template: whalesay arguments: parameters: - name: message value: "I'm fine!" - name: always-fail script: image: python:alpine3.6 command: ["python"] source: | import sys; sys.exit(1) ...

Slide 73

Slide 73 text

CloudNative Days Tokyo 2021 | @makocchi 73 Kind: Workflow の書き方 直前の処理の結果によって処理を分岐させたい 条件付き実行は when を使うことで実現できま す 特定の処理のステータスは steps..status で取ることができます # ෳࡶͳॲཧΛ͢Δʹ͸ when ͸͔ܽͤͳ͍ ... - name: main steps: - - name: random-fail template: random-fail continueOn: failed: true - - name: after-succeeded-step when: "{{steps.random-fail.status}} == Succeeded" template: whalesay arguments: parameters: - name: message value: "Success!" - name: after-failed-step when: "{{steps.random-fail.status}} == Failed" template: whalesay arguments: parameters: - name: message value: "Fail!" ...

Slide 74

Slide 74 text

CloudNative Days Tokyo 2021 | @makocchi 74 Kind: Workflow の書き方 直前の処理の結果によって処理を分岐させたい 条件付き実行は when を使うことで実現できま す 特定の処理のステータスは steps..status で取ることができます # ෳࡶͳॲཧΛ͢Δʹ͸ when ͸͔ܽͤͳ͍ ... - name: main steps: - - name: random-fail template: random-fail continueOn: failed: true - - name: after-succeeded-step when: "{{steps.random-fail.status}} == Succeeded" template: whalesay arguments: parameters: - name: message value: "Success!" - name: after-failed-step when: "{{steps.random-fail.status}} == Failed" template: whalesay arguments: parameters: - name: message value: "Fail!" ...

Slide 75

Slide 75 text

CloudNative Days Tokyo 2021 | @makocchi 75 Kind: Workflow の書き方 処理の結果(ステータス)だけではなくて、 出力結果による分岐も同じような記述で可 能です 出力結果は steps..outputs.result で取得できます result を取得する場合は RBAC 的に pods/log が必要になります その為 serviceAccountName を設定しな いとエラーになることがありますので注意 して下さい # ෳࡶͳॲཧΛ͢Δʹ͸ when ͸͔ܽͤͳ͍ ... serviceAccountName: workflow-sa templates: - name: main steps: - - name: random-output template: random-output - - name: zero-step when: "{{steps.random-output.outputs.result}} == zero" template: whalesay arguments: parameters: - name: message value: "zero" - name: one-step when: "{{steps.random-output.outputs.result}} == one" template: whalesay arguments: parameters: - name: message value: "one" - name: random-output script: image: python:alpine3.6 command: ["python"] source: | import random; result = "zero" if random.randint(0,1) == 0 else "zero" print(result) ...

Slide 76

Slide 76 text

CloudNative Days Tokyo 2021 | @makocchi 76 Kind: Workflow の書き方 各処理ではなくて、ワークフロー全体として成 功したか失敗したかをハンドリングして特定の 処理をさせたい ワークフローには onExit を設定することで ワークフローが終了した時の処理を定義するこ とが可能です(exit-handler) この機能を使えば、例えばワークフローが失敗 した場合に Slack に通知する、なんてことも可 能です 本格的に運用する場合は必ず設定しておくとい いでしょう # େࣄͳϫʔΫϑϩʔʹ͸ඞͣ exit-handler Λઃఆ͠·͠ΐ͏ ... spec: entrypoint: main onExit: slack-post templates: - name: main steps: - - name: hello template: hello - name: hello container: image: alpine:latest command: [sh, -c] args: ["echo hello"] - name: slack-post container: image: curlimages/curl command: [sh, -c] args: ["curl -XPOST -d ‘payload={....}'"] ... ワークフローが終 わった時に呼ばれる

Slide 77

Slide 77 text

CloudNative Days Tokyo 2021 | @makocchi 77 Kind: Workflow の書き方 ワークフローが失敗した時だけ onExit で処理 させたい onExit の処理を記述する時に steps と when を使うことで実現できます 残念ながら steps の内部じゃないと when は 使えないのでこんな書き方になります もちろん onExit の処理の中でワークフローが 成功した時と失敗した時で処理を分岐させるこ とも可能です # େࣄͳϫʔΫϑϩʔʹ͸ඞͣ exit-handler Λઃఆ͠·͠ΐ͏ ... spec: entrypoint: main onExit: exit-handler templates: - name: main steps: - - name: hello template: hello - name: hello container: image: alpine:latest command: [sh, -c] args: ["echo hello"] - name: exit-handler steps: - - name: webhook when: "{{workflow.status}} != Succeeded" template: slack-post - name: slack-post container: image: curlimages/curl command: [sh, -c] args: ["curl -XPOST -d 'payload={....}'"]

Slide 78

Slide 78 text

CloudNative Days Tokyo 2021 | @makocchi 78 Kind: Workflow の書き方 処理の途中で一旦止めて、確認が済んだら続き を開始したい steps の中に suspend を入れることで実現で きます 「Suspend: {}」とすることで無限 sleep 状態 処理を再開させるには UI では RESUME をク リックします コマンドラインで再開させるには「argo resume <ワークフロー名>」を実行します # approve ॲཧΛೖΕΔ ... - name: main steps: - - name: hello template: whalesay - - name: need-approve template: need-approve - - name: after-approve template: whalesay - name: need-approve suspend: {} - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world”] ...

Slide 79

Slide 79 text

CloudNative Days Tokyo 2021 | @makocchi # approve ॲཧΛೖΕΔ ... - name: main steps: - - name: hello template: whalesay - - name: need-approve template: need-approve - - name: after-approve template: whalesay - name: need-approve suspend: {} - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world”] ... 79 Kind: Workflow の書き方 処理の途中で一旦止めて、確認が済んだら続き を開始したい steps の中に suspend を入れることで実現で きます 処理を再開させるには UI では RESUME をク リックします コマンドラインで再開させるには「argo resume <ワークフロー名>」を実行します RESUME

Slide 80

Slide 80 text

CloudNative Days Tokyo 2021 | @makocchi 80 Kind: Workflow の書き方 処理の途中で一旦止めるんだけど一定時間経っ たら自動で進めたい、もしくは明示的に間隔を 空けたい場合は suspend で duration を設定 します もちろん duration の時間が過ぎる前に RESUME で進めることも可能です # Ұఆ࣌ؒܦͬͨΒࣗಈͰ approve ͯ͠ਐΉ ... - name: main steps: - - name: hello template: whalesay - - name: 1min-sleep template: 1min-sleep - - name: after-approve template: whalesay - name: 1min-sleep suspend: duration: 1m - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world”] ...

Slide 81

Slide 81 text

CloudNative Days Tokyo 2021 | @makocchi 81 Kind: Workflow の書き方 GitHub や S3 からアプリケーションのソース を入手して処理させたい inputs.artifacts を使うことで簡単にコンテナ 内部にソースを持ってくることができます 「git」の他に「s3」や「http」があります http は例えば GitHub のリリースからバイナ リを落としてきて配置する、みたいな時に便利 です # git ͔Β clone ͢Δͷ΋ָͪΜ ... - name: main steps: - - name: git-clone template: git-clone - name: git-clone inputs: artifacts: - name: argo-source path: /src git: repo: https://github.com/argoproj/argo-workflows.git revision: "master" container: image: alpine:latest command: [sh, -c] args: ["ls -l /src”] ...

Slide 82

Slide 82 text

CloudNative Days Tokyo 2021 | @makocchi 82 Kind: Workflow の書き方 GitHub や S3 からアプリケーションのソース を入手して処理させたい inputs.artifacts を使うことで簡単にコンテナ 内部にソースを持ってくることができます 「git」の他に「s3」や「http」があります http は例えば GitHub のリリースからバイナ リを落としてきて配置する、みたいな時に便利 です # git ͔Β clone ͢Δͷ΋ָͪΜ ... - name: main steps: - - name: git-clone template: git-clone - name: git-clone inputs: artifacts: - name: argo-source path: /src git: repo: https://github.com/argoproj/argo-workflows.git revision: "master" container: image: alpine:latest command: [sh, -c] args: ["ls -l /src”] ...

Slide 83

Slide 83 text

CloudNative Days Tokyo 2021 | @makocchi 83 Kind: Workflow の書き方 ちなみに http を使った例はこんな感じになります # ϦϞʔτʹ͋ΔόΠφϦΛ഑ஔ͢Δͷ΋ָͪΜ ... - name: main steps: - - name: place-kubectl template: place-kubectl - name: place-kubectl inputs: artifacts: - name: kubectl path: /usr/local/bin/kubectl mode: 0755 http: url: https://storage.googleapis.com/kubernetes-release/release/v1.22.2/bin/linux/amd64/kubectl container: image: alpine:latest command: [sh, -c] args: ["/usr/local/bin/kubectl version --client”] ...

Slide 84

Slide 84 text

CloudNative Days Tokyo 2021 | @makocchi 84 Kind: Workflow の書き方 ちなみに http を使った例はこんな感じになります # ϦϞʔτʹ͋ΔόΠφϦΛ഑ஔ͢Δͷ΋ָͪΜ ... - name: main steps: - - name: place-kubectl template: place-kubectl - name: place-kubectl inputs: artifacts: - name: kubectl path: /usr/local/bin/kubectl mode: 0755 http: url: https://storage.googleapis.com/kubernetes-release/release/v1.22.2/bin/linux/amd64/kubectl container: image: alpine:latest command: [sh, -c] args: ["/usr/local/bin/kubectl version --client”] ...

Slide 85

Slide 85 text

CloudNative Days Tokyo 2021 | @makocchi 85 Kind: Workflow の書き方 バックグラウンドでずっとアプリケーションを 起動させておいて、各処理からアクセスさせた い そんな時は daemon を true にすることで ワークフローが処理されている間ずっと動かし 続けることができます ⏩ の例は Nginx ですが、データベースを起動 させておいて各種テストを走らせる、とかの用 途にも適していると思います # daemon Ͱىಈͬ͠ͺͳ͠Λ࣮ݱ ... - name: main steps: - - name: nginx-server template: nginx-server - - name: nginx-client template: nginx-client arguments: parameters: - name: server-ip value: "{{steps.nginx-server.ip}}" - name: nginx-server daemon: true container: image: nginx:1.21 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 2 timeoutSeconds: 1 ...

Slide 86

Slide 86 text

CloudNative Days Tokyo 2021 | @makocchi 86 Kind: Workflow の書き方 生成したファイルを次の処理に渡したい 処理間でファイルのやりとりをする方法はいく つか考えられます result で渡していく (ただしバイナリの時に 使うことができない) ボリュームを作成して各処理で mount して 使い回す artifact を使う

Slide 87

Slide 87 text

CloudNative Days Tokyo 2021 | @makocchi 87 Kind: Workflow の書き方 生成したファイルを次の処理に渡したい 処理間でファイルのやりとりをする方法はいく つか考えられます result で渡していく (ただしバイナリの時に 使うことができない) ボリュームを作成して各処理で mount して 使い回す artifact を使う # volumeClaimTemplates Ͱ volume Λ࡞Δ ... spec: entrypoint: main volumeClaimTemplates: - metadata: name: workdir spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi templates: - name: main steps: ... volume を定義する

Slide 88

Slide 88 text

CloudNative Days Tokyo 2021 | @makocchi 88 Kind: Workflow の書き方 生成したファイルを次の処理に渡したい 処理間でファイルのやりとりをする方法はいく つか考えられます result で渡していく (ただしバイナリの時に 使うことができない) ボリュームを作成して各処理で mount して 使い回す artifact を使う # volumeClaimTemplates Ͱ volume Λ࡞Δ ... spec: entrypoint: main volumeClaimTemplates: - metadata: name: workdir spec: accessModes: ["ReadWriteOnce"] resources: requests: storage: 1Gi templates: - name: main steps: ... # ͋ͱ͸࡞ΒΕͨ volume Λ mount ͯ͠࢖͏͚ͩʂ ... - name: main steps: - - name: generate template: whalesay - - name: print template: print-message - name: whalesay container: image: docker/whalesay:latest command: [sh, -c] args: ["cowsay hello | tee /mnt/vol/hello_world.txt"] volumeMounts: - name: workdir mountPath: /mnt/vol - name: print-message container: image: alpine:latest command: [sh, -c] args: ["cat /mnt/vol/hello_world.txt"] volumeMounts: - name: workdir mountPath: /mnt/vol ... 各処理で mount Claim された volume は ワークフローを消すと消える

Slide 89

Slide 89 text

CloudNative Days Tokyo 2021 | @makocchi 89 Kind: Workflow の書き方 生成したファイルを次の処理に渡したい 処理間でファイルのやりとりをする方法はいく つか考えられます result で渡していく (ただしバイナリの時に 使うことができない) ボリュームを作成して各処理で mount して 使い回す artifact を使う s3 互換のオブジェクトストレージを使う ことができます # artifact Λ configMap Ͱઃఆ͢Δ apiVersion: v1 kind: ConfigMap metadata: name: artifact-repositories data: minio-artifact: | s3: bucket: my-bucket endpoint: argo-artifacts:9000 insecure: true accessKeySecret: name: argo-artifacts key: accesskey secretKeySecret: name: argo-artifacts key: secretkey 例としてクラスター内の minio を使ってみます

Slide 90

Slide 90 text

CloudNative Days Tokyo 2021 | @makocchi 90 Kind: Workflow の書き方 生成したファイルを次の処理に渡したい 処理間でファイルのやりとりをする方法はいく つか考えられます result で渡していく (ただしバイナリの時に 使うことができない) ボリュームを作成して各処理で mount して 使い回す artifact を使う s3 互換のオブジェクトストレージを使う ことができます # artifact Λઃఆ͢Δ apiVersion: v1 kind: ConfigMap metadata: name: artifact-repositories data: default-v1: | s3: bucket: my-bucket endpoint: argo-artifacts:9000 insecure: true accessKeySecret: name: argo-artifacts key: accesskey secretKeySecret: name: argo-artifacts key: secretkey # ઌఔઃఆͨ͠ configMap Λࢀরͤ͞Δ ... spec: artifactRepositoryRef: configMap: artifact-repositories key: minio-artifact entrypoint: main templates: - name: main ...

Slide 91

Slide 91 text

CloudNative Days Tokyo 2021 | @makocchi 91 Kind: Workflow の書き方 生成したファイルを次の処理に渡したい 処理間でファイルのやりとりをする方法はいく つか考えられます result で渡していく (ただしバイナリの時に 使うことができない) ボリュームを作成して各処理で mount して 使い回す artifact を使う s3 互換のオブジェクトストレージを使う ことができます # artifact Λઃఆ͢Δ apiVersion: v1 kind: ConfigMap metadata: name: artifact-repositories data: default-v1: | s3: bucket: my-bucket endpoint: argo-artifacts:9000 insecure: true accessKeySecret: name: argo-artifacts key: accesskey secretKeySecret: name: argo-artifacts key: secretkey # ͋ͱ͸ step ͷॲཧʹ artifacts Λઃఆ͢Δ͜ͱͰ࢖͏͜ͱ͕Ͱ͖Δ ... - name: main steps: - - name: generate-artifact template: whalesay - - name: consume-artifact template: print-message arguments: artifacts: - name: message from: “{{steps.generate-artifact.outputs.artifacts.hello-art}}" - name: whalesay serviceAccountName: workflow-sa container: image: docker/whalesay command: [sh, -c] args: ["sleep 1; cowsay hello world | tee /tmp/hello_world.txt"] outputs: artifacts: - name: hello-art path: /tmp/hello_world.txt - name: print-message serviceAccountName: workflow-sa container: image: alpine:latest command: [sh, -c] args: ["cat /tmp/message"] inputs: artifacts: - name: message path: /tmp/message ...

Slide 92

Slide 92 text

CloudNative Days Tokyo 2021 | @makocchi # ͋ͱ͸ step ͷॲཧʹ artifacts Λઃఆ͢Δ͜ͱͰ࢖͏͜ͱ͕Ͱ͖Δ ... - name: main steps: - - name: generate-artifact template: whalesay - - name: consume-artifact template: print-message arguments: artifacts: - name: message from: “{{steps.generate-artifact.outputs.artifacts.hello-art}}" - name: whalesay serviceAccountName: workflow-sa container: image: docker/whalesay command: [sh, -c] args: ["sleep 1; cowsay hello world | tee /tmp/hello_world.txt"] outputs: artifacts: - name: hello-art path: /tmp/hello_world.txt - name: print-message serviceAccountName: workflow-sa container: image: alpine:latest command: [sh, -c] args: ["cat /tmp/message"] inputs: artifacts: - name: message path: /tmp/message ... 92 Kind: Workflow の書き方 生成したファイルを次の処理に渡したい 処理間でファイルのやりとりをする方法はいく つか考えられます result で渡していく (ただしバイナリの時に 使うことができない) ボリュームを作成して各処理で mount して 使い回す artifact を使う s3 互換のオブジェクトストレージを使う ことができます minio の中に格納されてる

Slide 93

Slide 93 text

CloudNative Days Tokyo 2021 | @makocchi 93 Kind: Workflow の書き方 ワークフロー全体で使える変数を定義したい ワークフローのパラメーターを使うことで実現 することができます パラメーターの設定の仕方はいくつかあります ベタ書きで定義する(オーバーライド可) configMap から参照して定義する ワークフローのラベルから定義する

Slide 94

Slide 94 text

CloudNative Days Tokyo 2021 | @makocchi 94 Kind: Workflow の書き方 ワークフロー全体で使える変数を定義したい ワークフローのパラメーターを使うことで実現 することができます パラメーターの設定の仕方はいくつかあります ベタ書きで定義する(オーバーライド可) configMap から参照して定義する ワークフローのラベルから定義する # άϩʔόϧม਺ͷఆٛͷ࢓ํ ... spec: entrypoint: main arguments: parameters: - name: message value: “hello world” templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["{{workflow.parameters.message}}"] argo submit する時に 「--parameter message=hoge」 とすることで上書き可能

Slide 95

Slide 95 text

CloudNative Days Tokyo 2021 | @makocchi 95 Kind: Workflow の書き方 ワークフロー全体で使える変数を定義したい ワークフローのパラメーターを使うことで実現 することができます パラメーターの設定の仕方はいくつかあります ベタ書きで定義する(オーバーライド可) configMap から参照して定義する ワークフローのラベルから定義する # άϩʔόϧม਺ͷఆٛͷ࢓ํ ... spec: entrypoint: main arguments: parameters: - name: message valueFrom: configMapKeyRef: name: simple-parameters key: msg templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["{{workflow.parameters.message}}"]

Slide 96

Slide 96 text

CloudNative Days Tokyo 2021 | @makocchi # άϩʔόϧม਺ͷఆٛͷ࢓ํ ... spec: entrypoint: main arguments: parameters: - name: message valueFrom: configMapKeyRef: name: simple-parameters key: msg templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["{{workflow.parameters.message}}"] 96 Kind: Workflow の書き方 ワークフロー全体で使える変数を定義したい ワークフローのパラメーターを使うことで実現 することができます パラメーターの設定の仕方はいくつかあります ベタ書きで定義する(オーバーライド可) configMap から参照して定義する ワークフローのラベルから定義する # configMap ଆͷઃఆ apiVersion: v1 kind: ConfigMap metadata: labels: workflows.argoproj.io/configmap-type: Parameter data: msg: from-configmap この configmap-type の ラベルが無いと コントローラーが認識してくれない 必須

Slide 97

Slide 97 text

CloudNative Days Tokyo 2021 | @makocchi 97 Kind: Workflow の書き方 ワークフロー全体で使える変数を定義したい ワークフローのパラメーターを使うことで実現 することができます パラメーターの設定の仕方はいくつかあります ベタ書きで定義する(オーバーライド可) configMap から参照して定義する ワークフローのラベルから定義する # labels Λ௚઀ࢀর͢Δύλʔϯ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: global-parameters3 labels: message-from-labels: hoge spec: entrypoint: main templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["{{workflow.labels.message-from-labels}}"] argo submit する時に 「--labels message-from-labels=foo」 とすることで上書き可能

Slide 98

Slide 98 text

CloudNative Days Tokyo 2021 | @makocchi 98 Kind: Workflow の書き方 ワークフローの同時実行数を制御して同時に動 かないようにしたい ワークフローが同時に実行されてしまうと不都 合な場合ってありますよね その場合には同時実行数を制御しておくとより 安全に運用できます 制御するには synchronization を使い、方式 は 2 つあります semaphore による制御 mutex による制御

Slide 99

Slide 99 text

CloudNative Days Tokyo 2021 | @makocchi 99 Kind: Workflow の書き方 ワークフローの同時実行数を制御して同時に動 かないようにしたい ワークフローが同時に実行されてしまうと不都 合な場合ってありますよね その場合には同時実行数を制御しておくとより 安全に運用できます 制御するには synchronization を使い、方式 は 2 つあります semaphore による制御 mutex による制御 # ಉ࣮࣌ߦ੍ޚ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: synchronization-wf-level spec: entrypoint: main synchronization: semaphore: configMapKeyRef: name: my-semaphore key: workflow templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world”] semaphore の場合は configMap を指定する

Slide 100

Slide 100 text

CloudNative Days Tokyo 2021 | @makocchi 100 Kind: Workflow の書き方 ワークフローの同時実行数を制御して同時に動 かないようにしたい ワークフローが同時に実行されてしまうと不都 合な場合ってありますよね その場合には同時実行数を制御しておくとより 安全に運用できます 制御するには synchronization を使い、方式 は 2 つあります semaphore による制御 mutex による制御 # ಉ࣮࣌ߦ੍ޚ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: synchronization-wf-level spec: entrypoint: main synchronization: semaphore: configMapKeyRef: name: my-semaphore key: workflow templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world”] # semaphore ༻ͷ configMap apiVersion: v1 kind: ConfigMap metadata: name: my-semaphore data: workflow: "1" この場合は同時 1 まで

Slide 101

Slide 101 text

CloudNative Days Tokyo 2021 | @makocchi 101 Kind: Workflow の書き方 ワークフローの同時実行数を制御して同時に動 かないようにしたい ワークフローが同時に実行されてしまうと不都 合な場合ってありますよね その場合には同時実行数を制御しておくとより 安全に運用できます 制御するには synchronization を使い、方式 は 2 つあります semaphore による制御 mutex による制御 # ಉ࣮࣌ߦ੍ޚ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: synchronization-wf-level spec: entrypoint: main synchronization: semaphore: configMapKeyRef: name: my-semaphore key: workflow templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world”] # semaphore ༻ͷ configMap apiVersion: v1 kind: ConfigMap metadata: name: my-semaphore data: workflow: "1" 1 つ実行中なので Waiting になってる

Slide 102

Slide 102 text

CloudNative Days Tokyo 2021 | @makocchi 102 Kind: Workflow の書き方 ワークフローの同時実行数を制御して同時に動 かないようにしたい ワークフローが同時に実行されてしまうと不都 合な場合ってありますよね その場合には同時実行数を制御しておくとより 安全に運用できます 制御するには synchronization を使い、方式 は 2 つあります semaphore による制御 mutex による制御 # ಉ࣮࣌ߦ੍ޚ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: synchronization-wf-level spec: entrypoint: main synchronization: mutex: name: my-mutex templates: - name: main steps: - - name: whalesay template: whalesay - name: whalesay container: image: docker/whalesay command: [cowsay] args: ["hello world”]

Slide 103

Slide 103 text

CloudNative Days Tokyo 2021 | @makocchi 103 Kind: Workflow の書き方 semaphore と mutex どっちがいいのか semaphore の場合は configMap で柔軟に同 時実行数を設定可能 mutex の場合は同時に 1 しか制御できない mutex は workflow-controller のメモリ上 で管理されているので、1 つのワークフロー が実行中に workflow-controller が再起動 した場合は pending になっているワークフ ローが同時に実行されてしまうリスクがあり ます # Ͳ͕͍͍ͬͪͷ͔ʁ ... synchronization: mutex: name: my-mutex ... synchronization: semaphore: configMapKeyRef: name: my-semaphore key: workflow ... 個人的には・・ semaphore かなぁ

Slide 104

Slide 104 text

CloudNative Days Tokyo 2021 | @makocchi 104 Kind: Workflow の書き方 渡されたパラメーターを加工したい、json から特定の key の value を取り出したい等あると思います その時は組み込みの関数や sprig を使って加工・抽出が可能です 組み込みの関数を使う場合は {{ の部分を {{= にする必要があります 全ての箇所で対応しているわけではないので注意が必要 ؔ਺ આ໌ asInt จࣈྻΛ Int ʹม׵͢Δ asFloat จࣈྻΛ Float ʹม׵͢Δ string Int/Float Λจࣈྻʹม׵͢Δ jsonpath Json ͔ΒΤϨϝϯτΛநग़͢Δ sprig Λ࢖ͬͨهड़ http://masterminds.github.io/sprig/

Slide 105

Slide 105 text

CloudNative Days Tokyo 2021 | @makocchi 105 Kind: Workflow の書き方 例えば asInt を使うとこんな感じに書くことが できます parameter で渡されるのは全て文字列扱いにな るので、int に変換しないと計算できません # ྫ(asInt) # parameter Λ 10 ഒͯ͠౉͢ ... templates: - name: main steps: - - name: multiple template: whalesay arguments: parameters: - name: foo value: "1" - name: whalesay inputs: parameters: - name: foo container: image: docker/whalesay:latest command: [cowsay] args: ["{{=asInt(inputs.parameters.foo) * 10}}"

Slide 106

Slide 106 text

CloudNative Days Tokyo 2021 | @makocchi 106 Kind: Workflow の書き方 jsonpath を使うと json の扱いが楽になります # ྫ(jsonpath) ... spec: entrypoint: main arguments: parameters: - name: config value: '{"key": “abcdef"}' templates: - name: main steps: - - name: jsonpath template: whalesay arguments: parameters: - name: foo value: "{{=jsonpath(workflow.parameters.config, '$.key')}}" ... パラメーターとして 抽出された abcdef が渡される

Slide 107

Slide 107 text

CloudNative Days Tokyo 2021 | @makocchi 107 Kind: Workflow の書き方 sprig は更にいろいろ柔軟に加工できます # ྫ(sprig) ... spec: entrypoint: main arguments: parameters: - name: config value: '{"key": “dmFsdWU="}' templates: - name: main steps: - - name: jsonpath template: whalesay arguments: parameters: - name: foo value: "{{=sprig.upper(sprig.b64dec(jsonpath(workflow.parameters.config, ‘$.key')))}}" ... Base64 でデコードして さらに大文字にしちゃう例

Slide 108

Slide 108 text

CloudNative Days Tokyo 2021 | @makocchi 108 Kind: Workflow の書き方 sprig は記述が長くなりがちなのでこんな感じで書いても大丈夫です # ྫ(sprig) ... - name: main steps: - - name: jsonpath template: whalesay arguments: parameters: - name: foo value: >- {{= sprig.upper( sprig.b64dec( jsonpath(workflow.parameters.config, '$.key') ) ) }} ... 縦に長くなっちゃいますが 分かりやすいかもですね

Slide 109

Slide 109 text

CloudNative Days Tokyo 2021 | @makocchi 109 Kind: Workflow の書き方 他にも色々できます ちなみに sprig の記述をミスると value にはそのままの文字列({{=...}})が渡ってしまいますので気 を付けて下さい(特にエラーになるわけではない) # ྫ(sprig) # ϥϯμϜͳจࣈྻɾ਺ࣈΛੜ੒͢Δ (Ҿ਺͸จࣈ਺) value: “{{=sprig.randAscii(10)}}" # => @‘yCH_Lbs value: “{{=sprig.randAlpha(10)}}" # => XnNXvYqZea value: “{{=sprig.randNumeric(10)}}" # => 6909735364 value: “{{=sprig.randAlphaNum(10)}}" # => tCZDhEXb1c # ࣌ࠁͷૢ࡞ value: "{{=sprig.dateModify('-3h', sprig.now())}}” # => 3 ࣌ؒલ # Trim value: "{{=sprig.trim(' hoge ‘)}}" # => ‘hoge’ value: "{{=sprig.trimSuffix('.txt', ‘hoge.txt')}}" # => ‘hoge’ value: “{{=sprig.trimPrefix('my-', ‘my-hoge.txt’)}}” # => ‘hoge.txt’

Slide 110

Slide 110 text

CloudNative Days Tokyo 2021 | @makocchi 110 ワークフローのテンプレートを使って 効率よく管理しよう

Slide 111

Slide 111 text

CloudNative Days Tokyo 2021 | @makocchi 111 ワークフローのテンプレートを使おう ワークフローテンプレートを定義することで、定義を再利用して使うことが可能です (Steps 内で使う template の定義ではなくて、ワークフロー自体をテンプレート化する) カスタムリソースとして「kind: WorkflowTemplate」を使って定義します spec の内容は「kind: Workflow」と同じなので kind をリネームするだけでテンプレート化が完 了します ワークフロー側からテンプレートを呼び出す時には templateRef でテンプレートを指定します ちなみに WorkflowTemplate は argo submit できない(無視される)・・・ので kubectl で作 る必要があります

Slide 112

Slide 112 text

CloudNative Days Tokyo 2021 | @makocchi 112 こんなワークフローの場合 # ΋ͱͷఆٛ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: whalesay-original spec: entrypoint: main templates: - name: main steps: - - name: whalesay template: whalesay arguments: parameters: - name: message value: hoge - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay command: [cowsay] args: ["{{inputs.parameters.message}}"] ワークフローのテンプレートを使おう

Slide 113

Slide 113 text

CloudNative Days Tokyo 2021 | @makocchi 113 こんなワークフローの場合こうなる # ΋ͱͷఆٛ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: whalesay-original spec: entrypoint: main templates: - name: main steps: - - name: whalesay template: whalesay arguments: parameters: - name: message value: hoge - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay command: [cowsay] args: ["{{inputs.parameters.message}}"] # ςϯϓϨʔτݺͼग़͠ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: hello-world-from-template spec: workflowTemplateRef: name: whalesay-template # ςϯϓϨʔτԽ apiVersion: argoproj.io/v1alpha1 kind: WorkflowTemplate metadata: name: whalesay-template spec: entrypoint: main templates: - name: main steps: - - name: whalesay template: whalesay arguments: parameters: - name: message value: hoge - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay command: [cowsay] args: ["{{inputs.parameters.message}}"] ワークフローの定義は シンプルになる ワークフローのテンプレートを使おう

Slide 114

Slide 114 text

CloudNative Days Tokyo 2021 | @makocchi 114 いったいテンプレート化に旨味はあるのでしょうか? 同じような処理をパラメーターだけ変えて処理させたい場合にはとても有効です またテンプレートは CronWorkflow からも参照することができます CronWorkflow を手動でも実行できるように Workflow としても定義しておきたい、なんて場合 には同じテンプレートを参照するだけなので楽に実現できる WorkflowTemplate は namespaced なリソースですが、WorkflowTemplate と同じものとして ClusterWorkflowTemplate も同じ使い方で使うことができます workflowTemplateRef をする時に「clusterScope: true」を設定するだけで使えます ClusterWorkflowTemplate を定義することで、namespace をまたいでテンプレートを使い回すこ とが可能になります ワークフローのテンプレートを使おう

Slide 115

Slide 115 text

CloudNative Days Tokyo 2021 | @makocchi 115 こんなイメージ WorkflowTemplate A Workflow A namespace foo Parameter: A Workflow A’ Workflow A’’ Parameter: B Parameter: C CronWorkflow A Parameter: A ワークフローのテンプレートを使おう

Slide 116

Slide 116 text

CloudNative Days Tokyo 2021 | @makocchi 116 こんなイメージ ClusterWorkflowTemplate A Workflow A namespace foo Parameter: A Workflow A’ namespace bar Parameter: B Workflow A’’ namespace buz Param eter: C namespace をまたいで 使うことが可能 ワークフローのテンプレートを使おう

Slide 117

Slide 117 text

CloudNative Days Tokyo 2021 | @makocchi 117 いやいやいや この部分だけテンプレート 化したいよ そしたらワークフローでは処理の依存関係 を、テンプレートでは処理内容という風に 分離して管理できるでしょ? # ॲཧ಺༰͚ͩςϯϓϨʔτԽ͍ͤͨ͞ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: whalesay-original spec: entrypoint: main templates: - name: main steps: - - name: whalesay template: whalesay arguments: parameters: - name: message value: hoge - name: whalesay inputs: parameters: - name: message container: image: docker/whalesay command: [cowsay] args: ["{{inputs.parameters.message}}"] ここだけ抜き出したい! ワークフローのテンプレートを使おう

Slide 118

Slide 118 text

CloudNative Days Tokyo 2021 | @makocchi 118 もちろんできます! steps 内からも templateRef で指定可能 です 呼び出すテンプレートは name で指定し ます name で指定したテンプレート内のどの template を使うのかを template で指定 します もちろん 「clusterScope: true」 も設定 可能 # ॲཧ಺༰͚ͩςϯϓϨʔτԽ͍ͤͨ͞ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: whalesay-original spec: entrypoint: main templates: - name: main steps: - - name: whalesay templateRef: name: whalesay-step-template template: whalesay arguments: parameters: - name: message value: hoge ワークフローのテンプレートを使おう 実際のテンプレート名は どっちに書いたら良いんだ問題 ちょっと分かりにくい

Slide 119

Slide 119 text

CloudNative Days Tokyo 2021 | @makocchi 119 もちろんできます! steps 内からも templateRef で指定可能 です 呼び出すテンプレートは name で指定し ます name で指定したテンプレート内のどの template を使うのかを template で指定 します もちろん 「clusterScope: true」 も設定 可能 # ॲཧ಺༰͚ͩςϯϓϨʔτԽ͍ͤͨ͞ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: name: whalesay-original spec: entrypoint: main templates: - name: main steps: - - name: whalesay templateRef: name: whalesay-step-template template: whalesay arguments: parameters: - name: message value: hoge ワークフローのテンプレートを使おう 実際のテンプレート名は どっちに書いたら良いんだ問題 ちょっと分かりにくい # ͜͏͍͏͜ͱ apiVersion: argoproj.io/v1alpha1 kind: WorkflowTemplate metadata: name: whalesay-step-template spec: templates: - name: whalesay inputs: parameters: - name: message value: hogehoge container: image: docker/whalesay command: [cowsay] args: ["{{inputs.parameters.message}}"]

Slide 120

Slide 120 text

CloudNative Days Tokyo 2021 | @makocchi 120 より柔軟に管理できるようになりますね! WorkflowTemplate A Workflow A namespace foo Parameter: A ワークフローのテンプレートを使おう ClusterWorkflowTemplate A ClusterWorkflowTemplate B よく使うような処理、例えば onExit で使う 「ワークフローの結果を slack に通知する」 を ClusterWorkflowTemplate にしておけば いろいろなワークフローに仕込むのが簡単になります

Slide 121

Slide 121 text

CloudNative Days Tokyo 2021 | @makocchi 121 ワークフローを 定期実行したい

Slide 122

Slide 122 text

CloudNative Days Tokyo 2021 | @makocchi 122 定期的に実行させたい(Cron)場合は CronWorkflowTemplate で定義すること ができます workflowSpec に処理内容を書きます Kubernetes の batch/v1 Cronjob の定 義でできるような項目(concurrentPolicy や startingDeadlineSeconds など)は同じ ように設定可能 # Cronͷఆٛ apiVersion: argoproj.io/v1alpha1 kind: CronWorkflow metadata: name: hello-world spec: schedule: "* * * * *" timezone: "Asia/Tokyo" startingDeadlineSeconds: 0 concurrencyPolicy: “Forbid" successfulJobsHistoryLimit: 4 failedJobsHistoryLimit: 4 suspend: false workflowSpec: entrypoint: whalesay templates: - name: whalesay container: image: docker/whalesay:latest command: [cowsay] args: ["Scheduled on: {{workflow.scheduledTime}}"] ワークフローの定期実行

Slide 123

Slide 123 text

CloudNative Days Tokyo 2021 | @makocchi 123 Cron の手動実行は「argo submit --from cronwf/」可能です debug 処理を仕込んでおいて、「argo submit --from cronwf/mycron -- parameter debug=true」みたいにする といいかもしれません もちろん workflowSpec ではテンプレー トを呼び出すこともできます 既存の cronjob を移行してみてはいかが でしょうか # Cronͷఆٛ apiVersion: argoproj.io/v1alpha1 kind: CronWorkflow metadata: name: hello-world spec: schedule: "* * * * *" timezone: "Asia/Tokyo" startingDeadlineSeconds: 0 concurrencyPolicy: “Forbid" successfulJobsHistoryLimit: 4 failedJobsHistoryLimit: 4 suspend: false workflowSpec: entrypoint: whalesay workflowTemplateRef: name: whalesay-template arguments: parameters: - name: message value: hogehoge ワークフローの定期実行

Slide 124

Slide 124 text

CloudNative Days Tokyo 2021 | @makocchi 124 イベントを検知して ワークフローを実行させたい

Slide 125

Slide 125 text

CloudNative Days Tokyo 2021 | @makocchi 125 イベントをきっかけにワークフローを実行させることができれば、いろいろなシステムとの連携が用 意になります ワークフローからワークフローへ連携させるようなことも可能になります やりかたはいろいろあると思いますが、ここでは下記の 2 つの方法を紹介します イベントを検知してワークフローを実行させたい Argo Events WorkflowEventBinding

Slide 126

Slide 126 text

CloudNative Days Tokyo 2021 | @makocchi 126 WorkflowEventBinding は Argo Workflows の中 に組み込まれている Webhook の仕組みです API のエンドポイントに対し、「argo auth token」の token (もしくはサービスアカウントの token)を使って POST することで特定のテンプ レートを実行させることが可能になります ちなみに WorkflowEventBinding は定義すると UI からも確認できます イベントを検知してワークフローを実行させたい (WorkflowEventBinding)

Slide 127

Slide 127 text

CloudNative Days Tokyo 2021 | @makocchi 127 定義はこんな感じです discriminator はエンドポイント の識別子に使います どうやら workflow-controller と同じ namespace に定義しな いと動かないぽいです なので発火させるテンプレート は同じ namespace 内か、 ClusterWorkflowTemplate にし ないとダメそうです # WorkflowEventBinding ͷఆٛ apiVersion: argoproj.io/v1alpha1 kind: WorkflowEventBinding metadata: name: event-consumer namespace: argo spec: event: selector: payload.message != "" && discriminator == "whalesay-hook" submit: workflowTemplateRef: name: whalesay-param-template arguments: parameters: - name: message valueFrom: event: payload.message イベントを検知してワークフローを実行させたい (WorkflowEventBinding) workflow-controller と 同じ namespace にする

Slide 128

Slide 128 text

CloudNative Days Tokyo 2021 | @makocchi 128 定義はこんな感じです discriminator はエンドポイント の識別子に使います どうやら workflow-controller と同じ namespace に定義しな いと動かないぽいです なので発火させるテンプレート は同じ namespace 内か、 ClusterWorkflowTemplate にし ないとダメそうです # WorkflowEventBinding ͷఆٛ apiVersion: argoproj.io/v1alpha1 kind: WorkflowEventBinding metadata: name: event-consumer namespace: argo spec: event: selector: payload.message != "" && discriminator == "whalesay-hook" submit: workflowTemplateRef: name: whalesay-param-template arguments: parameters: - name: message valueFrom: event: payload.message イベントを検知してワークフローを実行させたい (WorkflowEventBinding) # event Λ hook ͢Δͱ࣮ߦ͞ΕΔ͸ͣ # (argo-server ʹରͯ͠ port-forward ͍ͯ͠Δ৔߹͸ localhost:2746 ʹͳΓ·͢) $ curl -sk https://localhost:2746/api/v1/events/argo/whalesay-hook -H "Authorization: $TOKEN" -d '{"message": "hello events”}’ # discliminator Λ࢖༻͠ͳ͍৔߹ $ curl -sk https://localhost:2746/api/v1/events/argo -H "Authorization: $TOKEN" -d '{"message": "hello events”}’

Slide 129

Slide 129 text

CloudNative Days Tokyo 2021 | @makocchi 129 Argo Events は Argo ファミリーの1つで、様々な イベントを検知してアクションを実行させることが できるソフトウェアになります Webhook はもちろん、例えば Pub/Sub や SNS を subscribe してイベント発火させることができま す 同じ Argo ファミリーということもあって、連携は しやすい作りになっていると思います イベントを検知してワークフローを実行させたい (Argo Events) https://argoproj.github.io/argo-events/sensors/triggers/argo-workflow/

Slide 130

Slide 130 text

CloudNative Days Tokyo 2021 | @makocchi 130 Argo Events では「EventSource」でウォッチする イベント(Pub/Sub や SNS や Lambda 等)を定義し ます 「EventSource」で検知したものは「Sensor」でト リガーされます 「EventSource」と「Sensor」のやりとりには 「EventBus」が使われます(NATS streaming) イベントを検知してワークフローを実行させたい (Argo Events) https://argoproj.github.io/argo-events/sensors/triggers/argo-workflow/

Slide 131

Slide 131 text

CloudNative Days Tokyo 2021 | @makocchi 131 例えば Pub/Sub を EventSource にする場合はこ んな感じで定義しておきます GCP の project や subscribe する topic を指定 します Workload Identity を使わない場合は credentialSecret のフィールドが必要になります イベントを検知してワークフローを実行させたい (Argo Events) # EventSource ͷఆٛ (Pub/Sub) apiVersion: argoproj.io/v1alpha1 kind: EventSource metadata: name: pubsub-event-source spec: pubSub: my-pubsub: jsonBody: true projectID: my-gcp-project topic: my-pubusub-topic subscriptionID: my-pubsub-subscription

Slide 132

Slide 132 text

CloudNative Days Tokyo 2021 | @makocchi 132 一方で Sensor からワークフローを実行させる定義 はこんな感じで定義します dependencies に先程定義した EventSource の情報 を指定します なお filter を使って細かい条件の判定や複数の EventSource を使う等可能です 実際のワークフローの定義は triggers 内で行いま す ここでの定義をスッキリさせるために、テンプレー ト化しておいて workflowTemplateRef で参照させ るのがいいと思います イベントを検知してワークフローを実行させたい (Argo Events) # Sensor ͷఆٛ apiVersion: argoproj.io/v1alpha1 kind: Sensor metadata: name: my-sensor spec: dependencies: - name: my-dep eventSourceName: pubsub-event-source eventName: my-pubsub triggers: - template: name: workflow-from-pubsub argoWorkflow: operation: submit source: resource: apiVersion: argoproj.io/v1alpha1 kind: Workflow ... 先程の EventSource 情報 ワークフローの実体

Slide 133

Slide 133 text

CloudNative Days Tokyo 2021 | @makocchi 133 その他の(役に立つかもしれない) Tips

Slide 134

Slide 134 text

CloudNative Days Tokyo 2021 | @makocchi 134 その他の(役に立つかもしれない)Tips 内部で使われる containerRuntimeExecutor について Argo Workflows では Pod の処理や log の取得等の内部的な処理を containerRuntimeExecutor という概念で実装しています この containerRuntimeExecutor には種類があり、デフォルトでは「docker executor」が設 定されています どの containerRuntimeExecutor が実行されているかは、起動された Pod 内の wait という コンテナのログを見ることで確認できます 最近 Kubernetes では Dockerd ではなく、containerd を kubelet のランタイムとして設定し てあるケースも増えてきていると思います containerd が使用されている場合、このデフォルトの「docker executor」ではうまくワーク フローは動いてくれません

Slide 135

Slide 135 text

CloudNative Days Tokyo 2021 | @makocchi 135 その他の(役に立つかもしれない)Tips 内部で使われる containerRuntimeExecutor について containerRuntimeExecutor にはいくつか種類があり、workflow-controller の設定で変更が可 能です containerRuntimeExecutor 特徴 docker deprecated / 3.2 までのデフォルト k8sapi いくつかの機能制限あり / 大規模環境に適さない kubelet いくつかの機能制限あり / 大規模環境に適さない pns Windows 環境で動かない emissary 出てきて間もないが大規模環境にも対応できる / 3.3 からデフォルト

Slide 136

Slide 136 text

CloudNative Days Tokyo 2021 | @makocchi 136 その他の(役に立つかもしれない)Tips 内部で使われる containerRuntimeExecutor について 結局どれつかえばいいの? Argo Workflows のバージョンが新しい(v3.1.0 以降)であれば emissary でいいと思います もし古いバージョンを使っているのなら新しくしたほうが良いでしょう なんかワークフローが上手く動かない(いつまで経っても Pod が正常に終わらない、とか)場合 は executor を変えることで解決する場合があります

Slide 137

Slide 137 text

CloudNative Days Tokyo 2021 | @makocchi 137 その他の(役に立つかもしれない)Tips 内部で使われる containerRuntimeExecutor について わかったわかった ではどうやって設定するの? Argo Workflows が参照する configMap で設定します 例えば「containerRuntimeExecutor: emissary」 もし記述されていない場合はデフォルトの executor になっています(docker) # ࠓͷઃఆΛ֬ೝ͢Δ # ΋͠Կ΋ग़ͯ͜ͳ͚Ε͹σϑΥϧτ͕࢖ΘΕ͍ͯΔ $ kubectl get configmap -n argo workflow-controller-configmap -o yaml | grep containerRuntimeExecutor containerRuntimeExecutor: emissary

Slide 138

Slide 138 text

CloudNative Days Tokyo 2021 | @makocchi 138 その他の(役に立つかもしれない)Tips 内部で使われる containerRuntimeExecutor について ワークフロー毎に containerRuntimeExecutor を選択できるようにしたい場合はラベルによっ て切り替えるようにすることも可能です # workflow-controller ͕ࢀর͍ͯ͠Δ configMap Ͱͷઃఆ߲໨ # containerRuntimeExecutor ͱ containerRuntimeExecutors Ͱҧ͏ͷͰ஫ҙ containerRuntimeExecutors: | - name: emissary selector: matchLabels: workflows.argoproj.io/container-runtime-executor: emissary - name: docker selector: matchLabels: workflows.argoproj.io/container-runtime-executor: docker

Slide 139

Slide 139 text

CloudNative Days Tokyo 2021 | @makocchi 139 その他の(役に立つかもしれない)Tips 内部で使われる containerRuntimeExecutor について ワークフロー毎に containerRuntimeExecutor を選択できるようにしたい場合はラベルによっ て切り替えるようにすることも可能です # workflow-controller ͕ࢀর͍ͯ͠Δ configMap Ͱͷઃఆ߲໨ # containerRuntimeExecutor ͱ containerRuntimeExecutors Ͱҧ͏ͷͰ஫ҙ containerRuntimeExecutors: | - name: emissary selector: matchLabels: workflows.argoproj.io/container-runtime-executor: emissary - name: docker selector: matchLabels: workflows.argoproj.io/container-runtime-executor: docker # ͜ΕͰ੾Γସ͑์୊ʹͳΓ·͢ # ྫ͑͹ submit ͢Δ࣌ʹ͸ --labels Ͱࢦఆ͠·͢ $ argo submit hello-world.yaml --labels workflows.argoproj.io/container-runtime-executor=docker # Workflow ͷఆٛʹ label Λ෇༩͓ͯ͘͠Ͱ΋͍͍Ͱ͠ΐ͏ apiVersion: argoproj.io/v1alpha1 kind: Workflow metadata: labels: workflows.argoproj.io/container-runtime-executor: docker ...

Slide 140

Slide 140 text

CloudNative Days Tokyo 2021 | @makocchi 140 その他の(役に立つかもしれない)Tips ワークフロー全体で実行数を制限しておく なにかの拍子でワークフローが大量に🔥爆誕🔥してしまってリソースが食いつぶされた・・なん てことの無いようにしておくといいかもしれません workflow-controller の下記の設定を調整しておくといいでしょう しきい値を超えたワークフローは Pending になります ઃఆ߲໨ 特徴 parallelism workflow-controller が実行できるワークフローの同時実行数 namespaceParallelism namespace のワークフローの同時実行数 resourceRateLimit limit と burst の値があり Pod の数を制御する

Slide 141

Slide 141 text

CloudNative Days Tokyo 2021 | @makocchi 141 その他の(役に立つかもしれない)Tips ワークフローのメトリクスを取得する メトリクスは workflow-controller の port 9090 で取得可能です (Prometheus 形式) grafana のダッシュボードも用意されています https://github.com/argoproj/argo-workflows/blob/master/examples/grafana-dashboard.json

Slide 142

Slide 142 text

CloudNative Days Tokyo 2021 | @makocchi 142 その他の(役に立つかもしれない)Tips ワークフローのテンプレートレベルのメトリクスを取得する Workflow の spec でメトリクスの設定が可能です # ಠࣗͷϝτϦΫεͷઃఆ ... spec: metrics: prometheus: - name: exec_duration_gauge_hello_world labels: - key: name value: hello_world help: "hello_world duration gauge" gauge: value: "{{workflow.duration}}" entrypoint: main templates: - name: main steps: - - name: step1 template: whalesay ... # ಠࣗͷϝτϦΫεͱͯ͠ग़ͯ͘Δ ... # HELP argo_workflows_exec_duration_gauge_hello_world hello_world duration gauge # TYPE argo_workflows_exec_duration_gauge_hello_world gauge argo_workflows_exec_duration_gauge_hello_world{name="hello_world"} 10.548116 ...

Slide 143

Slide 143 text

CloudNative Days Tokyo 2021 | @makocchi 143 Argo Workflows とは、ワークフローの処理をカスタムリソース で管理することができるオープンソースのソフトウェア(再掲) テンプレートの概念を上手く使うことで効率よく管理できる 本格的に運用する時は workflow-controller 側の設定項目をちゃ んと把握しておくこと 特に kubelet のランタイムが docker ではない人は containerRuntimeExecutor を変更することを忘れずに! 君も今日から Argo Workflows 使いだ! 本日のまとめ

Slide 144

Slide 144 text

CloudNative Days Tokyo 2021 使いこなせ!Argo Workflows @makocchi ご清聴ありがとうございました!