본문 바로가기
IT/k8s

[k8s] ArgoCD 프로덕션 환경 GitOps 베스트 프랙티스: 안정적인 배포와 보안 강화

by 수누다 2026. 4. 30.

ArgoCD 프로덕션 환경 GitOps 베스트 프랙티스: 안정적인 배포와 보안 강화

안녕하세요, 13년차 인프라 엔지니어입니다. 오늘은 쿠버네티스(Kubernetes) 배포의 핵심 툴 중 하나인 ArgoCDGitOps에 대해 이야기해보려고 해요. 사실 제가 처음 인프라 엔지니어를 시작했을 때는 배포라고 하면 SSH로 서버에 접속해서 스크립트 돌리고, 수동으로 설정을 변경하고, 문제가 터지면 눈으로 찾아 헤매는 게 일상이었거든요. 그러다 쿠버네티스 세상이 열리고 CI/CD 파이프라인이 중요해지면서, 더 안정적이고 효율적인 배포 방식에 대한 갈증이 커졌습니다.

수많은 삽질 끝에 제가 정착한 방법이 바로 GitOps였습니다. 그리고 그 중심에는 ArgoCD가 있었죠. 처음엔 이게 뭔가 싶었는데, 막상 써보니까 '아, 이거 진짜 편하고 안전하네!' 싶더라고요. 프로덕션 환경에서 ArgoCD를 안정적으로 운영하고 GitOps 보안을 강화하기 위한 저만의 경험과 베스트 프랙티스를 공유해볼까 합니다. 혹시 쿠버네티스 배포 때문에 밤잠 설치고 계신 분들이 있다면, 이 글이 조금이나마 도움이 되었으면 좋겠네요. 💡

ArgoCD와 GitOps의 전체 아키텍처는 위 그림처럼 구성됩니다. Git을 중심으로 모든 것이 돌아가는 모습을 보실 수 있어요.

왜 ArgoCD와 GitOps인가요? – 삽질 끝에 찾은 안정성

저도 처음에는 Jenkins 같은 전통적인 CI/CD 툴로 쿠버네티스 배포를 시도했어요. 하지만 배포 스크립트 관리도 어렵고, 배포 이력 추적도 쉽지 않더라고요. 특히 긴급 롤백(Rollback) 상황에서는 정말 아찔한 경험도 많았습니다. 😱

GitOps는 쉽게 말해, Git을 인프라의 '단 하나의 진실된 소스(Single Source of Truth)'로 삼는 운영 방식입니다. 모든 인프라와 애플리케이션의 상태를 Git 리포지토리(Repository)에 코드(Code)로 저장하고, Git에 변경사항이 푸시(Push)되면 자동으로 인프라에 반영하는 방식이죠. ArgoCD는 이 GitOps 철학을 쿠버네티스 환경에서 구현해주는 강력한 선언적(Declarative) GitOps 지속적 배포(Continuous Delivery) 툴입니다.

ArgoCD는 쿠버네티스 클러스터(Cluster) 내부에서 동작하면서, Git 리포지토리의 상태와 실제 클러스터의 상태를 계속 비교합니다. 만약 두 상태가 다르면, Git 리포지토리의 상태(원하는 상태)로 클러스터의 상태를 동기화(Sync)하려고 시도하죠. 이걸 풀 기반(Pull-based) 배포라고 하는데, 기존의 푸시 기반(Push-based) CI/CD 방식보다 훨씬 안정적이고 보안에도 유리합니다. 직접 써보니, 이 방식이 정말 믿음직하더라고요. ✅

ArgoCD와 GitOps, 쉽게 이해하기

복잡하게 생각할 것 없이, GitOps는 우리가 늘 쓰던 Git으로 인프라도 관리하자는 이야기입니다. 애플리케이션 코드를 Git으로 관리하듯이, 쿠버네티스 매니페스트(Manifest) 파일들도 Git에 넣고 관리하는 거죠. 이렇게 하면 다음과 같은 장점들이 생깁니다.

  • 버전 관리(Version Control): 모든 변경 이력이 Git에 남으니, 누가 언제 무엇을 바꿨는지 명확하게 알 수 있습니다.
  • 롤백(Rollback) 용이: 문제가 생기면 Git 커밋(Commit)을 되돌리는 것만으로 이전 상태로 쉽게 돌아갈 수 있습니다.
  • 감사(Auditing) 및 보안 강화: 모든 변경이 Git을 통해 이루어지므로, 승인된 변경만 반영될 수 있도록 워크플로우(Workflow)를 구축하기 좋습니다.
  • 단일 진실 공급원(Single Source of Truth): 개발, 운영팀 모두 Git만 보면 현재 인프라 상태를 파악할 수 있습니다.

