Skip to content
Published on

ArgoCD ApplicationSetとProgressive Rollout:GitOpsマルチクラスターデプロイ実践ガイド

Authors
  • Name
    Twitter

1. ArgoCD ApplicationSetとは

ApplicationSetはArgoCDの拡張リソースで、一つのテンプレートから複数のApplicationを自動生成する。マルチクラスター、マルチテナント、モノレポ環境で数十〜数百のApplicationを手動管理する代わりに、宣言的に自動化できる。

1.1 なぜApplicationSetなのか?

従来の方式:
  app-dev.yamlApplication (dev)
  app-staging.yamlApplication (staging)
  app-prod.yamlApplication (prod)
  ... × 50サービス = 150個のYAMLを手動管理

ApplicationSet:
  appset.yaml → 一つのテンプレートで150個を自動生成

2. ApplicationSet Generatorの種類

2.1 List Generator

最もシンプルな形式。明示的なパラメータリストからApplicationを生成する:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp-envs
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - cluster: dev
            url: https://dev-k8s.example.com
            namespace: myapp-dev
          - cluster: staging
            url: https://staging-k8s.example.com
            namespace: myapp-staging
          - cluster: prod
            url: https://prod-k8s.example.com
            namespace: myapp-prod
  template:
    metadata:
      name: 'myapp-{{cluster}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/org/myapp.git
        targetRevision: HEAD
        path: 'k8s/overlays/{{cluster}}'
      destination:
        server: '{{url}}'
        namespace: '{{namespace}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true

2.2 Git Generator(Directory)

モノレポ構造でのディレクトリベースの自動検出:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cluster-addons
  namespace: argocd
