Skip to content
Published on

[ArgoCD] ApplicationSetコントローラー深層分析

Authors

1. ApplicationSet概要

ApplicationSetはArgoCDの拡張コントローラーで、1つのApplicationSetリソースから複数のArgoCD Applicationを自動的に作成・管理します。大規模マルチクラスタ、マルチテナント環境で数百のApplicationを効率的に管理できます。

コア構成要素

ApplicationSet Controller
    |
    +-- Generator: Applicationリスト生成のためのデータソース
    |
    +-- Template: Applicationリソースのテンプレート
    |
    +-- Sync Policy: Application作成/削除/更新ポリシー

基本構造

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: my-appset
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - cluster: staging
            url: https://staging.example.com
          - cluster: production
            url: https://production.example.com
  template:
    metadata:
      name: 'myapp-{{cluster}}'
    spec:
      project: default
      source:
        repoURL: https://github.com/org/myapp.git
        targetRevision: HEAD
        path: 'overlays/{{cluster}}'
      destination:
        server: '{{url}}'
        namespace: myapp

2. Generatorタイプ詳細

List Generator

最もシンプルなGeneratorで、静的リストからパラメータを生成します:

spec:
  generators:
    - list:
        elements:
          - cluster: staging
            url: https://staging.example.com
            revision: develop
          - cluster: production
            url: https://production.example.com
            revision: main

Cluster Generator

ArgoCDに登録されたクラスタに基づいてApplicationを作成します:

spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: production
            region: ap-northeast-2

Cluster Generatorのパラメータ:

パラメータ説明
nameクラスタ名
serverクラスタAPIサーバーURL
metadata.labelsクラスタに設定されたラベル
metadata.annotationsクラスタに設定されたアノテーション

Git Generator - Directory

Gitリポジトリのディレクトリ構造をスキャンしてApplicationを作成します:

spec:
  generators:
    - git:
        repoURL: https://github.com/org/gitops-config.git
        revision: HEAD
        directories:
          - path: apps/*
          - path: apps/excluded-app
            exclude: true

生成されるパラメータ:

パラメータ
pathapps/frontend
path.basenamefrontend
path[0]apps
path[1]frontend
path.basenameNormalizedfrontend(RFC 1123準拠)

Git Generator - File

Gitリポジトリ内のJSON/YAMLファイルからパラメータを読み取ります:

spec:
  generators:
    - git:
        repoURL: https://github.com/org/gitops-config.git
        revision: HEAD
        files:
          - path: 'clusters/*/config.json'

config.jsonファイル例:

{
  "cluster": {
    "name": "production-east",
    "server": "https://prod-east.example.com",
    "environment": "production",
    "region": "us-east-1"
  }
}

Matrix Generator

2つのGeneratorを結合してデカルト積(Cartesian Product)を生成します:

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

Merge Generator

複数のGeneratorの結果を共通キーでマージします:

spec:
  generators:
    - merge:
        mergeKeys:
          - server
        generators:
          - clusters:
              values:
                replicas: '3'
                env: default
          - list:
              elements:
                - server: https://production.example.com
                  values.replicas: '5'
                  values.env: production

PullRequest Generator

GitホスティングサービスのPRを検知してプレビュー環境を自動作成します:

spec:
  generators:
    - pullRequest:
        github:
          owner: myorg
          repo: myapp
          labels:
            - preview
        requeueAfterSeconds: 60
  template:
    metadata:
      name: 'preview-{{branch}}-{{number}}'
    spec:
      source:
        repoURL: https://github.com/myorg/myapp.git
        targetRevision: '{{head_sha}}'
        path: deploy/preview
      destination:
        server: https://kubernetes.default.svc
        namespace: 'preview-{{number}}'

PullRequest Generatorパラメータ:

パラメータ説明
numberPR番号
branchソースブランチ名
branch_slugURL安全なブランチ名
head_shaHEADコミットSHA
head_short_sha短いHEAD SHA
labelsPRに付与されたラベル

SCMProvider Generator

SCM(Source Code Management)プロバイダーからリポジトリを自動発見します:

spec:
  generators:
    - scmProvider:
        github:
          organization: myorg
          allBranches: false
        filters:
          - repositoryMatch: '^gitops-.*'
            pathsExist:
              - deploy/kustomization.yaml

サポートSCMプロバイダー: GitHub、GitLab、Bitbucket Server、Azure DevOps、Gitea

3. テンプレートレンダリングエンジン

デフォルトテンプレート構文

ApplicationSetは二重中括弧構文でパラメータを参照します。Generatorが提供する値で置換されます。

template:
  metadata:
    name: 'app-{{cluster}}-{{path.basename}}'
  spec:
    source:
      repoURL: '{{url}}'
      path: '{{path}}'
    destination:
      server: '{{server}}'

Goテンプレートモード

より複雑なロジックが必要な場合、Goテンプレートを使用できます:

spec:
  goTemplate: true
  goTemplateOptions: ['missingkey=error']
  template:
    metadata:
      name: 'app-{{ .cluster | lower }}'
    spec:
      source:
        path: '{{ if eq .env "production" }}overlays/prod{{ else }}overlays/dev{{ end }}'

