중소기업 쿠버네티스 구축 – 07. GitOps 배포 자동화: ArgoCD 도입과 판단 (ArgoCD·Gitea·app-of-apps)

2026.07.27

·

guniq 인사이트 썸네일 — 중소기업 쿠버네티스 구축 – 07. GitOps 배포 자동화: ArgoCD 도입과 판단 (ArgoCD·Gitea·app-of-apps)

시리즈 안내
이 글은 “중소기업 쿠버네티스 구축” 시리즈의 7편입니다. 6편에서 대시보드로 클러스터에 눈을 달았습니다. 이번 편에서는 배포를 자동화하는 ArgoCD를 설치합니다. 다만 그 전에 시리즈를 통틀어 가장 중요한 질문에 먼저 답합니다 — “ArgoCD가 정말 필요한가? 배포 전략에 따라 어떻게 달라지는가?”


들어가며

지금까지 우리는 무언가를 배포할 때 kubectl apply를 직접 쳤습니다. 대시보드도, Ingress도 그렇게 올렸죠. 이 방식도 잘 동작합니다. 그런데 서비스가 늘고 변경이 잦아지면 의문이 생깁니다.

  • 지금 클러스터에 떠 있는 게 정확히 어떤 설정인지, 누가 언제 바꿨는지 추적할 수 있나?
  • 누군가 실수로 kubectl edit으로 운영 설정을 바꿔도 아무도 모르는 거 아닌가?
  • 새 멤버가 “어떻게 배포해요?”라고 물으면 답이 명확한가?

GitOpsArgoCD가 이 질문들에 답하는 방식입니다. 하지만 모든 팀에 필요한 건 아닙니다. 그래서 설치 명령을 치기 전에, 도입 판단부터 정직하게 따져봅니다.


1. GitOps란 무엇인가

GitOps는 “클러스터의 원하는 상태를 Git에 선언해두고, 그 Git을 단일 진실 공급원(Single Source of Truth)으로 삼는” 운영 방식입니다.

핵심 차이는 방향입니다.

  • 전통 방식 (Push): 사람이나 CI가 클러스터에 직접 kubectl apply로 밀어넣습니다. 클러스터 상태와 Git이 어긋나도 알기 어렵습니다.
  • GitOps 방식 (Pull): Git에 원하는 상태를 적어두면, 클러스터 안의 에이전트(ArgoCD)가 Git을 계속 지켜보다가 클러스터를 그 상태에 맞춥니다. Git이 곧 운영 상태입니다.

GitOps가 주는 것:

  • 이력 추적: 모든 인프라 변경이 Git 커밋으로 남습니다. “언제 누가 왜 바꿨나”가 코드 리뷰처럼 보입니다.
  • 자동 동기화: Git을 바꾸면 클러스터가 따라옵니다. 배포 = git push.
  • 드리프트 교정: 누가 클러스터를 손으로 바꿔도, ArgoCD가 Git 상태로 되돌립니다(self-heal).
  • 롤백: 잘못 배포했으면 Git을 이전 커밋으로 되돌리면 끝.

2. ArgoCD는 꼭 필요한가? — 정직한 판단

이 시리즈를 시작할 때부터 받은 질문입니다. 결론부터 말하면 “필수는 아니다. 배포 전략에 따라 다르다.”입니다.

ArgoCD 없이도 잘 되는 경우

  • 서비스가 적고 배포가 가끔이다. 앱 한두 개를 어쩌다 한 번 배포하는 정도라면, kubectl apply나 Helm으로 직접 배포하는 게 더 단순합니다. ArgoCD를 깔고 GitOps 레포 구조를 잡는 비용이 얻는 것보다 큽니다.
  • CI 파이프라인에서 직접 배포한다. Jenkins·GitHub Actions 같은 CI가 빌드 후 kubectl apply까지 해버리는 Push 방식도 완전히 유효합니다. 많은 팀이 이렇게 잘 운영합니다.
  • GitOps 개념을 운영할 인력이 없다. ArgoCD도 결국 하나의 시스템입니다. 이걸 이해하고 관리할 사람이 없으면 또 다른 장애 포인트가 됩니다.

ArgoCD가 빛나는 경우

  • 여러 서비스를, 자주 배포한다. 마이크로서비스가 여럿이고 배포가 잦을수록 Git 기반 자동화의 가치가 커집니다.
  • 여러 환경/클러스터를 일관되게 관리한다. dev·prd를 같은 매니페스트 구조로 운영하고 싶을 때.
  • 드리프트 교정과 배포 이력이 중요하다. 손으로 바꾼 변경이 자동으로 되돌려지고, 모든 배포가 Git에 남는 게 운영 안정성에 직결될 때.
  • 배포를 UI로 가시화하고 싶다. 누가 무엇을 배포했고 현재 동기화 상태가 어떤지를 한눈에 보고 싶을 때.

