ArgoWorkflow + Events を導入して撤退した話 - SRE的振り返り
はじめに
こんにちは。saorioと申します。普段はDevOpsを担当しています。最近、一度は使ってみたものの、運用を続ける中でビジネス要件や再現性の低い失敗対応に苦しみ、最終的にリプレースしたシステムの話をしたいと思います。
SRE的な観点も交えつつ、導入当時の判断、運用中に露呈した問題、そして撤退という意思決定までを振り返ります。
学んだこと
- Argo Workflow には CronWorkflow はあるが、PubSub トリガー構成では Job 発火と Node 確保のタイミングを揃える標準機能がない
- RAM が多い GCE Node を Cluster Autoscaler で 0 -> 1 起動すると、公式記載の 80 〜 120 秒に加えてイメージ Pull でさらに時間がかかる
- 運用がつらくても「やめたい」と言い出しづらい。だからこそ、思い切って言語化することが重要
- Observability を後付けするのは高コスト。失敗原因を追える設計は導入時に行うべきだった
- Bus Factor = 1 のシステムは崩れやすい。推進者が抜けた瞬間に ownership が消える
前提となるシステム
このシステムは PubSub から Job 起動メッセージを受け取り、GKE 上で重量級のデータ処理を Job 実行していました。
利用技術としては、Argo Workflows と Argo Events を採用していました。
利用していた構成は次の通りです。
PubSub -> Argo Events(Sensor) -> Argo Workflow(Workflow起動) -> Pod(GKE Node起動) -> Job実行
RAM が多い Compute Engine を必要とするため、コスト最適化として NodeSelector + Cluster Autoscaler で Node を 0 から起動する構成にしていました。
タイムライン
- 2023年前半: 最初の Argo Workflow manifest を導入
- 2023年後半: Role/ServiceAccount 整備、PubSub -> Argo Sensor 経由の起動体制を構築
- 2024年: メインアプリケーションエンジニア 2 名 + 私で運用継続
- 2024年後半: 導入推進エンジニアが退職。引き継ぎ・ドキュメントはほぼ無し
- 2025年: Job 数増加とアプリケーション heavy 化により運用問題が顕在化
- 2025年中旬:
retryStrategy追加(効果は限定的) - 2025年後半: node affinity 更新、Slack 通知修正など断続的にパッチ
- 2025年末: Argo Events の NATS から JetStream への切り替えを試行
- 2026年前半: Datadog metrics 統合を追加、撤退提案を開始
- 2026年中旬: retry 回数調整、Slack 通知削除、
autoscalingpolicy見直し - 2026年6月: Argo 関連 manifest 全削除
- 2026年7月: Argo helm/role 一式削除。撤退完了
導入から撤退まで実質約 3 年半、私が主に対応してから約 1 年運用しました。
運用中に露呈した問題
問題1: Node 起動タイミングと Workflow スケジュールが噛み合わない
結論として、Argo Workflow(+Events) と Cluster Autoscaling はタイミング次第で Workflow がスケジュール失敗することがありました。
NodeSelector を使って Pod をスケジュールしたい場合、Cluster Autoscaler で 0 -> 1 起動すると、立ち上げに時間がかかり、Scheduler が対象 Node を見つけられないことがありました。
Predicate NodeAffinity failed
didn't match Pod's node affinity/selector
GKE 公式には Cluster Autoscaler の反映目安が 80 〜 120 秒とあります。
Provision extra compute capacity for rapid Pod scaling | Google Kubernetes Engine (GKE) | Google Cloud Documentation Reserve extra compute capacity in your clusters to improve Pod scaling times.実際には heavy なイメージの Pull 時間が上乗せされ、120 秒を超えるケースが常態化していました。
また、この現象は私たち固有ではなく、Argo Workflows の issue でも同系統の問題として報告があります。
GKE Pod/Node Exhaustion Resulting in Failed Workflows · Issue #4794 · argoproj/argo-workflows Summary We're evaluating utilizing Argo (Workflows and Events) to replace our current utilization of Airflow. We have some fairly high volume requirements, starting at around 100 Workflows/minute a...問題2: retryStrategy を書いても効かなかった
2025 年 7 月に次の設定を導入しました。
retryStrategy:
limit: 3
retryPolicy: "OnFailure"
backoff:
duration: "20s"
expression: |
lastRetry.message.contains("Predicate NodeAffinity failed") ||
lastRetry.message.contains("didn't match Pod's node affinity/selector")
しかし効果は限定的でした。
backoff.duration: 20sは短い。20 秒 x 3 回 = 60 秒では Node 起動完了を待てないexpressionが文字列一致依存で、環境差分に弱いretryStrategyの適用境界と scheduling failure の関係で、期待通りに効かないケースがある
問題3: 失敗原因通知が空になる
Argo Workflow 失敗時に Slack 通知していましたが、本文が空の通知が多発しました。
修正を重ねても、workflow status と通知テンプレートの整合が安定せず、結局 kubectl logs を毎回確認する運用が続きました。
SRE 的には、これは「actionable でないアラート」であり、Observability failure です。
問題4: NATS のハートビート問題で Argo Events Pod が消える
Argo Events の EventBus は当初 NATS (stan.go) を使っていましたが、ハートビート由来で Pod が一時消失する事象がありました。
stan.go は deprecated であり、Argo Events 側も JetStream への移行を推奨していたため、切り替えを試しました。
# 変更前
nats:
native:
replicas: 3
auth: token
# 変更後
jetstream:
version: 2.10.10
replicas: 3
persistence:
...
ただし検証結果と移行コストを踏まえ、本番採用は見送りました。
撤退の意思決定
次の観点を Issue に整理し、アプリケーションメンバーへ提案しました。
- Job fail 原因調査の運用負荷が高い
- Cluster Autoscaling 頼りの構造的失敗リスクが消えない
- 観測性の後付けコストが見合わない
結果として、予想より早く撤退方針に合意できました。
SRE 的には次の要因が大きかったと考えています。
- Ownership が薄れたシステムに unresolved な critical 問題が積み重なっていた
- 心理的安全性があり、撤退提案を出せた
- 可逆性を持った構成だったため、Kubernetes Job へ移行しやすかった
撤退後
- Argo 関連 manifest を削除
- Argo helm/role を削除
SRE 的教訓
- 観測性は導入時に組み込む
- Bus Factor を意識する
- Toil を数値化して可視化する
- 可逆性を保つ設計を選ぶ
- 心理的安全性は技術的意思決定を速くする
- 導入時テストには限界がある。だから戻せる設計が必要
- E2E テスト結果と運用設計はレビュー責務を明確にする
おわりに
Argo Workflow + Events は多くの現場で成功しているツールです。
今回の問題は「Cluster Autoscaling 0 -> 1」「Heavy なイメージ」「NodeSelector 必須」という条件での組み合わせに起因していました。ツールが悪いのではなく私たちのユースケースに合わなかったのです。
この振り返りは Argo 批判ではなく、導入時想定の甘さ、運用変化、そして撤退判断を含めた SRE 的学びとして残しておきます。