ArgoCD

ArgoCD 完全ガイド — GitOpsによるKubernetes継続的デリバリーの実践

目次

  1. はじめに — ArgoCDとは何か
  2. GitOpsの基本概念とArgoCDの位置づけ
  3. アーキテクチャの全体像
  4. コアコンポーネントの詳細
  5. インストールと初期設定
  6. Applicationリソースの定義と管理
  7. リポジトリ管理と認証設定
  8. Sync戦略とSyncポリシー
  9. ヘルスチェックとステータス管理
  10. Helm / Kustomize / Jsonnet との統合
  11. ApplicationSetによる大規模管理
  12. マルチクラスタ管理
  13. RBAC(ロールベースアクセス制御)
  14. SSO連携と認証設定
  15. Webhook連携とCI/CDパイプライン統合
  16. Notificationによる通知設定
  17. Image Updaterによる自動イメージ更新
  18. カスタムヘルスチェックとリソースフック
  19. Diffカスタマイズとリソース除外
  20. ディザスタリカバリとバックアップ
  21. パフォーマンスチューニング
  22. セキュリティベストプラクティス
  23. トラブルシューティング
  24. 実践的なプロダクション構成例
  25. まとめと今後の展望

1. はじめに — ArgoCDとは何か

ArgoCD は、Kubernetes 向けの宣言的な GitOps 継続的デリバリー(CD)ツールである。Argo プロジェクトの一部として CNCF(Cloud Native Computing Foundation)に所属し、Graduated プロジェクトとして広く採用されている。

ArgoCD の基本的な思想は極めてシンプルである。「Git リポジトリに格納されたマニフェストの状態を、Kubernetes クラスタ上の実際の状態と常に一致させる」ことを自動化する。これにより、以下のような利点が得られる。

  • 宣言的な構成管理: すべてのアプリケーション構成が Git に格納され、変更履歴が完全に追跡可能
  • 自動同期: Git の変更が検出されると、自動的にクラスタへ反映可能
  • ドリフト検出: クラスタ上の手動変更(drift)を検出し、アラートまたは自動修復が可能
  • マルチクラスタ対応: 単一の ArgoCD インスタンスから複数の Kubernetes クラスタを管理
  • 監査証跡: すべてのデプロイ操作が Git コミットとして記録される

ArgoCDが解決する課題

従来の CI/CD パイプラインでは、CI ツール(Jenkins、GitHub Actions など)がビルドからデプロイまでを一気通貫で実行することが一般的であった。しかし、このアプローチにはいくつかの問題がある。

  1. クレデンシャルの散在: CI システムが Kubernetes クラスタへの書き込み権限を持つ必要があり、セキュリティリスクが増大する
  2. 状態の不一致: パイプラインの途中で失敗した場合、Git の状態とクラスタの状態が乖離する
  3. 手動変更の検出不能: kubectl で直接行われた変更を追跡できない
  4. 再現性の欠如: 特定の時点のクラスタ状態を再現することが困難

ArgoCD はこれらの課題を「Pull 型デプロイ」によって解決する。CI システムは Git リポジトリへのプッシュまでを担当し、ArgoCD がクラスタ内部から Git の変更を検出してデプロイを実行する。


2. GitOpsの基本概念とArgoCDの位置づけ

GitOpsとは

GitOps は、Weaveworks の Alexis Richardson によって2017年に提唱された運用モデルである。その核心は以下の4つの原則に集約される。

原則1: 宣言的な記述 システムの望ましい状態はすべて宣言的に記述されなければならない。Kubernetes のマニフェスト(YAML/JSON)はこの原則に完全に適合する。

原則2: バージョン管理と不変性 望ましい状態は Git に格納され、バージョン管理される。すべての変更はコミットとして記録され、任意の時点への巻き戻しが可能である。

原則3: 自動的な適用 承認された変更は自動的にシステムに適用される。手動の kubectl apply は不要であり、推奨されない。

原則4: 継続的な調整(Reconciliation) ソフトウェアエージェントが実際の状態と望ましい状態の差分を継続的に監視し、乖離が検出された場合は自動的に修復する。

ArgoCDとFlux CDの比較

GitOps ツールとして広く知られるのは ArgoCD と Flux CD の2つである。

特性ArgoCDFlux CD
UIリッチな Web UI を標準搭載UI なし(Weave GitOps で補完可能)
マルチテナンシーProject による詳細な RBACNamespace ベースの分離
アプリケーション定義Application CRDKustomization / HelmRelease CRD
マルチクラスタネイティブサポートCluster API 連携
Helm サポートテンプレートレンダリング方式Helm Controller による管理
通知機能ArgoCD NotificationsFlux Notification Controller
学習曲線やや高い比較的低い

ArgoCD は特に、Web UI による視覚的な管理、詳細な RBAC、マルチクラスタ管理の容易さにおいて優位性がある。一方、Flux CD はよりシンプルで Kubernetes ネイティブなアプローチを採用している。


3. アーキテクチャの全体像

ArgoCD のアーキテクチャは、複数のマイクロサービスコンポーネントで構成されている。各コンポーネントは Kubernetes の Pod として動作し、それぞれが明確な責務を持つ。

アーキテクチャ概要図

                                    +---------------------------------------------+
                                    |            Git Repository                   |
                                    |  (GitHub / GitLab / Bitbucket etc.)         |
                                    +---------------------+-----------------------+
                                                          |
                                                          | Poll / Webhook
                                                          v
