IMG-LOGO
공지사항 :

Argo CD + GitOps 기반 Kubernetes 자동 배포 및 운영 자동화

lmkfox - 2026-09-16 06:36:18 3 Views 0 Comment

Argo CD + GitOps 기반 Kubernetes 자동 배포 및 운영 자동화

1. 들어가며

앞에서 Kubernetes 운영 환경을 구축하면서 다음과 같은 구성까지 살펴봤다.

  • Kubernetes

  • Helm

  • FastAPI

  • PostgreSQL

  • Redis

  • Nginx

  • Ingress

  • HTTPS

  • Prometheus

  • Grafana

  • Alertmanager

  • Loki

  • Tempo

  • Kubernetes 자동 복구

  • SRE 운영 체계

여기까지 구성하면 Kubernetes의 상태를 관찰하고 장애를 감지하며 일부 장애를 자동으로 복구할 수 있다.

하지만 실제 운영 환경에서는 또 하나의 중요한 문제가 남는다.

바로 **애플리케이션을 어떻게 안전하고 일관되게 배포할 것인가?**이다.

전통적인 Kubernetes 배포는 관리자가 직접 다음과 같은 명령을 실행하는 방식으로 이루어질 수 있다.

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

또는 Helm을 사용한다면 다음과 같이 배포할 수도 있다.

helm upgrade --install tax-app ./helm/tax-app \
  -f values-prod.yaml

개발 환경에서는 큰 문제가 없지만 운영 환경에서는 다음과 같은 문제가 발생할 수 있다.

  • 누가 배포했는지 추적하기 어렵다.

  • 현재 Kubernetes에 어떤 설정이 적용되어 있는지 Git과 다를 수 있다.

  • 운영자가 직접 YAML을 수정할 수 있다.

  • 여러 Kubernetes 클러스터의 설정이 달라질 수 있다.

  • 롤백 기준이 명확하지 않을 수 있다.

  • CI/CD와 Kubernetes 배포 과정이 분리될 수 있다.

이 문제를 해결하기 위한 대표적인 방식이 바로 GitOps다.

그리고 Kubernetes GitOps 환경에서 대표적으로 사용되는 도구가 Argo CD다.


2. GitOps란 무엇인가?

GitOps는 간단하게 표현하면 다음과 같다.

Git을 Kubernetes 운영 환경의 최종 상태를 정의하는 Source of Truth로 사용하는 방식

즉 Kubernetes에 직접 명령을 내려 상태를 변경하는 것이 아니라 Git에 원하는 상태를 기록한다.

예를 들어 Git에 다음과 같은 Deployment가 있다고 가정하자.

apiVersion: apps/v1
kind: Deployment

metadata:
  name: backend

spec:
  replicas: 3

  selector:
    matchLabels:
      app: backend

  template:
    metadata:
      labels:
        app: backend

    spec:
      containers:
        - name: backend
          image: tax-backend:1.2.0

Git에는 다음 상태가 저장되어 있다.

backend
replicas = 3
image = tax-backend:1.2.0

Kubernetes가 실제로 다음 상태라고 가정하자.

backend
replicas = 2
image = tax-backend:1.1.0

GitOps에서는 이 차이를 Drift라고 한다.

즉,

Git 상태
    │
    │ desired state
    ▼
replicas = 3
image = 1.2.0

        ≠

Kubernetes 실제 상태
replicas = 2
image = 1.1.0

GitOps 시스템은 이 차이를 감지하고 Kubernetes를 Git의 상태와 일치시키는 작업을 수행한다.


3. GitOps의 핵심 개념

GitOps를 이해하려면 다음 네 가지 개념을 이해해야 한다.

3.1 Desired State

Git에 정의된 원하는 상태다.

예:

Deployment replicas = 3
Image = 1.2.0
CPU request = 500m
Memory request = 512Mi

3.2 Actual State

현재 Kubernetes에서 실제로 동작하고 있는 상태다.

Deployment replicas = 2
Image = 1.1.0
CPU request = 500m
Memory request = 512Mi

3.3 Drift

Desired State와 Actual State의 차이다.

Desired State
      │
      │
      ▼
   replicas 3
      │
      │ Drift
      ▼
Actual State
   replicas 2

3.4 Reconciliation

GitOps 시스템이 Desired State와 Actual State를 비교하고 차이를 수정하는 과정이다.

Git
 │
 │ Desired State
 ▼
Argo CD
 │
 │ compare
 ▼
Kubernetes
 │
 │ Actual State
 ▼
Difference?
 │
 ├── No → Synced
 │
 └── Yes → Sync

이 과정을 계속 반복한다.


4. Argo CD란 무엇인가?

Argo CD는 Kubernetes를 위한 GitOps Continuous Delivery 도구다.

핵심 역할은 다음과 같다.

Git Repository
      │
      │ YAML / Helm
      ▼
   Argo CD
      │
      │ Reconciliation
      ▼
 Kubernetes

Argo CD는 Git Repository에 저장된 Kubernetes 설정을 읽고 Kubernetes의 실제 상태와 비교한다.

그리고 설정에 따라 자동으로 동기화할 수 있다.


5. 전체 DevOps 플랫폼 구조

