내가 ArgoCD를 사용해 Kubernetes에서 GitOps를 설정한 방법: 아무도 말해주지 않는 이야기

발행: (2026년 3월 8일 PM 02:23 GMT+9)
24 분 소요
원문: Dev.to

Source: Dev.to

Kubernetes에서 GitOps를 위한 ArgoCD 설정 방법: 아무도 알려주지 않는 것

소개

ArgoCD는 Kubernetes 클러스터에 선언형 GitOps 워크플로우를 구현하기 위한 강력한 툴입니다. 이 가이드에서는 ArgoCD를 설치하고, 기본 설정을 마친 뒤, 실제 애플리케이션을 Git 리포지토리와 연결하는 전체 과정을 단계별로 살펴봅니다.
특히 초보자들이 흔히 놓치는 세부 설정과 팁을 중점적으로 다루어, 실제 운영 환경에서도 바로 적용할 수 있도록 돕습니다.

사전 요구 사항

항목설명
Kubernetes 클러스터kubectl이 정상적으로 연결된 상태
kubectl버전 1.18 이상 권장
helm (선택)Helm 차트를 이용해 ArgoCD를 설치하려는 경우
Git 리포지토리애플리케이션 매니페스트가 저장된 원격 저장소 (GitHub, GitLab 등)
도메인 (선택)ArgoCD UI에 접근하기 위한 Ingress 설정 시 필요

1️⃣ ArgoCD 설치

가장 간단한 방법은 공식 Helm 차트를 이용하는 것입니다.

helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argo-cd argo/argo-cd --namespace argocd --create-namespace

Tip: --create-namespace 플래그를 사용하면 argocd 네임스페이스가 자동으로 생성됩니다.

설치 확인

kubectl get pods -n argocd

모든 파드가 Running 상태가 되면 설치가 정상적으로 완료된 것입니다.

2️⃣ ArgoCD UI 접근

기본적으로 ArgoCD UI는 LoadBalancer 혹은 NodePort 형태로 노출됩니다. 로컬 환경에서는 포트 포워딩을 이용해 접근할 수 있습니다.

kubectl port-forward svc/argocd-server -n argocd 8080:443

브라우저에서 https://localhost:8080 으로 접속하면 로그인 화면이 나타납니다.

초기 비밀번호

초기 로그인 비밀번호는 argocd 네임스페이스에 있는 argocd-initial-admin-secret 시크릿에 저장되어 있습니다.

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo

보안 주의: 로그인 후 반드시 비밀번호를 변경하세요.

3️⃣ Git 리포지토리 연결

ArgoCD UI → SettingsRepositories 로 이동한 뒤, Connect Repo 버튼을 클릭합니다.

필드설명
Repository URLhttps://github.com/your-org/your-repo.git
TypeGit
Username / PasswordPrivate 리포지토리인 경우 인증 정보 입력
SSH Private KeySSH 키를 이용하는 경우 해당 키 입력

CLI 로도 추가 가능

argocd repo add https://github.com/your-org/your-repo.git \
  --username YOUR_USERNAME \
  --password YOUR_PASSWORD

4️⃣ 애플리케이션 생성

ArgoCD는 Application 리소스를 통해 Git 리포지토리와 Kubernetes 클러스터를 연결합니다.

UI에서 생성

  1. + NEW APP 클릭
  2. Application name 입력 (예: my-app)
  3. Project 선택 (default 권장)
  4. Sync policy: Automatic 혹은 Manual 선택
  5. Repository URL: 앞서 연결한 리포지토리 선택
  6. Path: 매니페스트가 위치한 디렉터리 지정 (예: k8s/manifests)
  7. Cluster: https://kubernetes.default.svc (현재 클러스터)
  8. Namespace: 배포할 네임스페이스 입력 (예: production)

Create 버튼을 눌러 애플리케이션을 생성하면, ArgoCD가 자동으로 매니페스트를 읽어와 Sync 상태를 표시합니다.

CLI 로 생성

argocd app create my-app \
  --repo https://github.com/your-org/your-repo.git \
  --path k8s/manifests \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace production \
  --sync-policy automated

5️⃣ Sync 정책과 자동화

