はじめに
こんにちは。ブランドソリューション開発本部 バックエンド部 SREの笹沢(@sasamuku)です。
ZOZOではショップスタッフの販売サポートツール「FAANS」を2022年8月に正式リリースしました。FAANSはアパレルのショップスタッフ様を支援する様々な機能を提供しています。例えば、ZOZOTOWN上で実店舗の在庫取り置きができる機能や、コーディネート投稿の機能などがあります。投稿されたコーディネートはZOZOTOWNやWEAR、Yahoo!ショッピングに連携が可能で、今後はブランド様のECサイトとも連携できる予定です。これによりお客様のコーディネート選びをサポートし購買体験をより充実したものにします。機能の詳細に関しましては下記プレスリリースをご覧ください。
今回はFAANSで採用しているワークフローエンジン「Argo Workflows」について、その採用理由や構成例をご紹介します。ワークフローエンジンの採用を検討している方、Kubernetesネイティブなワークフローエンジンに興味をお持ちの方の参考になれば幸いです。
なお本稿は単体でもお読みいただけますが、過去の記事をご覧いただくとFAANSの技術変遷をよりご理解いただけます。
ワークフローエンジン選定の過程
本章では、Kubernetesネイティブなワークフローエンジンに対する考察を交えながら、Argo Workflowsの導入を決めた過程をご説明します。
ワークフローエンジン導入の背景
FAANSが提供する機能の1つに「成果確認」があります。これはショップスタッフ様が投稿したコーディネートに対する閲覧数や経由売上といった指標を成果として可視化するものです。この機能の裏側ではそれらのデータを集計するワークフローが必要となりますが、実装当時のFAANSにはワークフローを実行する基盤はまだありませんでした。
どのツールでワークフローを実行するか検討するために、まずFAANSに求められる最低限の要件を書き出しました。それが下記になります。
- スケジュール実行
- リトライ機構
- タスク間依存関係の表現
- Webコンソールでの手動実行やログの確認1
スケジュール実行やリトライ機構が備わっていることは大前提です。加えて、複雑なワークフローの構成にはタスク間の依存関係を表現できなければなりません。タスク間の依存関係とは、例えば「タスクAとBの完了を待ってからCを実行する」というものです。さらに開発者体験も重要です。ログの確認やワークフローの再実行はWebコンソールでできると便利です。
よって、これらの要件を満たすワークフローエンジンを選定する必要がありました。
代表的なワークフローエンジンの紹介
まずは、フラットな視点で代表的なワークフローエンジンを調査しました。スター数が1kを超えるワークフローエンジンをいくつか抜粋すると以下のようなものがあります2。()内は2022/10時点のスター数になります。
それぞれの特徴を簡単に見ていきます。
LuigiとApache AirflowはPythonでワークフローを記述します。これらは機械学習での利用が多いのですが、より一般的なユースケースにも利用可能です。Pythonによるツール独自の記法も含むため慣れていない場合は一定の学習が必要になります。
Tekton PipelinesとArgo WorkflowsはKubernetesネイティブなワークフローエンジンであり、Kubernetesマニフェストを使ってワークフローを記述します。Kubernetesの利用が前提となるため、運用基盤が整っていない場合は導入の障壁が高いです。
Digdagはdigファイルと呼ばれる独自ファイルにワークフローを定義します。記法はYAMLに近くシンプルな表現が可能です。ZOZOでは採用しているプロダクトが多いためノウハウは蓄積されています。
Kubernetesネイティブなワークフローエンジン
FAANSでは「Kubernetesネイティブなワークフローエンジン」を採用する方針にしました。FAANSはKubernetesを採用しており、エコシステムの1つとして迎え入れる基盤が既にありました。そして、後述の「Kubernetesネイティブであることの利点の大きさ」が決め手となりました。
Kubernetesネイティブとは
ここでは「Kubernetesネイティブ」を「Kubernetesで動かすことを前提に設計された」と定義しています。つまりコンテナでのタスク実行を前提としたワークフローエンジンと言えます。では、Kubernetesネイティブであると何がよいのでしょうか。次のような利点があると考えます。
- ワークフロー定義をマニフェストで管理できる
- ワークフローエンジンの移行性が高い
- リソース利用効率が高い
それでは1点ずつ詳解していきます。
ワークフロー定義をマニフェストで管理できる
ワークフロー定義をマニフェストで管理できるということは、DeploymentやIngressといった既存のKubernetesリソースと同じ方法でワークフロー定義を扱えるということです。ここでの「ワークフロー定義」は「どのようなタスクをどのような順番で実行するかの決まりごと」という抽象的な意味合いで捉えてください。
次の図はワークフローがKubernetes上で実行されるまでの流れを示しています。
【1】のステップではワークフロー定義をマニフェストに落とし込みます。【2】のステップではマニフェストをkube-apiserver経由でクラスタに登録します。そして【3】のステップで実際にPod上で処理が実行されます。実際にはカスタムリソースの作成もありますがここでは省略しています。
このようにワークフロー定義をマニフェストとして管理できることで次のメリットがあります。
- GitOpsのプラクティスを適用
- Control loopによる制御
- データストアとしてetcdを使用
一点ずつ補足していきます。
GitOpsとはGitを一元的なソースとしてKubernetesリソースを管理する手法です3。ワークフロー定義をマニフェストとして管理することでGitOpsのプラクティスを適用できます。これによりKubernetes上のワークフローが自動的にGitの状態と一致するようになります。
続いて、Control loopについてです。Control loopはKubernetesにおける更新ロジックです。現実状態をマニフェストに記載された理想状態へ収束させることができます。これを実現するのがControllerです。ApplyされたワークフローはControllerによって監視されます。そして、ControllerがControl loopを回すことでワークフローが常に理想状態と一致するように更新されます。
最後にデータストアについてです。ワークフロー定義をマニフェストで管理できるということは、これらの保存のためにデータストアを別途用意する必要がありません。なぜならマニフェストはetcdに保存されるからです。etcdはKubernetesクラスタ内部のコンポーネントで、クラスタに登録される全ての情報が保存されます。別途データベースを構成するとEOLや脆弱性対応に運用負荷がかかるため、このメリットは大きいと感じます。ただし、ログの永続化にはロギングサービスやデータベースが必要となります。あくまでワークフロー定義を保存する上で別途データストアは不要ということですのでご注意ください。
以上から、ワークフロー定義をマニフェストで管理することにより、Kubernetesの既存の仕組みをパワフルに活用したワークフローの運用が可能だと分かります。
ワークフローエンジンの移行性が高い
Kubernetesネイティブなワークフローエンジンではワークフロー内の各タスクはコンテナで実行されます。どのタスクをどのような順番で実行するかはマニフェストで記述されますが、タスク内でどのような処理を実行するのかという関心事はコンテナに寄せられます。これによりワークフローを利用するシーンにおいても、コンテナ一般のメリットである「可搬性」を享受できます。これには具体的に次のようなメリットがあります。
- ローカルで簡単な動作検証ができる
- ワークフローエンジンの移行性が高い
2点目は特に強力です。タスクを独自仕様や特定言語で定義する場合と比較し、コンテナでパッケージングされたタスクは再利用可能です。つまり、コンテナをサポートする他ワークフローエンジンへの移行が比較的容易です。加えて、規模縮小によりワークフローエンジンを廃止したとしてもKubernetes Job/Kubernetes CronJobで動作させることが可能です。
リソース利用効率が高い
Kubernetesネイティブなワークフローエンジンはリソース利用効率が高く、相性のよいマネージドサービスと組み合わせることでコストパフォーマンスを上げることができます。
ここでの「リソース利用効率」とは、アサインされたコンピューティングリソースに対して、実質的に利用されるリソースの割合を意味しています。ワークフローで必要となるリソースとアサインされるリソースに過不足がないほど、リソース利用効率の高い状態となります。ワークフローという処理形態では、必要なときに必要な分だけリソースを確保できればよいため、要求に応じてアサイン量を調整できることがより重要となります。
この点において、Kubernetesネイティブなワークフローエンジンは優秀です。なぜなら、タスクをPodとして切り出して実行できるからです。Kubernetesのマネージドサービスが提供する機能を利用すれば、Podの需要に合わせてNodeをスケールできます4。さらに、Pod単位でスケール可能なサービス5を利用すればさらに効率が高まります。このように、Kubernetesネイティブなワークフローエンジンをクラウド環境のマネージドサービスで動作させることにより、リソース利用効率ひいてはコストパフォーマンスを高めることができます。
Argo Workflowsの選定理由
以上から、選定候補として残ったのがKubernetesネイティブなワークフローエンジンであるTekton PipelinesとArgo Workflowsの2つでした。最終的にArgo Workflowsを選択しましたが、どちらもFAANSにおける最低限の要件は満たしていました。
その上でArgo Workflowsを選んだ理由は、既にArgo CDを運用しており親和性があったからです。具体的にはArgo CD Dexと連携可能であり認証のための設定を1から構築する手間が省けるという点です。
Argo Workflowsの構成
本章ではArgo Workflowsをどのような構成で利用しているかを解説していきます。Argo Workflowsの基本的な概念からFAANSでの構成例まで説明しています。
続きはこちら