내가 ArgoCD를 사용해 Kubernetes에서 GitOps를 설정한 방법: 아무도 말해주지 않는 이야기
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 → Settings → Repositories 로 이동한 뒤, Connect Repo 버튼을 클릭합니다.
| 필드 | 설명 |
|---|---|
| Repository URL | https://github.com/your-org/your-repo.git |
| Type | Git |
| Username / Password | Private 리포지토리인 경우 인증 정보 입력 |
| SSH Private Key | SSH 키를 이용하는 경우 해당 키 입력 |
CLI 로도 추가 가능
argocd repo add https://github.com/your-org/your-repo.git \
--username YOUR_USERNAME \
--password YOUR_PASSWORD
4️⃣ 애플리케이션 생성
ArgoCD는 Application 리소스를 통해 Git 리포지토리와 Kubernetes 클러스터를 연결합니다.
UI에서 생성
- + NEW APP 클릭
- Application name 입력 (예:
my-app) - Project 선택 (
default권장) - Sync policy:
Automatic혹은Manual선택 - Repository URL: 앞서 연결한 리포지토리 선택
- Path: 매니페스트가 위치한 디렉터리 지정 (예:
k8s/manifests) - Cluster:
https://kubernetes.default.svc(현재 클러스터) - 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 계정 외에 팀별 역할을 정의하려면 Project와 Role을 활용합니다.
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 또는
kubectlmanifest 사용 - UI/CLI 로 로그인 → 초기 비밀번호 변경 필수
- Git 리포지토리 연결 → SSH 또는 HTTPS 인증 방식 선택
- Application 생성 → 경로, 네임스페이스, Sync 정책 지정
- 자동 Sync & Prune 로 Git과 클러스터 상태를 일치시킴
- RBAC 로 팀별 접근 권한을 세밀하게 제어
- Prometheus 와 Alertmanager 로 배포 상태를 실시간 모니터링
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가 이미 설치된 상태)에서 사전에 알았으면 좋았을 문제들을 겪었습니다.
발견한 문제들
-
네트워크 제한 – egress가 제한된 클러스터에서는
argocd-serverpod가 클러스터 내부에서git clone을 할 수 없습니다. 로그는 설명이 부족합니다; 해결 방법은 security groups에 명시적인 아웃바운드 규칙을 추가하는 것이었습니다. -
매니페스트 버전 –
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를 수행하는 것을 고려하세요. 그렇지 않으면 마이그레이션 과정이 제대로 조율되지 않을 경우 중요한 리소스를 잃을 수 있습니다.
빠른 요약
- 도구를 선택하세요 팀에 가장 적합한 (Flux vs. Argo CD).
- Helm으로 설치하세요 더 큰 제어와 업그레이드 용이성을 위해.
- egress를 구성하고 네트워크 제한이 있는 환경에서 작업할 때 매니페스트 버전을 확인하세요.
- 리포지토리를 등록하세요 (SSH 또는 HTTPS).
- YAML에서
Applications을 정의하고 Git에 저장하세요. selfHeal와prune을 활성화하여 클러스터가 항상 원하는 상태를 반영하도록 하세요.- 리포지토리 구조를 재구성할 때 주의하세요; 예상치 못한 삭제를 방지하기 위해 일시정지나 수동 동기화를 사용하세요.
이 단계들을 따르면 클러스터가 진실의 소스와 일치하게 유지되고, 실수로 인한 수동 배포로 발생하는 두려운 “500 오류”를 피할 수 있습니다. 🚀
ArgoCD를 이용한 디렉터리 마이그레이션 교훈
초기 문제
새 경로에 있는 리소스들은 아직 동기화되지 않았습니다. 4분 동안 여러 Deployment가 0개의 복제본 상태에 있었습니다.
- 문제는 ArgoCD가 아니라 문서에 명시된 대로 동작했기 때문입니다.
- 문제는 디렉터리 구조 마이그레이션 시 작업 순서를 고려하지 않았던 점에 있습니다.
해야 했던 일
- PR 전에 자동 sync를 비활성화합니다.
- 구조 재배치를 병합합니다.
- 수동으로 동기화하고 모든 것이 정상인지 확인합니다.
- 자동 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 Manager와 External Secrets Operator를 사용합니다.
- ArgoCD와의 통합 시 external secret이 채워지는 데 시간이 걸리면 sync states가 혼란스러워질 때가 있습니다.
정확히 버그는 아니지만, timing 문제와 ArgoCD가 리소스의 health를 평가하는 방식에 관한 것입니다. 현재 솔루션이 현재 12 서비스를 넘어선 규모에서도 잘 확장될 수 있을지 100 % 확신하지 못합니다. 이 문제에 대한 우아한 해결책을 아시는 분이 있다면 정말 알고 싶습니다.
Lecciones aprendidas (más de un año en producción)
-
Empieza sin sync automático.
- 두 주간 수동 동기화를 직접 해보면 어떤 튜토리얼보다 많은 것을 배울 수 있습니다:
prune이 무엇을 하는지, ArgoCD가 적용하기 전에 보여주는 diff를 어떻게 읽는지, 그리고selfHeal이 결국 어떻게 여러분을 구해줄지 이해하게 됩니다. - 자동 sync는 여러분의 매니페스트와 PR 검토 프로세스에 충분히 신뢰가 생긴 뒤에만 활성화하세요.
- 두 주간 수동 동기화를 직접 해보면 어떤 튜토리얼보다 많은 것을 배울 수 있습니다:
-
Usa ApplicationSets si tienes más de tres o cuatro Applications con estructura similar.
- 반복 작업을 줄일 수 있고, 전역 설정 변경을 훨씬 더 관리하기 쉬워집니다.
-
Invierte tiempo en el control de acceso desde el principio — no después.
- ArgoCD는 프로젝트 기반 RBAC와 Casbin 정책을 사용합니다: 유연하지만, 이미 열 명 정도가 시스템을 사용하고 있을 때 권한을 조정하면서 뭔가를 망가뜨리지 않으려면 나중에 되돌리기가 매우 어렵습니다.
ArgoCD vs. Flux
| 특징 | ArgoCD | Flux |
|---|---|---|
| 일상 작업을 위한 친숙한 UI | ✅ | ❌ |
| 터미널에서 작업, 작은 컨트롤러 | ❌ | ✅ |
| 순수 선언형 접근 | ✅ | ✅ |
| 학습 곡선 | 보통 | 보통‑높음 |
보편적인 답은 없지만, 여러분의 특정 상황에 맞는 올바른 답은 있습니다.
우리 팀을 위한 결론
우리 팀에게 ArgoCD는 올바른 선택이었습니다.
- 결제 서비스 사고 다음 금요일에, PR 병합에 걸린 시간과 정확히 같은 시간이 걸린 배포를 수행했습니다.
- 아무도 로컬 명령을 실행하지 않았습니다.
- 아무도 누군가가 올바른 브랜치를 체크아웃했는지 신뢰할 필요가 없었습니다.
- 배포 기록은 Git에 있었으며, 작성자 이름과 커밋 메시지가 포함되었습니다.
이것이, 특정 기능보다도 GitOps가 초기 노력을 들일 가치가 있는 이유입니다.