지금까지 구성한 시스템에 Argo CD를 추가하면 전체 구조는 다음과 같이 발전한다.

                  Developer
                      │
                      ▼
                 Git Push
                      │
                      ▼
              ┌──────────────┐
              │     Git      │
              │ Application  │
              │ Helm / YAML  │
              └──────┬───────┘
                     │
                     ▼
              ┌──────────────┐
              │   CI Build   │
              │ GitHub       │
              │ Actions      │
              └──────┬───────┘
                     │
                     ▼
                 Container
                   Image
                     │
                     ▼
               Container
                Registry
                     │
                     │ Image Tag
                     ▼
              ┌──────────────┐
              │  GitOps Repo │
              │ values-prod  │
              └──────┬───────┘
                     │
                     ▼
                ┌─────────┐
                │ Argo CD │
                └────┬────┘
                     │
                     ▼
               Kubernetes
                     │
          ┌──────────┼──────────┐
          ▼          ▼          ▼
       FastAPI     Redis    PostgreSQL
          │
          ▼
    ┌───────────────┐
    │ Observability │
    └───────┬───────┘
            │
      ┌─────┼─────┐
      ▼     ▼     ▼
 Prometheus Loki  Tempo
      │     │     │
      └─────┼─────┘
            ▼
         Grafana
            │
            ▼
       Alertmanager
            │
            ▼
       Slack / Email

이 구조가 바로 실전적인 CI/CD → GitOps → Observability → 자동 복구 구조다.


6. CI/CD와 GitOps의 차이

많은 사람들이 CI/CD와 GitOps를 같은 개념으로 생각하지만 역할이 다르다.

CI

CI는 주로 코드 변경을 검증하고 빌드하는 과정이다.

Git Push
   ↓
Test
   ↓
Build
   ↓
Docker Image
   ↓
Registry

예:

tax-backend:1.2.0

CD

CD는 변경된 애플리케이션을 배포하는 과정이다.

전통적인 방식에서는 GitHub Actions가 직접 Kubernetes에 접근할 수 있다.

GitHub Actions
      │
      │ kubectl
      ▼
Kubernetes

하지만 GitOps에서는 구조가 다르다.

GitHub Actions
      │
      ▼
Container Registry

GitOps Repository
      │
      ▼
Argo CD
      │
      ▼
Kubernetes

즉 CI가 Kubernetes에 직접 배포하는 것이 아니라 Git의 배포 설정을 변경하고 Argo CD가 배포를 수행한다.


7. 왜 GitOps가 필요한가?

운영 환경에서 가장 중요한 장점 중 하나는 변경 이력이다.

예를 들어 운영 서버의 Deployment 이미지가 다음과 같이 변경되었다고 가정하자.

1.1.0
 ↓
1.2.0

GitOps에서는 Git Commit으로 추적할 수 있다.

commit abc123
image: 1.2.0

누가 변경했는지 확인할 수 있다.

git log

특정 변경도 확인할 수 있다.

git show abc123

그리고 문제가 발생하면 이전 Commit으로 되돌릴 수 있다.

git revert abc123

Argo CD가 다시 Kubernetes에 반영한다.

즉,

Rollback

Git
 │
 │ revert
 ▼
Argo CD
 │
 ▼
Kubernetes

라는 구조가 만들어진다.


8. Git Repository 구조

실전에서는 Application Repository와 GitOps Repository를 분리하는 방식도 많이 사용한다.

예를 들어 다음과 같이 구성할 수 있다.

application-repo
├── backend
│   ├── main.py
│   ├── requirements.txt
│   └── Dockerfile
│
├── frontend
│   └── ...
│
└── .github
    └── workflows
        └── build.yml

GitOps Repository:

gitops-repo
├── apps
│   └── tax-app
│       ├── Chart.yaml
│       ├── values.yaml
│       ├── values-dev.yaml
│       ├── values-prod.yaml
│       │
│       └── templates
│           ├── deployment.yaml
│           ├── service.yaml
│           ├── ingress.yaml
│           ├── configmap.yaml
│           ├── secret.yaml
│           └── pvc.yaml
│
└── argocd
    └── tax-app.yaml

9. Helm과 Argo CD를 함께 사용하는 이유

Argo CD는 YAML뿐만 아니라 Helm Chart도 사용할 수 있다.

기존에 작성한 Helm Chart를 그대로 GitOps에 사용할 수 있다.

예:

tax-app
├── Chart.yaml
├── values.yaml
├── values-dev.yaml
├── values-prod.yaml
└── templates

환경별 설정은 다음과 같이 관리할 수 있다.

values-dev.yaml

replicaCount: 1

image:
  tag: "1.2.0"
values-prod.yaml

replicaCount: 3

image:
  tag: "1.2.0"

그러면 Argo CD가 해당 Helm Chart를 렌더링하여 Kubernetes에 적용한다.


10. Argo CD 설치

먼저 Namespace를 생성한다.

kubectl create namespace argocd

Argo CD 공식 설치 방법을 기준으로 설치할 수 있다.

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

설치 상태를 확인한다.

kubectl get pods -n argocd

정상적으로 설치되었다면 여러 Argo CD Pod가 실행된다.

argocd-server
argocd-repo-server
argocd-application-controller
argocd-dex-server
argocd-redis

11. Argo CD CLI 설치 및 접속

CLI 설치 후 서버를 확인한다.

argocd version

외부 LoadBalancer가 없다면 Port Forward를 사용할 수 있다.