ArgoCD는 자동 Sync자동 Prune 옵션을 제공해, Git에 변경이 감지될 때마다 자동으로 클러스터를 업데이트합니다.

spec:
  syncPolicy:
    automated:
      prune: true          # 불필요한 리소스 자동 삭제
      selfHeal: true      # 클러스터 상태가 drift 하면 자동 복구

핵심 포인트

  • selfHeal을 활성화하면, 수동으로 변경된 리소스가 자동으로 원래 상태로 복구됩니다.
  • prune을 사용하면, Git에서 삭제된 리소스가 클러스터에서도 자동으로 제거됩니다.

6️⃣ 롤백 및 히스토리

ArgoCD는 Git 커밋 기반으로 롤백을 지원합니다.

argocd app rollback my-app <COMMIT_HASH>

또는 UI에서 History & Rollback 탭을 열어 원하는 커밋을 선택하면 됩니다.

7️⃣ 보안 및 RBAC 설정

기본 admin 계정 외에 팀별 역할을 정의하려면 ProjectRole을 활용합니다.

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: dev-team
  namespace: argocd
spec:
  description: Development 팀 전용 프로젝트
  sourceRepos:
    - https://github.com/your-org/dev-repo.git
  destinations:
    - namespace: dev
      server: https://kubernetes.default.svc
  clusterResourceWhitelist:
    - group: '*'
      kind: '*'

위와 같이 프로젝트를 만든 뒤, argocd role create 명령으로 역할을 부여합니다.

8️⃣ 모니터링 및 알림

ArgoCD는 Prometheus 메트릭을 기본 제공하며, Alertmanager와 연동해 배포 실패 시 알림을 받을 수 있습니다.

apiVersion: v1
kind: Service
metadata:
  name: argocd-metrics
  namespace: argocd
spec:
  ports:
    - name: metrics
      port: 8082
      targetPort: 8082
  selector:
    app.kubernetes.io/name: argocd-server

Prometheus 설정 예시:

scrape_configs:
  - job_name: 'argocd'
    static_configs:
      - targets: ['argocd-server.argocd.svc:8082']

9️⃣ 정리

  • ArgoCD 설치 → Helm 또는 kubectl manifest 사용
  • UI/CLI 로 로그인 → 초기 비밀번호 변경 필수
  • Git 리포지토리 연결 → SSH 또는 HTTPS 인증 방식 선택
  • Application 생성 → 경로, 네임스페이스, Sync 정책 지정
  • 자동 Sync & Prune 로 Git과 클러스터 상태를 일치시킴
  • RBAC 로 팀별 접근 권한을 세밀하게 제어
  • PrometheusAlertmanager 로 배포 상태를 실시간 모니터링

ArgoCD를 제대로 활용하면, Git을 진실된 단일 진실 소스로 삼아 Kubernetes 환경을 안정적이고 자동화된 방식으로 운영할 수 있습니다. 이제 여러분의 클러스터에 GitOps를 적용해 보세요! 🚀

금요일 오후, 약 14개월 전…

프로덕션에 결제 서비스의 잘못된 버전을 배포했습니다. 코드 오류가 아니라 프로세스 오류였습니다. 다음 명령을 실행했습니다:

kubectl apply -f .

커밋되지 않은 로컬 변경 사항이 있는 내 노트북에서 실행했으며, 23분 동안 시스템이 500 오류를 반환했습니다. 팀의 네 명은 슬랙에서 완전히 침묵했고, 저는 정확히 무슨 일이 일어났는지 모른 채 로그를 바라보고 있었습니다.

교훈

그 주에 진짜 GitOps를 조사하기 시작했습니다. 주요 두 옵션을 검토했습니다:

도구철학장점
Flux v2“Kubernetes 네이티브”: 모든 것이 CRD와 작은 컨트롤러입니다. 조각을 조합하는 것을 좋아한다면 이상적입니다.매우 가볍고 파이프라인과 쉽게 통합됩니다.
Argo CD기본 제공 UI가 훌륭하고 Application 모델이 더 명시적이며 커뮤니티 문서가 풍부합니다.친숙한 UI, 터미널을 사용하지 않고도 가시성이 필요한 작은 팀에 탁월합니다.

제 작은 팀에게 UI가 결정적인 요인이었습니다. 필수적이라서가 아니라 터미널을 잘 다루지 못하는 사람이 배포 상태를 알아야 할 때, kubectl을 실행해 달라고 요청하는 대신 브라우저를 열 수 있기 때문입니다. 이는 큰 가치가 있습니다.

(이 글의 다른 버전에서는 Flux를 선택했습니다. 팀이 각 도구의 운영 모델에 얼마나 익숙한지에 크게 좌우됩니다.)

Argo CD 빠른 설치 (전형적인 예시)

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

네, 작동합니다. 하지만 내 설정(EKS on AWS, ALB Controller가 이미 설치된 상태)에서 사전에 알았으면 좋았을 문제들을 겪었습니다.

발견한 문제들

  1. 네트워크 제한 – egress가 제한된 클러스터에서는 argocd-server pod가 클러스터 내부에서 git clone을 할 수 없습니다. 로그는 설명이 부족합니다; 해결 방법은 security groups에 명시적인 아웃바운드 규칙을 추가하는 것이었습니다.

  2. 매니페스트 버전stable 브랜치는 항상 기대하는 버전을 가리키지는 않습니다. 저는 최신이라고 생각하고 Argo CD 2.9.3을 설치했습니다. 실행 중인 이미지가 무엇인지 항상 확인하세요:

    kubectl get pods -n argocd -o jsonpath='{range .items[*]}{.spec.containers[0].image}{"\n"}{end}'

Helm으로 설치 (프로덕션 권장)

helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

helm install argocd argo/argo-cd \
  --namespace argocd \
  --create-namespace \
  --version 6.7.3 \
  --set server.service.type=ClusterIP \
  --set configs.params."server\.insecure"=true

server.insecure=true 플래그는 ALB에 TLS 종료가 설정되어 있고 Argo CD 자체에는 TLS가 없었기 때문에 사용했습니다. 설정이 다르면 이 옵션이 필요 없을 수도 있습니다.

초기 접근

# Obtén la contraseña inicial del admin
kubectl get secret argocd-initial-admin-secret \
  -n argocd \
  -o jsonpath="{.data.password}" | base64 -d

# Port‑forward para acceder localmente
kubectl port-forward svc/argocd-server -n argocd 8080:443

재미있는 사실: 초기 비밀번호는 argocd-initial-admin-secret 시크릿에 저장되어 있으며, Argo CD는 첫 번째 비밀번호 변경 후 자동으로 삭제합니다. 생각은 좋았지만, 몇 주 뒤에 비밀번호를 찾으려 했을 때 이미 사라져서 당황했습니다.

Argo CD에서 GitOps 시작하기

아이디어: Kubernetes 매니페스트(또는 Helm 차트, Kustomize) 저장소가 있고 Argo CD가 그 저장소를 감시하여 클러스터 상태를 동기화합니다.

1. 레포지토리 등록

# SSH 사용 (내 선호)
argocd repo add git@github.com:tu-org/tu-repo-k8s.git \
  --ssh-private-key-path ~/.ssh/id_rsa

# 또는 HTTPS와 GitHub 토큰 사용
argocd repo add https://github.com/tu-org/tu-repo-k8s.git \
  --username tu-usuario \
  --password ghp_tu_token_aqui

2. 첫 번째 Application 만들기

UI에서 만들거나 YAML 매니페스트로 만들 수 있습니다 — 저는 Git에 살아 있기 때문에 YAML을 선호합니다 (진정한 GitOps).