+------------------------------------------------------------------------------+
|                          ArgoCD Control Plane                                 |
|                                                                              |
|  +--------------+  +--------------+  +--------------+  +----------------+   |
|  |  API Server  |  | Repo Server  |  | Application  |  |  Redis Cache   |   |
|  |  (argocd-    |  | (argocd-     |  | Controller   |  |                |   |
|  |   server)    |<-|  repo-server)|  | (argocd-     |  |                |   |
|  |              |  |              |  |  application- |  |                |   |
|  |  - Web UI    |  |  - Git clone |  |   controller) |  |  - Manifest    |   |
|  |  - gRPC API  |  |  - Manifest  |  |              |  |    Cache       |   |
|  |  - REST API  |  |    render    |  |  - Reconcile |  |  - App State   |   |
|  |  - Auth      |  |  - Helm      |  |  - Sync      |  |    Cache       |   |
|  |  - RBAC      |  |  - Kustomize |  |  - Health    |  |                |   |
|  |              |  |  - Jsonnet   |  |    Check     |  |                |   |
|  +------+-------+  +--------------+  +------+-------+  +----------------+   |
|         |                                    |                               |
|         |           +--------------+         |                               |
|         |           |  Dex Server  |         |                               |
|         +---------->|  (SSO/OIDC)  |         |                               |
|                     +--------------+         |                               |
|                                              |                               |
|         +------------------+                 |                               |
|         | ApplicationSet   |                 |                               |
|         | Controller       |                 |                               |
|         +------------------+                 |                               |
|                                              |                               |
|         +------------------+                 |                               |
|         | Notifications    |                 |                               |
|         | Controller       |                 |                               |
|         +------------------+                 |                               |
+----------------------------------------------+-------------------------------+
                                               |
                                               | Kubernetes API
                                               v
                              +--------------------------------+
                              |      Target Kubernetes         |
                              |        Cluster(s)              |
                              |                                |
                              |  +----------+  +----------+   |
                              |  |Namespace |  |Namespace |   |
                              |  |  app-a   |  |  app-b   |   |
                              |  +----------+  +----------+   |
                              +--------------------------------+

データフロー

ArgoCD の基本的なデータフローは以下の通りである。

  1. マニフェスト取得: Repo Server が Git リポジトリからマニフェストをクローン/プルする
  2. テンプレートレンダリング: Repo Server が Helm、Kustomize、Jsonnet などのテンプレートを展開し、最終的な Kubernetes マニフェストを生成する
  3. 差分計算: Application Controller がレンダリングされたマニフェスト(desired state)と、Kubernetes API から取得した実際の状態(live state)を比較する
  4. 同期実行: 差分がある場合、Application Controller が kubectl apply 相当の操作を実行してクラスタの状態を更新する
  5. ヘルスチェック: Application Controller がデプロイされたリソースのヘルスステータスを継続的に監視する
  6. 状態報告: 結果が API Server を通じて Web UI やCLI に報告される

4. コアコンポーネントの詳細

4.1 API Server(argocd-server)

API Server は ArgoCD のフロントエンドであり、以下の機能を提供する。

  • Web UI: React ベースのシングルページアプリケーション(SPA)
  • gRPC API: CLI や外部システムからのプログラマティックなアクセス
  • REST API: gRPC-Gateway による REST エンドポイント
  • 認証・認可: ローカルユーザー、SSO(Dex 経由)、RBAC の管理
  • Webhook 処理: Git リポジトリからの Webhook を受信し、即座にリフレッシュをトリガー

API Server はステートレスであり、水平スケーリングが可能である。HA(高可用性)構成では複数のレプリカを配置できる。

# API Server のデプロイメント例(HA構成)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-server
  namespace: argocd
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: argocd-server
  template:
    metadata:
      labels:
        app.kubernetes.io/name: argocd-server
    spec:
      containers:
      - name: argocd-server
        image: quay.io/argoproj/argocd:v2.13.3
        command:
        - argocd-server
        args:
        - --staticassets
        - /shared/app
        - --redis
        - argocd-redis-ha-haproxy:6379
        - --repo-server
        - argocd-repo-server:8081
        - --dex-server
        - http://argocd-dex-server:5556
        ports:
        - containerPort: 8080  # HTTP
        - containerPort: 8083  # gRPC
        readinessProbe:
          httpGet:
            path: /healthz?full=true
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 30
        livenessProbe:
          httpGet:
            path: /healthz?full=true
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 30
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi

4.2 Repository Server(argocd-repo-server)

Repo Server は Git リポジトリの操作とマニフェストの生成を担当する。主な責務は以下の通りである。

  • Git リポジトリのクローンとキャッシュ: 効率的なリポジトリアクセスのため、ローカルキャッシュを保持
  • マニフェストのレンダリング: Helm テンプレート、Kustomize オーバーレイ、Jsonnet ファイルの展開
  • Config Management Plugin(CMP): カスタムツールによるマニフェスト生成のサポート
  • シークレット置換: <path:vault/data/secret#key> 形式のプレースホルダーをシークレットに置換

Repo Server はセキュリティの観点から、ネットワークアクセスが制限された状態で動作することが推奨される。マニフェスト生成のプロセスは信頼できないリポジトリのコードを実行する可能性があるため、サンドボックス的な役割を果たす。

