ArgoCDによるGitOpsの実装:Kubernetesを「信頼できる唯一の情報源」にする

Development tutorial - IT technology blog
Development tutorial - IT technology blog

本番環境で直接「kubectl edit」を実行して冷や汗をかいたことはありませんか?

正直に言いましょう。インフラエンジニアの多くは、緊急事態にクラスター上の設定を直接修正した経験が一度はあるはずです。しかし、その結果はどうでしょう。一週間後には何を修正したか誰も覚えていません。新しいデプロイを行うと、手動で行った設定はすべて消え去り、古いバグが再発します。こうした混乱に終止符を打つのがGitOpsです。

簡単に言えば、GitOpsはGitを「信頼できる唯一の情報源(Single Source of Truth)」として扱います。インフラからアプリケーションまで、あらゆる変更はGitのコミットを経由しなければなりません。ArgoCDは、いわば「クルーズコントロール」のような役割を果たします。Kubernetes上の実際の状態が、Gitに定義された状態と一致しているかを常に監視し、差異を検知すると自動的に元の正しい状態へと戻してくれます。

クイックスタート:5分でArgoCDを導入する

Kubernetesクラスター(Minikube、K3s、EKSなど)があれば準備完了です。以下のコマンドを実行してインストールしましょう。

# 専用のNamespaceを作成
kubectl create namespace argocd

# 安定版をインストール
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Web UIに素早くアクセスするには、ポートフォワードを使用します:

kubectl port-forward svc/argocd-server -n argocd 8080:443

次に、https://localhost:8080を開きます。デフォルトのユーザー名はadminです。パスワードは自動生成されるため、以下のコマンドで取得してください:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

注意:セキュリティのため、すぐにパスワードを変更し、このSecretを削除することをお勧めします。

なぜArgoCDは従来のJenkinsやGitHub Actionsよりも優れているのか?

「GitHub Actionsでkubectl applyを実行すれば十分では?」と思うかもしれません。この手法はPush型(Push-based)と呼ばれます。コマンドを送り込み、成功することを祈るスタイルです。しかし、その瞬間にクラスターとの接続が切れたり、誰かが手動でDeploymentを削除したりしても、CI/CDツールはその事実に全く気づけません。

ArgoCDはPull型(Pull-based)モデルを採用しており、以下のような圧倒的なメリットがあります:

  • 自動同期(Auto-sync):Gitを継続的にポーリングします。YAMLの変更を検知すると、即座にクラスターを更新します。
  • ドリフト検知(Drift Detection):誰かがクラスターを手動操作しても、ArgoCDは「OutOfSync」状態を報告します。クリック一つでシステムを標準状態に戻せます。
  • 視覚的なモニタリング:ArgoCDのダッシュボードでは、コマンドを打ち込むことなく、各PodやServiceのヘルス状態を一目で把握できます。

複雑なYAMLやJSONの構成ファイルを扱う際、私はよくJSON Formatterを使用してデータ構造を素早くチェックしています。これにより、Gitにコミットする前の初歩的なフォーマットエラーを防ぐことができます。

GitOps標準に則った最初のアプリケーション作成

Nginxアプリケーションのdeployment.yamlを含むリポジトリがあると仮定しましょう。このリポジトリを監視するための「Application」をArgoCD上に作成します。

ステップ1:Git上でマニフェストを準備する

シンプルなnginx-app.yamlを作成します:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

ステップ2:ArgoCDにアプリケーションを管理させる

UIを使う代わりに、YAMLファイルを使用してArgoCD自体を構成します(App-of-Appsパターン):

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-nginx-app
  namespace: argocd
spec:
  source:
    repoURL: 'https://github.com/your-username/your-repo.git'
    path: 'manifests'
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

ここで最も重要な2つの機能は、Prune(Gitから削除された際にクラスター上の不要なリソースを自動削除する)と、SelfHeal(外部から変更が加えられた際に自動修復する)です。

実践から得た「現場の知恵」

多くの大規模システムでGitOpsを導入してきた経験から、3つの重要な教訓を共有します:

  1. SecretをGitにプッシュしない:パスワードをプレーンテキストでコミットしてはいけません。Sealed SecretsExternal Secrets Operatorを使用して、VaultやAWS Secrets Managerと連携させましょう。
  2. CodeリポジトリとManifestリポジトリを分離する:これは黄金律です。CIが新しいイメージをビルドしたら、Manifestリポジトリのタグを更新するだけにします。これにより、デプロイプロセスをコードのビルドから独立して制御できます。
  3. Kustomizeを活用する:Dev/Prod環境ごとにYAMLをコピー&ペーストするのではなく、Kustomizeを使用して差分(レプリカ数やリソース制限など)を管理しましょう。

GitOpsを導入することで、システムの平均復旧時間(MTTR)を最大80%短縮できます。消火活動のようにコマンドを探し回る代わりに、ArgoCDをGitリポジトリに向けるだけで、すべてが一瞬で復元されます。それこそが、すべてのDevOpsエンジニアが目指すべき「安心感」なのです。

Share: