본문 바로가기

Devops

Argocd - Application CR 이해하기

개요

2026.01.03 - [Devops] - GitOps – Argo CD 구축 가이드(Helm)

 

이번 글은 지난 글에 이어 Argo CD의 Application 커스텀 리소스(CR)를 다룹니다.

 

Application은 Git에 정의된 매니페스트를 기준으로 클러스터의 리소스 집합을 관리·동기화하는 Argo CD의 기본 단위입니다.

 

UI에서 설정하는 항목이 Application 스펙의 어떤 필드(source, destination, syncPolicy 등)로 매핑되는지 기준으로 구조를 분해하고, 동일 구성을 YAML로 재현하는 방법까지 정리합니다.

 

이를 통해 앞으로 설명드릴 App of Apps, ApplicationSet 등을 이해하는데 도움이 될 수 있는 글이 될 수 있으면 좋겠습니다.

Application이란 무엇일까?

하단의 사진은 ArgoCD의 동작원리를 보여주는 사진 중 캡처해 온 것이며 여기서 빨간 박스에 위치한 Application은 실제 배포를 담당하는 부분을 보여준다고 할 수 있겠습니다.

 

Application은 “Git(또는 Helm/Kustomize 등으로 생성되는 매니페스트)이 표현하는 리소스 집합을, 특정 클러스터/네임스페이스에 배포하고 상태를 추적·동기화하기 위한 Argo CD의 Custom Resource(CR)”입니다.

 

Application은 한 번 생성하면 알아서 배포되는 무언가라기보다, Argo CD가 계속 배포하고 조정하게 할 배포 단위를 선언하는 오브젝트입니다. 즉, Application이 가리키는 정보가 곧 “무엇을/어디에/어떻게” 배포할지를 고정합니다.

 

Application이 고정하는 최소 범위는 아래 3~4가지 축으로 정리할 수 있습니다. (UI에서 입력하는 값들도 결국 이 필드들로 매핑됩니다)

  • Source(무엇을 배포할지): repoURL / targetRevision / path(또는 Helm chart 등)
  • Destination(어디에 배포할지): server(클러스터) / namespace
  • Project(어떤 정책 경계 안에서 배포할지): AppProject 기반의 허용 리포/클러스터/네임스페이스 범위
  • SyncPolicy(선택, 어떻게 동기화할지): 자동 동기화 여부, prune/selfHeal, syncOptions 등
정리하면, **Application = (Source + Destination + Policy)로 정의된 “배포 단위”**이고, Argo CD는 그 단위를 기준으로 Target↔Live를 비교해 Sync를 계산하고, 관리 리소스의 상태를 평가해 Health를 계산합니다.

Application을 이루는 각 요소를 자세히 들여다보자

GUI를 통해 볼 수 있듯이 ArgoCD가 배포하기 위해 생성해야 할 Application은 New APP을 통해 만들 수 있고 yaml 형식으로 보게 된다면 두 번째 사진과 같은 구조를 가진 파일을 작성하는 것이 됩니다.

 

UI에서 만드는 위와 같은 Application과 코드로 만든 Application은 둘다 같으므로 지금부턴 각 구성요소에 대해 알아보겠습니다.

 

Source

 

Source는 다시 3가지 섹션으로 나뉘며 어떤 경로의 파일, 어떤 기준으로 메니패스트(Target)를 만들 것인가를 고정하는 영역입니다.

 