대안도 있다

GitOps를 원하더라도 ArgoCD가 유일한 답은 아닙니다. FluxCD도 널리 쓰이는 GitOps 도구입니다. ArgoCD는 강력한 UI가 강점이고, Flux는 더 가볍고 쿠버네티스 네이티브한 느낌이 강합니다.

우리의 선택

우리는 여러 마이크로서비스(프론트·API·인증·결제 등)를 운영하고, dev/prd 두 환경을 다루며, 배포 이력과 자동 교정이 필요한 상황입니다. 이 조건이면 ArgoCD의 이점이 비용을 넘어섭니다. 그래서 도입합니다. UI로 배포 상태를 보며 운영하고 싶은 점도 컸습니다.

정리: ArgoCD는 “쿠버네티스니까 당연히 깐다”가 아니라, 배포 빈도·서비스 수·환경 수·운영 인력을 따져 선택하는 도구입니다. 이 글을 읽는 분이 앱 하나를 가끔 배포하는 상황이라면, 이번 편은 “지금은 건너뛰어도 된다”는 답이 정답일 수 있습니다.


3. ArgoCD 설치 (Helm)

도입을 결정했으니 설치합니다. 플랫폼 노드에 배치하고, 우리 TLS 전략(5편)에 맞춰 평문 수신으로 설정합니다.

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

helm install argocd argo/argo-cd 
  --namespace argocd --create-namespace 
  --set server.insecure=true 
  --set global.nodeSelector.role=platform

옵션 설명:

  • server.insecure=true: ArgoCD 서버가 평문 HTTP로 수신하도록. 5편에서 정한 “TLS는 Caddy에서만 종단, 내부는 평문” 원칙과 일치합니다. 이걸 안 하면 ArgoCD가 자체 TLS를 또 시도해 Caddy와 포트·프로토콜이 충돌합니다.
  • global.nodeSelector.role=platform: 플랫폼 노드 배치.

설치 확인

kubectl get pods -n argocd

argocd-server, argocd-repo-server, argocd-application-controller, argocd-redis 등이 모두 Running이 되면 준비 완료입니다.


4. Ingress로 외부 노출

5편 경로에 ArgoCD를 연결합니다.

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-ingress
  namespace: argocd
spec:
  ingressClassName: nginx
  rules:
    - host: argocd.prd.dztechwill.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: argocd-server
                port:
                  number: 80
EOF

초기 비밀번호 확인

ArgoCD는 설치 시 admin 계정의 초기 비밀번호를 시크릿에 저장합니다.

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

출력된 비밀번호로 https://argocd.prd.dztechwill.comadmin으로 로그인합니다. 로그인 후 반드시 비밀번호를 변경하세요(User Info 메뉴).

외부에서 ArgoCD UI에 한 번에 접속됐다면, 이 역시 5편 경로가 정상이라는 또 하나의 증거입니다.


5. Git 저장소 연결 (Gitea)

ArgoCD가 지켜볼 Git 저장소를 연결합니다. 우리는 자체 호스팅 Git 서비스인 Gitea를 씁니다(별도 VM에서 운영, 컨테이너 이미지 레지스트리 겸용).

ArgoCD UI의 Settings → Repositories에서 Gitea 저장소 URL과 자격 증명을 등록합니다. 또는 CLI로:

argocd repo add https://git.dev.dztechwill.com/myorg/gitops.git 
  --username <user> --password <token>

운영(prd)용으로는 dev와 분리된 별도 토큰을 발급해 쓰는 게 안전합니다. 환경별로 자격 증명을 나눠두면 한쪽이 유출돼도 영향 범위가 제한됩니다.


6. app-of-apps 패턴

ArgoCD를 제대로 쓰려면 app-of-apps 패턴을 알아두면 좋습니다.

개별 서비스마다 ArgoCD Application을 하나씩 손으로 등록하는 대신, “여러 Application을 묶어 관리하는 최상위 Application 하나”를 둡니다. 이 최상위 앱이 Git의 특정 디렉토리를 보고, 그 안의 모든 하위 Application을 자동으로 만들어줍니다.

gitops-repo/
├── apps/                    ← 최상위 app-of-apps가 보는 곳
│   ├── headlamp.yaml         (Application 정의)
│   ├── minio.yaml            (Application 정의)
│   └── workloads.yaml        (Application 정의)
└── manifests/               ← 실제 매니페스트
    ├── headlamp/
    ├── minio/
    └── workloads/

