Skip to content
Published on

[ArgoCD] アーキテクチャ内部分析:ソースコードレベルディープダイブ

Authors

1. ArgoCD全体アーキテクチャ概要

ArgoCDはKubernetes環境でGitOpsを実現するための宣言的継続デリバリー(Continuous Delivery)ツールです。CNCF Graduatedプロジェクトとして、Pull基盤デプロイモデルを通じてGitリポジトリに定義された望ましい状態とクラスタの実際の状態を継続的に同期します。

コアコンポーネント

ArgoCDは次の5つのコアコンポーネントで構成されます:

  • argocd-server(API Server):Web UI、CLI、CI/CD統合のためのgRPC/REST APIを提供
  • argocd-repo-server(Repository Server):Gitクローン、マニフェスト生成を担当
  • argocd-application-controller(Application Controller):アプリケーション状態の監視と同期
  • Redis:マニフェストキャッシュ、セッションデータ保存
  • Dex:SSO(Single Sign-On)認証を提供

コンポーネント間通信

すべての内部コンポーネントはgRPCで通信します:

ユーザー (Web UI / CLI / CI)
       |
       v
  API Server (gRPC/REST)
       |
       +-------> Repository Server (gRPC)
       |                |
       +-------> Application Controller
       |                |
       +-------> Redis (TCP)
       |
       +-------> Dex (OIDC)

2. API Server内部分析

役割と責任

API ServerはArgoCDのフロントエンドゲートウェイの役割を果たします。外部リクエストを受信し、内部コンポーネントに委任します。

gRPCとRESTデュアルインターフェース

API ServerはgRPCを基本プロトコルとして使用し、grpc-gatewayを通じてREST APIを自動生成します:

// API ServerのgRPCサービス登録
func (s *ArgoCDServer) Run(ctx context.Context, listeners ...net.Listener) {
    grpcServer := grpc.NewServer(grpcOpts...)
    application.RegisterApplicationServiceServer(grpcServer, s.appService)
    repository.RegisterRepositoryServiceServer(grpcServer, s.repoService)
    project.RegisterProjectServiceServer(grpcServer, s.projectService)
    session.RegisterSessionServiceServer(grpcServer, s.sessionService)
}

主要gRPCサービス

サービス説明
ApplicationServiceApplication CRUD、Sync、Rollback
RepositoryServiceGitリポジトリの登録/管理
ClusterService対象クラスタの登録/管理
ProjectServiceAppProject CRUD
SessionServiceログイン/ログアウト、トークン管理
AccountServiceローカルユーザーアカウント管理

認証フロー

1. ユーザーがログインリクエストを送信
2. API ServerがDexにOIDC認証を委任(SSOの場合)
3. Dexが外部IdP(GitHub、LDAPなど)に認証リクエスト
4. 認証成功時にJWTトークンを発行
5. 以降のリクエストでJWTトークンをBearerヘッダーで送信
6. API ServerがJWTを検証しRBACポリシーで認可を実行

RBACモデル

ArgoCDのRBACはCasbinライブラリをベースに実装されています:

# 基本ポリシーフォーマット
p, ROLE, RESOURCE, ACTION, OBJECT, EFFECT

