DevOps定着バイブル

GitOpsで実現するKubernetes環境の継続的デリバリー:Flux/Argo CDを活用した実践ガイド

Tags: GitOps, Kubernetes, CI/CD, Flux, Argo CD

DevOps文化の確立において、継続的インテグレーション(CI)と継続的デリバリー(CD)は不可欠な要素です。特にKubernetesのようなコンテナオーケストレーション環境においては、インフラストラクチャもアプリケーションもコードとして管理するInfrastructure as Code(IaC)のアプローチが主流となっています。しかし、これらの複雑な設定を手動で適用したり、CIパイプラインから直接クラスタに変更をプッシュする「プッシュ型」のデプロイメントモデルには、セキュリティ、監査性、そして運用の安定性といった点で課題が存在します。

本記事では、これらの課題を解決し、Kubernetes環境におけるデプロイメントの信頼性と効率性を劇的に向上させる「GitOps」について、その基本概念から実践的な導入方法、そして主要なツールであるFluxおよびArgo CDの活用例までを深く掘り下げて解説します。

GitOpsとは何か?基本的な概念と原則

GitOpsは、クラウドネイティブな環境における継続的デリバリーを実現するための運用フレームワークであり、Gitリポジトリを「唯一の信頼できる情報源(Single Source of Truth)」として、システムの状態を宣言的に管理するプラクティスです。その核となる原則は以下の通りです。

  1. システム全体がGitで宣言的に記述されていること: アプリケーションのマニフェスト、Kubernetesリソース定義、インフラ構成など、システムの状態を構成する全ての要素がGitリポジトリにYAMLなどの宣言的な形式で格納されます。
  2. システムのあるべき状態(Desired State)がGitによってバージョン管理されていること: Gitの強力なバージョン管理機能により、全ての変更履歴が追跡可能であり、いつでも過去の状態に復元できます。
  3. ソフトウェアエージェントがクラスタにデプロイされており、GitのDesired StateとクラスタのActual Stateを自動的に同期すること: この「コントローラー」または「オペレーター」と呼ばれるソフトウェアが、Gitリポジトリの変更を検知し、クラスタの状態をDesired Stateに一致させるように自動的に調整します。これにより、手動によるデプロイ作業が不要になります。
  4. プルリクエスト(PR)によってすべての変更が承認されていること: システムへの変更は、Gitのプルリクエストを通じて提案され、レビューと承認を経てマージされます。これにより、変更の透明性、コラボレーション、監査性が確保されます。

従来のCI/CDとの違いとGitOpsの優位性

従来のプッシュ型CI/CDパイプラインでは、CIツール(例: Jenkins, GitLab CI, GitHub Actions)がビルド、テストを実行し、その後にデプロイのロジックが組み込まれています。このモデルでは、CIツールがKubernetesクラスタへのアクセス権を持ち、クラスタに対して直接変更を「プッシュ」します。

一方、GitOpsは「プル型」のデプロイメントモデルを採用します。CIパイプラインはアプリケーションイメージのビルドとテストのみを行い、そのイメージタグをGitリポジトリ内のマニフェストファイルにコミットします。その後、クラスタ内にデプロイされたGitOpsオペレーターが、Gitリポジトリの変更を検知し、自身でクラスタの状態を更新します。

GitOpsの優位性は以下の点に集約されます。

GitOpsの主要ツール:FluxとArgo CDの比較

GitOpsを実現するための代表的なツールとして、FluxとArgo CDがあります。どちらもKubernetesネイティブなツールであり、Gitリポジトリを監視し、Kubernetesクラスタの状態を同期させる機能を提供します。

Flux

Argo CD

両者ともに強力なツールですが、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に監視させ、クラスタと同期させます。これは、GitRepositoryKustomizationというカスタムリソースを用いて行います。

例として、clusters/my-cluster/infrastructure.yamlclusters/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のワークフローに組み込まれる点にあります。

  1. 開発: 開発者はアプリケーションコードやKubernetesマニフェストに変更を加えます。
  2. プルリクエスト: 変更をGitリポジトリにコミットし、メインブランチ(またはデプロイ対象のブランチ)へのプルリクエストを作成します。
  3. レビューと承認: チームメンバーがプルリクエストをレビューし、変更内容を承認します。
  4. マージ: 承認されたプルリクエストがメインブランチにマージされます。
  5. 自動同期: FluxオペレーターがGitリポジトリの変更を検知し、Kubernetesクラスタに自動的に適用します。

このプロセスにより、手動でのデプロイコマンド実行が不要となり、変更の履歴と承認プロセスがGitに集約されるため、高い信頼性と透明性が確保されます。

GitOpsの高度な利用とベストプラクティス

GitOpsは基本的なデプロイメントだけでなく、より複雑なシナリオにも対応できます。

結論

GitOpsは、Kubernetes環境における継続的デリバリーを次のレベルに引き上げる強力なパラダイムです。Gitを唯一の信頼できる情報源とし、プルリクエストベースのワークフローと自動同期メカニズムを組み合わせることで、デプロイメントの信頼性、セキュリティ、監査性、そして開発者エクスペリエンスを大幅に向上させます。

本記事で解説したFluxやArgo CDのようなツールを活用し、GitOpsの原則を組織のDevOps文化に組み込むことで、より効率的で安定したソフトウェアデリバリーを実現できるでしょう。導入初期は学習曲線が存在するかもしれませんが、長期的な運用安定性とチームの生産性向上に大きく貢献します。ぜひ、貴社のKubernetes環境にGitOpsの導入を検討し、その恩恵を享受してください。