3가지 섹션은 repoURL, targetRevision, Path(또는 Helm Chart)등이 들어가며, 템플릿 엔진별 매니페스트 생성 방식별 설정도 spec.source 하위에 포함된다고 할 수 있습니다

  • 추가적으로 kustomize, helm등 Application에서 직접 명시하여 템플릿 엔진으로 파일을 랜더링 하는 경우 매니페스트 생성 과정에서 필요한 옵션을 source하위에 명시하여 ArgoCD가 템플릿 엔진을 통해 파일을 생성할 때 파라미터를 전달해 ArgoCD가 사용하도록 전달할 수 있습니다.
  1. repoURL + targetRevision + path가 합쳐져서 “어느 저장소의 어느 리비전에서 어떤 디렉토리를 읽을지”가 결정됩니다.
  2. Helm을 쓰는 경우 Argo CD는 Helm chart를 “설치 도구”로 쓰지 않고, helm template매니페스트를 생성하는 단계에만 사용합니다
source:
  repoURL: 'ssh://git@github.com:argoproj/argo-cd.git'
  path: applicationset
  targetRevision: HEAD

 

위 파일을 해석하자면 github.com:argoproj/argo-cd.git에 접근하여 HEAD 즉 main(master) branch에서 가장 최근에 커밋한 브랜치를 가리켜 applicationset이라는 상대경로로 접근하여 그 하위의 파일들을 배포 대상으로 삼아라라고 이해할 수 있겠습니다.

 

Destination

Destination은 만들어진 페니패스트 파일들을 어디(클러스터/네임스페이스)에 적용할 것인가를 고정합니다.

 

Destination 섹션 또한 server, name, namespace 3개의 섹션으로 나뉘어 있으며 server는 생략할 수 있습니다.

  1. server는 대상 클러스터의 Kubernetes API Server URL
  2. name은 Argo CD에 등록된 클러스터 엔트리의 이름(등록 정보에 따라 내부적으로 server로 해석되어 동작).
  3. namespace는 k8s 리소스를 배포할 네임스페이스를 지정하는 데 사용됩니다.
    • namespace를 명시했다고 하더라도 메니페스트 파일의 metadata.namespace를 덮어씌우는 부분이 아니며 각 리소스 파일의 namespace가 명시되어 있지 않은 경우에만 파일을 적용할 때 namespace가 사용됩니다.
  4. Destination은 Project(AppProject)가 허용한 목적지(destinations)와 반드시 일치해야만 배포가 가능합니다.

Destination은 주의할 점이 하나 있는데 server, name 필드를 모두 채우는 것 이 아니라 한 필드만 채워야 하며 둘 다 지정하면 validation error가 발생되는 점을 유의해야 합니다.

 

Destination의 Server에 명시되는 URL은 사진과 같은 클러스터의 주소가 되며 name에 명시하는 건 별칭으로 들어가 ArgoCD에 저장된 Clusters 정보 중 매칭되는 것 에서 server를 추출해 연결을 시도한다라고 이해해 주시면 될 것 같습니다.

 

ArgoCD를 배포하게 되면 배포된 클러스터는 자동적으로 Clusters에 등록되고 멀티 클러스터를 배포하려면 타 클러스터는 등록하고 사진과 같이 Successful이라고 접속 상태가 나와야 ArgoCD에서 대상지로 배포할 수 있게 됩니다.

 

Project

 

Project는 타 섹션과 다르게 참조로 진행되며 AppProject는 ArgoCD가 관리하는 타 CR이므로 여기선 자세하게 다루지 않고 개념과 간략하게 알아야 할 부분에 대해 설명드리겠습니다.

 

  • Project는 Application이 속하는 정책 경계이며 Application spec의 spec.project로 프로젝트 이름이 들어가 참조하게 되는 구조이며실제 구체적인 명세는 AppProject 리소스의 Spec에 정의되게 됩니다.
  • 모든 Application은 1개의 Project에만 속하며 project를 생략하면 default Project로 간주됩니다.
  • Project는 sourceRepos/ destinations/ 배포 가능한 리소스 종류 (whitelist, blacklist) , RBAC로 Application의 허용 범위를 정의합니다.

Sync/Health

 

