バッチジョブは、データ処理、シミュレーション、科学計算などの分野で広く利用されています。バッチジョブは通常、大規模な計算リソースを必要とします。分散型 Argo ワークフロー向けの Kubernetes クラスターは、オープンソースの Argo Workflows プロジェクトを基盤として開発されており、オープンソースワークフローの標準に準拠しています。ワークフロークラスターでは、ワークフローの容易なオーケストレーション、各ステップをコンテナ内で実行、大規模な機械学習やシミュレーションといったコンピューティング集約型のタスクを短期間で完了させることが可能です。また、継続的インテグレーションおよび継続的デリバリー(CI/CD)パイプラインジョブも迅速に実行できます。スケジュールされたジョブおよびバッチジョブをワークフロークラスターへ移行することで、運用・保守(O&M)の複雑さとコストを効率的に削減できます。
Argo Workflows への移行理由
バッチコンピューティングには、以下の制約があります:
ジョブ定義には製品固有の仕様を学習する必要があります。また、一部のシステムでは指定されたデバイスやソフトウェアの購入が求められます。
計算環境は手動で管理する必要があります:vSwitch のモデルおよびインスタンス数を明示的に指定します。サーバーレスではないため、全体的な O&M コストが高くなります。
利用可能な計算環境が限定されているため、キュー内でジョブの優先度を割り当てる必要があります。これにより、構成の複雑さが増します。
Argo Workflows はこれらの制約を解消します:
クラウドネイティブであり、オープンソースの Argo Workflows を基盤としており、独自プロダクトやソフトウェアへの依存はありません。
データ処理、シミュレーション、科学計算などにおける複雑なタスクオーケストレーションをサポートします。
Alibaba Cloud が提供するノードレスのエラスティックコンテナインスタンス上で実行されます。
ジョブキューなしの従量課金方式です。需要に応じて任意の規模で計算リソースを展開でき、効率性の向上とコスト削減を実現します。
基本概念
バッチコンピューティング
バッチコンピューティングには、線形の依存関係チェーンを形成する 5 つのコアコンポーネントがあります:計算環境はインフラストラクチャをホストし、ジョブキューは計算環境間でワークロードをルーティングし、ジョブ定義はジョブの実行方法を指定し、ジョブ(または配列ジョブ)は実際に提出・実行される作業単位です。
| 概念 | 説明 |
|---|---|
| ジョブ | シェルスクリプト、Linux 実行可能ファイル、または Docker コンテナイメージをバッチコンピューティングシステムに提出した後に開始される作業単位です。システムは計算リソースを割り当て、ジョブを起動します。 |
| 配列ジョブ | 類似したジョブをまとめて提出・実行するコレクションです。配列ジョブ内のすべてのジョブは、同一のジョブ定義を共有します。個々のジョブを識別するためにインデックスを使用します。各ジョブインスタンスは、異なるデータセットまたはタスクを処理することがあります。 |
| ジョブ定義 | ジョブの実行方法を指定します。ジョブを実行する前に作成する必要があります。含まれる要素:コンテナイメージ、コマンドおよびパラメーター、必要な CPU およびメモリ、環境変数、ディスク領域です。 |
| ジョブキュー | バッチコンピューティングシステムに提出されたジョブはジョブキューに入り、スケジューリング後にキューから退出します。キュー内でのジョブ優先度を指定したり、キューを特定の計算環境に関連付けたりできます。 |
| 計算環境 | ジョブを実行するための計算リソースで構成されます。各計算環境について、vSwitch のモデル、最大および最小 vCPU 数、プリエンプティブルインスタンスの単位価格を指定する必要があります。 |
Argo Workflows
Argo Workflows には 3 つのコア構成要素があります。テンプレートは最小の作業単位を定義します。ワークフローは 1 つ以上のテンプレートをオーケストレーションします。ワークフローテンプレートは、複数のワークフロー間で再利用可能な静的なワークフロー定義を提供します。すべてのタスクは最終的に ACK サーバーレスクラスター上の Pod で実行されます。
| 概念 | 説明 |
|---|---|
| テンプレート | タスク(またはジョブ)を定義します。各ワークフローには少なくとも 1 つのテンプレートが必要です。テンプレートは、Kubernetes コンテナ構成および入出力パラメーターも指定します。 |
| ワークフロー | 1 つ以上のタスク(テンプレート)で構成されます。タスクを直列化、並列実行、または指定された条件を満たすタスクのみを実行するように設定できます。タスクは Kubernetes クラスターの Pod で実行されます。 |
| ワークフローテンプレート | 再利用可能な静的なワークフロー定義で、関数と同様の役割を果たします。異なるワークフロー間でワークフローテンプレートを参照・実行でき、複雑なワークフロー構築時に定義を再利用できます。 |
| ACK サーバーレスクラスター | ワークフロークラスター向けの組み込み計算環境を提供します。ワークフローが提出されると、タスクはサーバーレスのエラスティックコンテナインスタンス上で実行されます — Kubernetes ノードのメンテナンスは不要です。数万の Pod および数十万の vCPU を扱う大規模ワークフローに対応します。ワークフローの完了後、計算リソースは自動的に解放されます。 |
機能対応表
下記の表は、バッチコンピューティングの機能とその Argo Workflows における対応機能をマッピングし、主な動作の違いをハイライトしています。
| カテゴリ | バッチコンピューティング | Argo Workflows | 主な違い |
|---|---|---|---|
| ユーザーエクスペリエンス | バッチ処理 CLI | Argo Workflows CLI | Argo CLI は JSON ジョブ定義ではなく、Kubernetes ネイティブの YAML リソースを操作します |
| JSON で定義されたジョブ | YAML で定義されたジョブ | Argo は Kubernetes 標準の YAML を使用し、独自のジョブスキーマを学習する必要はありません | |
| SDK | SDK | Argo SDK はオープンソースであり、コミュニティによってメンテナンスされています | |
| 主要機能 | ジョブ | ワークフロー | ワークフローはバッチシステムの構成要素ではなく、Kubernetes リソースです |
| 配列ジョブ | Argo Workflows - ループ | ループは withSequence または withItems を使用 — 別途配列ジョブタイプは存在しません | |
| ジョブの依存関係 | Argo Workflows - DAG | 依存関係はジョブ ID ではなくタスク名で宣言 — スクリプト不要 | |
| ジョブの環境変数 | Argo Workflows - パラメーター | パラメーターは静的値および上流タスクからの動的出力を両方サポート | |
| 自動ジョブリトライ | Argo Workflows - リトライ | リトライポリシーはテンプレート仕様内にインラインで定義 | |
| ジョブタイムアウト | Argo Workflows - タイムアウト | タイムアウトはワークフロー全体および個別のステップレベルの両方で適用可能 | |
| 該当なし | Argo Workflows - アーティファクト | タスク間でファイルを渡すためのネイティブサポート — 外部スクリプト不要 | |
| 該当なし | Argo Workflows - 条件 | 上流タスクの結果に基づいて条件付きでタスクを実行 | |
| 該当なし | Argo Workflows - 再帰 | ワークフローは自身を再帰呼び出し可能 — ほとんどのバッチシステムでは不可能 | |
| 該当なし | Argo Workflows - 一時停止/再開 | 実行中のワークフローを状態を保持したまま一時停止および再開可能 | |
| GPU ジョブ | 指定タイプの ECS インスタンスでワークフローを実行 | ノードセレクターを用いて、GPU インスタンスを含む特定の ECS インスタンスタイプをターゲットに指定可能 | |
| ボリューム | ボリューム | Object Storage Service (OSS)、File Storage NAS (NAS)、Cloud Parallel File System (CPFS)、またはディスクをマウント可能 | |
| ジョブ優先度 | Argo Workflows - 優先度 | 優先度は提出時に設定 — サーバーレスのエラスティシティにより競合が軽減 | |
| ジョブ定義 | ワークフローテンプレート | ワークフロー間で再利用可能 — Kubernetes リソースとしてバージョン管理 | |
| 計算環境 | ジョブキュー | サーバーレスかつエラスティック。ジョブキューは不要です。 | Argo は需要に応じてエラスティックにスケール — キュー構成や優先度管理は不要 |
| 計算環境 | ACK サーバーレスクラスター | クラスターが計算リソースを自動管理 — vSwitch やインスタンス数の設定は不要 | |
| エコシステム統合 | イベンティング | イベント通知 | 外部イベントからワークフローをトリガー可能 |
| 可観測性 | 可観測性 | ワークフロー向けの統合監視およびログ記録 |
ワークフローの例
シンプルなワークフロー
以下のワークフローは、alpine イメージを使用する Pod を作成し、シェルコマンド echo helloworld を実行します。
このワークフローをカスタマイズして、任意のシェルコマンドを実行したり、カスタムイメージ内のコマンドを実行したりできます。
cat > helloworld.yaml << EOF
apiVersion: argoproj.io/v1alpha1
kind: Workflow # 新しい k8s 仕様の種類
metadata:
generateName: hello-world- # ワークフロー仕様の名前
spec:
entrypoint: main # main テンプレートを呼び出します
templates:
- name: main # テンプレートの名前
container:
image: registry.cn-hangzhou.aliyuncs.com/acs/alpine:3.18-update
command: [ "sh", "-c" ]
args: [ "echo helloworld" ]
EOF
argo submit helloworld.yamlループ
大量のデータを並列処理する場合にループを使用します — 各反復は独立した Pod として実行されます。
以下の例では、pets.input という名前のテキストファイルと print-pet.sh という名前のスクリプトをカスタムイメージにパッケージ化しています。ループは 5 つの Pod を作成し、job-index の値として 1 ~ 5 を入力パラメーターとして渡します。各 Pod は pets.input の対応する行に記載されたペットを出力します。ソースファイルの詳細については、GitHub リポジトリをご参照ください。
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: loops-
spec:
entrypoint: loop-example
templates:
- name: loop-example
steps:
- - name: print-pet
template: print-pet
arguments:
parameters:
- name: job-index
value: "{{item}}"
withSequence: # print-pet テンプレートを、job-index パラメーターの値を 1 ~ 5 としてそれぞれ実行するループ。
start: "1"
end: "5"
- name: print-pet
inputs:
parameters:
- name: job-index
container:
image: acr-multiple-clusters-registry.cn-hangzhou.cr.aliyuncs.com/ack-multiple-clusters/print-pet
command: [/tmp/print-pet.sh]
args: ["{{inputs.parameters.job-index}}"] # コンテナの引数として入力パラメーター job-index を渡します詳細については、「Argo Workflows - ループ」をご参照ください。
DAG(MapReduce)
バッチコンピューティングシステムでは、ジョブの依存関係をジョブ ID を用いて指定する必要があります — しかしジョブ ID はジョブが提出された後にのみ利用可能になります。典型的な回避策は、以下のようなスクリプトです:
// ジョブ B はジョブ A に依存。ジョブ A の完了後にジョブ B が開始されます。
batch submit JobA | get job-id
batch submit JobB --dependency job-id (JobA)ジョブ数が増えるにつれて、このような依存関係スクリプトのメンテナンスは困難になります。
Argo Workflows では、ワークフロー定義内に直接タスク名で依存関係を宣言できます:
タスク B およびタスク C はタスク A に依存します。
タスク D はタスク B およびタスク C に依存します。
# 以下のワークフローはダイヤモンド型ワークフローを実行します
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: dag-diamond-
spec:
entrypoint: diamond
templates:
- name: diamond
dag:
tasks:
- name: A
template: echo
arguments:
parameters: [{name: message, value: A}]
- name: B
depends: "A"
template: echo
arguments:
parameters: [{name: message, value: B}]
- name: C
depends: "A"
template: echo
arguments:
parameters: [{name: message, value: C}]
- name: D
depends: "B && C"
template: echo
arguments:
parameters: [{name: message, value: D}]
- name: echo
inputs:
parameters:
- name: message
container:
image: alpine:3.7
command: [echo, "{{inputs.parameters.message}}"]シャードを作成して結果を集約するサンプル MapReduce ワークフローについては、「map-reduce」をご参照ください。
バッチコンピューティングから Argo Workflows への移行
ステップ 1:評価と計画
ジョブの変換を開始する前に、既存のバッチワークロードを以下の観点で包括的に評価してください:
ジョブの在庫調査:すべてのジョブ(依存関係、リソース要求(CPU、メモリ、GPU)、実行時パラメーターを含む)をリストアップします。
優先順位付け:ビジネス上重大なジョブと高複雑度のジョブを別々に特定します。まずシンプルで非重要なジョブから移行を開始し、複雑なワークフローに着手する前に信頼性を確立してください。
機能ギャップの確認:上記の機能対応表を用いて、各バッチコンピューティング機能を Argo Workflows の対応機能にマッピングします。計算環境設計およびジョブ優先度設定はスキップしてください — 分散型 Argo ワークフロー向けの Kubernetes クラスターはサーバーレスのエラスティックコンテナインスタンスを使用し、キュー管理を必要としません。
ステップ 2:分散型 Argo ワークフロー向けの Kubernetes クラスターの作成
「ワークフロークラスターの作成」をご参照ください。
ステップ 3:ジョブ定義の変換
機能対応表に基づき、バッチジョブを Argo ワークフローに変換します。必要に応じて、Argo Workflows SDK を使用して、ワークフロー作成およびシステム統合を自動化できます。
ステップ 4:ストレージの準備
クラスターがワークフローで必要なデータにアクセスできるよう、事前に準備を行います。OSS バケット、NAS ファイルシステム、CPFS ファイルシステム、またはディスクをクラスターにマウントします。手順については、「ボリュームの使用」をご参照ください。
ステップ 5:ワークフローの検証
バッチシステムを廃止する前に、両方のシステムを並行して実行します:
既存のバッチジョブは無効化したまま、比較用に利用可能にしておきます。
同一の入力データに対して、両方のシステムで同一のワークロードを実行します。
出力を競合しないよう、別々のパスに書き込みます。
結果(データ精度、出力構造、リソース使用量)を比較し、同等性を確認します。
正しさが確認された後、バッチジョブを廃止します。
並行実行期間は短く保ってください。長期にわたる二重運用は、運用オーバーヘッドおよび乖離リスクを増加させます。
ステップ 6:監視およびログ記録の有効化
ワークフローのステータスおよびログを確認するため、クラスターの可観測性を有効化します。さらに計算コストを削減するため、プリエンプティブルインスタンスを利用できます。
注意事項
Argo ワークフローは、ユーザーエクスペリエンス、コア機能、計算環境、エコシステム統合の全領域において、主流のバッチコンピューティングシステムを置き換えます。特に複雑なワークフローオーケストレーションや、エラスティックかつノードレスな計算を活かせるシナリオに適しています。
ワークフロー定義は Kubernetes YAML 仕様に準拠し、タスク定義は Kubernetes コンテナ仕様に準拠します。チームがすでに Kubernetes を使用している場合、習得コストは最小限です。
計算環境にはエラスティックコンテナインスタンス(ノードレス)が使用されます。リソースは需要に応じてスケールし、従量課金方式で課金され、ジョブキューは不要です。
プリエンプティブルインスタンスを使用することで、さらに計算コストを削減できます。
分散型ワークフローは、CI/CD、データ処理、シミュレーション、科学計算に適しています。