kubectl port-forward svc/argocd-server \
  -n argocd 8080:443

브라우저에서 다음 주소로 접근할 수 있다.

https://localhost:8080

초기 관리자 Password는 다음과 같이 확인할 수 있다.

kubectl -n argocd \
  get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" \
  | base64 -d

로그인:

argocd login localhost:8080

12. Argo CD Application이란?

Argo CD의 핵심 객체가 바로 Application이다.

Application은 다음을 정의한다.

Git Repository
      │
      ├── Repository URL
      ├── Path
      ├── Revision
      │
      ▼
Kubernetes
      │
      ├── Cluster
      └── Namespace

즉,

이 Git Repository의 특정 경로에 있는 Kubernetes 설정을 특정 Kubernetes Namespace에 배포하라.

라는 의미다.


13. Argo CD Application YAML

예를 들어 다음과 같은 Application을 만들 수 있다.

apiVersion: argoproj.io/v1alpha1
kind: Application

metadata:
  name: tax-app
  namespace: argocd

spec:

  project: default

  source:
    repoURL: https://github.com/example/tax-gitops.git
    targetRevision: main
    path: apps/tax-app

    helm:
      valueFiles:
        - values-prod.yaml

  destination:
    server: https://kubernetes.default.svc
    namespace: tax-prod

  syncPolicy:

    automated:
      prune: true
      selfHeal: true

    syncOptions:
      - CreateNamespace=true

적용한다.

kubectl apply -f tax-app.yaml

14. automated sync

Argo CD의 중요한 기능 중 하나가 자동 Sync다.

다음 설정을 보면:

syncPolicy:
  automated:
    prune: true
    selfHeal: true

Git 변경을 감지하면 자동으로 Kubernetes에 반영한다.

예를 들어:

Git

image:
  tag: 1.3.0

변경:

image:
  tag: 1.4.0

Git Push가 발생한다.

Git Push
   ↓
Argo CD 감지
   ↓
Diff 확인
   ↓
Sync
   ↓
Kubernetes Deployment 변경
   ↓
Rolling Update

15. selfHeal이란?

selfHeal은 운영에서 매우 중요한 기능이다.

Git에는 다음과 같이 정의되어 있다고 가정하자.

replicas: 3

그런데 운영자가 Kubernetes에서 직접 변경했다.

kubectl scale deployment backend \
  --replicas=1

실제 상태:

Git:
replicas = 3

Kubernetes:
replicas = 1

Argo CD는 Drift를 감지한다.

OutOfSync

selfHeal이 활성화되어 있다면 다시 Git 상태로 맞춘다.

replicas 1
    ↓
Argo CD
    ↓
replicas 3

이것이 GitOps의 핵심이다.


16. prune이란?

Git에서 Kubernetes Resource를 제거했는데 Kubernetes에는 여전히 Resource가 남아 있을 수 있다.

예:

Git:

deployment.yaml
service.yaml
configmap.yaml

변경 후:

deployment.yaml
service.yaml

ConfigMap을 Git에서 삭제했다면 prune: true일 때 Argo CD가 Kubernetes에서도 해당 Resource를 제거할 수 있다.

Git Resource 삭제
       ↓
Argo CD
       ↓
Kubernetes Resource 삭제

다만 운영 환경에서는 데이터가 포함된 Resource에 특히 주의해야 한다.

특히 다음은 무조건적인 자동 삭제를 신중하게 설계해야 한다.

PVC
Database
StatefulSet
Secret

17. Sync 상태 확인

Argo CD CLI에서 확인할 수 있다.

argocd app list

예:

NAME       SYNC STATUS   HEALTH STATUS
tax-app    Synced        Healthy

상세 정보:

argocd app get tax-app

Sync:

argocd app sync tax-app

History:

argocd app history tax-app

18. Argo CD의 Health 상태

Argo CD는 단순히 Git과 Kubernetes Resource가 같은지만 확인하지 않는다.

Application의 Health 상태도 확인한다.

대표적인 상태:

Healthy
Progressing
Degraded
Missing
Unknown
Suspended

예를 들어 Deployment가 정상적으로 Pod를 생성하고 Ready 상태가 되면:

Healthy

반대로 Pod가 계속 실패한다면:

Degraded

가 될 수 있다.


19. 실제 배포 흐름

이제 전체 과정을 살펴보자.

개발자가 FastAPI 코드를 수정한다.

main.py

Git Push:

git add .
git commit -m "Update API"
git push

GitHub Actions가 실행된다.

GitHub Actions

1. Checkout
2. Test
3. Build
4. Docker Image
5. Push Registry

예:

tax-backend:1.5.0

다음으로 GitOps Repository의 Helm Values를 변경한다.

image:
  repository: registry.example.com/tax-backend
  tag: "1.5.0"

Commit:

Update backend image to 1.5.0

Argo CD가 변경을 감지한다.

GitOps Repository
        ↓
      Argo CD
        ↓
       Sync
        ↓
 Kubernetes

20. CI에서 GitOps Repository 변경하기

GitHub Actions에서 이미지 빌드 후 GitOps Repository의 Image Tag를 변경하는 방법도 있다.

개념적으로는 다음과 같다.

- name: Build Docker Image
  run: |
    docker build -t registry.example.com/tax-backend:${GITHUB_SHA} .

