GitOpsで実現するKubernetes環境の継続的デリバリー:Flux/Argo CDを活用した実践ガイド
DevOps文化の確立において、継続的インテグレーション(CI)と継続的デリバリー(CD)は不可欠な要素です。特にKubernetesのようなコンテナオーケストレーション環境においては、インフラストラクチャもアプリケーションもコードとして管理するInfrastructure as Code(IaC)のアプローチが主流となっています。しかし、これらの複雑な設定を手動で適用したり、CIパイプラインから直接クラスタに変更をプッシュする「プッシュ型」のデプロイメントモデルには、セキュリティ、監査性、そして運用の安定性といった点で課題が存在します。
本記事では、これらの課題を解決し、Kubernetes環境におけるデプロイメントの信頼性と効率性を劇的に向上させる「GitOps」について、その基本概念から実践的な導入方法、そして主要なツールであるFluxおよびArgo CDの活用例までを深く掘り下げて解説します。
GitOpsとは何か?基本的な概念と原則
GitOpsは、クラウドネイティブな環境における継続的デリバリーを実現するための運用フレームワークであり、Gitリポジトリを「唯一の信頼できる情報源(Single Source of Truth)」として、システムの状態を宣言的に管理するプラクティスです。その核となる原則は以下の通りです。
- システム全体がGitで宣言的に記述されていること: アプリケーションのマニフェスト、Kubernetesリソース定義、インフラ構成など、システムの状態を構成する全ての要素がGitリポジトリにYAMLなどの宣言的な形式で格納されます。
- システムのあるべき状態(Desired State)がGitによってバージョン管理されていること: Gitの強力なバージョン管理機能により、全ての変更履歴が追跡可能であり、いつでも過去の状態に復元できます。
- ソフトウェアエージェントがクラスタにデプロイされており、GitのDesired StateとクラスタのActual Stateを自動的に同期すること: この「コントローラー」または「オペレーター」と呼ばれるソフトウェアが、Gitリポジトリの変更を検知し、クラスタの状態をDesired Stateに一致させるように自動的に調整します。これにより、手動によるデプロイ作業が不要になります。
- プルリクエスト(PR)によってすべての変更が承認されていること: システムへの変更は、Gitのプルリクエストを通じて提案され、レビューと承認を経てマージされます。これにより、変更の透明性、コラボレーション、監査性が確保されます。
従来のCI/CDとの違いとGitOpsの優位性
従来のプッシュ型CI/CDパイプラインでは、CIツール(例: Jenkins, GitLab CI, GitHub Actions)がビルド、テストを実行し、その後にデプロイのロジックが組み込まれています。このモデルでは、CIツールがKubernetesクラスタへのアクセス権を持ち、クラスタに対して直接変更を「プッシュ」します。
一方、GitOpsは「プル型」のデプロイメントモデルを採用します。CIパイプラインはアプリケーションイメージのビルドとテストのみを行い、そのイメージタグをGitリポジトリ内のマニフェストファイルにコミットします。その後、クラスタ内にデプロイされたGitOpsオペレーターが、Gitリポジトリの変更を検知し、自身でクラスタの状態を更新します。
GitOpsの優位性は以下の点に集約されます。
- セキュリティの向上: クラスタへの直接的なアクセス権限が、CIツールではなくクラスタ内部のエージェントに限定されるため、攻撃対象領域が減少します。
- 監査性と透明性: すべての変更がGitのコミット履歴として残り、誰が、いつ、どのような変更を行ったかが明確に追跡できます。
- 信頼性と復元性: Gitリポジトリが常にシステムのあるべき状態を保持しているため、予期せぬ障害が発生した場合でも、簡単に過去の安定した状態に復元できます。
- 開発者エクスペリエンスの向上: Gitのワークフローに集中できるため、開発者はデプロイの詳細を意識することなく、プルリクエストを通じて変更を提案できます。
GitOpsの主要ツール:FluxとArgo CDの比較
GitOpsを実現するための代表的なツールとして、FluxとArgo CDがあります。どちらもKubernetesネイティブなツールであり、Gitリポジトリを監視し、Kubernetesクラスタの状態を同期させる機能を提供します。
Flux
- 特徴: CNCF Graduatedプロジェクトであり、GitOps Toolkitという一連のコンポーネントで構成されます。Gitリポジトリの監視、KustomizeやHelmの適用、コンテナイメージの自動更新など、幅広いGitOps機能を提供します。
- アーキテクチャ: さまざまなカスタムリソース(
GitRepository
,Kustomization
,HelmRelease
,ImageRepository
,ImagePolicy
など)とそれらを管理するコントローラー群で構成されます。これらのリソースをKubernetes APIを介して操作することで、GitOpsワークフローを制御します。 - 強み: モジュラーな設計であり、コンポーネントを組み合わせて柔軟なGitOpsパイプラインを構築できます。特にイメージの自動更新機能は非常に強力です。
Argo CD
- 特徴: CNCF Graduatedプロジェクトであり、Kubernetes上で動作するGitOps継続的デリバリーツールです。豊富なWeb UIを持ち、デプロイの状態を視覚的に把握しやすいのが特徴です。
- アーキテクチャ:
Application
というカスタムリソースが核となり、Gitリポジトリの指定、同期オプション、デプロイ戦略などを定義します。Argo CDサーバー、リポジトリサーバー、アプリケーションコントローラー、APIサーバーなどで構成されます。 - 強み: 直感的で使いやすいWeb UIとCLIを提供し、複雑なKubernetesアプリケーションの管理を簡素化します。Sync HooksやSync Wavesといった高度なデプロイ戦略もサポートします。
両者ともに強力なツールですが、FluxはよりAPI駆動でモジュラーなアプローチを好み、Argo CDはより統合されたUIと高い操作性を求める場合に適していると言えるでしょう。
実践ステップ:Kubernetes環境へのGitOps導入ガイド(Fluxを例に)
ここでは、Fluxを例にとり、Kubernetes環境にGitOpsを導入する基本的なステップを解説します。
1. Gitリポジトリの準備
まず、Kubernetesクラスタにデプロイするアプリケーションのマニフェストや、クラスタ設定を格納するGitリポジトリを用意します。例えば、以下のような構成です。
├── applications/
│ └── frontend/
│ ├── kustomization.yaml
│ └── deployment.yaml
│ └── service.yaml
└── infrastructure/
└── namespaces/
├── kustomization.yaml
└── frontend-namespace.yaml
frontend-namespace.yaml
の例:
apiVersion: v1
kind: Namespace
metadata:
name: frontend
frontend/deployment.yaml
の例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-app
namespace: frontend
spec:
replicas: 3
selector:
matchLabels:
app: frontend-app
template:
metadata:
labels:
app: frontend-app
spec:
containers:
- name: frontend-container
image: your-repo/frontend-app:v1.0.0 # イメージはCIパイプラインで更新される
ports:
- containerPort: 80
2. Flux CLIのインストールとクラスタへのデプロイ
Flux CLIをローカルマシンにインストールし、これを使ってKubernetesクラスタにFluxをデプロイします。
# Flux CLIのインストール (macOSの例)
brew install fluxcd/tap/flux
# クラスタへのFluxのデプロイ
# GitHub Enterpriseを使用する場合など、ホスト名を指定します
# export GITHUB_HOSTNAME=github.com
flux bootstrap github \
--owner=<your-github-username-or-org> \
--repository=<your-gitops-repo-name> \
--branch=main \
--path=./clusters/my-cluster \
--personal
このコマンドは、指定されたGitリポジトリにFluxの設定ファイル(clusters/my-cluster
ディレクトリ内)を作成し、その設定に基づいてKubernetesクラスタにFluxオペレーターをデプロイします。Fluxオペレーターは、このリポジトリのclusters/my-cluster
パスを監視するようになります。
3. アプリケーションとインフラ設定の同期設定
Fluxがデプロイされたら、アプリケーションやインフラの定義が格納されたGitリポジトリのパスをFluxに監視させ、クラスタと同期させます。これは、GitRepository
とKustomization
というカスタムリソースを用いて行います。
例として、clusters/my-cluster/infrastructure.yaml
と clusters/my-cluster/applications.yaml
を作成します。
clusters/my-cluster/infrastructure.yaml
の例:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 1m0s
url: https://github.com/<your-github-username-or-org>/<your-gitops-repo-name>
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 10m0s
path: ./infrastructure
prune: true
sourceRef:
kind: GitRepository
name: infrastructure
targetNamespace: default
clusters/my-cluster/applications.yaml
の例:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: applications
namespace: flux-system
spec:
interval: 1m0s
url: https://github.com/<your-github-username-or-org>/<your-gitops-repo-name>
ref:
branch: main
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: frontend-app
namespace: flux-system
spec:
interval: 10m0s
path: ./applications/frontend
prune: true
sourceRef:
kind: GitRepository
name: applications
targetNamespace: frontend # frontend名前空間はinfrastructure Kustomizationによって作成される
dependsOn:
- name: infrastructure # infrastructure Kustomizationが完了してから実行
これらのファイルをGitリポジトリにプッシュすると、Fluxオペレーターが変更を検知し、Kubernetesクラスタに定義されたリソース(例: frontend
名前空間、frontend-app
デプロイメント)を自動的に作成・更新します。
4. 変更管理と承認ワークフロー
GitOpsの真髄は、デプロイプロセスが完全にGitのワークフローに組み込まれる点にあります。
- 開発: 開発者はアプリケーションコードやKubernetesマニフェストに変更を加えます。
- プルリクエスト: 変更をGitリポジトリにコミットし、メインブランチ(またはデプロイ対象のブランチ)へのプルリクエストを作成します。
- レビューと承認: チームメンバーがプルリクエストをレビューし、変更内容を承認します。
- マージ: 承認されたプルリクエストがメインブランチにマージされます。
- 自動同期: FluxオペレーターがGitリポジトリの変更を検知し、Kubernetesクラスタに自動的に適用します。
このプロセスにより、手動でのデプロイコマンド実行が不要となり、変更の履歴と承認プロセスがGitに集約されるため、高い信頼性と透明性が確保されます。
GitOpsの高度な利用とベストプラクティス
GitOpsは基本的なデプロイメントだけでなく、より複雑なシナリオにも対応できます。
- マルチクラスタ管理: 複数のKubernetesクラスタを持つ場合でも、各クラスタの状態をそれぞれのGitリポジトリのパスやブランチで管理し、単一のGitOpsワークフローで運用できます。
- 環境ごとの設定管理: KustomizeやHelmのValuesファイルを利用して、開発、ステージング、本番といった異なる環境に合わせた設定を効果的に管理できます。GitOpsツールはこれらのツールと深く統合されています。
- シークレット管理: Gitリポジトリにシークレットを平文で格納するのは避けるべきです。SOPS(Secrets OPerationS)やKubernetes Secrets Store CSI Driverのようなツールと組み合わせることで、暗号化されたシークレットをGitで管理し、クラスタ内で復号するセキュアな運用が可能です。
- ロールバック戦略: Gitのコミット履歴がシステムのあるべき状態を保持しているため、問題が発生した場合には、以前の安定したコミットにGitをロールバックするだけで、クラスタの状態も自動的にロールバックされます。
- オブザーバビリティとの統合: Prometheus、Grafana、OpenTelemetryといった監視・トレーシングツールと組み合わせることで、GitOpsによってデプロイされたアプリケーションのパフォーマンスや健全性を継続的に監視し、DevOpsループを完成させます。
結論
GitOpsは、Kubernetes環境における継続的デリバリーを次のレベルに引き上げる強力なパラダイムです。Gitを唯一の信頼できる情報源とし、プルリクエストベースのワークフローと自動同期メカニズムを組み合わせることで、デプロイメントの信頼性、セキュリティ、監査性、そして開発者エクスペリエンスを大幅に向上させます。
本記事で解説したFluxやArgo CDのようなツールを活用し、GitOpsの原則を組織のDevOps文化に組み込むことで、より効率的で安定したソフトウェアデリバリーを実現できるでしょう。導入初期は学習曲線が存在するかもしれませんが、長期的な運用安定性とチームの生産性向上に大きく貢献します。ぜひ、貴社のKubernetes環境にGitOpsの導入を検討し、その恩恵を享受してください。