Argoとは?
ArgoはコンテナネイティブなOSSのワークフローエンジンです。
2018-04-25 追記
Argoはプロジェクトが分割されているようです。
この記事はその中の`Argo Workflows`について記載しています。
その他のプロジェクトはこちら 「これからと期待」に少しだけ記載しています。
ワークフローエンジンだと色々な意味が含まれるため、イメージを掴むため類似するプロダクトを挙げるとAirflow
、Digdag
、Luigi
となります。
名前の由来はギリシア神話に登場する巨大な船の名前のアルゴ船?かも
ArgoはKubernetes(以後k8s)上に構築することにより、k8sの機能を利用できる大きなアドバンテージを獲得しています。
例えばワークフローの定義はCustom Resource Definition(以後CRD)で定義できます。
つまりYAMLで定義できるため、k8sのマニフェスト管理と同じにようにhelm
、ksonnet
を使用できます。
その他にもk8sリソースのSecret
やPersistent volume
にアクセスすることも可能です。
k8sを利用しているユーザーには馴染みやすい定義方法となる点は大きな魅力です。
表題の通り個人的には「こういうの待ってた!」という気持ちです。
先日はコミュニティの法人会員(corporate members)にGoogleとNVIDIAの参加がアナウンスされ、これからの成長が楽しみです。
hello-world
で実行までの流れ!
どんなことができるかを説明する前に、まずはhello-world
なワークフローを実行し、イメージを掴んでいきます。
ワークフローの定義はこちら。
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hello-
spec:
# 実行するテンプレートを指定
entrypoint: hello
# テンプレートの定義
templates:
- name: hello
container:
image: docker/whalesay:latest
command: [cowsay]
args: ["hello world"]
CRDで定義されたkind: Workflow
を使うため、k8sのマニフェストを管理している人には馴染みやすいですね。
そして実行方法は以下のようになります。
# ワークフローを作成
$ kubectl create -f hello.yaml
workflow "hello-7wlnt" created
# Podが作成され、ワークフローが実行されている
$ kubectl get pod hello-7wlnt
NAME READY STATUS RESTARTS AGE
hello-7wlnt 0/2 Completed 0 5m
# 実行内容を見てみる(コンテナ名はmainとなる)
$ kubectl logs -c main hello-7wlnt
_____________
< hello world >
-------------
\
\
\
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
k8sと同じ感覚で使えてとっても簡単ですね。
また上の例ではkubectl
のみでワークフローが実行できており、既存のエコシステムとの連携も簡単そうです。
Webコンソールで結果をみるとこんな感じです。
どんなワークフローを定義ができる?(v2.1.0-beta2)
それではもう少しどのようなワークフローが定義できるか見ていきます。
公式のドキュメントはまだ少ないのですが、サンプルと合わせて読み取った機能を一問一答の方式で書きます。
処理ごとにパラメーターの変更はできる?
-
spec.arguments.paramters
で定義したパラメーターをargo submit --parameters
で指定できるよ。
CPUとMemoryの指定はできる?
- k8sと同じように
resources
で指定できるよ。
Gitからコードをチェックアウトできる?
-
spec.templates[].inputs.artifacts[].git
で指定できるよ。
同じワークフローの中でファイルデータの共有はできる?
- k8sの
Persistent Volume
を使って共有できるよ。
同じワークフローの中でパラメーターの引渡しはできる?
- パラメーターは
spec.templates[].outputs.parameters[].(name|globalName)
で引き渡せるよ。
定期実行はできる?
- 現状はできないけど、k8sの
CronJob
で実現できると思うよ。
(Source)入力のソースとしては何が使える?
- Git、HTTP、S3が標準では用意されているよ。
- GCSもS3互換APIを有効にすれば対応できるよ。
(Sink)アーティファクトの保存には何が使える?
- S3が標準では用意されているよ。
- GCSもS3互換APIを有効にすれば対応できるよ。
既存の監視設定に組み込みたいから、Podにラベルをつけたいけどできる?
-
metadata
の情報としてアノテーションとラベルを付与できるよ。
ワークロードが違うから実行するノードも分けたい。Argoで実行するPodってノードセレクターを指定できる?
-
spec.templates.nodeSelector
が使えるよ。
並列に実行したいけどできる?
- もちろんできるし、
spec.parallelism
で並列数の上限も指定できるよ。
フローを分岐できる?
-
when
を使って処理をスキップできるから、擬似的に分岐できるよ。 -
when
の条件には終了ステータスコード、標準出力の内容などが使えるよ。
Slackに通知できる?
- ネイティブの機能はないので、自分で用意する必要があるよ。
-
curl
を使ってSlackに通知できるので簡単に実現できるよ。 - メールに通知したい場合は
Sendgrid
のようなサービスを使えば簡単に実現できるよ。
ワークフローの全体の処理結果によって通知先を変更ってできる?
-
spec.onExit
を使えばできるよ。
失敗した処理を再実行できる?
-
spec.templates[].retryStrategy
で指定できるよ。 - 回数制限もできるし、成功するまで実行することもできるよ。
k8sのSecret
って読み込める?
- 環境変数、またはファイルとして参照できるよ。
実行するワークフローに必要なデーモンがあるんだけど、通信させる方法はある?
-
Sidecar
もできるし、Daemon
の実行もできるからできるよ。
Dockerイメージをビルドってできる?
- Docker in docker(sidecar)できるよ。
- kanikoを使ってもいいかもね。
既存のPersistent Volume
って参照できる?
- できるよ。
タイムアウトって設定できる?
- できるよ。
CI/CDとして利用できる?
- 大きなトピックになりそうだから、次の章で!!
CI/CDはできるのか
Continuous integration is a popular appication for workflows. Currently, Argo does not provide event triggers for automatically kicking off your CI jobs, but we plan to do so in the near future. Until then, you can easily write a cron job that checks for new commits and kicks off the needed workflow, or use your existing Jenkins server to kick off the workflow.
Argoのドキュメントに書かれている通り、まだトリガー機能が実装されていないのでArgo Workflow単体では実現できません。
JekinsやBotkitなどでトリガーを実装するか、Argo-CI、Argo-CDを使ってみるのもありだと思います。
Argo-CI
とArgo-CD
は名前の通りまさにCIとCDをするためのツールです。
ただしArgo-CI
は欠けているトリガー機能を提供してくれますが、ARLY DEVELOPMENT
の状態です。
またArgo-CD
はksonnet
を使うことが前提のため、既存システムによっては使いにくいツールかなと感じています(将来的に分離して欲しいな)。
これからと期待
v2.1ではDAGモデルもサポートされます。
これでワークフローエンジンとしては便利に使えると思いますが、ワークフローの定義内容がGUIからは確認できなため、事前定義や再利用の機能が入ればいいなと思っています。
また次のコミュニティミーティングでは以下のプロジェクトについて話し会われるようです。
- Argo Workflows
- Argo CI
- Argo CD
- Argo Events
CI/CDツールとして使える日が近づきそうです!
おまけ
インストール手順(for MAC)
- kubernetes: v1.9.6(Docker for MAC)
- Namespace:
kube-system
にArgoのコンポーネントがインストールされる
- Namespace:
- Argo: v2.1.0-beta2
# インストールパスの適当に設定
$ install_path=/usr/local/bin
# バージョンを指定
$ version=2.1.0-beta2
# バイナリをダウンロード
# brewであればstableなバージョンをインストールできます
# brew install argoproj/tap/argo
$ curl -sSL -o ${install_path}/argo https://github.com/argoproj/argo/releases/download/v${version}/argo-darwin-amd64
# 実行権限を追加
$ chmod +x ${install_path}/argo
# バイナリインストール確認
$ argo version
argo: v2.1.0-beta2
BuildDate: 2018-03-29T20:49:33Z
GitCommit: fe23c2f651a61a2d7aa877a86edff9802d7b5b47
GitTreeState: clean
GitTag: v2.1.0-beta2
GoVersion: go1.9.3
Compiler: gc
Platform: darwin/amd64
# インストール
$ argo install
Installing Argo v2.1.0-beta2 into namespace 'kube-system'
Proceeding with Kubernetes version 1.9.6
CustomResourceDefinition 'workflows.argoproj.io' created
ServiceAccount 'argo' created
ClusterRole 'argo-cluster-role' created
ClusterRoleBinding 'argo-binding' created
Deployment 'workflow-controller' created
ServiceAccount 'argo-ui' created
ClusterRole 'argo-ui-cluster-role' created
ClusterRoleBinding 'argo-ui-binding' created
Deployment 'argo-ui' created
Service 'argo-ui' created
# インストール確認
$ kubectl -n kube-system get pod
NAME READY STATUS RESTARTS AGE
argo-ui-b94f57cc5-lc7g8 1/1 Running 0 1h
...
workflow-controller-6ff45f57b7-b4s42 1/1 Running 0 1h
...
# argo-uiにアクセスできるようにserviceの内容を変更
# アクセスできれば何でもOK
$ kubectl patch svc argo-ui -n kube-system -p '{"spec":{"$setElementOrder/ports":[{"port":8001}],"ports":[{"port":8001,"protocol":"TCP","targetPort":8001},{"$patch":"delete","port":80}],"type":"LoadBalancer"}}'
# ポート確認
$ kubectl get svc argo-ui -n kube-system -o yaml
kubectl get svc argo-ui -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argo-ui LoadBalancer 10.105.20.7 localhost 8001:30780/TCP 3h
# Webコンソールにアクセス
$ open http://localhost:8001/
# 試しに実行してみる
$ argo submit https://raw.githubusercontent.com/argoproj/argo/master/examples/hello-world.yaml
Name: hello-world-svlpd
Namespace: default
ServiceAccount: default
Status: Pending
Created: Mon Apr 23 16:35:04 +0900 (29 seconds from now)
# 実行コンテナの内容確認
$ argo list
NAME STATUS AGE DURATION
hello-world-svlpd Succeeded 16s 5s
# 実行内容確認
$ argo get hello-world-svlpd
Name: hello-world-svlpd
Namespace: default
ServiceAccount: default
Status: Succeeded
Created: Mon Apr 23 16:35:04 +0900 (3 seconds from now)
Started: Mon Apr 23 16:35:04 +0900 (3 seconds from now)
Finished: Mon Apr 23 16:35:09 +0900 (8 seconds from now)
Duration: 5 seconds
# 実行ログの内容確認
$ argo logs hello-world-svlpd
_____________
< hello world >
-------------
\
\
\
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/