# Repo Server の設定例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-repo-server
  namespace: argocd
spec:
  replicas: 2
  template:
    spec:
      containers:
      - name: argocd-repo-server
        image: quay.io/argoproj/argocd:v2.13.3
        command:
        - argocd-repo-server
        args:
        - --redis
        - argocd-redis-ha-haproxy:6379
        - --parallelism-limit
        - "10"
        env:
        - name: ARGOCD_EXEC_TIMEOUT
          value: "180"  # マニフェスト生成のタイムアウト(秒)
        - name: HELM_CACHE_HOME
          value: /helm-working-dir
        - name: HELM_CONFIG_HOME
          value: /helm-working-dir
        - name: HELM_DATA_HOME
          value: /helm-working-dir
        volumeMounts:
        - name: tmp
          mountPath: /tmp
        - name: helm-working-dir
          mountPath: /helm-working-dir
        resources:
          requests:
            cpu: 200m
            memory: 256Mi
          limits:
            cpu: "1"
            memory: 1Gi
      volumes:
      - name: tmp
        emptyDir: {}
      - name: helm-working-dir
        emptyDir: {}

4.3 Application Controller(argocd-application-controller)

Application Controller は ArgoCD の心臓部であり、以下の処理を継続的に実行する。

  • Reconciliation ループ: 定期的に(デフォルト180秒)各 Application の状態を確認
  • Diff 計算: desired state(Git)と live state(クラスタ)の差分を計算
  • Sync 操作: 手動または自動で Kubernetes リソースの作成・更新・削除を実行
  • ヘルスチェック: デプロイされたリソースの健全性を評価
  • イベント管理: Kubernetes イベントの生成、ステータスの更新

Application Controller は StatefulSet としてデプロイされることが推奨される。HA 構成では、シャーディングにより複数のコントローラが Application を分担して処理する。

# Application Controller の StatefulSet 例
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: argocd-application-controller
  namespace: argocd
spec:
  replicas: 1  # HA 構成では 2 以上
  serviceName: argocd-application-controller
  selector:
    matchLabels:
      app.kubernetes.io/name: argocd-application-controller
  template:
    spec:
      containers:
      - name: argocd-application-controller
        image: quay.io/argoproj/argocd:v2.13.3
        command:
        - argocd-application-controller
        args:
        - --redis
        - argocd-redis-ha-haproxy:6379
        - --repo-server
        - argocd-repo-server:8081
        - --status-processors
        - "50"        # ステータス処理の並列数
        - --operation-processors
        - "25"        # Sync操作の並列数
        - --app-resync
        - "180"       # 再同期間隔(秒)
        - --self-heal-timeout-seconds
        - "5"         # Self-heal のタイムアウト
        env:
        - name: ARGOCD_CONTROLLER_REPLICAS
          value: "1"
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: "2"
            memory: 2Gi

4.4 Redis

Redis は ArgoCD のキャッシュレイヤーとして使用される。主なキャッシュ対象は以下の通りである。

  • マニフェストキャッシュ: Repo Server が生成したマニフェストのキャッシュ
  • Git リポジトリの状態: リポジトリのコミットハッシュや変更検出情報
  • アプリケーションの状態: ヘルスステータスやSync状態のキャッシュ
  • RBAC ポリシーのキャッシュ: 認可ポリシーの評価結果

プロダクション環境では Redis Sentinel または Redis HA 構成が推奨される。

# Redis HA 構成の Helm values 例
redis-ha:
  enabled: true
  exporter:
    enabled: true
  haproxy:
    enabled: true
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
  redis:
    resources:
      requests:
        cpu: 200m
        memory: 256Mi
  sentinel:
    resources:
      requests:
        cpu: 100m
        memory: 128Mi

4.5 Dex Server

Dex は CNCF のフェデレーテッド OIDC プロバイダーであり、ArgoCD の SSO 機能を実現する。ArgoCD は Dex を通じて以下のアイデンティティプロバイダーと連携可能である。

  • LDAP / Active Directory
  • SAML 2.0
  • GitHub / GitHub Enterprise
  • GitLab
  • Google / Google Workspace
  • Okta
  • Microsoft Entra ID(旧 Azure AD)
  • OIDC 準拠の任意のプロバイダー

5. インストールと初期設定

5.1 インストール方法

ArgoCD は複数の方法でインストール可能である。

方法1: マニフェストによる直接インストール

# Namespace の作成
kubectl create namespace argocd

# 標準インストール(Non-HA)
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

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

方法2: Helm Chart によるインストール

# Helm リポジトリの追加
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

# values ファイルを使用したインストール
helm install argocd argo/argo-cd \
  --namespace argocd \
  --create-namespace \
  -f values.yaml

推奨 Helm values.yaml

# values.yaml -- プロダクション向け設定例
global:
  image:
    tag: "v2.13.3"
  logging:
    format: json
    level: info

controller:
  replicas: 2
  env:
  - name: ARGOCD_CONTROLLER_REPLICAS
    value: "2"
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true
  resources:
    requests:
      cpu: 500m
      memory: 512Mi
    limits:
      cpu: "2"
      memory: 4Gi

server:
  replicas: 3
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 5
    targetCPUUtilizationPercentage: 80
  ingress:
    enabled: true
    ingressClassName: nginx
    hosts:
    - argocd.example.com
    tls:
    - hosts:
      - argocd.example.com
      secretName: argocd-tls
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true

