ArgoCD Application, AppProject 본문
- 1편 — ArgoCD Helm 설치 시 생성되는 컴포넌트 역할 정리
- 2편 — ArgoCD Application, AppProject 개념 정리 (현재 글)
- 3편 — ApplicationSet으로 멀티 클러스터 배포 자동화
- 4편 — ArgoCD Notifications Slack 연동 가이드
ArgoCD를 처음 쓰면 Application과 AppProject가 헷갈립니다. 이 두 가지는 ArgoCD의 핵심 커스텀 리소스로, 이 개념을 잘 이해해야 멀티 팀 환경에서 ArgoCD를 제대로 운영할 수 있습니다.
Application과 AppProject의 역할과 관계, 그리고 실무에서 어떻게 구성하는지를 다룹니다.
Application — "무엇을 어디에 배포할 것인가"
Application은 ArgoCD에서 배포의 기본 단위입니다. Git 레포의 어느 경로에 있는 매니페스트를 어느 클러스터/네임스페이스에 배포할지를 정의합니다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd # ArgoCD가 설치된 namespace
spec:
project: default # 어느 AppProject에 속하는지
# 소스: Git 어디에서 가져오나
source:
repoURL: https://github.com/my-org/my-repo
targetRevision: main # 브랜치, 태그, 커밋 SHA 모두 가능
path: k8s/overlays/prod # 레포 내 경로 (Kustomize, Helm 등)
# 목적지: 어느 클러스터/네임스페이스에 배포하나
destination:
server: https://kubernetes.default.svc # 현재 클러스터
namespace: production
# Sync 정책
syncPolicy:
automated:
prune: true # Git에서 삭제된 리소스 자동 제거
selfHeal: true # 수동으로 변경된 리소스 자동 복구
syncOptions:
- CreateNamespace=true # namespace 없으면 자동 생성
source — Helm 차트 배포
Helm 차트를 사용할 경우 source에 helm 섹션을 추가합니다.
source:
repoURL: https://charts.bitnami.com/bitnami
chart: redis # 차트 이름
targetRevision: 18.x.x # 차트 버전
helm:
releaseName: my-redis
values: |
auth:
enabled: false
replica:
replicaCount: 2
syncPolicy — Sync 동작 제어
| 옵션 | 설명 | 권장 |
|---|---|---|
automated.prune | Git에서 삭제된 리소스를 클러스터에서도 삭제 | 운영 환경 주의 |
automated.selfHeal | 클러스터에서 수동 변경 시 Git 상태로 되돌림 | GitOps 원칙상 권장 |
CreateNamespace=true | destination namespace가 없으면 자동 생성 | 권장 |
ServerSideApply=true | kubectl apply 대신 server-side apply 사용 | CRD 충돌 방지 시 유용 |
RespectIgnoreDifferences=true | ignoreDifferences 설정을 Sync 시에도 적용 | 상황에 따라 |
Application 상태 이해하기
ArgoCD Web UI에서 보이는 상태는 Sync 상태와 Health 상태 두 가지 축으로 표시됩니다.
Sync 상태
- Synced — Git desired state와 클러스터 실제 상태가 일치
- OutOfSync — 차이가 있음. 아직 Sync 안 했거나 수동 변경이 있는 경우
- Unknown — 상태를 알 수 없음 (클러스터 연결 문제 등)
Health 상태
- Healthy — 모든 리소스가 정상 동작 중
- Progressing — Deployment rollout 중 등 아직 완료되지 않은 상태
- Degraded — 일부 리소스가 비정상 (Pod CrashLoopBackOff 등)
- Missing — Git에는 있는데 클러스터에 리소스가 없음
AppProject — "누가 어디에 배포할 수 있나"
AppProject는 Application을 묶는 논리적 그룹입니다. 팀별 또는 환경별로 배포 가능한 Git 레포, 클러스터, 네임스페이스를 제한하는 RBAC 경계 역할을 합니다.
Application
"무엇을 어디에 배포할 것인가"를 정의하는 배포 단위. 반드시 하나의 AppProject에 속해야 합니다.
AppProject
Application들의 논리적 묶음. 허용된 Git 레포, 클러스터, 네임스페이스, 리소스 종류를 제한합니다.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-backend
namespace: argocd
spec:
description: "백엔드 팀 프로젝트"
# 이 프로젝트의 Application이 사용할 수 있는 Git 레포
sourceRepos:
- https://github.com/my-org/backend-* # 와일드카드 가능
- https://charts.bitnami.com/bitnami
# 배포 가능한 클러스터와 네임스페이스
destinations:
- server: https://kubernetes.default.svc
namespace: backend-prod
- server: https://kubernetes.default.svc
namespace: backend-staging
# 배포 허용 리소스 종류 (화이트리스트)
clusterResourceWhitelist:
- group: ""
kind: Namespace # Namespace 생성 허용
namespaceResourceBlacklist:
- group: ""
kind: ResourceQuota # ResourceQuota는 배포 금지
# RBAC 역할 정의
roles:
- name: developer
description: "배포 권한만 있는 개발자 역할"
policies:
- p, proj:team-backend:developer, applications, get, team-backend/*, allow
- p, proj:team-backend:developer, applications, sync, team-backend/*, allow
groups:
- my-org:backend-team # GitHub org 팀과 연동
default 프로젝트
ArgoCD 설치 시 default AppProject가 자동으로 생성됩니다. sourceRepos: ["*"], destinations: [서버: *, 네임스페이스: *]로 모든 것을 허용하기 때문에, 운영 환경에서는 반드시 팀별 AppProject를 별도로 만들고 default 프로젝트 사용을 제한하는 것을 권장합니다.
실무 구성 패턴
패턴 1 — 팀별 AppProject 분리
# 백엔드 팀 프로젝트
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-backend
spec:
sourceRepos:
- https://github.com/my-org/backend-*
destinations:
- server: https://kubernetes.default.svc
namespace: "backend-*" # backend- 로 시작하는 네임스페이스만 허용
---
# 프론트엔드 팀 프로젝트
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-frontend
spec:
sourceRepos:
- https://github.com/my-org/frontend-*
destinations:
- server: https://kubernetes.default.svc
namespace: "frontend-*"
패턴 2 — 환경별 AppProject 분리
# 운영 환경 프로젝트 (수동 Sync만 허용)
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: env-production
spec:
sourceRepos:
- https://github.com/my-org/*
destinations:
- server: https://prod-cluster.example.com
namespace: "*"
# 운영 환경: Auto-sync 비활성화를 정책으로 강제
syncWindows:
- kind: deny
schedule: "* * * * *" # 항상 자동 배포 차단
duration: 1h
applications: ["*"]
manualSync: true # 수동 Sync는 허용
패턴 3 — ignoreDifferences로 Sync 노이즈 줄이기
Deployment의 replicas처럼 HPA가 관리하는 필드는 ArgoCD가 OutOfSync로 감지합니다. ignoreDifferences로 제외할 수 있습니다.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # HPA가 관리하는 replicas 무시
- group: ""
kind: Secret
jsonPointers:
- /data # 외부에서 주입된 Secret 데이터 무시
자주 하는 실수
prune: true는 Git에서 파일을 삭제하면 클러스터 리소스도 같이 삭제합니다. 처음에는 prune: false로 시작해서 ArgoCD가 어떤 리소스를 prune 대상으로 잡는지 확인한 뒤 활성화하세요.
default 프로젝트는 모든 레포와 클러스터에 접근 가능합니다. 팀이 늘어나면 반드시 AppProject를 분리해서 격리하세요.
Application을 하나씩 수동으로 만들지 않고, 하나의 "루트 Application"이 다른 Application YAML들을 Git에서 읽어서 자동으로 생성하게 할 수 있습니다. 이를 App of Apps 패턴이라고 부릅니다. ArgoCD를 처음 부트스트랩할 때 유용합니다.
마치며
Application은 배포 단위, AppProject는 그 배포의 경계와 권한을 정의합니다. 작은 팀에서는 default 프로젝트 하나로 시작해도 되지만, 팀이 여러 개거나 운영/개발 환경을 명확히 분리해야 한다면 처음부터 AppProject 구조를 잡아두는 것을 권장합니다.
다음 편에서는 ApplicationSet을 사용해서 여러 클러스터에 배포를 자동화하는 방법을 다룹니다.
- 3편 — ApplicationSet으로 멀티 클러스터 배포 자동화
'Kubernetes' 카테고리의 다른 글
| ArgoCD Notifications Slack 연동 (0) | 2026.05.16 |
|---|---|
| ArgoCD ApplicationSet (0) | 2026.05.16 |
| ArgoCD Helm 설치 시 생성되는 컴포넌트 역할 정리 (0) | 2026.05.16 |
| Loki write / read / backend 역할 정리 (0) | 2026.05.16 |
