Push と Pull:Flux が Kubernetes にデリバリーする仕組み
Git 主導の pull 型デリバリーが、デプロイ、セキュリティ、復旧の方法をどう変えるか。
多くのチームは、Kubernetes へのデプロイを同じ方法で始めます。CI システムがイメージをビルドし、クラスターに対して kubectl apply や helm upgrade を実行します。これは機能しますが、アプリケーションやクラスターの数が増えるまでです。このガイドでは、Flux のようなクラスター内のエージェントが代わりに Git から望ましい状態を pull する場合に何が変わるのか、そしてどのようなトレードオフがあるのかを説明します。
push モデルと、その限界
push 型パイプラインでは、CI ジョブだけがクラスターに触れます。
- commit がテストとイメージビルドを起動します。
- ジョブがマニフェストの新しいイメージタグを更新します。
- ジョブがクラスターに対して
kubectl apply(またはhelm upgrade)を実行します。
スケールすると、3 つの問題が現れます。
- 認証情報がクラスターの外にある。 すべてのパイプラインに kubeconfig やクラウドの認証情報が必要で、アプリケーションとクラスターが増えるたびにそれが増えます。
- 一度きりで終わる。 ジョブが終了すると、クラスターを監視するものは何もありません。2 週間前の誰かの
kubectl editは、インシデントを引き起こすまで見えません。 - 「何がデプロイされているか」への簡単な答えがない。 パイプラインの最後の実行は信頼できる記録ではないため、クラスター自体を調べる必要があります。
方向を反転する:pull
pull モデルでは、エージェントがクラスター内で動作し、Git リポジトリを監視して、そこに宣言されている内容と稼働中の内容を比較し、差分を適用します。Flux がそのエージェントです。それぞれが 1 つの仕事を担当する、いくつかの小さなコントローラーで構成されています。
| コントローラー | 役割 |
|---|---|
| source-controller | Git リポジトリ、Helm リポジトリ、OCI アーティファクト、バケットを取得し、他のコントローラーが使えるようにする |
| kustomize-controller | ソースから Kubernetes マニフェスト(プレーンな YAML または Kustomize オーバーレイ)をビルドして適用する |
| helm-controller | Helm リリースをインストール、アップグレード、テスト、ロールバックする |
| notification-controller | アラート(Slack、Teams など)を送信し、webhook を受信する |
| image-reflector / image-automation コントローラー | オプション。コンテナレジストリをスキャンし、新しいイメージタグを Git に commit する |
Developer ─▶ App repo ─▶ CI (test, build) ─▶ Image registry
│
└─ commits new image tag ─▶ Config repo
▲
Flux (in cluster) ┘ pulls, compares, applies
│
▼
Kubernetes
変更を適用するのはクラスター内で動作するエージェントだけなので、クラスターの認証情報はクラスターの外に出ません。エンジニアや CI システムに必要なのは Git への書き込み権限だけです。
GitOps の 4 つの原則
OpenGitOps ワーキンググループは、GitOps を 4 つの原則で定義しています。Flux は 4 つすべてを実装しています。
- 宣言的。 システムは、スクリプトではなく YAML で記述されます。
- バージョン管理され、不変。 Git が唯一の信頼できる情報源です。すべての変更は、監査して元に戻せる commit です。
- 自動的に pull される。 承認された変更は、クラスターに押し込まれるのではなく、クラスターによって取得されます。
- 継続的に調整される。 エージェントが、望ましい状態と実際の状態を比較し、ドリフトを修正します。
Flux は自分自身を管理する
Flux の特徴的な機能は bootstrap です。flux bootstrap コマンドは、Flux をクラスターにインストールし、Flux 自身のマニフェストを Git リポジトリに commit し、その同じリポジトリから同期するように Flux を設定します。初日から、GitOps のツール自体も Git を通じて管理されます。次のガイドで説明します。
アプリケーションコードと設定を別のリポジトリに分ける
一般的な推奨は 2 つのリポジトリです。1 つはアプリケーションのソースコード用、もう 1 つは Kubernetes の設定(Deployment、Service、HelmRelease など)用です。
設定は、独自のスケジュールで変わります。Service や ConfigMap を編集するたびに、変更のないコードのビルドとテストのパイプライン全体を実行すべきではありません。2 つのリポジトリがあれば、CI パイプラインの最後のステップは「新しいイメージタグを設定リポジトリに commit する」になり、あとは Flux が引き継ぎます。責任範囲もきれいに分かれ、開発者が CI を、プラットフォームチームや運用チームがデリバリーを担当します。
Flux は、新しいイメージタグを設定リポジトリに取り込む方法を 2 つ提供しています。
- CI が commit する。 パイプラインのスクリプトが YAML のタグを更新して push します。どの CI システムでも機能します。
- Flux が commit する。 オプションのイメージ自動化コントローラーが、レジストリを監視し、タグの変更を自分で Git に push します。このシリーズのイメージ自動化のガイドを参照してください。
Git を唯一の入口にする:ドリフトの修正
Flux は一定の間隔で調整を行います。稼働中のクラスターが Git と異なる場合、Flux は Git のバージョンを再度適用するため、手動の変更は元に戻されます。これには実用的な効果があります。
- すべての変更に commit、作成者、通常はレビュー済みのプルリクエストがあり、監査証跡が得られます。
- 権限が Git に移ります。多くの人がプルリクエストを開けますが、マージできるのは少数だけです。
- 本番環境での手軽な
kubectl editが、黙って残り続ける変更ではなくなります。
ロールバックと復旧が Git の操作になる
望ましい状態がバージョン管理されているため、既知の正常な状態に戻すには git revert を実行するだけで、Flux がクラスターをそれに収束させます。復旧にも同じ考え方が当てはまります。クラスターが失われた場合は、新しいクラスターを作成し、同じリポジトリとパスに対して flux bootstrap を実行すれば、ワークロードは Git から再作成されます。永続データや別の場所で管理しているシークレットなど、Git にないものについては、引き続き独自のバックアップ戦略が必要です。
Flux が置き換えないもの
Flux はデリバリーのツールキットであり、ビルドツールではありません。コードのテスト、イメージのビルド、レジストリへのプッシュには、引き続き CI が必要です。Kubernetes 専用なので、他のデプロイ先には別のツールが必要です。そして唯一の GitOps コントローラーでもありません。Argo CD は同じ原則を異なる設計で実装しており、このシリーズの比較ガイドで説明しています。このシリーズの残りは Flux を前提とし、そのインストールから始めます。詳しいリファレンスは、Flux の公式ドキュメントを参照してください。
人気のガイド
-
GitRepository と Kustomization で最初のアプリケーションをデプロイする Kustomization リソースを使って Flux を Git のマニフェストに向け、同期の様子を確認します。 -
同期動作を制御する:間隔、prune、ドリフトの修正、ロールバック Flux がいつ変更を適用するか、何を削除するか、どう一時停止するか、失敗したデプロイをどう元に戻すかを決めます。 -
Flux Image Automation でイメージの更新を自動化する 新しいコンテナイメージのタグを Flux に検出させ、Git に commit させます。 -
Flux でマルチクラスターを構成する 共有インフラとクラスターごとの違いを持たせて、1 つのリポジトリから複数のクラスターを管理します。 -
Flux CD と Argo CD:GitOps ツールの選び方 アーキテクチャ、UI、Helm、シークレット、テナンシー、イメージの自動化を比較して、適切なツールを選びます。