# 例:proj-admin役割にmy-projectのすべてのapplication権限を付与
p, role:proj-admin, applications, *, my-project/*, allow

# グループマッピング
g, my-github-team, role:proj-admin

ポリシーはargocd-rbac-cm ConfigMapに保存されます。主要リソースとアクション:

リソースアクション
applicationsget, create, update, delete, sync, override, action
repositoriesget, create, update, delete
clustersget, create, update, delete
projectsget, create, update, delete
logsget
execcreate

3. Repository Server内部分析

役割と責任

Repository ServerはGitリポジトリからソースを取得し、最終的なKubernetesマニフェストを生成するコアコンポーネントです。

Gitクローンメカニズム

1. Application Controllerがrepo-serverにマニフェスト生成をリクエスト
2. repo-serverがGitリポジトリをクローン(shallow cloneがデフォルト)
3. 指定されたリビジョン(branch、tag、commit)にcheckout
4. パス内のマニフェストを検出し適切なツールでレンダリング
5. 結果をApplication Controllerに返却しRedisにキャッシュ

マニフェスト生成パイプライン

Repository Serverは様々なツールをサポートします:

// マニフェスト生成ツール検出ロジック(簡略化)
func detectTool(path string) string {
    if fileExists(path, "Chart.yaml") {
        return "helm"
    }
    if fileExists(path, "kustomization.yaml") ||
       fileExists(path, "kustomization.yml") ||
       fileExists(path, "Kustomization") {
        return "kustomize"
    }
    return "directory" // plain YAML
}

ツール別レンダリング方式:

ツール検出条件レンダリング方式
HelmChart.yamlが存在helm templateを実行
Kustomizekustomization.yamlが存在kustomize buildを実行
DirectoryデフォルトYAMLファイルを直接ロード
Pluginplugin.yamlが存在CMPサイドカーに委任

Helmレンダリングプロセス

1. Chart.yamlをパースしてチャートメタデータを確認
2. dependenciesがあればhelm dependency buildを実行
3. valuesファイルをロード(デフォルトvalues.yaml + ユーザーオーバーライド)
4. helm templateコマンドで最終マニフェストを生成
5. 生成されたYAMLをパースしてバリデーション

Kustomizeレンダリングプロセス

1. kustomization.yamlをパース
2. bases/resources参照を解決
3. patches、overlaysを適用
4. namePrefix、nameSuffix、labels、annotations変換
5. 最終YAMLを出力

Config Management Plugin(CMP)

CMPはサイドカーパターンで実装されます:

# CMP設定例 - plugin.yaml
apiVersion: argoproj.io/v1alpha1
kind: ConfigManagementPlugin
metadata:
  name: custom-jsonnet
spec:
  version: v1.0
  generate:
    command: [jsonnet]
    args: [main.jsonnet]
  discover:
    fileName: main.jsonnet

CMPサイドカーはrepo-server Podに追加され、Unixソケットを通じて通信します。

Redisキャッシュ戦略

キャッシュキー:HASH(git-url + revision + path + tool + params)
キャッシュTTL:デフォルト24時間(ARGOCD_REPO_SERVER_CACHE_EXPIRATIONキャッシュ無効化:Gitリビジョン変更時

キャッシュにより同一リビジョンに対する繰り返しのマニフェスト生成を防止し、Repository ServerのCPU/メモリ使用量を大幅に削減します。

4. Application Controller内部分析

役割と責任

Application ControllerはArgoCDのコアエンジンで、Kubernetesリソースを監視し同期を実行します。

Informer基盤Watchメカニズム

Application ControllerはKubernetesのInformerパターンを使用してリソース状態を効率的に追跡します:

// Informer基盤リソース監視(簡略化)
func (c *ApplicationController) watchResources() {
    factory := informers.NewSharedInformerFactory(clientset, resyncPeriod)

    factory.Apps().V1().Deployments().Informer().AddEventHandler(
        cache.ResourceEventHandlerFuncs{
            AddFunc:    c.onResourceAdd,
            UpdateFunc: c.onResourceUpdate,
            DeleteFunc: c.onResourceDelete,
        },
    )
}

Reconciliation Loop

Application Controllerの核心はReconciliation Loopです:

ループ:
  1. すべてのApplicationリソースを照会
  2. 各Applicationに対して:
     a. Repository Serverに望ましい状態(マニフェスト)をリクエスト
     b. 対象クラスタから実際の状態を照会
     c. 望ましい状態と実際の状態を比較(Diff)
     d. Sync Statusを更新(Synced / OutOfSync)
     e. Health Statusを更新(Healthy / Degraded / Progressingなど)
     f. Auto-Syncが有効であれば自動同期を実行
  3. 次のサイクルまで待機(デフォルト180秒)

Diffエンジン

ArgoCDのDiffエンジンはKubernetesの3-way mergeに基づいています:

比較対象:
  - Last Applied Configuration(annotationに保存)
  - Live State(クラスタの実際の状態)
  - Desired State(Gitから生成されたマニフェスト)

Diffプロセス:
  1. Live StateとDesired Stateを正規化(normalization)
  2. デフォルト値を除去(Kubernetesが自動追加するフィールド)
  3. 無視フィールドを除外(resourceVersion、generationなど)
  4. 残りのフィールド間で構造的比較を実行

正規化(Normalization)

Kubernetesはリソースを保存する際に様々なデフォルト値を自動追加します。ArgoCDはこれを正規化して不要なdiffを防止します:

// 正規化の例
func normalizeResource(resource *unstructured.Unstructured) {
    // metadataから管理フィールドを除去
    removeFields(resource, "metadata.managedFields")
    removeFields(resource, "metadata.resourceVersion")
    removeFields(resource, "metadata.uid")
    removeFields(resource, "metadata.generation")
    removeFields(resource, "metadata.creationTimestamp")

    // statusフィールドを除去(宣言的状態ではない)
    removeFields(resource, "status")
}

Health Assessment

Application Controllerは各リソースの健康状態を評価します:

状態説明
Healthyリソースが正常動作中
Progressingリソースがまだ望ましい状態に到達していない(ロールアウト進行中)
Degradedリソースが異常状態(CrashLoopBackOffなど)
Suspendedリソースが一時停止中
Missingリソースがクラスタに存在しない
Unknown状態を判断できない

カスタムHealth Check(Lua)

ArgoCDはLuaスクリプトでカスタムHealth Checkを定義できます:

-- argocd-cm ConfigMapに定義するカスタムhealth check
hs = {}
if obj.status ~= nil then
    if obj.status.conditions ~= nil then
        for _, condition in ipairs(obj.status.conditions) do
            if condition.type == "Ready" and condition.status == "True" then
                hs.status = "Healthy"
                hs.message = condition.message
                return hs
            end
        end
    end
end
hs.status = "Progressing"
hs.message = "Waiting for resource to become ready"
return hs

5. Sync Operation詳細分析

Sync実行フロー

1. ユーザーまたはAuto-SyncがSyncをトリガー
2. Application ControllerがRepository Serverに最新マニフェストをリクエスト
3. マニフェスト生成完了後にSync作業を開始
4. PreSync Hookを実行(ある場合)
5. メインリソースの同期(kubectl apply相当の作業)
6. PostSync Hookを実行(ある場合)
7. Health Checkでリソース状態を確認
8. Sync Statusを更新

Resource Ordering

ArgoCDはSync WaveとPhaseを通じてリソース適用順序を制御します:

# Sync Waveの例
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: '-1' # 小さい番号が先に実行

デフォルト適用順序:

  1. Namespace
  2. NetworkPolicy
  3. ResourceQuota
  4. LimitRange
  5. ServiceAccount
  6. Role、ClusterRole
  7. RoleBinding、ClusterRoleBinding
  8. ConfigMap、Secret
  9. Service
  10. Deployment、StatefulSet、DaemonSet
  11. Ingress

Pruning(整理)

PruneはGitから削除されたリソースをクラスタから削除する機能です:

Prune対象の判別:
  1. クラスタに存在するリソース一覧を照会
  2. ArgoCDのtracking label/annotationがあるリソースをフィルタ
  3. 現在のGitマニフェストに存在しないリソースを識別
  4. cascadeまたはforeground削除ポリシーに従って削除

6. Redis内部分析

役割

RedisはArgoCDで2つの主要な役割を果たします:

キャッシュストア:

  • Repository Serverが生成したマニフェストキャッシュ
  • クラスタ状態キャッシュ
  • アプリ状態情報キャッシュ

セッションストア:

  • ユーザーログインセッション
  • JWTトークン関連データ

キャッシュキー構造

app|resources|CLUSTER_URL|NAMESPACE: リソースツリーキャッシュ
git|manifest|REPO_URL|REVISION|PATH: マニフェストキャッシュ
repo|connection|REPO_URL: 接続状態キャッシュ

7. Dex内部分析

役割

DexはOIDC(OpenID Connect)Identity Providerとして、ArgoCDにSSO機能を提供します。

サポートコネクタ

コネクタ説明
LDAPActive DirectoryなどLDAPサーバー連携
SAMLSAML 2.0プロトコルサポート
GitHubGitHub OAuth認証
GitLabGitLab OAuth認証
GoogleGoogle OIDC認証
OIDC汎用OIDCプロバイダー連携

詳細認証フロー

1. ユーザーがArgoCD UISSOログインをクリック
2. API ServerがDexのauthorization endpointにリダイレクト
3. Dexが設定されたコネクタ(GitHubなど)に認証を委任
4. ユーザーが外部IdPで認証を実行
5. 外部IdPがDex callback URLにリダイレクト
6. DexがID Tokenを生成(ユーザー情報、グループを含む)
7. API ServerがID Tokenを検証しArgoCD JWTを発行
8. JWTにユーザーグループ情報を含む(RBACに活用)

8. AppProjectとアクセス制御

AppProjectリソース構造

AppProjectはArgoCDの論理的分離単位です:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-alpha
  namespace: argocd
spec:
  description: 'Team Alphaのプロジェクト'
  # 許可ソースリポジトリ
  sourceRepos:
    - 'https://github.com/org/team-alpha-*'
  # 許可対象クラスタ/ネームスペース
  destinations:
    - server: 'https://kubernetes.default.svc'
      namespace: 'team-alpha-*'
  # 作成可能なクラスタリソース(制限)
  clusterResourceWhitelist:
    - group: ''
      kind: Namespace
  # ネームスペースリソース拒否リスト
  namespaceResourceBlacklist:
    - group: ''
      kind: ResourceQuota
    - group: ''
      kind: LimitRange
  # 役割定義
  roles:
    - name: developer
      description: '開発チーム役割'
      policies:
        - p, proj:team-alpha:developer, applications, get, team-alpha/*, allow
        - p, proj:team-alpha:developer, applications, sync, team-alpha/*, allow
      groups:
        - team-alpha-devs

制限項目

制限説明
sourceRepos使用可能なGitリポジトリURLパターン
destinationsデプロイ可能なクラスタとネームスペース
clusterResourceWhitelist作成可能なクラスタスコープリソース
namespaceResourceBlacklist作成不可のネームスペーススコープリソース
signatureKeys必須GPG署名キー
syncWindows同期許可/禁止時間帯

9. gRPC通信アーキテクチャ

内部通信フロー

Application Controller
  --gRPC--> Repository Server(マニフェスト生成リクエスト)
  --gRPC--> API Server(状態更新)

API Server
  --gRPC--> Repository Server(リポジトリ検証)
  --HTTP--> Dex(認証)
  --TCP---> Redis(キャッシュ/セッション)

Repository Server
  --TCP---> Redis(マニフェストキャッシュ)
  --HTTPS--> Git Server(リポジトリクローン)

TLS設定

コンポーネント間gRPC通信はデフォルトでTLSで保護されます:

- API ServerがTLS証明書を生成し管理
- 各コンポーネントはargocd-server-tls Secretから証明書をロード
- mTLS(相互TLS)はオプションで有効化可能

10. まとめ

ArgoCDのアーキテクチャを要約すると次の通りです:

  1. API Server:外部インターフェース + 認証/認可ゲートウェイ
  2. Repository Server:マニフェスト生成の単一責任(Helm、Kustomize、Plain YAML、CMP)
  3. Application Controller:状態監視 + 同期実行のコアエンジン
  4. Redis:パフォーマンス最適化のためのキャッシュレイヤー
  5. Dex:SSO統合のための認証ブローカー

これらのコンポーネントがgRPCを通じて緊密に連携し、安定的でスケーラブルなGitOpsプラットフォームを構成します。次のポストではSyncエンジンの内部動作をより深く分析します。