spec:
  generators:
    - git:
        repoURL: https://github.com/org/cluster-addons.git
        revision: HEAD
        directories:
          - path: addons/*
          - path: addons/exclude-this
            exclude: true
  template:
    metadata:
      name: '{{path.basename}}'
    spec:
      project: addons
      source:
        repoURL: https://github.com/org/cluster-addons.git
        targetRevision: HEAD
        path: '{{path}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: '{{path.basename}}'

2.3 Cluster Generator

ArgoCDに登録されたすべてのクラスターに自動デプロイ:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: monitoring-stack
  namespace: argocd
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: production
  template:
    metadata:
      name: 'monitoring-{{name}}'
    spec:
      project: infrastructure
      source:
        repoURL: https://github.com/org/monitoring.git
        path: helm-chart
        helm:
          valueFiles:
            - 'values-{{metadata.labels.region}}.yaml'
      destination:
        server: '{{server}}'
        namespace: monitoring

2.4 Matrix Generator(組み合わせ)

2つのGeneratorを交差結合する:

spec:
  generators:
    - matrix:
        generators:
          - git:
              repoURL: https://github.com/org/apps.git
              revision: HEAD
              directories:
                - path: apps/*
          - clusters:
              selector:
                matchLabels:
                  env: production

3. Progressive Sync:段階的ロールアウト

3.1 コンセプト

Progressive Syncは、ApplicationSetが生成したApplicationを一度にデプロイするのではなく段階的にデプロイする戦略である。QA → Staging → Productionの順序で検証しながら進行できる。

3.2 設定

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: myapp-progressive
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - cluster: qa
            url: https://qa-k8s.example.com
          - cluster: staging
            url: https://staging-k8s.example.com
          - cluster: prod-east
            url: https://prod-east-k8s.example.com
          - cluster: prod-west
            url: https://prod-west-k8s.example.com
  strategy:
    type: RollingSync
    rollingSync:
      steps:
        - matchExpressions:
            - key: cluster
              operator: In
              values:
                - qa
          # QAを最初にデプロイ → 自動Sync
        - matchExpressions:
            - key: cluster
              operator: In
              values:
                - staging
          maxUpdate: 100%
          # QA成功後、stagingを自動実行
        - matchExpressions:
            - key: cluster
              operator: In
              values:
                - prod-east
                - prod-west
          maxUpdate: 50%
          # prodは50%ずつ段階的に
  template:
    metadata:
      name: 'myapp-{{cluster}}'
      labels:
        cluster: '{{cluster}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/org/myapp.git
        targetRevision: HEAD
        path: 'k8s/overlays/{{cluster}}'
      destination:
        server: '{{url}}'
        namespace: myapp
      syncPolicy:
        automated:
          prune: true

4. Argo Rollouts:CanaryとBlue-Green

4.1 Canaryデプロイ

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: myapp
spec:
  replicas: 10
  strategy:
    canary:
      steps:
        - setWeight: 10
        - pause: { duration: 5m }
        - setWeight: 30
        - pause: { duration: 5m }
        - analysis:
            templates:
              - templateName: success-rate
            args:
              - name: service-name
                value: myapp
        - setWeight: 60
        - pause: { duration: 10m }
        - setWeight: 100
      canaryService: myapp-canary
      stableService: myapp-stable
      trafficRouting:
        istio:
          virtualServices:
            - name: myapp-vsvc
              routes:
                - primary
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: myapp:v2
          ports:
            - containerPort: 8080

4.2 AnalysisTemplate(自動ロールバック)

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  args:
    - name: service-name
  metrics:
    - name: success-rate
      interval: 30s
      count: 10
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{
              service="{{args.service-name}}",
              status=~"2.."
            }[5m])) /
            sum(rate(http_requests_total{
              service="{{args.service-name}}"
            }[5m]))

4.3 Blue-Greenデプロイ

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: myapp-bluegreen
spec:
  replicas: 5
  strategy:
    blueGreen:
      activeService: myapp-active
      previewService: myapp-preview
      autoPromotionEnabled: false
      prePromotionAnalysis:
        templates:
          - templateName: success-rate
      scaleDownDelaySeconds: 300
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: myapp:v2

5. 実践:ApplicationSet + Rollouts統合

5.1 ディレクトリ構造

repo/
├── apps/
│   ├── frontend/
│   │   ├── base/
│   │   │   ├── rollout.yaml
│   │   │   ├── service.yaml
│   │   │   └── kustomization.yaml
│   │   └── overlays/
│   │       ├── dev/
│   │       ├── staging/
│   │       └── prod/
│   └── backend/
│       ├── base/
│       └── overlays/
└── appsets/
    └── all-apps.yaml

5.2 統合ApplicationSet

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: all-apps
  namespace: argocd
spec:
  generators:
    - matrix:
        generators:
          - git:
              repoURL: https://github.com/org/gitops.git
              revision: HEAD
              directories:
                - path: apps/*
          - list:
              elements:
                - env: dev
                  cluster: https://dev-k8s.example.com
                - env: staging
                  cluster: https://staging-k8s.example.com
                - env: prod
                  cluster: https://prod-k8s.example.com
  strategy:
    type: RollingSync
    rollingSync:
      steps:
        - matchExpressions:
            - key: env
              operator: In
              values: [dev]
        - matchExpressions:
            - key: env
              operator: In
              values: [staging]
        - matchExpressions:
            - key: env
              operator: In
              values: [prod]
  template:
    metadata:
      name: '{{path.basename}}-{{env}}'
      labels:
        app: '{{path.basename}}'
        env: '{{env}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/org/gitops.git
        targetRevision: HEAD
        path: '{{path}}/overlays/{{env}}'
      destination:
        server: '{{cluster}}'
        namespace: '{{path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

6. ArgoCD CLI運用コマンド

# ApplicationSetの状態確認
argocd appset list
argocd appset get myapp-progressive

# 特定ApplicationのSync状態確認
argocd app get myapp-prod --refresh

# 手動Sync(Progressiveで手動承認が必要な場合)
argocd app sync myapp-staging

# Rollout状態確認(Argo Rollouts kubectlプラグイン)
kubectl argo rollouts status myapp -n myapp
kubectl argo rollouts get rollout myapp -n myapp -w

# Canary手動承認
kubectl argo rollouts promote myapp -n myapp

# ロールバック
kubectl argo rollouts undo myapp -n myapp

7. ベストプラクティス

  1. Progressive Syncは必須:本番デプロイ時は必ず段階的ロールアウトを行う
  2. AnalysisTemplate連携:メトリクスベースの自動ロールバックを設定する
  3. App of Appsの代わりにApplicationSet:管理の複雑さを大幅に削減
  4. Matrix Generatorの活用:アプリ × 環境の組み合わせを自動化
  5. Sync Waveの活用:依存関係のあるリソースの順序を制御
  6. Notification連携:Slack/Telegramでデプロイ状態を通知

8. クイズ

Q1. ApplicationSetの核心的な役割とは?

一つのテンプレートから複数のArgoCD Applicationを自動生成する。マルチクラスター・マルチ環境デプロイの自動化を実現する。

Q2. Matrix Generatorはどのように動作するか?

2つのGeneratorの結果を**交差結合(直積)**して、すべての組み合わせに対してApplicationを生成する。

Q3. Progressive SyncのmaxUpdate: 50%は何を意味するか?

該当ステップのApplicationの50%のみを同時にSyncし、成功後に残りの50%を進行する。

Q4. Argo RolloutsのAnalysisTemplateが失敗した場合はどうなるか?

自動的にロールバックされる。failureLimitを超過するとRolloutがDegraded状態になり、以前のバージョンに復元される。

Q5. Blue-GreenにおけるautoPromotionEnabled: falseの意味は?

Preview環境の検証後、手動でpromoteしなければActiveに切り替わらない。kubectl argo rollouts promoteコマンドが必要。

Q6. CanaryデプロイでtrafficRoutingを設定する理由は?

実際のトラフィックの割合を精密に制御するため。Istio/Nginx/ALBなどと連携して、Pod数ではなくトラフィック比率ベースのCanaryを実装する。

Q7. App of Appsパターンに対するApplicationSetの利点は?

(1) 単一リソースで管理 (2) Generatorによる自動検出 (3) Progressive Syncサポート (4) コードの重複排除