ArgoCD는 이 GitOps를 쿠버네티스에서 실현시켜주는 컨트롤러(Controller)입니다. 주요 특징은 다음과 같아요.

  • 선언적(Declarative) 관리: 원하는 상태를 YAML 파일로 선언해두면, ArgoCD가 알아서 그 상태를 유지합니다.
  • 자동 동기화(Automatic Synchronization): Git 리포지토리의 변경을 감지하고 자동으로 클러스터에 반영할 수 있습니다.
  • 시각적인 UI: 웹 UI를 통해 애플리케이션의 배포 상태, 리소스(Resource) 현황, 동기화 이력 등을 한눈에 확인할 수 있습니다. 저처럼 눈으로 확인해야 직성이 풀리는 사람에겐 정말 최고더라고요.
  • 다양한 배포 전략 지원: 롤링 업데이트(Rolling Update), 카나리 배포(Canary Deployment), 블루/그린 배포(Blue/Green Deployment) 등 다양한 배포 전략을 연동하여 구현할 수 있습니다.

프로덕션 환경을 위한 ArgoCD 설정 팁

이제 본격적으로 프로덕션 환경에서 ArgoCD를 효과적으로 사용하는 베스트 프랙티스를 공유해볼게요. 제가 직접 겪으면서 터득한 노하우들이니, 꼭 참고하시면 좋겠습니다.

1. Git Repository 구조화: Monorepo vs. Multirepo

Git 리포지토리를 어떻게 구성할지는 GitOps 전략의 첫 단추입니다. 크게 모노레포(Monorepo)멀티레포(Multirepo) 두 가지 방식이 있어요.

  • 모노레포(Monorepo): 모든 애플리케이션과 인프라 설정 파일을 하나의 Git 리포지토리에 저장하는 방식입니다. 초기 설정이 간단하고, 모든 것을 한곳에서 관리할 수 있다는 장점이 있습니다.
  • 멀티레포(Multirepo): 각 애플리케이션이나 환경별로 별도의 Git 리포지토리를 사용하는 방식입니다. 팀별 권한 분리나 대규모 서비스 운영에 유리할 수 있습니다.

저 같은 경우, 초기에는 모노레포로 시작했다가 규모가 커지면서 멀티레포 형태로 전환했어요. 하지만 ArgoCD를 통해 여러 애플리케이션을 관리할 때는 애플리케이션별 Git 리포지토리 + 인프라 설정용 Git 리포지토리를 분리하는 방식이 가장 효율적이라고 느꼈습니다. 프로덕션 환경에서는 GitOps 보안과 관리의 용이성을 위해 인프라 설정과 애플리케이션 코드를 분리하는 것을 추천합니다.

예시: 인프라 설정 Git 리포지토리 구조

├── applications # ArgoCD Application 정의
│   ├── app1.yaml
│   ├── app2.yaml
│   └── ...
├── environments
│   ├── dev
│   │   ├── kustomization.yaml
│   │   ├── namespace.yaml
│   │   └── ...
│   ├── stage
│   │   ├── kustomization.yaml
│   │   └── ...
│   └── prod
│       ├── kustomization.yaml
│       └── ...
└── base # 공통 설정
    ├── deployment.yaml
    ├── service.yaml
    └── ...

위 다이어그램은 제가 주로 사용하는 Git Repository 구조를 시각적으로 보여줍니다. 환경별로 설정을 분리하고, 공통 설정은 base에 두는 방식이에요.

2. 환경별 분리 및 Kustomize/Helm 활용

