Skip to main content

ArgoCD vs Flux、K3sのGitOpsで知るべき「Traefik OutOfSync」の罠

K3sクラスタにGitOpsを導入しようとして、ArgoCDとFluxのどちらを選ぶべきか迷っていないだろうか。 どちらもCNCF Graduatedの成熟したプロジェクトであり、機能比較表を見ても優劣がつけにくい。 しかし実際にK3sへArgoCDやFluxを導入してみると、K3sが標準で持っているコンポーネント構成が原因で、 一般的なGitOpsツール比較記事には書かれていない罠にぶつかることがある。本記事ではArgoCD/Fluxの 基本的な違いに加えて、K3s特有の落とし穴を具体的に解説し、選定基準を示す。 (この種の相性調査自体を事前に済ませた環境が欲しい場合は、Kuboのような K3sベースのマネージドサービスを検討する価値がある)

section01

1. ArgoCD vs Flux、何がどう違うのか

ArgoCDとFluxはどちらも2022年にCNCFのGraduatedプロジェクトとなった、GitOpsの代表的なツールだ。 Fluxは2022年11月30日に卒業を発表し、Argo(ArgoCDを含むArgo Project)はその約1週間後に卒業している (CNCF: Argo graduates from CNCF Incubator)。 ライセンスはいずれもApache 2.0で、技術的な成熟度に大きな差はない。違いはアーキテクチャの思想に出る。

UIの有無とチーム運用

ArgoCDは組み込みのWeb UIを持ち、アプリケーションの同期状態・差分・履歴を一画面で確認できる。 インストールから30分程度でUIが使える状態になり、kubectlに不慣れなメンバーのオンボーディングもしやすい (oneuptime.com: ArgoCD vs FluxCD in 2026)。 一方Fluxには標準UIがなく、flux CLIやkubectlでの操作が基本になる。Weave GitOps等のサードパーティUIも 存在するが、成熟度はArgoCDの組み込みUIには及ばない。

マルチクラスタ管理の方式

ArgoCDは単一のコントロールプレーンから複数クラスタを登録し、一元管理できる設計になっている。 管理用クラスタにArgoCDを1つ立て、開発・ステージング・本番の各クラスタをターゲットとして登録する構成が 一般的だ(Tailscale: Manage multi-cluster Kubernetes deployments with ArgoCD)。 対してFluxはクラスタごとに個別インストールするのが基本で、各クラスタが自律的にGitリポジトリを Pullする構成になる。エッジに多数のK3sクラスタを展開するような構成では、この自律性がむしろ強みになる。

Helmチャートのライフサイクル管理

FluxはHelmReleaseリソースを介してHelmのinstall/upgrade/test/rollbackといった操作をコントローラーが 継続的に調整する仕組みを持つのに対し(Flux公式: Helm Releases)、 ArgoCDはHelmチャートをレンダリングしてSync対象のマニフェストとして扱うアプローチを取る。 この違いが、次章で説明するK3s特有の罠に直結してくる。

section02

2. K3sで起きる罠1 — ArgoCD導入時、Traefik標準搭載が「OutOfSync」を生むことがある

K3sは標準でIngressコントローラーとしてTraefikを同梱している。このTraefikをArgoCDの管理対象に含めると、 実際に「常にOutOfSyncと表示され続ける」トラブルが報告されたことがある。