Argo CD는 Application 단위로 Target State(Git에 정의된 원하는 상태)Live State(클러스터에 실제 존재하는 상태)를 지속적으로 비교합니다. 이 비교 결과가 Sync/Health로 요약되어 UI에 표시됩니다.

 

  • Sync Status는 Live State가 Target State와 일치하는지(차이가 있는지)를 나타내는 “diff 요약”입니다.
    • Sync Status는 리소스 배포 성공/실패 유무를 나타내는 것이 아니라 git의 원하는 상태를 클러스터에 배포했는지 여부에 대한 신호이므로 Sync Status가 잘 됐다고 배포가 잘 됐다를 확정 지을 순 없습니다.
  • Healthy Status는 Application이 관리하는 리소스들의 상태 체크(ready/rollout/오류 등)을 종합한 값입니다.
  • 몇 가지 상태값의 조합에 대한 설명만 간략하게 추가하여 설명드리겠습니다.
    • Sync는 Synced , Health는 Progressing
      • Git과 클러스터는 일치하지만, 배포/롤링업데이트/준비 상태가 진행 중인 상황
    • Sync는 OutOfSync , Health는 Healthy
      • 리소스는 정상 동작 중이지만, Git과 클러스터에 차이가 존재 

Sync Policy(Manual vs Automated)

Sync Policy도 ArgoCD를 배포하게 된다면 수동 배포, 자동 배포를 관여하는 부분이기 때문에 설명드리겠습니다.

 

syncPolicy:
  automated:
    prune: true
    selfHeal: true
  syncOptions:
    - CreateNamespace=true
    - ServerSideApply=true
    - ApplyOutOfSyncOnly=true

 

Manual Sync

  • 의미: Sync 작업(클러스터에 Target State를 적용하는 오퍼레이션)을 사용자가 명시적으로 트리거하는 방식입니다. UI에서 Sync  Synchronize를 눌러 실행합니다.

Automated Sync

  • 의미: Argo CD가 Git의 desired manifests와 클러스터 live state의 차이를 감지했을 때 자동으로 sync를 수행하는 방식입니다.
  • Automated Sync 하위 옵션(“자동 배포”를 어디까지 자동화할지)
    • spec.syncPolicy.automated.enabled자동 sync 자체를 on/off할 수 있습니다. falseprune/selfHeal/allowEmpty를 값으로 갖고 있어도 controller가 자동 sync를 스킵합니다.
    • prune: true를 켜면 자동 sync에 리소스 삭제(pruning)가 포함되며 기본적으로는 git과 차이나는 리소스를 삭제하지 않습니다.
    • selfHeal: true를 켜면 live state가 Git 정의와 달라질 때 자동으로 sync(복구)합니다.
    • allowEmpty라는 속성도 있으며 타깃 리소스가 0개가 되는 상황을 허용할 것인지 아닌지에 대한 옵션입니다.
  • 대부분의 Sync Option은 Application.spec.syncPolicy.syncOptions에 설정합니다.
  • https://argo-cd.readthedocs.io/en/latest/user-guide/sync-options/ 에서 파라미터들을 확인할 수 있습니다.
위 파일에서 적혀있는 옵션은 차례대로 앱 배포 시 네임스페이스 생성, ServerSide로 리소스 생성, 앱 diff시 변경된 파일에 대해서만 배포를 진행하도록 하는 성능상의 옵션 같은 것 들입니다.

Application으로 앱을 배포할 때 알아두어야 할 사항

  1. source의 git 레포 등이 private이라면 repository 정보에서 연결 정보를 정의하여 Cluster 정보와 마찬가지로 연결이 Success가 나오는지 확인이 되어야만 ArgoCD가 파일에 접근할 수 있습니다.
  2. 하단의 ROLLBACK 기능으로 앱을 이전 버전으로 배포하도록 설정한다면 auto sync가 걸려있던 부분이 풀려 manual로 바뀌게 되니 사용할땐 유의해야 합니다.
    • ApplicationSet으로 sync를 명시한 경우엔 롤백을 하더라도 git의 버전으로 다시 돌아오며 sync 또한 명세에 맞춰져 사용하기 어려운 점은 유의해야 합니다.
    • ROLLBACK으로 앱을 롤백하는 기능은 git을 커밋하지 않고 앱 배포만 바꾸는 버전이기 때문에 그렇습니다.