- name: Push Image
  run: |
    docker push registry.example.com/tax-backend:${GITHUB_SHA}

- name: Update GitOps
  run: |
    sed -i \
      "s/tag:.*/tag: ${GITHUB_SHA}/" \
      values-prod.yaml

    git add values-prod.yaml
    git commit -m "Update backend image"
    git push

그러면 Kubernetes에 직접 kubectl apply를 하지 않는다.


21. 중요한 보안 구조

GitHub Actions에서 Kubernetes API에 직접 접근하지 않는 것도 중요한 장점이다.

전통적인 구조:

GitHub Actions
       │
       │ Kubeconfig
       ▼
Kubernetes API

이 구조에서는 CI 서버가 Kubernetes 접근 권한을 가져야 한다.

GitOps 구조:

GitHub Actions
       │
       ▼
GitOps Repository
       │
       ▼
Argo CD
       │
       ▼
Kubernetes

Argo CD가 Kubernetes 내부 또는 접근 가능한 위치에서 동작한다면 CI 시스템에 Kubernetes 관리자 권한을 직접 제공할 필요를 줄일 수 있다.


22. GitOps 운영 원칙

운영 환경에서는 다음 원칙을 권장한다.

개발자
  │
  ▼
Git
  │
  ▼
Pull Request
  │
  ▼
Code Review
  │
  ▼
Merge
  │
  ▼
Argo CD
  │
  ▼
Kubernetes

운영자가 직접 다음 명령을 실행하는 것은 최소화한다.

kubectl edit deployment

또는:

kubectl scale deployment ...

운영 변경은 가능하면 Git을 통해 수행한다.


23. Dev / Stage / Prod 환경 분리

실제 운영에서는 환경을 분리해야 한다.

예:

GitOps
│
├── dev
│   └── values.yaml
│
├── staging
│   └── values.yaml
│
└── production
    └── values.yaml

또는:

apps
└── tax-app
    ├── values-dev.yaml
    ├── values-stage.yaml
    └── values-prod.yaml

환경별 설정:

DEV

replicas = 1
CPU = 100m
Memory = 256Mi
STAGE

replicas = 2
CPU = 500m
Memory = 512Mi
PROD

replicas = 3
CPU = 1000m
Memory = 1Gi

24. Production 배포 승인

운영 환경에서는 모든 Git Commit이 즉시 Production에 반영되도록 하는 것이 항상 적절한 것은 아니다.

예를 들어:

DEV
 ↓
STAGE
 ↓
TEST
 ↓
PRODUCTION

Production은 Pull Request 승인 후 Merge하도록 구성할 수 있다.

Developer
    ↓
Pull Request
    ↓
Code Review
    ↓
Test
    ↓
Approval
    ↓
Merge
    ↓
Argo CD
    ↓
Production

이렇게 하면 변경 통제와 감사 추적이 쉬워진다.


25. Progressive Delivery

대규모 서비스에서는 새로운 버전을 한 번에 전체 Pod에 배포하지 않는 방식도 사용할 수 있다.

대표적으로:

Rolling Update
Blue/Green
Canary

등이 있다.

예를 들어 Canary 배포:

Version 1
████████████████████ 90%

Version 2
██                    10%

새 버전에서 문제가 없다면:

Version 1
██████████            50%

Version 2
██████████            50%

이후:

Version 2
████████████████████ 100%

이러한 Progressive Delivery는 Argo CD 생태계의 추가 도구들과 함께 구성할 수 있다.


26. 배포 후 Observability 검증

여기서 지금까지 구축한 Prometheus, Grafana, Loki, Tempo가 중요해진다.

단순히:

Argo CD = Synced

라고 해서 배포가 성공했다고 판단해서는 안 된다.

왜냐하면 Kubernetes Resource는 정상이어도 애플리케이션이 실제로 문제가 있을 수 있기 때문이다.

예:

Argo CD
Healthy
   ↓
Pod Running
   ↓
HTTP 500 증가

따라서 배포 이후에는 Observability 데이터로 실제 서비스 상태를 검증해야 한다.


27. Prometheus로 배포 상태 확인

배포 후 다음 지표를 확인할 수 있다.

CPU
Memory
Pod Restart
Request Rate
Error Rate
Latency
Availability

예를 들어 HTTP 5xx 비율을 확인할 수 있다.

sum(rate(http_requests_total{
  status=~"5.."
}[5m]))
/
sum(rate(http_requests_total[5m]))

배포 직후:

Error Rate

Before Deploy
0.2%

After Deploy
8.5%

이런 상황이라면 Argo CD에서는:

Healthy

라고 보여도 실제 서비스에는 문제가 발생한 것이다.


28. Grafana에서 배포 전후 비교

Grafana Dashboard를 이용해 다음과 같이 비교할 수 있다.

Deployment
     │
     ├── CPU
     ├── Memory
     ├── Request Rate
     ├── Error Rate
     ├── Latency
     └── Pod Restart

예를 들어:

                 Deploy
                   │
Error Rate ────────┼────────────
                   │
                   │      /^^^^^^
                   │     /
                   │____/

배포 시점을 기준으로 Error Rate가 증가했다면 애플리케이션 변경과 장애 사이의 상관관계를 확인할 수 있다.


29. Loki로 배포 후 로그 분석

