Files
2nd/10_Wiki/Topics/Coding/DevOps_ArgoCD_GitOps.md
T
2026-05-09 21:08:02 +09:00

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
devops
argocd
gitops
vibe-coding
language applicable_to
YAML / K8s
DevOps
ArgoCD
Flux
GitOps
declarative deploy
App of Apps
sync wave

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.

🔗 관련 문서