Skip to content

Split View: ArgoCD 아키텍처 내부 분석: 소스코드 레벨 딥다이브

|

ArgoCD 아키텍처 내부 분석: 소스코드 레벨 딥다이브

1. ArgoCD 전체 아키텍처 개요

ArgoCD는 Kubernetes 환경에서 GitOps를 구현하기 위한 선언적 지속 배포(Continuous Delivery) 도구입니다. CNCF Graduated 프로젝트로, Pull 기반 배포 모델을 통해 Git 저장소에 정의된 원하는 상태와 클러스터의 실제 상태를 지속적으로 동기화합니다.

핵심 컴포넌트

ArgoCD는 다음 5개의 핵심 컴포넌트로 구성됩니다:

  • argocd-server (API Server): 웹 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 sidecar로 위임

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 revision 변경 시

캐시를 통해 동일 리비전에 대한 반복적인 매니페스트 생성을 방지하고, 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상태를 판단할 수 없음

Custom 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에서 두 가지 주요 역할을 수행합니다:

캐시 저장소:

  • 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 UI에서 SSO 로그인 클릭
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 엔진의 내부 동작을 더 깊이 분석하겠습니다.

[ArgoCD] Architecture Internals: Source Code Level Deep Dive

1. ArgoCD Architecture Overview

ArgoCD is a declarative continuous delivery tool for implementing GitOps on Kubernetes. As a CNCF Graduated project, it continuously synchronizes the desired state defined in Git repositories with the actual state of clusters using a pull-based deployment model.

Core Components

ArgoCD consists of five core components:

  • argocd-server (API Server): Provides gRPC/REST API for Web UI, CLI, and CI/CD integrations
  • argocd-repo-server (Repository Server): Handles Git cloning and manifest generation
  • argocd-application-controller (Application Controller): Monitors application state and performs synchronization
  • Redis: Stores manifest caches and session data
  • Dex: Provides SSO (Single Sign-On) authentication

Inter-Component Communication

All internal components communicate via gRPC:

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

2. API Server Internals

Role and Responsibilities

The API Server serves as the front-end gateway for ArgoCD. It receives external requests and delegates them to internal components.

Dual gRPC and REST Interface

The API Server uses gRPC as its primary protocol and auto-generates REST APIs via grpc-gateway:

// API Server gRPC service registration
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)
}

Key gRPC Services

ServiceDescription
ApplicationServiceApplication CRUD, Sync, Rollback
RepositoryServiceGit repository registration/management
ClusterServiceTarget cluster registration/management
ProjectServiceAppProject CRUD
SessionServiceLogin/logout, token management
AccountServiceLocal user account management

Authentication Flow

1. User sends login request
2. API Server delegates OIDC auth to Dex (for SSO)
3. Dex authenticates against external IdP (GitHub, LDAP, etc.)
4. On success, JWT token is issued
5. Subsequent requests include JWT in Bearer header
6. API Server validates JWT and performs RBAC authorization

RBAC Model

ArgoCD's RBAC is implemented using the Casbin library:

# Default policy format
p, ROLE, RESOURCE, ACTION, OBJECT, EFFECT