Prometheus가 문제가 있다는 것을 알려줬다면 Loki에서는 실제 로그를 확인한다.

예:

{namespace="tax-prod", app="backend"}
|= "ERROR"

HTTP 500:

{namespace="tax-prod", app="backend"}
|= "500"

Exception:

{namespace="tax-prod", app="backend"}
|~ "Exception|Traceback"

예를 들어 다음 로그를 발견했다고 가정하자.

ERROR Database connection failed
ERROR psycopg2.OperationalError

그러면 다음과 같은 가설을 세울 수 있다.

Deployment
    ↓
Backend 1.5.0
    ↓
DB Connection Error
    ↓
HTTP 500
    ↓
Error Rate 증가

30. Tempo로 Trace 분석

로그만으로 원인을 찾기 어려운 경우 Tempo를 사용한다.

예를 들어 사용자의 요청:

GET /api/expenses

Trace:

HTTP Request
    │
    ▼
FastAPI
    │
    ├── authentication
    │
    ├── PostgreSQL
    │
    └── Redis

Trace ID:

4f7c8a...

각 Span의 시간을 확인할 수 있다.

HTTP Request       1200ms
 ├─ FastAPI          50ms
 ├─ PostgreSQL      950ms
 └─ Redis            20ms

그러면 PostgreSQL에서 지연이 발생하고 있다는 사실을 빠르게 확인할 수 있다.


31. Metrics + Logs + Traces 연결

실전 Observability에서는 세 가지 데이터를 연결해야 한다.

              ┌─────────────┐
              │ Prometheus  │
              │   Metrics   │
              └──────┬──────┘
                     │
                     ▼
                 Grafana
                     ▲
                     │
       ┌─────────────┼─────────────┐
       │             │             │
       ▼             ▼             ▼
  Prometheus        Loki         Tempo
    Metrics          Logs        Traces

예를 들어:

Alert
 ↓
Error Rate 증가
 ↓
Grafana
 ↓
Loki
 ↓
ERROR 로그 확인
 ↓
Trace ID 확인
 ↓
Tempo
 ↓
DB Query 지연 확인

이렇게 장애 분석 시간을 줄일 수 있다.


32. Argo CD + Observability 통합 구조

이제 중요한 부분이다.

배포 시스템과 관측 시스템을 하나의 흐름으로 연결한다.

Developer
    │
    ▼
Git
    │
    ▼
CI
    │
    ▼
Container Registry
    │
    ▼
GitOps Repository
    │
    ▼
Argo CD
    │
    ▼
Kubernetes
    │
    ├──────────────┐
    ▼              ▼
Application      Infrastructure
    │
    ▼
Observability
    │
 ┌──┼─────────┐
 ▼  ▼         ▼
Prometheus Loki      Tempo
 │      │           │
 └──────┼───────────┘
        ▼
      Grafana
        │
        ▼
   Alertmanager
        │
        ▼
 Slack / Email

33. 배포 장애 시나리오

실제 상황을 하나 만들어보자.

개발자가 FastAPI 코드를 수정했다.

Version 1.4.0
      ↓
Version 1.5.0

CI가 이미지를 만든다.

tax-backend:1.5.0

GitOps Repository가 변경된다.

image:
  tag: "1.5.0"

Argo CD가 자동 Sync한다.

Argo CD
Synced
Healthy

하지만 배포 후 문제가 발생한다.

HTTP 500
증가

Prometheus Alertmanager가 알림을 발생시킨다.

HighHTTP5xxRate

Slack:

[CRITICAL]
Backend HTTP 5xx rate exceeded threshold

운영자는 Grafana를 확인한다.

Error Rate
0.2%
   ↓
12.8%

Loki를 검색한다.

{app="backend"} |= "ERROR"

로그:

DatabaseError
relation "expense_items" does not exist

Tempo를 확인한다.

HTTP
 ↓
FastAPI
 ↓
PostgreSQL
 ↓
SQL Error

원인은 DB Migration 누락으로 판단할 수 있다.


34. 자동 복구를 연결할 때의 원칙

여기서 중요한 것은 모든 장애를 자동 복구하면 안 된다는 것이다.

예를 들어 Pod 하나가 죽었다.

Pod
 ↓
Crash

Kubernetes가 자동으로 재시작하는 것이 적절하다.

하지만 다음 상황은 다르다.

새로운 Application Version
        ↓
Database Schema Error
        ↓
HTTP 500 증가

이 경우 단순히 Pod를 계속 재시작하면 문제가 해결되지 않는다.

오히려:

Pod Restart
 ↓
Application Start
 ↓
DB Error
 ↓
Pod Restart
 ↓
DB Error

무한 반복이 될 수 있다.

따라서 자동화 수준을 구분해야 한다.


35. 자동 복구 Level

Level 1 — Kubernetes Self Healing

Pod 장애
 ↓
ReplicaSet
 ↓
Pod 재생성

자동화해도 좋다.


Level 2 — Application Restart

Liveness Probe 실패
 ↓
Container Restart

자동화 가능하다.


Level 3 — HPA

CPU 증가
 ↓
HPA
 ↓
Replica 증가

자동화 가능하다.


Level 4 — Rollback

Deployment
 ↓
Error Rate 증가
 ↓
자동 Rollback

운영 환경에서는 매우 신중하게 설계해야 한다.