repoServer:
  replicas: 2
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 5
  resources:
    requests:
      cpu: 200m
      memory: 256Mi
    limits:
      cpu: "1"
      memory: 1Gi

redis-ha:
  enabled: true
  exporter:
    enabled: true

dex:
  enabled: true

applicationSet:
  replicas: 2

notifications:
  enabled: true

configs:
  params:
    server.insecure: false
    controller.status.processors: 50
    controller.operation.processors: 25
    reposerver.parallelism.limit: 10

5.2 初期設定

# ArgoCD CLI のインストール
# macOS
brew install argocd

# Linux
curl -sSL -o argocd-linux-amd64 \
  https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64

# 初期パスワードの取得
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d

# ログイン
argocd login argocd.example.com --username admin --password <initial-password>

# パスワードの変更
argocd account update-password

# 初期パスワードシークレットの削除
kubectl -n argocd delete secret argocd-initial-admin-secret

5.3 argocd-cm ConfigMap

ArgoCD の主要な設定は argocd-cm ConfigMap で管理される。

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  url: https://argocd.example.com

  dex.config: |
    connectors:
    - type: github
      id: github
      name: GitHub
      config:
        clientID: $dex.github.clientID
        clientSecret: $dex.github.clientSecret
        orgs:
        - name: my-org

  statusbadge.enabled: "true"
  exec.enabled: "true"
  server.enable.server.side.diff: "true"

  resource.exclusions: |
    - apiGroups:
      - "velero.io"
      kinds:
      - "Backup"
      clusters:
      - "*"

  resource.customizations: |
    admissionregistration.k8s.io/MutatingWebhookConfiguration:
      ignoreDifferences: |
        jsonPointers:
        - /webhooks/0/clientConfig/caBundle

  kustomize.buildOptions: --enable-helm --load-restrictor LoadRestrictionsNone

6. Applicationリソースの定義と管理

6.1 Application CRD の基本構造

ArgoCD の中核となるカスタムリソースが Application である。Application は、ソース(Git リポジトリ)とデスティネーション(Kubernetes クラスタ/Namespace)のマッピングを定義する。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-application
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
  labels:
    team: platform
    env: production
  annotations:
    notifications.argoproj.io/subscribe.on-sync-succeeded.slack: my-channel
spec:
  project: my-project

  source:
    repoURL: https://github.com/my-org/my-app-manifests.git
    targetRevision: main
    path: overlays/production

  destination:
    server: https://kubernetes.default.svc
    namespace: my-app

  syncPolicy:
    automated:
      prune: true
      selfHeal: true
      allowEmpty: false
    syncOptions:
    - CreateNamespace=true
    - PrunePropagationPolicy=foreground
    - PruneLast=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

  ignoreDifferences:
  - group: apps
    kind: Deployment
    jsonPointers:
    - /spec/replicas
  - group: "*"
    kind: "*"
    managedFieldsManagers:
    - kube-controller-manager

6.2 マルチソース Application

ArgoCD v2.6 以降では、複数のソースからマニフェストを取得する sources フィールドがサポートされている。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-multi-source
  namespace: argocd
spec:
  project: default
  sources:
  - repoURL: https://charts.example.com
    chart: my-app
    targetRevision: 1.5.0
    helm:
      valueFiles:
      - $values/environments/production/values.yaml
      - $values/environments/production/secrets.yaml
  - repoURL: https://github.com/my-org/helm-values.git
    targetRevision: main
    ref: values
  destination:
    server: https://kubernetes.default.svc
    namespace: my-app

6.3 Helm アプリケーションの定義

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: prometheus-stack
  namespace: argocd
spec:
  project: monitoring
  source:
    repoURL: https://prometheus-community.github.io/helm-charts
    chart: kube-prometheus-stack
    targetRevision: 65.1.0
    helm:
      releaseName: prometheus
      values: |
        grafana:
          enabled: true
          adminPassword: <path:secret/data/grafana#admin-password>
          ingress:
            enabled: true
            hosts:
            - grafana.example.com
        prometheus:
          prometheusSpec:
            retention: 30d
            storageSpec:
              volumeClaimTemplate:
                spec:
                  storageClassName: gp3
                  resources:
                    requests:
                      storage: 100Gi
        alertmanager:
          alertmanagerSpec:
            retention: 120h
      parameters:
      - name: grafana.replicas
        value: "2"
      skipCrds: false
  destination:
    server: https://kubernetes.default.svc
    namespace: monitoring
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
    - ServerSideApply=true
    - RespectIgnoreDifferences=true

6.4 Kustomize アプリケーションの定義

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-kustomize-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/my-app.git
    targetRevision: main
    path: overlays/production
    kustomize:
      images:
      - my-app=registry.example.com/my-app:v1.2.3
      commonLabels:
        app.kubernetes.io/managed-by: argocd
      commonAnnotations:
        team: platform-engineering
      namePrefix: prod-
      namespace: production
  destination:
    server: https://kubernetes.default.svc
    namespace: production

6.5 App of Apps パターン

App of Apps は、ArgoCD で複数のアプリケーションを階層的に管理するためのパターンである。

repo-root/
+-- apps/                          # ルート Application が参照
|   +-- app-a.yaml
|   +-- app-b.yaml
|   +-- monitoring.yaml
|   +-- cert-manager.yaml
+-- manifests/
    +-- app-a/
    |   +-- kustomization.yaml
    +-- app-b/
    |   +-- kustomization.yaml
    +-- monitoring/
        +-- values.yaml