fasttemplate vs Goテンプレート比較

特性fasttemplate(デフォルト)Goテンプレート
構文二重中括弧(変数置換のみ)Go template全構文
条件文不可可能(if/else)
ループ不可可能(range)
関数不可Sprig関数使用可能
パフォーマンス高速相対的に遅い
設定デフォルトgoTemplate: true必要

4. Progressive Sync(段階的同期)

Rolling Sync戦略

ApplicationSetは複数のApplicationを段階的に同期する機能を提供します:

spec:
  strategy:
    type: RollingSync
    rollingSync:
      steps:
        - matchExpressions:
            - key: env
              operator: In
              values:
                - staging
          maxUpdate: 100%
        - matchExpressions:
            - key: env
              operator: In
              values:
                - production
          maxUpdate: 25%

Progressive Sync動作原理

Step 1: stagingラベルのすべてのApplicationを同期
  -> すべてがHealthyになるまで待機

Step 2: productionラベルのApplicationの25%のみ同期
  -> Healthy確認後、次の25%に進む
  -> すべてのproduction Applicationが完了するまで繰り返し

maxUpdateオプション

説明
100%マッチするすべてのApplicationを同時に更新
25%マッチするApplicationの25%のみ更新
1一度に1つのみ更新
0自動更新なし(手動で進行)

5. Reconciliation Loop

ApplicationSet ControllerのReconciliation

ループ:
  1. すべてのApplicationSetリソースを監視(Informer)
  2. 各ApplicationSetに対して:
     a. Generatorを実行してパラメータセットを生成
     b. テンプレートをレンダリングして望ましいApplicationリストを生成
     c. 現在存在するApplicationリストを照会
     d. 比較して:
        - 新規追加するApplicationを作成
        - 変更されたApplicationを更新
        - 削除対象のApplicationを削除(ポリシーに従って)
  3. requeueAfterSeconds後に再実行

Event-Driven Reconciliation

コントローラーは以下のイベントに反応して即座にreconciliationを実行します:

  • ApplicationSetリソースの変更
  • ArgoCDクラスタSecretの変更
  • Git Webhookの受信(Git Generator)

6. Applicationライフサイクル管理

削除ポリシー

spec:
  syncPolicy:
    preserveResourcesOnDeletion: true # ApplicationSet削除時もApplicationを維持
オプション動作
preserveResourcesOnDeletion: falseApplicationSet削除時にすべてのApplicationも削除
preserveResourcesOnDeletion: trueApplicationSet削除してもApplicationは維持

7. 実践パターン

マルチクラスタデプロイ

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: platform-services
  namespace: argocd
spec:
  generators:
    - matrix:
        generators:
          - clusters:
              selector:
                matchLabels:
                  tier: production
          - git:
              repoURL: https://github.com/org/platform.git
              revision: HEAD
              directories:
                - path: services/*
  template:
    metadata:
      name: '{{name}}-{{path.basename}}'
    spec:
      project: platform
      source:
        repoURL: https://github.com/org/platform.git
        targetRevision: HEAD
        path: '{{path}}'
      destination:
        server: '{{server}}'
        namespace: '{{path.basename}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

PRプレビュー環境

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: preview-envs
  namespace: argocd
spec:
  generators:
    - pullRequest:
        github:
          owner: myorg
          repo: myapp
          labels:
            - deploy-preview
        requeueAfterSeconds: 30
  template:
    metadata:
      name: 'preview-{{number}}'
    spec:
      project: previews
      source:
        repoURL: https://github.com/myorg/myapp.git
        targetRevision: '{{head_sha}}'
        path: deploy/preview
        helm:
          parameters:
            - name: ingress.host
              value: 'pr-{{number}}.preview.example.com'
            - name: image.tag
              value: '{{head_short_sha}}'
      destination:
        server: https://kubernetes.default.svc
        namespace: 'preview-{{number}}'
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
        syncOptions:
          - CreateNamespace=true

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

デバッグコマンド

# ApplicationSetの状態確認
kubectl get applicationset -n argocd

# ApplicationSetの詳細情報確認
kubectl describe applicationset my-appset -n argocd

# ApplicationSet Controllerのログ確認
kubectl logs -n argocd deployment/argocd-applicationset-controller

# 生成されたApplicationの確認
argocd app list

9. まとめ

ApplicationSet Controllerの核心要素:

  1. Generator:多様なデータソース(クラスタ、Git、PR、SCM)からパラメータを生成
  2. Matrix/Merge:Generatorを組み合わせて複雑なデプロイトポロジーを実現
  3. テンプレートエンジン:fasttemplateまたはGoテンプレートでApplicationリソースをレンダリング
  4. Progressive Sync:Rollingアップデート戦略で安全な大規模デプロイ
  5. Reconciliation:Event-driven + 周期的pollingで状態を同期
  6. ライフサイクル管理:作成/更新/削除ポリシーでApplicationを自動管理

ApplicationSetを効果的に活用すれば数百のApplicationを1つのリソースで管理でき、大規模GitOps環境の運用複雑度を大幅に削減できます。