GitOps란
GitOps는 **Git 저장소를 인프라/애플리케이션의 단일 진실 원천(Single Source of Truth)**으로 삼고, 저장소 상태와 클러스터 상태를 자동으로 일치시키는 운영 패러다임입니다.
개발자 → git push → GitHub ──► ArgoCD(감지) ──► Kubernetes 클러스터
↑ 지속적으로 상태 동기화1. ArgoCD 설치
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> --insecureIngress로 외부 노출 (프로덕션)
# 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: 4432. 저장소 구조 설계
GitOps에서는 앱 코드 저장소와 인프라/배포 저장소를 분리하는 것이 표준입니다.
infra-repo/
├── apps/
│ ├── base/ # 공통 기본 설정
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── kustomization.yaml
│ ├── overlays/
│ │ ├── dev/ # 개발 환경 오버레이
│ │ │ ├── kustomization.yaml
│ │ │ └── patch-replicas.yaml
│ │ ├── staging/
│ │ └── production/
└── argocd/
├── projects/
└── applications/Kustomize 기반 멀티 환경 오버레이
# 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: 53. ApplicationSet — 멀티 환경 자동 배포
ApplicationSet은 하나의 템플릿으로 여러 환경의 Application을 자동 생성합니다.
# 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=truekubectl apply -f argocd/applicationset.yaml
# 생성된 Application 목록 확인
argocd app list
# 동기화 상태 확인
argocd app get api-production4. Sync Wave — 배포 순서 제어
Sync Wave를 사용하면 ConfigMap → DB 마이그레이션 → 애플리케이션 순서로 배포를 순차 실행할 수 있습니다.
# 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 — 카나리 · 블루그린 배포
# 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# 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]))# 배포 시작
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 api6. CI → GitOps 연동 — 이미지 태그 자동 업데이트
# .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 변경을 감지해 자동 배포이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.
질문 & 답변 (Q&A)
이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.