개발(dev), 스테이징(stage), 프로덕션(prod) 환경은 각각 다른 설정(리소스 요구 사항, 환경 변수 등)을 가집니다. 이를 효과적으로 관리하려면 KustomizeHelm을 적극적으로 활용해야 합니다.

  • Kustomize: 기존 YAML 파일을 수정하지 않고 덮어쓰기(Overlay) 방식으로 환경별 설정을 관리하는 데 매우 유용합니다. base 디렉터리에 공통 설정 파일을 두고, 각 환경별 overlays 디렉터리에서 필요한 부분만 변경하는 방식은 정말 깔끔하죠.
  • Helm: 재사용 가능한 쿠버네티스 애플리케이션 패키징(Packaging) 도구입니다. 데이터베이스(Database)나 메시지 큐(Message Queue)처럼 공통적으로 사용되는 미들웨어(Middleware)를 배포할 때 매우 편리합니다. 저도 처음엔 Helm이 좀 어렵게 느껴졌는데, 익숙해지니 없으면 안 되는 존재가 되더라고요.

ArgoCD 애플리케이션 정의에서 Kustomize나 Helm을 소스(Source)로 지정하면, ArgoCD가 알아서 해당 툴을 사용해서 매니페스트를 렌더링(Rendering)하고 배포해줍니다. 🚀

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app-prod
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/my-org/my-infra-gitops.git
    targetRevision: HEAD
    path: environments/prod/my-app # Kustomize overlay 경로
  destination:
    server: https://kubernetes.default.svc
    namespace: my-app-prod
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

3. Sync Options와 Health Checks

ArgoCD의 syncPolicy는 배포의 안정성을 결정하는 중요한 부분입니다. 프로덕션 환경에서는 다음 옵션들을 신중하게 설정해야 합니다.

  • automated.prune: true: Git 리포지토리에서 삭제된 리소스를 클러스터에서도 자동으로 삭제합니다. 클러스터의 불필요한 리소스 잔여물을 방지해줍니다.
  • automated.selfHeal: true: 클러스터의 상태가 Git 리포지토리의 상태와 다를 경우, ArgoCD가 자동으로 Git의 상태로 되돌립니다. 누군가 수동으로 클러스터 설정을 변경했을 때 원래대로 복구해주는 강력한 기능이죠. GitOps의 핵심 정신과 일치하는 부분입니다.
  • syncOptions: - CreateNamespace=true: 해당 네임스페이스(Namespace)가 없으면 ArgoCD가 자동으로 생성하도록 합니다.
  • 커스텀 헬스 체크(Custom Health Checks): 애플리케이션이 단순히 배포되었다고 끝이 아닙니다. 실제로 정상 작동하는지 확인하는 헬스 체크가 중요하죠. ArgoCD는 기본적으로 Pod의 Readiness/Liveness Probe를 활용하지만, 경우에 따라 ConfigMap에 커스텀 헬스 체크를 정의하여 더 정교한 상태 감지를 할 수 있습니다.

4. Rollback 전략

아무리 잘 준비해도 문제는 발생하기 마련이죠. 이때 빠르고 안전하게 롤백하는 것이 중요합니다. ArgoCD 환경에서의 롤백은 크게 두 가지 방식이 있어요.

  1. Git Revert: 가장 권장되는 방식입니다. 문제가 발생한 커밋을 Git에서 되돌리면(Revert) ArgoCD가 이를 감지하고 자동으로 이전 상태로 클러스터를 동기화합니다. 이 방식은 Git의 변경 이력이 그대로 남으므로 감사 추적에도 유리합니다.
  2. ArgoCD UI 롤백: ArgoCD 웹 UI에서 특정 애플리케이션의 History and Rollback 탭을 통해 이전 동기화 지점(Sync Point)으로 롤백할 수 있습니다. 긴급 상황에서 빠르게 대처할 수 있는 방법이지만, Git의 변경 이력에는 남지 않으므로 나중에 Git Revert로 맞춰주는 게 좋습니다.

저도 예전에 새벽에 긴급 롤백을 해야 했던 적이 있었는데, Git Revert 하나로 모든 상황이 깔끔하게 정리되었을 때의 안도감이란... 정말 겪어봐야 알 수 있습니다. 👍

GitOps 보안 강화: ArgoCD 프로덕션 환경 보안 설정

프로덕션 환경에서는 GitOps 보안이 최우선 고려사항입니다. ArgoCD를 통해 모든 것이 배포되므로, ArgoCD 자체의 보안 설정은 물론 주변 환경과의 연동도 중요합니다.

1. RBAC (Role-Based Access Control)

