Split View: ArgoCD 아키텍처 내부 분석: 소스코드 레벨 딥다이브
ArgoCD 아키텍처 내부 분석: 소스코드 레벨 딥다이브
- 1. ArgoCD 전체 아키텍처 개요
- 2. API Server 내부 분석
- 3. Repository Server 내부 분석
- 4. Application Controller 내부 분석
- 5. Sync Operation 상세 분석
- 6. Redis 내부 분석
- 7. Dex 내부 분석
- 8. AppProject와 접근 제어
- 9. gRPC 통신 아키텍처
- 10. 정리
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 서비스
| 서비스 | 설명 |
|---|---|
| ApplicationService | Application CRUD, Sync, Rollback |
| RepositoryService | Git 저장소 등록/관리 |
| ClusterService | 대상 클러스터 등록/관리 |
| ProjectService | AppProject 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에 저장됩니다. 주요 리소스와 액션:
| 리소스 | 액션 |
|---|---|
| applications | get, create, update, delete, sync, override, action |
| repositories | get, create, update, delete |
| clusters | get, create, update, delete |
| projects | get, create, update, delete |
| logs | get |
| exec | create |
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
}
지원 도구별 렌더링 방식:
| 도구 | 감지 조건 | 렌더링 방식 |
|---|---|---|
| Helm | Chart.yaml 존재 | helm template 실행 |
| Kustomize | kustomization.yaml 존재 | kustomize build 실행 |
| Directory | 기본 | YAML 파일 직접 로드 |
| Plugin | plugin.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' # 낮은 번호가 먼저 실행
기본 적용 순서:
- Namespace
- NetworkPolicy
- ResourceQuota
- LimitRange
- ServiceAccount
- Role, ClusterRole
- RoleBinding, ClusterRoleBinding
- ConfigMap, Secret
- Service
- Deployment, StatefulSet, DaemonSet
- 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 기능을 제공합니다.
지원 커넥터
| 커넥터 | 설명 |
|---|---|
| LDAP | Active Directory 등 LDAP 서버 연동 |
| SAML | SAML 2.0 프로토콜 지원 |
| GitHub | GitHub OAuth 인증 |
| GitLab | GitLab OAuth 인증 |
| Google 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의 아키텍처를 요약하면 다음과 같습니다:
- API Server: 외부 인터페이스 + 인증/인가 게이트웨이
- Repository Server: 매니페스트 생성의 단일 책임 (Helm, Kustomize, Plain YAML, CMP)
- Application Controller: 상태 감시 + 동기화 실행의 핵심 엔진
- Redis: 성능 최적화를 위한 캐시 계층
- Dex: SSO 통합을 위한 인증 브로커
이 컴포넌트들이 gRPC를 통해 긴밀하게 연동되면서 안정적이고 확장 가능한 GitOps 플랫폼을 구성합니다. 다음 포스트에서는 Sync 엔진의 내부 동작을 더 깊이 분석하겠습니다.
[ArgoCD] Architecture Internals: Source Code Level Deep Dive
- 1. ArgoCD Architecture Overview
- 2. API Server Internals
- 3. Repository Server Internals
- 4. Application Controller Internals
- 5. Sync Operation Detailed Analysis
- 6. Redis Internals
- 7. Dex Internals
- 8. AppProject and Access Control
- 9. gRPC Communication Architecture
- 10. Summary
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
| Service | Description |
|---|---|
| ApplicationService | Application CRUD, Sync, Rollback |
| RepositoryService | Git repository registration/management |
| ClusterService | Target cluster registration/management |
| ProjectService | AppProject CRUD |
| SessionService | Login/logout, token management |
| AccountService | Local 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:
| Resource | Actions |
|---|---|
| applications | get, create, update, delete, sync, override, action |
| repositories | get, create, update, delete |
| clusters | get, create, update, delete |
| projects | get, create, update, delete |
| logs | get |
| exec | create |
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:
| Tool | Detection Condition | Rendering Method |
|---|---|---|
| Helm | Chart.yaml exists | Run helm template |
| Kustomize | kustomization.yaml exists | Run kustomize build |
| Directory | Default | Direct YAML file loading |
| Plugin | plugin.yaml exists | Delegate 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:
| Status | Description |
|---|---|
| Healthy | Resource is operating normally |
| Progressing | Resource has not reached desired state yet (rollout in progress) |
| Degraded | Resource is in an unhealthy state (CrashLoopBackOff, etc.) |
| Suspended | Resource is paused |
| Missing | Resource does not exist in the cluster |
| Unknown | Status 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:
- Namespace
- NetworkPolicy
- ResourceQuota
- LimitRange
- ServiceAccount
- Role, ClusterRole
- RoleBinding, ClusterRoleBinding
- ConfigMap, Secret
- Service
- Deployment, StatefulSet, DaemonSet
- 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
| Connector | Description |
|---|---|
| LDAP | Active Directory and LDAP server integration |
| SAML | SAML 2.0 protocol support |
| GitHub | GitHub OAuth authentication |
| GitLab | GitLab OAuth authentication |
| Google OIDC authentication | |
| OIDC | Generic 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
| Field | Description |
|---|---|
| sourceRepos | Allowed Git repository URL patterns |
| destinations | Allowed deployment clusters and namespaces |
| clusterResourceWhitelist | Allowed cluster-scoped resources |
| namespaceResourceBlacklist | Denied namespace-scoped resources |
| signatureKeys | Required GPG signature keys |
| syncWindows | Allowed/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:
- API Server: External interface + authentication/authorization gateway
- Repository Server: Single responsibility for manifest generation (Helm, Kustomize, Plain YAML, CMP)
- Application Controller: Core engine for state monitoring + sync execution
- Redis: Cache layer for performance optimization
- 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.