Level 5 — Database 변경

DB Migration

이것은 자동화 전에 반드시 충분한 검증과 승인 절차가 필요하다.


36. Argo CD Rollback

Argo CD에서는 배포 History를 확인할 수 있다.

argocd app history tax-app

이전 Revision으로 되돌리는 방식도 사용할 수 있다.

argocd app rollback tax-app <ID>

하지만 GitOps 환경에서는 단순히 Kubernetes 상태만 이전으로 돌리는 것보다 Git의 선언 상태를 되돌리는 방식을 운영 원칙으로 삼는 것이 좋다.

예:

Git
1.5.0
 ↓
revert
 ↓
1.4.0
 ↓
Argo CD
 ↓
Kubernetes

이렇게 하면 Git과 실제 클러스터 상태가 일치한다.


37. GitOps와 자동 복구의 관계

여기서 매우 중요한 차이가 있다.

Kubernetes Self-Healing:

Runtime State 복구

Argo CD Self-Healing:

Configuration Drift 복구

예:

Pod 죽음
    ↓
Kubernetes
    ↓
Pod 재생성

반면:

Deployment replicas 변경
    ↓
Argo CD
    ↓
Git 상태로 복구

둘은 서로 다른 문제를 해결한다.


38. SRE 관점의 전체 장애 대응

이제 앞서 만든 SRE 체계와 연결해보자.

                    Incident
                       │
                       ▼
               Alertmanager
                       │
                       ▼
                    Grafana
                       │
            ┌──────────┼──────────┐
            ▼          ▼          ▼
        Metrics       Logs      Traces
        Prometheus    Loki       Tempo
            │          │          │
            └──────────┼──────────┘
                       ▼
                  Root Cause
                       │
                       ▼
                 Git Repository
                       │
                       ▼
                    Fix PR
                       │
                       ▼
                     CI
                       │
                       ▼
                  GitOps Merge
                       │
                       ▼
                    Argo CD
                       │
                       ▼
                 Kubernetes
                       │
                       ▼
                 Self Healing

이 구조에서는 장애 대응 자체가 다시 GitOps 프로세스로 연결된다.


39. GitOps에서 중요한 보안

GitOps 환경에서는 Git Repository가 사실상 운영 인프라의 중요한 관리 지점이 된다.

따라서 다음을 반드시 고려해야 한다.

Repository 접근 권한

Developer
 ↓
Read / PR
DevOps
 ↓
Write

Production 설정은 제한한다.


Secret 관리

Password나 API Key를 Git에 평문으로 저장하면 안 된다.

잘못된 예:

password: mypassword123

대신 다음과 같은 방식을 고려할 수 있다.

External Secrets
Sealed Secrets
Vault
Cloud Secret Manager

Git에는 실제 Secret 대신 참조 정보만 저장한다.


40. Argo CD RBAC

Argo CD 역시 사용자별 권한을 분리할 수 있다.

예:

Admin
 ├── Application 생성
 ├── Sync
 ├── Delete
 └── 변경

Developer
 ├── Application 조회
 └── 로그/상태 확인

Viewer
 └── Read Only

운영 환경에서는 최소 권한 원칙을 적용하는 것이 중요하다.


41. Kubernetes RBAC까지 연결

Argo CD가 Kubernetes에 접근하기 때문에 Argo CD Service Account의 권한도 중요하다.

구조:

Argo CD
   │
   ▼
ServiceAccount
   │
   ▼
RBAC
   │
   ▼
Kubernetes API

필요하지 않은 Cluster Admin 권한을 무조건 부여하지 않는 것이 좋다.


42. GitOps에서 하지 말아야 할 것

다음과 같은 운영 습관은 피하는 것이 좋다.

kubectl edit deployment
kubectl patch deployment ...
kubectl scale deployment ...

그리고 Git에 기록하지 않는 변경:

Manual kubectl
      ↓
Kubernetes 변경
      ↓
Git에는 없음

이 상태가 반복되면 GitOps의 의미가 사라진다.


43. GitOps 운영의 핵심 규칙

운영 변경:

Issue
 ↓
PR
 ↓
Review
 ↓
Merge
 ↓
Argo CD
 ↓
Kubernetes

긴급 장애 상황에서는 직접 조치할 수 있지만 이후 반드시 Git에 변경사항을 반영해야 한다.

즉:

Emergency Change
       ↓
Temporary Runtime Fix
       ↓
Git Update
       ↓
Reconciliation

이라는 원칙을 유지하는 것이 좋다.


44. 배포 성공 조건을 정의한다

실전 DevOps에서는 "Pod가 Running이면 배포 성공"이라고 판단하지 않는다.

배포 성공 조건을 여러 단계로 나눈다.

1. Git Sync
      ↓
2. Kubernetes Resource Healthy
      ↓
3. Pod Ready
      ↓
4. HTTP Health Check
      ↓
5. Error Rate 정상
      ↓
6. Latency 정상
      ↓
7. Logs 정상
      ↓
8. Trace 정상
      ↓
9. Deployment Success

이것이 Observability 기반 배포 검증이다.


45. Deployment Verification

예를 들어 다음 기준을 만들 수 있다.

Deployment Success

Argo CD
= Synced

AND

Health
= Healthy

AND

Ready Pods
= Desired Pods