# argocd/apps/mi-servicio.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: mi-servicio
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  source:
    repoURL: https://github.com/tu-org/tu-repo-k8s.git
    targetRevision: main
    path: manifests/mi-servicio
  destination:
    server: https://kubernetes.default.svc
    namespace: mi-servicio
  syncPolicy:
    automated:
      prune: true      # Git에 더 이상 없는 리소스를 삭제
      selfHeal: true   # 클러스터에서 수동으로 변경된 사항을 복구
    syncOptions:
      - CreateNamespace=true
  • **selfHeal: true**는 GitOps를 진정한 GitOps로 만들어 줍니다. 누군가(예: 제가 밤 11시에 “뭔가 빨리 시험해 보기 위해”) kubectl edit으로 클러스터를 직접 수정하면 Argo CD가 이를 감지하고 되돌립니다. 처음엔 귀찮지만, 나중엔 크게 감사하게 됩니다.
  • **prune: true**도 주목할 만합니다. 이 옵션을 켜면 저장소에서 매니페스트를 삭제했을 때 Argo CD가 해당 리소스를 클러스터에서도 삭제합니다. 이 옵션이 없으면 고아 리소스가 조용히 쌓이게 됩니다. 저는 직접 겪으며 배웠는데, 이전 버전의 Service가 쓸모 없이 떠다니던 적이 있었습니다.

배운 교훈 (조금 부끄러운)

Argo CD를 자동 동기화prune: true를 활성화한 상태로 설정했습니다. 몇 주 동안 완벽히 작동했습니다. 그 후 리팩터링 중에 여러 매니페스트를 디렉터리 이동했습니다(저장소 폴더 구조를 재구성).

Argo CD는 이전 경로에 있던 리소스가 Git에 더 이상 존재하지 않음을 감지했습니다. prune: true 덕분에 해당 리소스를 삭제했습니다.

팁: 디렉터리를 이동하거나 이름을 바꾸기 전에 일시 정지 모드 (sync: off)를 만들거나 Application을 새로운 경로로 업데이트하고 수동으로 sync를 수행하는 것을 고려하세요. 그렇지 않으면 마이그레이션 과정이 제대로 조율되지 않을 경우 중요한 리소스를 잃을 수 있습니다.

빠른 요약

  1. 도구를 선택하세요 팀에 가장 적합한 (Flux vs. Argo CD).
  2. Helm으로 설치하세요 더 큰 제어와 업그레이드 용이성을 위해.
  3. egress를 구성하고 네트워크 제한이 있는 환경에서 작업할 때 매니페스트 버전을 확인하세요.
  4. 리포지토리를 등록하세요 (SSH 또는 HTTPS).
  5. YAML에서 Applications을 정의하고 Git에 저장하세요.
  6. selfHealprune을 활성화하여 클러스터가 항상 원하는 상태를 반영하도록 하세요.
  7. 리포지토리 구조를 재구성할 때 주의하세요; 예상치 못한 삭제를 방지하기 위해 일시정지나 수동 동기화를 사용하세요.

이 단계들을 따르면 클러스터가 진실의 소스와 일치하게 유지되고, 실수로 인한 수동 배포로 발생하는 두려운 “500 오류”를 피할 수 있습니다. 🚀

ArgoCD를 이용한 디렉터리 마이그레이션 교훈

초기 문제

새 경로에 있는 리소스들은 아직 동기화되지 않았습니다. 4분 동안 여러 Deployment0개의 복제본 상태에 있었습니다.

  • 문제는 ArgoCD가 아니라 문서에 명시된 대로 동작했기 때문입니다.
  • 문제는 디렉터리 구조 마이그레이션 시 작업 순서를 고려하지 않았던 점에 있습니다.

해야 했던 일

  1. PR 전에 자동 sync를 비활성화합니다.
  2. 구조 재배치를 병합합니다.
  3. 수동으로 동기화하고 모든 것이 정상인지 확인합니다.
  4. 자동 sync를 다시 활성화합니다.

팁: 매니페스트 저장소에 구조적인 변화를 줄 경우, 그 PR을 데이터베이스 마이그레이션처럼 다루세요: 신중하게, 롤백 계획을 가지고, 가능하면 밤 화요일이 아닌 시간에 진행합니다.

동기화 윈도우

그때부터 syncWindows를 사용하여 ArgoCD가 프로덕션에서 자동으로 동기화할 수 있는 시간을 제한하고 있습니다.

# Configurado en el Project de ArgoCD, no en la Application
spec:
  syncWindows:
    - kind: allow
      schedule: '0 9-17 * * 1-5'   # Solo horario laboral, lunes a viernes
      duration: 8h
      applications:
        - 'produccion-*'
      namespaces:
        - produccion