# Example: grant proj-admin all application permissions for my-project
p, role:proj-admin, applications, *, my-project/*, allow

# Group mapping
g, my-github-team, role:proj-admin

Policies are stored in the argocd-rbac-cm ConfigMap. Key resources and actions:

ResourceActions
applicationsget, create, update, delete, sync, override, action
repositoriesget, create, update, delete
clustersget, create, update, delete
projectsget, create, update, delete
logsget
execcreate

3. Repository Server Internals

Role and Responsibilities

The Repository Server fetches source from Git repositories and generates final Kubernetes manifests.

Git Clone Mechanism

1. Application Controller requests manifest generation from repo-server
2. repo-server clones Git repository (shallow clone by default)
3. Checks out specified revision (branch, tag, commit)
4. Detects manifests in the path and renders with appropriate tool
5. Returns result to Application Controller and caches in Redis

Manifest Generation Pipeline

The Repository Server supports various tools:

// Tool detection logic (simplified)
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
}

Rendering by tool type:

ToolDetection ConditionRendering Method
HelmChart.yaml existsRun helm template
Kustomizekustomization.yaml existsRun kustomize build
DirectoryDefaultDirect YAML file loading
Pluginplugin.yaml existsDelegate to CMP sidecar

Helm Rendering Process

1. Parse Chart.yaml for chart metadata
2. Run helm dependency build if dependencies exist
3. Load values files (default values.yaml + user overrides)
4. Run helm template to generate final manifests
5. Parse generated YAML and validate

Kustomize Rendering Process

1. Parse kustomization.yaml
2. Resolve bases/resources references
3. Apply patches and overlays
4. Apply namePrefix, nameSuffix, labels, annotations transforms
5. Output final YAML

Config Management Plugin (CMP)

CMP is implemented using the sidecar pattern:

# CMP configuration example - 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 sidecars are added to the repo-server Pod and communicate via Unix sockets.

Redis Caching Strategy

Cache key: HASH(git-url + revision + path + tool + params)
Cache TTL: Default 24 hours (ARGOCD_REPO_SERVER_CACHE_EXPIRATION)
Cache invalidation: On Git revision change

Caching prevents repetitive manifest generation for the same revision, significantly reducing Repository Server CPU/memory usage.

4. Application Controller Internals

Role and Responsibilities

The Application Controller is the core engine of ArgoCD, monitoring Kubernetes resources and performing synchronization.

Informer-Based Watch Mechanism

The Application Controller uses Kubernetes Informer patterns to efficiently track resource state:

// Informer-based resource watching (simplified)
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

The core of the Application Controller is its Reconciliation Loop:

Loop:
  1. Query all Application resources
  2. For each Application:
     a. Request desired state (manifests) from Repository Server
     b. Query actual state from target cluster
     c. Compare desired vs actual state (Diff)
     d. Update Sync Status (Synced / OutOfSync)
     e. Update Health Status (Healthy / Degraded / Progressing, etc.)
     f. Execute auto-sync if enabled
  3. Wait until next cycle (default 180 seconds)

Diff Engine

ArgoCD's diff engine is based on Kubernetes 3-way merge:

Comparison targets:
  - Last Applied Configuration (stored in annotation)
  - Live State (actual cluster state)
  - Desired State (manifests from Git)

Diff process:
  1. Normalize Live State and Desired State
  2. Remove defaults (fields auto-added by Kubernetes)
  3. Exclude ignored fields (resourceVersion, generation, etc.)
  4. Perform structural comparison of remaining fields

Normalization

Kubernetes auto-adds various defaults when storing resources. ArgoCD normalizes these to prevent unnecessary diffs:

// Normalization example
func normalizeResource(resource *unstructured.Unstructured) {
    // Remove managed fields from metadata
    removeFields(resource, "metadata.managedFields")
    removeFields(resource, "metadata.resourceVersion")
    removeFields(resource, "metadata.uid")
    removeFields(resource, "metadata.generation")
    removeFields(resource, "metadata.creationTimestamp")

    // Remove status field (not declarative state)
    removeFields(resource, "status")
}

Health Assessment

The Application Controller evaluates the health status of each resource:

StatusDescription
HealthyResource is operating normally
ProgressingResource has not reached desired state yet (rollout in progress)
DegradedResource is in an unhealthy state (CrashLoopBackOff, etc.)
SuspendedResource is paused
MissingResource does not exist in the cluster
UnknownStatus cannot be determined

Custom Health Check (Lua)

ArgoCD supports custom Health Checks via Lua scripts:

-- Custom health check defined in argocd-cm ConfigMap
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 Detailed Analysis

Sync Execution Flow

1. User or Auto-Sync triggers Sync
2. Application Controller requests latest manifests from Repository Server
3. Start sync operation after manifest generation completes
4. Execute PreSync hooks (if any)
5. Synchronize main resources (equivalent to kubectl apply)
6. Execute PostSync hooks (if any)
7. Verify resource state via Health Check
8. Update Sync Status

Resource Ordering

ArgoCD controls resource application order through Sync Waves and Phases:

# Sync Wave example
metadata:
  annotations:
    argocd.argoproj.io/sync-wave: '-1' # Lower numbers execute first

Default application order:

  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 deletes resources from the cluster that have been removed from Git:

Prune target identification:
  1. Query list of resources in cluster
  2. Filter resources with ArgoCD tracking label/annotation
  3. Identify resources not present in current Git manifests
  4. Delete according to cascade or foreground deletion policy

6. Redis Internals

Role

Redis serves two primary functions in ArgoCD:

Cache Store:

  • Manifest caches from Repository Server
  • Cluster state cache
  • Application state information cache

Session Store:

  • User login sessions
  • JWT token-related data

Cache Key Structure

app|resources|CLUSTER_URL|NAMESPACE: resource tree cache
git|manifest|REPO_URL|REVISION|PATH: manifest cache
repo|connection|REPO_URL: connection state cache

7. Dex Internals

Role

Dex is an OIDC (OpenID Connect) Identity Provider that provides SSO capabilities to ArgoCD.

Supported Connectors

ConnectorDescription
LDAPActive Directory and LDAP server integration
SAMLSAML 2.0 protocol support
GitHubGitHub OAuth authentication
GitLabGitLab OAuth authentication
GoogleGoogle OIDC authentication
OIDCGeneric OIDC provider integration

Detailed Authentication Flow

1. User clicks SSO login in ArgoCD UI
2. API Server redirects to Dex authorization endpoint
3. Dex delegates auth to configured connector (e.g., GitHub)
4. User authenticates with external IdP
5. External IdP redirects to Dex callback URL
6. Dex generates ID Token (includes user info and groups)
7. API Server validates ID Token and issues ArgoCD JWT
8. JWT includes user group information (used for RBAC)

8. AppProject and Access Control

AppProject Resource Structure

AppProject is the logical isolation unit in ArgoCD:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: team-alpha
  namespace: argocd
spec:
  description: 'Team Alpha project'
  # Allowed source repositories
  sourceRepos:
    - 'https://github.com/org/team-alpha-*'
  # Allowed target clusters/namespaces
  destinations:
    - server: 'https://kubernetes.default.svc'
      namespace: 'team-alpha-*'
  # Allowed cluster-scoped resources (restricted)
  clusterResourceWhitelist:
    - group: ''
      kind: Namespace
  # Denied namespace-scoped resources
  namespaceResourceBlacklist:
    - group: ''
      kind: ResourceQuota
    - group: ''
      kind: LimitRange
  # Role definitions
  roles:
    - name: developer
      description: 'Development team role'
      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

Restriction Fields

FieldDescription
sourceReposAllowed Git repository URL patterns
destinationsAllowed deployment clusters and namespaces
clusterResourceWhitelistAllowed cluster-scoped resources
namespaceResourceBlacklistDenied namespace-scoped resources
signatureKeysRequired GPG signature keys
syncWindowsAllowed/denied sync time windows

9. gRPC Communication Architecture

Internal Communication Flow

Application Controller
  --gRPC--> Repository Server (manifest generation requests)
  --gRPC--> API Server (status updates)

API Server
  --gRPC--> Repository Server (repository validation)
  --HTTP--> Dex (authentication)
  --TCP---> Redis (cache/sessions)

Repository Server
  --TCP---> Redis (manifest cache)
  --HTTPS--> Git Server (repository clone)

TLS Configuration

Inter-component gRPC communication is protected by TLS by default:

- API Server generates and manages TLS certificates
- Each component loads certificates from argocd-server-tls Secret
- mTLS (mutual TLS) can be optionally enabled

10. Summary

ArgoCD architecture summarized:

  1. API Server: External interface + authentication/authorization gateway
  2. Repository Server: Single responsibility for manifest generation (Helm, Kustomize, Plain YAML, CMP)
  3. Application Controller: Core engine for state monitoring + sync execution
  4. Redis: Cache layer for performance optimization
  5. Dex: Authentication broker for SSO integration

These components work together via gRPC to form a stable and scalable GitOps platform. In the next post, we will dive deeper into the Sync engine internals.