# ルート Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: root-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/gitops-repo.git
    targetRevision: main
    path: apps
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
# apps/app-a.yaml -- 子 Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app-a
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/gitops-repo.git
    targetRevision: main
    path: manifests/app-a
  destination:
    server: https://kubernetes.default.svc
    namespace: app-a
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

7. リポジトリ管理と認証設定

7.1 リポジトリの登録

# HTTPS(ユーザー名/パスワード)
argocd repo add https://github.com/my-org/my-repo.git \
  --username git \
  --password ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# HTTPS(GitHub App)
argocd repo add https://github.com/my-org/my-repo.git \
  --github-app-id 12345 \
  --github-app-installation-id 67890 \
  --github-app-private-key-path /path/to/private-key.pem

# SSH
argocd repo add git@github.com:my-org/my-repo.git \
  --ssh-private-key-path ~/.ssh/id_ed25519

Secret による宣言的な登録

apiVersion: v1
kind: Secret
metadata:
  name: my-private-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: https://github.com/my-org/my-private-repo.git
  username: git
  password: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

7.2 リポジトリ認証情報テンプレート

apiVersion: v1
kind: Secret
metadata:
  name: github-org-creds
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repo-creds
stringData:
  type: git
  url: https://github.com/my-org
  username: git
  password: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

8. Sync戦略とSyncポリシー

8.1 手動 Sync と自動 Sync

# CLI による手動 Sync
argocd app sync my-application

# 特定のリソースのみ Sync
argocd app sync my-application \
  --resource ':Deployment:my-app' \
  --resource ':Service:my-app-svc'

# Dry-run
argocd app sync my-application --dry-run

自動 Sync の設定:

syncPolicy:
  automated:
    prune: true       # Git で削除されたリソースをクラスタからも削除
    selfHeal: true    # クラスタ上の手動変更を自動的にGitの状態に戻す
    allowEmpty: false  # マニフェストが空の場合でも同期を許可(危険)

8.2 Sync Options の詳細

syncPolicy:
  syncOptions:
  - CreateNamespace=true
  - ServerSideApply=true
  - PruneLast=true
  - PrunePropagationPolicy=foreground
  - Validate=false
  - ApplyOutOfSyncOnly=true
  - RespectIgnoreDifferences=true
  - Replace=true
  - FailOnSharedResource=true

8.3 Sync Wave と Resource Hook

Sync Wave は数値で指定し、小さい値から順にデプロイされる。

# Wave -1: まず Namespace を作成
apiVersion: v1
kind: Namespace
metadata:
  name: my-app
  annotations:
    argocd.argoproj.io/sync-wave: "-1"
---
# Wave 1: Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  annotations:
    argocd.argoproj.io/sync-wave: "1"
---
# Wave 2: Service
apiVersion: v1
kind: Service
metadata:
  name: my-app
  annotations:
    argocd.argoproj.io/sync-wave: "2"

Resource Hook

# PreSync Hook: データベースマイグレーション
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migration
  annotations:
    argocd.argoproj.io/hook: PreSync
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  template:
    spec:
      containers:
      - name: migration
        image: my-app:v1.2.3
        command: ["./migrate", "up"]
      restartPolicy: Never
  backoffLimit: 3

Hook のタイプ: PreSync, Sync, PostSync, SyncFail, Skip

Hook Delete Policy: HookSucceeded, HookFailed, BeforeHookCreation


9. ヘルスチェックとステータス管理

9.1 Application のステータス

Sync Status: Synced, OutOfSync, Unknown

Health Status: Healthy, Progressing, Degraded, Suspended, Missing, Unknown

9.2 組み込みヘルスチェック

リソースHealthy 条件
Deploymentすべてのレプリカが Available
StatefulSetすべてのレプリカが Ready
DaemonSetすべてのノードで Pod が Ready
ServiceEndpoints が存在
IngressIP アドレスが割り当て済み
PersistentVolumeClaimBound 状態
Job正常に完了
PodRunning かつ Ready

9.3 カスタムヘルスチェック

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  resource.customizations.health.cert-manager.io_Certificate: |
    hs = {}
    if obj.status ~= nil then
      if obj.status.conditions ~= nil then
        for _, condition in ipairs(obj.status.conditions) do
          if condition.type == "Ready" then
            if condition.status == "True" then
              hs.status = "Healthy"
              hs.message = "Certificate is ready"
              return hs
            else
              hs.status = "Degraded"
              hs.message = condition.message
              return hs
            end
          end
        end
      end
    end
    hs.status = "Progressing"
    hs.message = "Waiting for certificate"
    return hs

10. Helm / Kustomize / Jsonnet との統合

10.1 Helm との統合

ArgoCD は helm template でマニフェストをレンダリングし、kubectl apply する方式を採用。

source:
  repoURL: https://charts.example.com
  chart: my-chart
  targetRevision: 1.0.0
  helm:
    releaseName: my-release
    valueFiles:
    - values.yaml
    - values-production.yaml
    values: |
      replicaCount: 3
    parameters:
    - name: service.type
      value: ClusterIP
    valuesObject:
      replicaCount: 3
      resources:
        requests:
          cpu: 100m
          memory: 128Mi

10.2 Kustomize との統合

