8.9 KiB
8.9 KiB
id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id | title | category | status | source_trust_level | verification_status | created_at | updated_at | tags | tech_stack | applied_in | aliases | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| devops-argocd-gitops | ArgoCD / GitOps — Git = Source of Truth | Coding | draft | B | conceptual | 2026-05-09 | 2026-05-09 |
|
|
|
ArgoCD / GitOps
"Git = production state". ArgoCD / Flux 가 Git 의 manifest → cluster 자동 sync. Push 대신 pull. Kubernetes 의 modern 배포 표준.
📖 핵심 개념
- Git = single source of truth.
- Pull-based: ArgoCD 가 git poll → apply.
- Drift detection: cluster ≠ git → 자동 fix.
- App of Apps: meta-app 가 다른 app 관리.
💻 코드 패턴
ArgoCD 설치
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# CLI
brew install argocd
argocd login <argocd-server>
# UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests
targetRevision: main
path: apps/my-app/overlays/prod
destination:
server: https://kubernetes.default.svc
namespace: prod
syncPolicy:
automated:
prune: true # Git 에서 제거된 자원 cluster 에서도 제거
selfHeal: true # Manual 변경 시 자동 revert
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
→ Git push → 1-3 min 안 cluster 자동 update.
Helm + ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: { name: my-app }
spec:
source:
repoURL: https://github.com/myorg/charts
targetRevision: HEAD
path: charts/my-app
helm:
valueFiles:
- values.yaml
- values-prod.yaml
parameters:
- name: image.tag
value: 1.5.0
Kustomize + ArgoCD
spec:
source:
repoURL: https://github.com/myorg/manifests
path: apps/my-app/overlays/prod
kustomize:
images:
- my-app=ghcr.io/myorg/my-app:1.5.0
namePrefix: prod-
App of Apps (meta)
# argocd/applications.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: { name: bootstrap, namespace: argocd }
spec:
source:
repoURL: https://github.com/myorg/argocd
path: apps/
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated: { prune: true, selfHeal: true }
apps/
├── application.yaml
├── api.yaml # Application
├── web.yaml # Application
├── monitoring.yaml # Application
└── ...
→ 한 ArgoCD app 가 다른 app 들 관리.
ApplicationSet (multi-cluster / multi-tenant)
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata: { name: my-app, namespace: argocd }
spec:
generators:
- clusters: {} # 모든 등록된 cluster
template:
metadata:
name: my-app-{{name}}
spec:
project: default
source:
repoURL: ...
path: apps/my-app
destination:
server: '{{server}}'
namespace: prod
→ N cluster 에 자동 deploy.
Sync waves (dependency order)
# Wave 0 (CRDs)
metadata:
annotations:
argocd.argoproj.io/sync-wave: "0"
# Wave 1 (DB)
metadata:
annotations:
argocd.argoproj.io/sync-wave: "1"
# Wave 2 (App)
metadata:
annotations:
argocd.argoproj.io/sync-wave: "2"
→ ArgoCD 가 wave 별 순차 deploy.
Hooks
# DB migration before app deploy
metadata:
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded
RBAC
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata: { name: prod, namespace: argocd }
spec:
description: Production
sourceRepos:
- 'https://github.com/myorg/*'
destinations:
- namespace: 'prod-*'
server: '*'
roles:
- name: deployer
policies:
- p, proj:prod:deployer, applications, sync, prod/*, allow
groups:
- acme:platform
Notifications
# notifications.yaml
service.slack:
token: ...
template.app-sync-succeeded: |
message: 'Application {{.app.metadata.name}} synced successfully'
trigger.on-sync-succeeded: |
- when: app.status.operationState.phase in ['Succeeded']
send: [app-sync-succeeded]
subscriptions:
- recipients: [slack:engineering]
triggers: [on-sync-succeeded, on-sync-failed]
CI workflow
# .github/workflows/deploy.yml
- name: Build + push image
run: docker build -t $REGISTRY/my-app:$SHA . && docker push $REGISTRY/my-app:$SHA
- name: Update manifest
run: |
cd k8s-manifests
yq -i '.image.tag = "${{ github.sha }}"' apps/my-app/values-prod.yaml
git add . && git commit -m "Deploy my-app ${{ github.sha }}" && git push
→ Git push = ArgoCD 자동 deploy. 직접 kubectl 안 함.
Health check (ArgoCD 가 status 추정)
# Custom health check (Lua)
metadata:
name: argocd-cm
data:
resource.customizations: |
networking.k8s.io/Ingress:
health.lua: |
hs = {}
if obj.status ~= nil and obj.status.loadBalancer ~= nil then
...
end
return hs
Drift / self-heal
사용자가 cluster 에서 manual 변경:
- ArgoCD detect drift
- selfHeal: true → 자동 git state 로 revert
- selfHeal: false → 알람 만
Rollback
# History
argocd app history my-app
# Rollback to specific revision
argocd app rollback my-app 5
# 또는 git revert
git revert <commit>
git push # ArgoCD 자동 sync
Image automation (Argo Image Updater)
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
annotations:
argocd-image-updater.argoproj.io/image-list: my-app=ghcr.io/myorg/my-app
argocd-image-updater.argoproj.io/my-app.update-strategy: semver
argocd-image-updater.argoproj.io/my-app.allow-tags: "regexp:^v[0-9]+\\.[0-9]+\\.[0-9]+$"
→ 새 image tag 자동 detect → manifest update + commit.
Flux (alternative)
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata: { name: my-app, namespace: flux-system }
spec:
url: https://github.com/myorg/manifests
ref: { branch: main }
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata: { name: my-app, namespace: flux-system }
spec:
sourceRef: { kind: GitRepository, name: my-app }
path: apps/my-app/overlays/prod
prune: true
interval: 1m
→ ArgoCD 와 비슷. Git-friendly UX.
Flux vs ArgoCD
ArgoCD:
+ UI 강력
+ 큰 ecosystem
+ App-centric
Flux:
+ Cloud-native (CNCF graduated)
+ More automation features
+ Lighter weight
→ ArgoCD 가 더 인기 (2024+).
Multi-cluster
1. ArgoCD 가 central cluster
2. argocd cluster add — 다른 cluster
3. Application destination 이 어느 cluster
4. ApplicationSet 가 여러 cluster 동시 deploy
Progressive delivery (Argo Rollouts)
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata: { name: my-app }
spec:
replicas: 10
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 5m }
- setWeight: 25
- pause: { duration: 5m }
- setWeight: 50
- pause: { duration: 10m }
- setWeight: 100
analysis:
templates:
- templateName: success-rate
startingStep: 1
→ Auto canary + rollback if metric 깨짐.
Sealed Secrets / External Secrets
# Secret 가 git 안 안전 — encrypted
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
spec:
encryptedData:
api-key: AgB7...
→ ArgoCD 가 sealed secret apply → controller decrypt.
🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| K8s + Git workflow | ArgoCD |
| Cloud-native official | Flux |
| Multi-cluster | ApplicationSet |
| Progressive delivery | Argo Rollouts |
| 작은 / 단순 | Manual kubectl + CI |
| 매우 큰 organization | + Crossplane |
❌ 안티패턴
- kubectl apply manual prod: drift / no audit.
- Image tag latest: hash 안 명시 — 추적 불가.
- Secret in git plain: leak.
- Sync 너무 자주 (1s): API rate limit.
- Self-heal off: drift 누적.
- App of Apps 없이 100 application: 관리 불가.
- Sync wave 무시: dependency 순서 깨짐.
🤖 LLM 활용 힌트
- Git push = production update.
- App of Apps 패턴 + ApplicationSet.
- Argo Rollouts = canary / blue-green 자동.
- Sealed / External Secrets.