AND

HTTP 5xx
< 1%

AND

P95 Latency
< 500ms

이러한 기준을 기반으로 배포 자동화를 설계할 수 있다.


46. Prometheus Alert와 배포 검증

예를 들어 배포 직후 다음 Alert를 사용할 수 있다.

groups:
  - name: application

    rules:

      - alert: HighHTTP5xxRate

        expr: |
          (
            sum(rate(http_requests_total{
              status=~"5.."
            }[5m]))
            /
            sum(rate(http_requests_total[5m]))
          ) > 0.05

        for: 5m

        labels:
          severity: critical

        annotations:
          summary: "HTTP 5xx rate is high"

5분 이상 5xx가 5%를 초과하면 장애 알림을 발생시킬 수 있다.


47. 자동 Rollback 설계

자동 Rollback은 다음과 같은 구조로 생각할 수 있다.

New Version
     ↓
Argo CD Deploy
     ↓
Wait
     ↓
Prometheus Metrics
     ↓
Error Rate?
     │
 ┌───┴────┐
 │        │
No       Yes
 │        │
 ▼        ▼
Success  Rollback

하지만 실제 운영에서는 단순 Alert 발생만으로 Rollback을 결정하기보다 다음 조건을 함께 고려하는 것이 좋다.

Error Rate
+
Latency
+
Availability
+
Pod Restart
+
Business Metrics

그리고 DB Migration이나 비가역적인 데이터 변경이 포함된 배포는 자동 Rollback과 충돌할 수 있으므로 별도의 전략이 필요하다.


48. GitOps + Observability + SRE

이제 전체 시스템을 SRE 관점에서 정리할 수 있다.

                    Git
                     │
                     ▼
                    CI
                     │
              ┌──────┴──────┐
              ▼             ▼
          Test/Build     Security
              │
              ▼
          Container
           Registry
              │
              ▼
          GitOps Repo
              │
              ▼
           Argo CD
              │
              ▼
         Kubernetes
              │
       ┌──────┼──────┐
       ▼      ▼      ▼
    Metrics  Logs   Traces
       │      │      │
       ▼      ▼      ▼
 Prometheus  Loki   Tempo
       └──────┼──────┘
              ▼
           Grafana
              │
              ▼
        Alertmanager
              │
         ┌────┴────┐
         ▼         ▼
       Slack      Email

여기에 자동 복구를 추가한다.

Alert
  ↓
Analysis
  ↓
Automation
  ↓
Recovery
  ↓
Verification

49. 실제 운영 장애 시나리오

다음과 같은 상황을 생각해보자.

Step 1. 개발자가 코드 변경

FastAPI 1.5.0

Step 2. CI

Test
 ↓
Build
 ↓
Docker Image
 ↓
Registry

Step 3. GitOps 변경

image:
  tag: "1.5.0"

Step 4. Argo CD

OutOfSync
 ↓
Sync
 ↓
Progressing
 ↓
Healthy

Step 5. Prometheus

HTTP 500 증가

Step 6. Alertmanager

HighHTTP5xxRate

Step 7. Grafana

Error Rate ↑
Latency ↑

Step 8. Loki

DatabaseError

Step 9. Tempo

FastAPI
   ↓
PostgreSQL
   ↓
SQL Error

Step 10. Root Cause

Database migration 누락

Step 11. Git 수정

Migration 추가

Step 12. CI 재실행

Test
 ↓
Build
 ↓
Image

Step 13. GitOps 업데이트

1.5.1

Step 14. Argo CD

Sync

Step 15. Observability 검증

5xx ↓
Latency ↓
Logs 정상
Trace 정상

Step 16. 장애 종료

Incident
   ↓
Recovery
   ↓
Verification
   ↓
Postmortem

이것이 실제 SRE 운영 프로세스에 가까운 구조다.


50. Postmortem까지 연결

장애가 끝났다고 운영이 끝나는 것은 아니다.

장애 기록을 남긴다.

Incident ID
INC-2026-001

발생 시간

2026-09-16 10:30

영향

API 5xx 증가

원인

DB Migration 누락

탐지

Prometheus

분석

Grafana
Loki
Tempo

복구

Git Fix
Argo CD Deployment

개선

CI Migration Test 추가
Deployment Verification 추가

이런 Postmortem이 반복되면 운영 시스템 자체가 점점 개선된다.


51. 최종적으로 구축되는 DevOps 플랫폼

지금까지 배운 기술을 하나로 연결하면 다음과 같다.

                   Developer
                       │
                       ▼
                  Git Repository
                       │
                       ▼
                GitHub Actions
                       │
                ┌──────┴──────┐
                ▼             ▼
             Test          Build
                              │
                              ▼
                       Container Image
                              │
                              ▼
                     Container Registry
                              │
                              ▼
                        GitOps Repo
                              │
                              ▼
                           Argo CD
                              │
                              ▼
                       Kubernetes
                              │
              ┌───────────────┼───────────────┐
              │               │               │
              ▼               ▼               ▼
           FastAPI          Redis         PostgreSQL
              │
              ▼
        ┌────────────────────────┐
        │     Observability      │
        ├────────────────────────┤
        │ Prometheus             │
        │ Grafana                │
        │ Loki                   │
        │ Tempo                  │
        │ Alertmanager           │
        └────────────┬───────────┘
                     │
                     ▼
              Slack / Email
                     │
                     ▼
              Incident Response
                     │
                     ▼
                Auto Recovery
                     │
                     ▼
                  Git Fix
                     │
                     ▼
                  Argo CD