ArgoCD는 자체적인 RBAC(Role-Based Access Control)를 지원합니다. 이를 통해 누가 어떤 애플리케이션을 조회, 동기화, 삭제할 수 있는지 세밀하게 권한을 제어할 수 있어요. argocd-cm ConfigMap이나 argocd-rbac-cm ConfigMap을 수정하여 정책을 정의합니다.

또한, ArgoCD 프로젝트(Project)를 활용하여 애플리케이션들을 논리적으로 묶고, 프로젝트별로 RBAC 정책을 적용하면 관리 효율성과 보안을 동시에 잡을 수 있습니다. 예를 들어, 개발팀은 dev-project에만 접근 가능하고, 운영팀은 prod-project에만 접근 가능하도록 설정하는 식이죠.

# argocd-rbac-cm ConfigMap 예시
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    p, role:admin, applications, *, */*, allow
    p, role:dev, applications, get, dev-project/*, allow
    g, myuser, role:dev
  policy.default: role:readonly

2. Secret Management (외부 Secret 연동)

민감한 정보인 시크릿(Secret)을 Git 리포지토리에 평문으로 저장하는 것은 절대 금물입니다. 🙅‍♂️ GitOps 보안을 위해 외부 시크릿 관리 솔루션과 연동하는 것이 필수입니다.

  • Sealed Secrets: 클러스터에 배포된 컨트롤러가 시크릿을 암호화하고, Git에 암호화된 시크릿을 저장합니다. 암호화된 시크릿은 해당 클러스터에서만 복호화(Decrypt)될 수 있어 안전합니다. 제가 홈랩에서도 가장 즐겨 쓰는 방식이에요.
  • External Secrets Operator: AWS Secrets Manager, Azure Key Vault, Google Secret Manager, HashiCorp Vault 등 클라우드(Cloud) 기반 시크릿 관리 서비스와 연동하여 시크릿을 쿠버네티스 시크릿으로 동기화합니다. 프로덕션 환경에서는 이 방식이 가장 일반적입니다.

어떤 방법을 선택하든, 절대 시크릿을 Git에 직접 올리는 일은 없어야 합니다! 이건 제가 정말 피땀 흘려 배운 교훈입니다. ⚠️

3. Private Repository 접근

대부분의 프로덕션 환경에서는 프라이빗 Git 리포지토리(Private Git Repository)를 사용합니다. ArgoCD가 이 리포지토리에 접근하려면 인증 정보가 필요하겠죠. 다음 방법들을 사용할 수 있습니다.

  • SSH 키(SSH Key): 가장 일반적이고 강력한 방법입니다. ArgoCD에 SSH 키를 등록하고, 해당 키를 사용하여 리포지토리에 접근합니다.
  • HTTPS with Username/Password 또는 Personal Access Token (PAT): Git 서비스에서 발급받은 PAT를 ArgoCD에 등록하여 사용할 수 있습니다. 보안상 일반적인 비밀번호보다는 PAT를 사용하는 게 좋습니다.

인증 정보를 ArgoCD에 등록할 때는 쿠버네티스 시크릿으로 안전하게 관리해야 합니다. 당연한 이야기지만, 이걸 놓쳐서 문제가 되는 경우를 꽤 많이 봤거든요. 😅

ArgoCD 트러블슈팅: 제가 겪었던 문제들 (그리고 해결책)

13년차 엔지니어라고 해도 삽질은 피할 수 없는 운명이죠. ArgoCD를 쓰면서도 여러 번 머리를 쥐어뜯었습니다. 몇 가지 흔한 문제와 해결책을 공유해볼게요.

  • 문제: ImagePullBackOff 에러 (프라이빗 레지스트리)
    상황: 배포된 Pod에서 프라이빗 컨테이너 이미지 레지스트리(Private Container Image Registry)의 이미지를 당겨오지 못하고 ImagePullBackOff 에러가 발생하는 경우.
    해결: 해당 네임스페이스에 ImagePullSecrets를 제대로 설정했는지 확인해야 합니다. ArgoCD 애플리케이션이 배포될 때 이 시크릿이 같이 생성되도록 매니페스트에 포함하거나, 수동으로 시크릿을 생성하고 Pod Spec에 추가해야 합니다. 저는 주로 ArgoCD가 CreateNamespace=true와 함께 시크릿도 함께 배포하도록 설정합니다.
  • 문제: Resource is not available 또는 Failed to install CRD
    상황: 애플리케이션 배포 시 커스텀 리소스 정의(CRD: Custom Resource Definition)가 먼저 설치되어야 하는데, 순서가 맞지 않아 발생하는 에러.
    해결: ArgoCD의 Sync Waves 기능을 활용하면 배포 순서를 제어할 수 있습니다. CRD를 먼저 배포하고, 그 이후에 CRD를 사용하는 애플리케이션 리소스를 배포하도록 설정하는 거죠. 예를 들어, CRD는 sync-wave: "-1", 일반 리소스는 sync-wave: "0"으로 설정하면 됩니다. 이 기능을 알게 된 후로 정말 속이 시원했습니다. 🎉
  • 문제: 롤백 후에도 문제가 지속됨
    상황: Git Revert나 ArgoCD UI 롤백을 했는데도 애플리케이션이 정상 상태로 돌아오지 않는 경우.
    해결: 롤백 대상이 되는 커밋이 정말 이전의 '정상' 상태를 가리키는지 확인해야 합니다. 때로는 환경 변수나 외부 의존성(예: 데이터베이스 스키마 변경) 때문에 롤백만으로는 해결되지 않을 수 있거든요. 이럴 때는 문제 발생 시점을 정확히 파악하고, 관련된 모든 변경사항(Git, DB 스키마, 외부 서비스 설정 등)을 함께 되돌려야 합니다. 그리고 롤백 후 ArgoCD UI에서 애플리케이션의 Health 상태와 Events 탭을 꼼꼼히 확인하는 습관을 들이는 게 좋습니다.

결과 및 검증: 안정적인 배포, 이제 Git만 바라봅니다.

ArgoCD와 GitOps 베스트 프랙티스를 적용하고 나니, 정말 배포 과정이 안정적이고 예측 가능해졌습니다. 더 이상 불안에 떨며 배포 버튼을 누를 필요가 없어졌죠. ✅

배포가 완료되면 ArgoCD 웹 UI에서 각 애플리케이션의 상태를 한눈에 확인할 수 있습니다. 모든 리소스가 Healthy 상태이고, Synced 상태인지 확인하는 것이 중요해요. 혹시 OutOfSync 상태라면, 어떤 리소스가 Git과 다른지 명확하게 보여주므로 문제 파악이 매우 쉽습니다. 이 시각적인 피드백(Feedback) 덕분에 트러블슈팅 시간도 대폭 줄었습니다.

ArgoCD UI에서 모든 애플리케이션이 건강하고(Healthy) 동기화(Synced)된 상태를 보여주는 화면입니다. 이 화면을 볼 때마다 뿌듯하더라고요!

실제로 저는 홈랩에서 여러 서비스를 ArgoCD로 관리하고 있는데, Git에 커밋만 하면 알아서 배포가 되고, 문제가 생겨도 Git Revert 한 번으로 해결되는 경험은 정말 혁신적이었습니다. CI/CD 파이프라인의 완성도를 높이는 데 ArgoCD가 결정적인 역할을 했다고 생각합니다.

ArgoCD GitOps를 프로덕션 환경에 적용하기 위한 핵심 베스트 프랙티스를 요약한 인포그래픽입니다.

마무리: GitOps 여정, 계속됩니다

오늘은 ArgoCD 프로덕션 환경 GitOps 베스트 프랙티스에 대해 저의 경험을 바탕으로 이야기해봤습니다. 안정적인 배포와 GitOps 보안 강화를 위해 Git 리포지토리 구조화, 환경별 설정 관리, Sync Policy, 롤백 전략, RBAC, 시크릿 관리 등 다양한 측면을 다루었네요.

처음에는 복잡하게 느껴질 수도 있지만, 한 번 제대로 구축해두면 개발팀과 운영팀 모두에게 엄청난 효율성과 안정성을 가져다줄 겁니다. 저도 아직 배워야 할 것이 많고, 계속해서 새로운 기술을 실험하고 있습니다. 이 글이 여러분의 쿠버네티스 배포 여정에 작은 등불이 되기를 바랍니다. 궁금한 점이나 공유하고 싶은 삽질 경험이 있다면 언제든지 댓글로 남겨주세요! 다음에는 ArgoCD와 함께 CI/CD 파이프라인을 더욱 자동화하는 방법에 대해 다뤄보겠습니다. 그때까지 모두 즐거운 서버실 라이프 즐기시길 바랍니다! 😊