부록

멀티 클러스터 뿐만 아니라 repository 등의 연결 정보는 모두 코드화하여 ArgoCD를 Helm으로 설치하는 경우 values.yml로 전달하여
설정하도록 코드화 할 수 있습니다.

  • 이후 추가적으로 설정이 추가된다고 하더라도 values.yml을 추가하여 helm을 재 배포하면 다시 설정되므로 운영 중 추가하는 부분에 대해서는 리스크를 고려하지 않아도 됩니다.

ArgoCD가 In-Cluster로 배포된 클러스터와 통신하여 앱을 배포하는 경우엔 ArgoCD가 배포될 때 등록된 In-Cluster의 인증서를 사용하여 클러스터의 URL로 통신하게 되는데 인증서의 만료기한이 1년이기 때문에 유의해야 합니다.

  • 만료가 된다면 ArgoCD에선 모든 배포가 제대로 이뤄지는지 모니터링할 수 없으며 Clusters에도 연결이 성공하지 못하고 모든 앱 배포도 장애가 발생하게 되니 인증서의 만료기한 전 교체를 하거나 자동화하도록 두는 것이 필요합니다.

Application의 앱 배포는 아래와 같이 Sync Status, Health Status로 나뉠 수 있고 각 상태값에 대한 설명은 링크로 첨부해 두겠습니다.

 

ArgoCD의 Application은 UI와 Application.yml이라는 형태로 생성할 수 있고 UI에선 NEW APP을 통해 Cli로는 kubectl -f application.yml과 같은 형태로 배포하게 되면 ArgoCD에서 앱이 생성되어 확인이 가능합니다.

정리/회고

지금까지 ArgoCD에서 앱을 배포하기 위해 가장 작지만 중요한 단위인 Application과 각 구성요소에 대해 알아보았습니다.

 

ArgoCD를 UI와 코드와 함께 가장 중요한 개념들과 부분, 동작 원리 중 Application이 차지하는 역할에 대해 소개드렸으며 단순 배포를 넘어서서 배포할 때의 각 요소가 유기적으로 어떻게 기능하게 되는지를 설명드리려고 했던 것 같습니다.

 

부록에서 보셨던 것과 같이 Application은 UI로 생성할 수 도 있고 코드로 생성할 수 있는데 당연히 UI는 의도가 남지 않고 히스토리를 알 수 없어 유지보수가 어렵기 때문에 지양해야 하며 코드로 생성해야 합니다.

 

Application이 한개 두 개 일 땐 UI와 yaml형식의 파일로 배포하는 것이 둘 다 어려운 일은 아니지만 수십 개의 파일을 배포하고 관리하는 상황에서 배포하는 환경 즉 클러스터가 늘어나게 된다면 이는 많은 수고로움과 피로, 배포 중 오류를 낳게 되는 일일 수 있습니다.

 

또한 Application은 ArgoCD가 Git으로 관리할 수 없는 파일이기 때문에 코드로 한다고 하더라도 수동 작업이 필수적이며 코드화가 되어있다고 해도 배포작업이 필요한 상황에서 yaml 같은 코드가 정말 배포된 앱과 동일한 형상인가를 보장할 수 없게 됩니다.

 

이러한 것들을 방지하고자 나온 것이 App-of-Apps 패턴과 ApplicationSet이며 추후 다른 글들로 어떻게 앱을 GitOps스럽게 관리할 수 있는지 설명드려보겠습니다.

Reference

https://www.digitalocean.com/community/developer-center/implementing-gitops-using-argo-cd?utm_source=chatgpt.com