source:
  repoURL: https://github.com/my-org/my-app.git
  targetRevision: main
  path: overlays/production
  kustomize:
    images:
    - my-app=registry.example.com/my-app:v1.2.3
    commonLabels:
      environment: production
    namePrefix: prod-
    namespace: production

10.3 Config Management Plugin (CMP)

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmp-cm
  namespace: argocd
data:
  plugin.yaml: |
    apiVersion: argoproj.io/v1alpha1
    kind: ConfigManagementPlugin
    metadata:
      name: cdk8s
    spec:
      version: v1.0
      init:
        command: [sh, -c]
        args:
        - npm install
      generate:
        command: [sh, -c]
        args:
        - |
          npx cdk8s synth
          cat dist/*.yaml
      discover:
        fileName: "cdk8s.yaml"

11. ApplicationSetによる大規模管理

11.1 基本構造

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: my-appset
  namespace: argocd
spec:
  goTemplate: true
  generators:
  - # ジェネレーター
  template:
    metadata:
      name: '{{.name}}-{{.environment}}'
    spec:
      project: default
      source:
        repoURL: '{{.repoURL}}'
        targetRevision: '{{.revision}}'
        path: '{{.path}}'
      destination:
        server: '{{.cluster}}'
        namespace: '{{.namespace}}'
  strategy:
    type: RollingSync
    rollingSync:
      steps:
      - matchExpressions:
        - key: environment
          operator: In
          values: [staging]
      - matchExpressions:
        - key: environment
          operator: In
          values: [production]
        maxUpdate: "25%"

11.2 主要なジェネレーター

List Generator: 静的な値のリストから Application を生成

Git Generator: Git リポジトリの構造から Application を動的に生成

Cluster Generator: 登録されたクラスタごとに Application を生成

Matrix Generator: 複数ジェネレーターのデカルト積から生成

Merge Generator: 複数ジェネレーターの結果をキーベースでマージ

Pull Request Generator: PR 情報に基づいて一時的な Application を生成

# Pull Request Generator の例
generators:
- pullRequest:
    github:
      owner: my-org
      repo: my-app
      tokenRef:
        secretName: github-token
        key: token
      labels:
      - deploy-preview
    requeueAfterSeconds: 60
template:
  metadata:
    name: 'pr-{{.number}}-my-app'
  spec:
    source:
      repoURL: https://github.com/my-org/my-app.git
      targetRevision: '{{.head_sha}}'
      path: deploy
      helm:
        parameters:
        - name: ingress.host
          value: 'pr-{{.number}}.preview.example.com'
    destination:
      server: https://kubernetes.default.svc
      namespace: 'pr-{{.number}}'

12. マルチクラスタ管理

12.1 クラスタの登録

argocd cluster add my-production-context \
  --name production-cluster \
  --label environment=production \
  --label region=us-east-1

Secret による宣言的なクラスタ登録

apiVersion: v1
kind: Secret
metadata:
  name: production-cluster
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: cluster
    environment: production
stringData:
  name: production-cluster
  server: https://production.k8s.example.com
  config: |
    {
      "bearerToken": "eyJhbGciOi...",
      "tlsClientConfig": {
        "insecure": false,
        "caData": "LS0tLS1CRUdJTi..."
      }
    }

12.2 マルチクラスタ構成パターン

  • Hub-and-Spoke: 1つの ArgoCD が複数クラスタを管理
  • Standalone: 各クラスタに ArgoCD をデプロイ
  • Management Cluster(推奨): 専用管理クラスタに ArgoCD をデプロイ

13. RBAC(ロールベースアクセス制御)

13.1 Project によるアクセス制御

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-backend
  namespace: argocd
spec:
  description: "Backend team project"
  sourceRepos:
  - 'https://github.com/my-org/backend-*'
  destinations:
  - server: https://kubernetes.default.svc
    namespace: 'backend-*'
  clusterResourceWhitelist:
  - group: ''
    kind: Namespace
  roles:
  - name: developer
    policies:
    - p, proj:team-backend:developer, applications, get, team-backend/*, allow
    - p, proj:team-backend:developer, applications, sync, team-backend/*, allow
    groups:
    - my-org:backend-developers
  syncWindows:
  - kind: allow
    schedule: '0 6-22 * * 1-5'
    duration: 16h
    applications:
    - '*'
    timeZone: Asia/Tokyo

13.2 RBAC ポリシー

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.default: role:readonly
  policy.csv: |
    p, role:platform-admin, applications, *, */*, allow
    p, role:platform-admin, clusters, *, *, allow
    p, role:platform-admin, repositories, *, *, allow
    p, role:platform-admin, projects, *, *, allow

    p, role:developer, applications, get, */*, allow
    p, role:developer, applications, sync, */*, allow
    p, role:developer, logs, get, */*, allow

    p, role:sre, applications, *, */*, allow
    p, role:sre, exec, create, */*, allow

    g, my-org:platform-team, role:platform-admin
    g, my-org:developers, role:developer
    g, my-org:sre-team, role:sre
  scopes: '[groups, email]'

14. SSO連携と認証設定

14.1 Dex による SSO (GitHub)

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
data:
  url: https://argocd.example.com
  dex.config: |
    connectors:
    - type: github
      id: github
      name: GitHub
      config:
        clientID: $dex.github.clientID
        clientSecret: $dex.github.clientSecret
        orgs:
        - name: my-org
          teams:
          - platform-team
          - sre-team

14.2 OIDC 直接連携(Dex なし)

data:
  oidc.config: |
    name: Okta
    issuer: https://example.okta.com
    clientID: $oidc.okta.clientID
    clientSecret: $oidc.okta.clientSecret
    requestedScopes: [openid, profile, email, groups]

15. Webhook連携とCI/CDパイプライン統合

15.1 Webhook の設定

apiVersion: v1
kind: Secret
metadata:
  name: argocd-secret
  namespace: argocd
stringData:
  webhook.github.secret: my-github-webhook-secret

15.2 GitHub Actions との統合

# .github/workflows/deploy.yaml
name: Build and Deploy
on:
  push:
    branches: [main]
jobs:
  update-manifests:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        repository: my-org/gitops-repo
        token: ${{ secrets.GITOPS_TOKEN }}
    - name: Update image tag
      run: |
        cd apps/my-app/overlays/production
        kustomize edit set image \
          my-app=registry.example.com/my-app:${{ github.sha }}
    - name: Commit and push
      run: |
        git config user.name "github-actions[bot]"
        git config user.email "github-actions[bot]@users.noreply.github.com"
        git add .
        git commit -m "chore: update my-app image to ${{ github.sha }}"
        git push

16. Notificationによる通知設定

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  service.slack: |
    token: $slack-token

  template.app-sync-succeeded: |
    slack:
      attachments: |
        [{
          "color": "#18be52",
          "title": "{{.app.metadata.name}} - Sync Succeeded",
          "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}"
        }]

  trigger.on-sync-succeeded: |
    - when: app.status.operationState.phase in ['Succeeded']
      send: [app-sync-succeeded]

  context: |
    argocdUrl: https://argocd.example.com

Application への通知サブスクリプション:

metadata:
  annotations:
    notifications.argoproj.io/subscribe.on-sync-succeeded.slack: deploy-notifications
    notifications.argoproj.io/subscribe.on-sync-failed.slack: deploy-alerts
    notifications.argoproj.io/subscribe.on-health-degraded.slack: deploy-alerts

17. Image Updaterによる自動イメージ更新

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  annotations:
    argocd-image-updater.argoproj.io/image-list: myapp=registry.example.com/my-app
    argocd-image-updater.argoproj.io/myapp.update-strategy: semver
    argocd-image-updater.argoproj.io/myapp.allow-tags: "regexp:^v[0-9]+\\.[0-9]+\\.[0-9]+$"
    argocd-image-updater.argoproj.io/write-back-method: git
    argocd-image-updater.argoproj.io/git-branch: main
戦略説明ユースケース
semverセマンティックバージョニングに基づく最新バージョンプロダクション環境
latest最も新しく作成されたタグ開発環境
nameアルファベット順で最新のタグ日付ベースのタグ
digestタグのダイジェストが変更された場合に更新latest タグの追跡

18. カスタムヘルスチェックとリソースフック

18.1 カスタムリソースアクション

data:
  resource.customizations.actions.argoproj.io_Rollout: |
    discovery.lua: |
      actions = {}
      actions["resume"] = {["disabled"] = false}
      actions["abort"] = {["disabled"] = false}
      actions["promote-full"] = {["disabled"] = false}
      return actions
    definitions:
    - name: resume
      action.lua: |
        obj.status.pauseConditions = nil
        return obj
    - name: promote-full
      action.lua: |
        obj.status.promoteFull = true
        return obj

19. Diffカスタマイズとリソース除外

19.1 ignoreDifferences

spec:
  ignoreDifferences:
  - group: apps
    kind: Deployment
    jsonPointers:
    - /spec/replicas
  - group: admissionregistration.k8s.io
    kind: MutatingWebhookConfiguration
    jqPathExpressions:
    - '.webhooks[]?.clientConfig.caBundle'
  - group: "*"
    kind: "*"
    managedFieldsManagers:
    - kube-controller-manager

19.2 リソースの除外

data:
  resource.exclusions: |
    - apiGroups:
      - "cilium.io"
      kinds:
      - "CiliumIdentity"
      clusters:
      - "*"
    - apiGroups:
      - "velero.io"
      kinds:
      - "Backup"
      - "Restore"
      clusters:
      - "*"

20. ディザスタリカバリとバックアップ

# 全アプリケーションのエクスポート
argocd admin export > argocd-backup.yaml

# 特定リソースのバックアップ
kubectl get applications -n argocd -o yaml > applications-backup.yaml
kubectl get appprojects -n argocd -o yaml > projects-backup.yaml
kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type=repository -o yaml > repos-backup.yaml

# リストア
argocd admin import - < argocd-backup.yaml

21. パフォーマンスチューニング

21.1 大規模環境での設定

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cmd-params-cm
  namespace: argocd
data:
  controller.status.processors: "50"
  controller.operation.processors: "25"
  controller.repo.server.timeout.seconds: "300"
  reposerver.parallelism.limit: "10"

21.2 Application Controller のシャーディング

spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: argocd-application-controller
        env:
        - name: ARGOCD_CONTROLLER_REPLICAS
          value: "3"
        - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM
          value: "consistent-hashing"

21.3 モニタリング

メトリクス説明
argocd_app_infoApplication の基本情報
argocd_app_sync_totalSync 操作の合計数
argocd_app_reconcile_bucketReconcile の所要時間分布
argocd_app_health_statusヘルス状態
argocd_cluster_cache_age_secondsクラスタキャッシュの年齢
argocd_repo_server_queue_depthRepo Server のキュー深度

22. セキュリティベストプラクティス

22.1 シークレット管理

パターン1: Sealed Secrets -- Git に格納可能な暗号化シークレット

パターン2: External Secrets Operator -- Vault / AWS Secrets Manager から動的取得

パターン3: ArgoCD Vault Plugin (AVP) -- テンプレートベースのシークレット置換

22.2 追加のセキュリティ設定

data:
  admin.enabled: "false"        # 管理者アカウントの無効化
  exec.enabled: "false"         # Pod exec の無効化

22.3 NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: argocd-repo-server-network-policy
  namespace: argocd
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: argocd-repo-server
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app.kubernetes.io/name: argocd-server
    - podSelector:
        matchLabels:
          app.kubernetes.io/name: argocd-application-controller
    ports:
    - port: 8081
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
    ports:
    - port: 443
    - port: 22

23. トラブルシューティング

23.1 よくある問題

# OutOfSync の差分確認
argocd app diff my-app

# キャッシュのクリア
argocd app get my-app --hard-refresh

# Sync の詳細ログ
argocd app sync my-app --loglevel debug

# クラスタ接続確認
argocd cluster list

23.2 エラーメッセージと対処法

エラー対処法
ComparisonError--hard-refresh でキャッシュクリア
rpc error: PermissionDeniedargocd-rbac-cm のポリシー確認
Failed to load target stateリポジトリ認証情報を確認
resource mapping not foundCRD を先にインストール(Sync Wave 使用)
Too long: must have at most 262144 bytesServer-Side Apply を使用

24. 実践的なプロダクション構成例

24.1 リポジトリ構成

gitops-repo/
+-- argocd/
|   +-- base/
|   +-- overlays/
|   +-- projects/
|   +-- applicationsets/
+-- platform/
|   +-- cert-manager/
|   +-- external-secrets/
|   +-- ingress-nginx/
|   +-- monitoring/
+-- apps/
|   +-- api-server/
|   |   +-- base/
|   |   +-- overlays/
|   +-- web-frontend/
|   +-- worker/
+-- config/
    +-- production/
    +-- staging/

24.2 ApplicationSet によるマルチクラスタ管理

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: platform-apps
  namespace: argocd
spec:
  goTemplate: true
  generators:
  - matrix:
      generators:
      - git:
          repoURL: https://github.com/my-org/gitops-repo.git
          revision: main
          directories:
          - path: platform/*
      - clusters:
          selector:
            matchLabels:
              argocd.argoproj.io/secret-type: cluster
          values:
            environment: '{{.metadata.labels.environment}}'
  template:
    metadata:
      name: 'platform-{{.path.basename}}-{{.name}}'
    spec:
      project: platform
      source:
        repoURL: https://github.com/my-org/gitops-repo.git
        targetRevision: main
        path: 'platform/{{.path.basename}}/overlays/{{.values.environment}}'
      destination:
        server: '{{.server}}'
        namespace: '{{.path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
        - CreateNamespace=true
        - ServerSideApply=true
  strategy:
    type: RollingSync
    rollingSync:
      steps:
      - matchExpressions:
        - key: environment
          operator: In
          values: [staging]
      - matchExpressions:
        - key: environment
          operator: In
          values: [production]
        maxUpdate: "50%"

25. まとめと今後の展望

25.1 ArgoCD の導入効果

  1. デプロイの信頼性向上: Git を Single Source of Truth として、すべてのデプロイが追跡可能・再現可能
  2. セキュリティの強化: CI システムからクラスタへの直接アクセスが不要になり、攻撃対象面が縮小
  3. 運用効率の改善: 自動同期と Self-heal により、手動介入が大幅に削減
  4. 監査証跡の確保: すべての変更が Git コミットとして記録
  5. マルチクラスタ管理の簡素化: ApplicationSet により、大規模環境のデプロイを統一管理
  6. 開発者体験の向上: Web UI による視覚的な管理、ワンクリックロールバック

25.2 導入時の注意点

  • Git リポジトリの設計: モノレポ vs マルチレポの選択はチーム構成に依存
  • シークレット管理: Sealed Secrets、External Secrets Operator 等の補完ツールが必須
  • 学習コスト: 段階的な導入(まず非本番環境から)が推奨
  • パフォーマンス: 大量の Application を管理する場合、シャーディングとリソースサイジングが不可欠

25.3 今後の展望

  • Argo Rollouts との統合深化: Blue-Green / Canary デプロイメントの強化
  • ApplicationSet の機能拡張: Progressive Delivery、高度なテンプレート機能
  • セキュリティ機能の強化: Supply Chain Security(SLSA、Sigstore)との統合
  • マルチテナンシーの改善: より細かい粒度でのアクセス制御
  • AI/ML ワークフローの対応: ML パイプラインのデプロイ自動化

ArgoCD は Kubernetes エコシステムにおける GitOps CD ツールのデファクトスタンダードとしての地位を確立しつつあり、クラウドネイティブなデプロイメント戦略を構築する上で不可欠なツールである。


本記事は ArgoCD v2.13.x をベースに記述されている。最新バージョンでは一部の機能やAPIが変更されている可能性があるため、公式ドキュメント(https://argo-cd.readthedocs.io/)を合わせて参照されたい。