이것은 모든 사람에게 해당되는 것은 아닙니다. 근무 시간 외에 자주 배포한다면 장애가 될 수 있습니다. 하지만 우리 팀에게는 새벽 3시의 sync 서프라이즈를 없애는 것이 추가 설정을 할 가치가 있었습니다.

외부 클러스터 등록

우리는 세 개의 클러스터가 있습니다: development, staging, 그리고 production.
ArgoCD는 하나인 production에서 실행되며, 접근이 매우 제한된 상태에서 세 클러스터를 관리합니다.

# Asegúrate de tener el contexto correcto en tu kubeconfig
kubectl config get-contexts

# Registra el clúster de staging
argocd cluster add arn:aws:eks:us-east-1:123456789:cluster/staging \
  --name staging

문서에서 충분히 강조되지 않는 점: ArgoCD가 원격 클러스터에 생성하는 ServiceAccount는 기본적으로 cluster‑admin 권한을 가지고 있습니다. 시작 단계에서는 괜찮지만, 프로덕션에서는 이를 조정하고 싶을 것입니다. 저는 보안 담당자가 명시적으로 물어볼 때까지 이를 하지 않았습니다 — 질문을 받기 전에 미리 알아두는 것이 좋습니다.

환경 간 시크릿 관리

아직 완전히 해결되지 않은 한 가지가 있습니다: 환경 간 시크릿 관리.

  • AWS Secrets ManagerExternal Secrets Operator를 사용합니다.
  • ArgoCD와의 통합 시 external secret이 채워지는 데 시간이 걸리면 sync states가 혼란스러워질 때가 있습니다.

정확히 버그는 아니지만, timing 문제와 ArgoCD가 리소스의 health를 평가하는 방식에 관한 것입니다. 현재 솔루션이 현재 12 서비스를 넘어선 규모에서도 잘 확장될 수 있을지 100 % 확신하지 못합니다. 이 문제에 대한 우아한 해결책을 아시는 분이 있다면 정말 알고 싶습니다.

Lecciones aprendidas (más de un año en producción)

  1. Empieza sin sync automático.

    • 두 주간 수동 동기화를 직접 해보면 어떤 튜토리얼보다 많은 것을 배울 수 있습니다: prune이 무엇을 하는지, ArgoCD가 적용하기 전에 보여주는 diff를 어떻게 읽는지, 그리고 selfHeal이 결국 어떻게 여러분을 구해줄지 이해하게 됩니다.
    • 자동 sync는 여러분의 매니페스트와 PR 검토 프로세스에 충분히 신뢰가 생긴 뒤에만 활성화하세요.
  2. Usa ApplicationSets si tienes más de tres o cuatro Applications con estructura similar.

    • 반복 작업을 줄일 수 있고, 전역 설정 변경을 훨씬 더 관리하기 쉬워집니다.
  3. Invierte tiempo en el control de acceso desde el principio — no después.

    • ArgoCD는 프로젝트 기반 RBAC와 Casbin 정책을 사용합니다: 유연하지만, 이미 열 명 정도가 시스템을 사용하고 있을 때 권한을 조정하면서 뭔가를 망가뜨리지 않으려면 나중에 되돌리기가 매우 어렵습니다.

ArgoCD vs. Flux

특징ArgoCDFlux
일상 작업을 위한 친숙한 UI
터미널에서 작업, 작은 컨트롤러
순수 선언형 접근
학습 곡선보통보통‑높음

보편적인 답은 없지만, 여러분의 특정 상황에 맞는 올바른 답은 있습니다.

우리 팀을 위한 결론

우리 팀에게 ArgoCD는 올바른 선택이었습니다.

  • 결제 서비스 사고 다음 금요일에, PR 병합에 걸린 시간과 정확히 같은 시간이 걸린 배포를 수행했습니다.
  • 아무도 로컬 명령을 실행하지 않았습니다.
  • 아무도 누군가가 올바른 브랜치를 체크아웃했는지 신뢰할 필요가 없었습니다.
  • 배포 기록은 Git에 있었으며, 작성자 이름과 커밋 메시지가 포함되었습니다.

이것이, 특정 기능보다도 GitOps가 초기 노력을 들일 가치가 있는 이유입니다.

0 조회
Back to Blog

관련 글

더 보기 »