/엔지니어/Git / CI·CD/GitOps 실전 — ArgoCD로 Kubernet
Git / CI·CD고급UbuntumacOSGitOpsArgoCDKubernetes

GitOps 실전 — ArgoCD로 Kubernetes 배포 완전 자동화

GitOps 원칙에 따라 ArgoCD를 구성하고, ApplicationSet·Sync Wave·Rollout을 활용해 멀티 환경 Kubernetes 배포를 코드로 완전히 자동화하는 심화 가이드.

GitOps란

GitOps는 **Git 저장소를 인프라/애플리케이션의 단일 진실 원천(Single Source of Truth)**으로 삼고, 저장소 상태와 클러스터 상태를 자동으로 일치시키는 운영 패러다임입니다.

CODE
개발자 → git push → GitHub ──► ArgoCD(감지) ──► Kubernetes 클러스터
                                    ↑ 지속적으로 상태 동기화

1. ArgoCD 설치

Bash
kubectl create namespace argocd

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

# ArgoCD CLI 설치
curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x argocd && sudo mv argocd /usr/local/bin

# 초기 admin 비밀번호 확인
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# 포트 포워딩으로 UI 접근
kubectl port-forward svc/argocd-server -n argocd 8080:443

# CLI 로그인
argocd login localhost:8080 --username admin --password <password> --insecure

Ingress로 외부 노출 (프로덕션)

YAML
# argocd-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  ingressClassName: nginx
  rules:
    - host: argocd.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: argocd-server
                port:
                  number: 443

2. 저장소 구조 설계

GitOps에서는 앱 코드 저장소인프라/배포 저장소를 분리하는 것이 표준입니다.

CODE
infra-repo/
├── apps/
│   ├── base/                    # 공통 기본 설정
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   └── kustomization.yaml
│   ├── overlays/
│   │   ├── dev/                 # 개발 환경 오버레이
│   │   │   ├── kustomization.yaml
│   │   │   └── patch-replicas.yaml
│   │   ├── staging/
│   │   └── production/
└── argocd/
    ├── projects/
    └── applications/

Kustomize 기반 멀티 환경 오버레이

YAML
# apps/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: my-registry.com/api:latest
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
---
# apps/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
patches:
  - path: patch-replicas.yaml
  - path: patch-resources.yaml
images:
  - name: my-registry.com/api
    newTag: v1.5.0    # 프로덕션은 고정 태그 사용
---
# apps/overlays/production/patch-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 5

3. ApplicationSet — 멀티 환경 자동 배포

ApplicationSet은 하나의 템플릿으로 여러 환경의 Application을 자동 생성합니다.

YAML
# argocd/applicationset.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: api-appset
  namespace: argocd
spec:
  generators:
    - list:
        elements:
          - env: dev
            cluster: https://kubernetes.default.svc
            namespace: dev
            revision: main
          - env: staging
            cluster: https://staging-cluster.example.com
            namespace: staging
            revision: main
          - env: production
            cluster: https://prod-cluster.example.com
            namespace: production
            revision: v1.5.0   # 프로덕션은 태그로 고정
  template:
    metadata:
      name: api-{{env}}
    spec:
      project: default
      source:
        repoURL: https://github.com/myorg/infra-repo
        targetRevision: "{{revision}}"
        path: apps/overlays/{{env}}
      destination:
        server: "{{cluster}}"
        namespace: "{{namespace}}"
      syncPolicy:
        automated:
          prune: true           # Git에서 삭제된 리소스 자동 제거
          selfHeal: true        # 클러스터 수동 변경 자동 원복
        syncOptions:
          - CreateNamespace=true
          - ServerSideApply=true
Bash
kubectl apply -f argocd/applicationset.yaml

# 생성된 Application 목록 확인
argocd app list

# 동기화 상태 확인
argocd app get api-production

4. Sync Wave — 배포 순서 제어

Sync Wave를 사용하면 ConfigMap → DB 마이그레이션 → 애플리케이션 순서로 배포를 순차 실행할 수 있습니다.

YAML
# 1단계: ConfigMap 먼저 생성
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
  annotations:
    argocd.argoproj.io/sync-wave: "-2"   # 음수: 가장 먼저 실행
---
# 2단계: DB 마이그레이션 Job
apiVersion: batch/v1
kind: Job
metadata:
  name: db-migrate
  annotations:
    argocd.argoproj.io/sync-wave: "-1"
    argocd.argoproj.io/hook: Sync
    argocd.argoproj.io/hook-delete-policy: HookSucceeded
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: my-registry.com/api:v1.5.0
          command: ["python", "manage.py", "migrate"]
---
# 3단계: 실제 애플리케이션 (기본값: wave 0)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
  annotations:
    argocd.argoproj.io/sync-wave: "0"

5. Argo Rollouts — 카나리 · 블루그린 배포

Bash
# Argo Rollouts 설치
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

# kubectl 플러그인
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x kubectl-argo-rollouts-linux-amd64 && sudo mv kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
YAML
# rollout.yaml — 카나리 배포 전략
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: api
spec:
  replicas: 10
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
        - name: api
          image: my-registry.com/api:v1.5.0
  strategy:
    canary:
      steps:
        - setWeight: 10       # 10% 트래픽을 새 버전으로
        - pause: {duration: 5m}
        - analysis:
            templates:
              - templateName: success-rate   # 에러율 분석
        - setWeight: 50
        - pause: {duration: 10m}
        - setWeight: 100
      canaryService: api-canary
      stableService: api-stable
      trafficRouting:
        nginx:
          stableIngress: api-ingress
---
# 분석 템플릿
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: success-rate
spec:
  metrics:
    - name: success-rate
      interval: 1m
      successCondition: result[0] >= 0.95
      failureLimit: 3
      provider:
        prometheus:
          address: http://prometheus.monitoring:9090
          query: |
            sum(rate(http_requests_total{status!~"5.."}[5m]))
            /
            sum(rate(http_requests_total[5m]))
Bash
# 배포 시작
kubectl apply -f rollout.yaml

# 실시간 진행 모니터링
kubectl argo rollouts get rollout api --watch

# 수동으로 다음 단계 진행
kubectl argo rollouts promote api

# 문제 발생 시 즉시 롤백
kubectl argo rollouts abort api
kubectl argo rollouts undo api

6. CI → GitOps 연동 — 이미지 태그 자동 업데이트

YAML
# .github/workflows/deploy.yml
name: Build and Update Manifest

on:
  push:
    branches: [main]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build and push image
        run: |
          docker build -t my-registry.com/api:${{ github.sha }} .
          docker push my-registry.com/api:${{ github.sha }}

      - name: Update infra-repo image tag
        run: |
          git clone https://x-access-token:${{ secrets.INFRA_TOKEN }}@github.com/myorg/infra-repo.git
          cd infra-repo
          # kustomize로 이미지 태그 업데이트
          cd apps/overlays/staging
          kustomize edit set image my-registry.com/api=my-registry.com/api:${{ github.sha }}
          git config user.email "[email protected]"
          git config user.name "CI Bot"
          git add -A
          git commit -m "chore: update api to ${{ github.sha }}"
          git push
      # ArgoCD가 infra-repo 변경을 감지해 자동 배포
#GitOps#ArgoCD#Kubernetes#ApplicationSet#Rollout#CI/CD#DevOps
편집 안내 · Editorial Note

이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.

질문 & 답변 (Q&A)

이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.