새 서비스를 추가하려면 apps/에 Application 정의를 하나 커밋하면 됩니다. ArgoCD가 알아서 감지해 배포합니다. 클러스터 전체 구성이 Git 하나로 선언되니, “이 클러스터에 뭐가 떠 있나”의 답이 곧 이 레포입니다.


7. 동기화 정책: prune과 self-heal

ArgoCD Application에는 두 가지 중요한 자동화 옵션이 있습니다.

  • prune: Git에서 삭제한 리소스를 클러스터에서도 자동 삭제. Git이 진실이므로, Git에 없으면 클러스터에도 없어야 한다는 원칙.
  • selfHeal: 누가 클러스터를 손으로 바꿔도 Git 상태로 자동 복구. 드리프트 교정.
syncPolicy:
  automated:
    prune: true
    selfHeal: true

이 둘을 켜면 “Git = 클러스터”가 강하게 유지됩니다. 다만 주의할 점이 있는데, 다음 절의 트러블슈팅에서 다룹니다.


8. 트러블슈팅: prune이 건드리면 안 되는 것

self-heal과 prune은 강력하지만, ArgoCD가 관리하지 않아야 할 리소스까지 건드리면 문제가 됩니다.

실제 사례: 외부 시스템(클러스터 밖 API)을 쿠버네티스 서비스처럼 쓰려고 수동으로 만든 Endpoints가 있었는데, ArgoCD가 이걸 “Git에 없는 리소스”로 보고 prune하려는 상황이 생겼습니다. (이 패턴은 9편에서 자세히 다룹니다.)

해결: ArgoCD 설정에서 특정 리소스 종류를 동기화 대상에서 제외(exclusion)하거나, 해당 리소스에 “이건 건드리지 마”라는 annotation을 붙였습니다.

metadata:
  annotations:
    argocd.argoproj.io/sync-options: Prune=false
    argocd.argoproj.io/compare-options: IgnoreExtraneous

교훈: 자동화는 경계를 분명히 해야 안전합니다. “Git이 진실”이라는 원칙은 강력하지만, Git 바깥에서 수동 관리해야 하는 리소스(외부 연동용 Endpoints 등)는 명시적으로 자동화에서 빼줘야 사고가 안 납니다.


마치며

7편에서는 배포 자동화의 토대를 놓으며, 그 전에 도입 자체를 정직하게 판단했습니다.

  • GitOps: Git을 단일 진실 공급원으로 삼아, 클러스터가 Git을 따라오게 하는 Pull 방식.
  • 도입 판단: ArgoCD는 필수가 아니라 선택. 서비스가 많고 배포가 잦고 환경이 여럿이면 가치가 크지만, 앱 하나를 가끔 배포한다면 과할 수 있습니다. FluxCD나 CI 직접 배포도 유효한 대안입니다.
  • 설치와 연결: 평문 수신(Caddy 종단 원칙)으로 설치, Gitea 연결, app-of-apps 패턴, prune·self-heal 동기화.
  • 트러블슈팅: 자동화가 건드리면 안 될 리소스는 명시적으로 제외 — 자동화의 경계를 분명히.

이제 배포가 git push로 흐를 수 있습니다. 다음 편에서는 이 흐름에 얹을 실제 인프라 — 오브젝트 스토리지(MinIO)를 NFS 기반으로 구축합니다. 08편 — MinIO와 TrueNAS NFS로 이어집니다.


이전 글: 중소기업 쿠버네티스 구축 – 06. 웹 대시보드: 클러스터 시각화
다음 글: 중소기업 쿠버네티스 구축 – 08. 오브젝트 스토리지: S3 호환 구축 (MinIO·TrueNAS NFS·PV/PVC)


MORE POSTS

다른 글 보기

guniq 인사이트 썸네일 — 중소기업 쿠버네티스 구축 – 07. GitOps 배포 자동화: ArgoCD 도입과 판단 (ArgoCD·Gitea·app-of-apps)
테크 랩

중소기업 쿠버네티스 구축 – 07. GitOps 배포 자동화: ArgoCD 도입과 판단 (ArgoCD·Gitea·app-of-apps)

2026.07.27
Photo by Unsplash (unsplash.com) — Free to use
뉴스

API를 바꾸는 AI와 ‘의도 이해’ 기반 웹 — SOA 2.0의 부상

2026.07.24
guniq 인사이트 썸네일 — IT 프로젝트 관리 도구 완전 해부 – 20. PSTA의 장단점과 한계 — 그리고 시리즈를 마치며
프로젝트 관리

IT 프로젝트 관리 도구 완전 해부 – 20. PSTA의 장단점과 한계 — 그리고 시리즈를 마치며

2026.07.23

프로젝트 문의 환영합니다

기획부터 개발, 운영까지 함께 만들어 드립니다.