原因はTraefikのHelm Chartが、GOMEMLIMITとGOMAXPROCSという環境変数をresourceFieldRef経由で コンテナのリソース上限から取得する設定になっていたことだ。Kubernetesはこの参照にdivisor(除数)の 指定がない場合、デプロイ時に暗黙のデフォルト値を補完する。ところがHelmテンプレート側にはその divisorが明示されていなかったため、ArgoCDがクラスタ上の実際のマニフェストとGit上の定義を比較するたびに 差分を検出し、同期済みのはずのアプリケーションが永久にOutOfSyncと表示され続けていた (traefik/traefik-helm-chart Issue #1065)。

この問題はTraefik Helm Chart側のPR #1085で修正され、2024年6月にクローズ済みだ。したがって最新版の Traefik Helm Chartを使う限り同じ現象には遭遇しない。しかし重要なのは個別のバグそのものではなく、 「K3sが標準搭載するコンポーネントのHelm Chartが、環境変数のリソース参照など細かい仕様差でArgoCDの 差分検知と衝突しうる」という構造的なリスクパターンだ。K3sのバージョンアップでTraefikのHelm Chartが 更新された際や、他の組み込みコンポーネント(local-path-provisioner等)をArgoCD管理下に置く際にも、 同種の「終わらないOutOfSync」が再発しうることを踏まえておく必要がある。

対策としては、K3sの既定コンポーネントをGitOps管理対象に含めるかどうかを事前に設計段階で決め、 含める場合はignoreDifferencesでArgoCDに特定フィールドの差分を無視させる設定を併用するのが現実的だ (ArgoCD公式FAQ)。 Kubo Cloudでは、こうしたK3s標準コンポーネントとArgoCD/Fluxの既知の相性問題を 検証済みの構成をCaptain UI経由で提供しており、ignoreDifferencesの設計をゼロから洗い出す工数を省ける。

section03

3. K3sで起きる罠2 — FluxCDのHelmChartはK3sのHelmChartと同名の別物(補足)

Fluxを選ぶ場合に知っておくべき罠もある。K3sには組み込みのHelm Controllerがあり、 helm.cattle.io/v1のHelmChartというCRDでHelmチャートのインストール・アップグレードを管理している (K3s公式ドキュメント: Helm)。

一方、FluxのSource ControllerもHelmChartという名前のCRD(source.toolkit.fluxcd.ioグループ)を 定義している。つまりK3s上でFluxを使うと、Kind名が完全に一致する2つの別物のCRDが同一クラスタに 共存することになる。Flux公式のトラブルシューティングガイドでも、K3sのように別のHelm Controllerを 同梱する環境では、完全修飾名を使わずにkubectl get helmchartsを実行すると意図しない方のCRDが 返ってきてしまう既知の問題として明記されている (Flux公式: Troubleshooting cheatsheet)。

回避策はシンプルで、kubectl get helmcharts.source.toolkit.fluxcd.io -Aのように完全修飾名で 参照するか、Flux CLIのflux get source chartを使うことだ。なお、K3s自身のHelmChart CRDを 手動でhelm upgradeした際に設定が消える別種の罠については、過去記事 「K3sのHelmChart CRDで配ったアプリを直接helm upgradeしたら、次のreconcileで設定が消えた」で 詳しく扱っているので、K3sのHelm Controllerそのものを操作する場合はそちらも参照してほしい。

section04

4. 結局どちらを選ぶべきか — K3sクラスタの運用形態別の判断基準

ここまでの機能差と罠を踏まえると、判断基準は次のように整理できる。

  • 単一〜少数のK3sクラスタを、非エンジニアを含むチームで運用する場合: ArgoCDが有利。 組み込みUIで同期状態を可視化でき、オンボーディングコストが低い。ただしK3s標準コンポーネントを 管理対象に含めるなら、ignoreDifferencesの設計をあらかじめ検討する。
  • エッジに多数のK3sクラスタを展開し、各クラスタが自律的にGitから同期すればよい場合: Fluxが有利。 イメージの自動更新(Image Automation)によってCI側でタグを書き換える処理が不要になる点も 運用負荷を下げる(oneuptime.com: When to Choose Flux CD Over ArgoCD)。 ただし前述のHelmChart CRD名前衝突を避けるため、完全修飾名での運用ルールをチーム内で徹底する必要がある。
  • K3sの既定コンポーネント(Traefik, local-path-provisioner等)をGitOps管理対象に含めるか: 含めない(K3sの既定動作に任せる)選択肢もある。GitOpsの対象範囲をアプリケーション層に限定すれば、 本記事で挙げた2つの罠のいずれも回避できる。

section05

まとめ

ArgoCDとFluxはどちらもCNCF Graduatedの成熟したGitOpsツールであり、一般的な機能比較だけでは 優劣をつけにくい。しかしK3sで実際に運用すると、標準搭載のTraefikやK3s自身のHelm Controllerが持つ HelmChartという名前のCRDが、選んだGitOpsツールとの間で予想外の衝突を起こすことがある。 これらは個別のバグというより、「K3sの既定コンポーネント」と「GitOpsツールの管理範囲」が 交差する場所に共通して現れるリスクパターンだ。

こうした衝突調査やignoreDifferencesの設計は、GitOps運用を始める前に必ず踏まえておきたい工数だが、 本来はアプリケーションのデリバリーに集中したい作業でもある。Kuboは K3sベースのマネージドKubernetesサービスとして、ArgoCD・Fluxいずれとの組み合わせでも標準コンポーネントとの 相性を検証済みの環境を提供しており、Captain UI経由でのGitOps統合もサポートしている。 K3sクラスタのGitOps運用で同じ罠を踏みたくない場合は、Kuboの お問い合わせから構成の相談が可能だ。

EKSやAKSの高コスト・複雑さ・ベンダーロックインに悩む必要はもうない。K3sベースのKuboなら、 本格的なKubernetesの機能とGitOpsの柔軟性はそのままに、圧倒的なコスト効率で運用できる。

Related articles

← Back to all posts