52. CI/CD → GitOps → Observability → 자동 복구

전체 시스템을 한 문장으로 표현하면 다음과 같다.

코드를 변경한다
     ↓
CI가 테스트한다
     ↓
Container Image를 만든다
     ↓
Registry에 저장한다
     ↓
GitOps Repository의 배포 설정을 변경한다
     ↓
Argo CD가 변경을 감지한다
     ↓
Kubernetes에 배포한다
     ↓
Prometheus가 Metrics를 수집한다
     ↓
Grafana에서 상태를 확인한다
     ↓
Loki에서 로그를 분석한다
     ↓
Tempo에서 Trace를 분석한다
     ↓
Alertmanager가 장애를 알린다
     ↓
Kubernetes가 가능한 장애를 자동 복구한다
     ↓
필요하면 Git 변경으로 근본 원인을 수정한다
     ↓
Argo CD가 다시 배포한다
     ↓
Observability로 정상 상태를 검증한다

이렇게 연결하면 단순한 Kubernetes 클러스터가 아니라 운영 자동화 플랫폼이 된다.


53. 시스템 엔지니어 관점에서 반드시 이해해야 할 것

Argo CD를 단순히 "Kubernetes 배포 도구"로 이해하면 부족하다.

중요한 개념은 다음과 같다.

기술 핵심 역할
Git Desired State 저장
GitHub Actions CI / Build / Test
Registry Container Image 저장
Helm Kubernetes 패키징
Argo CD Git → Kubernetes 동기화
Kubernetes 실제 애플리케이션 실행
Prometheus Metrics
Grafana Visualization
Loki Logs
Tempo Traces
Alertmanager Alert Routing
Kubernetes Self-Healing Runtime 복구
GitOps Self-Healing Configuration Drift 복구
SRE 전체 운영 방법론

특히 다음 세 가지는 구분해야 한다.

Kubernetes
= 서비스를 실행한다

Argo CD
= 원하는 상태를 유지한다

Observability
= 실제 상태를 관찰한다

그리고 이 세 가지가 연결되면서 자동화 수준이 올라간다.


54. 최종 운영 구조

최종적으로 우리가 만들고 있는 Kubernetes 운영 환경은 다음과 같다.

                    ┌─────────────┐
                    │   Developer │
                    └──────┬──────┘
                           │
                           ▼
                    ┌─────────────┐
                    │     Git     │
                    └──────┬──────┘
                           │
                           ▼
                    ┌─────────────┐
                    │     CI      │
                    │ Test / Build│
                    └──────┬──────┘
                           │
                           ▼
                    ┌─────────────┐
                    │   Registry  │
                    └──────┬──────┘
                           │
                           ▼
                    ┌─────────────┐
                    │   GitOps    │
                    │ Repository  │
                    └──────┬──────┘
                           │
                           ▼
                    ┌─────────────┐
                    │   Argo CD   │
                    └──────┬──────┘
                           │
                           ▼
                 ┌────────────────────┐
                 │     Kubernetes     │
                 └─────────┬──────────┘
                           │
              ┌────────────┼────────────┐
              │            │            │
              ▼            ▼            ▼
           Metrics        Logs        Traces
              │            │            │
              ▼            ▼            ▼
         Prometheus       Loki         Tempo
              │            │            │
              └────────────┼────────────┘
                           ▼
                        Grafana
                           │
                           ▼
                     Alertmanager
                           │
                    ┌──────┴──────┐
                    ▼             ▼
                  Slack         Email
                    │
                    ▼
               Incident
                Response
                    │
                    ▼
              Auto Recovery
                    │
                    ▼
                  Git Fix
                    │
                    └──────────────► Argo CD

이 구조를 이해하면 Kubernetes를 단순히 "Pod를 실행하는 기술"로 보는 단계에서 벗어나 애플리케이션의 배포, 운영, 모니터링, 장애 대응, 복구까지 자동화하는 플랫폼으로 이해할 수 있다.


55. 마무리

Kubernetes 운영 자동화의 핵심은 특정 도구 하나를 설치하는 것이 아니다.

중요한 것은 각 기술의 역할을 연결하는 것이다.

Git
 ↓
CI
 ↓
Container
 ↓
Registry
 ↓
GitOps
 ↓
Argo CD
 ↓
Kubernetes
 ↓
Prometheus
 ↓
Grafana
 ↓
Loki
 ↓
Tempo
 ↓
Alertmanager
 ↓
자동 복구
 ↓
Postmortem
 ↓
Git 개선

이 구조에서는 사람이 모든 작업을 직접 수행하지 않는다.

사람은 코드와 운영 정책을 Git에 선언하고, 시스템은 그 선언된 상태를 기반으로 배포하고 관찰하고 복구한다.

결국 목표는 다음과 같다.

"운영자가 서버에 접속해서 명령을 실행하는 환경"에서 "Git에 변경을 기록하면 플랫폼이 배포·검증·관찰·복구하는 환경"으로 전환하는 것

이것이 Kubernetes 기반 GitOps + Observability + SRE 운영 체계의 핵심이다.


댓글