Files
project-infra/docs/standards/infra/operations-runbook-upgrade-rollback.md
T

12 KiB

operations / runbook / upgrade / rollback 기준

목적

이 문서는 1000+ 서비스를 운영하는 플랫폼에서 모든 변경이 거쳐야 하는 runbook 규칙을 고정한다. GitOps 원본, rolling update 파라미터 튜닝, 진보된 배포 전략 (Argo Rollouts, canary, blue/green), K3s 자동 업그레이드, node 작업(drain/cordon), rollback 의미와 경계가 대상이다.

공식 / 업계 근거

  • Kubernetes Deployment.spec.strategy: RollingUpdate (default, maxSurge/maxUnavailable 25%/25%) 또는 Recreate (singleton).
  • kubectl rollout: status --timeout, history, undo --to-revision, pause, resume, restart.
  • Argo Rollouts (https://argoproj.github.io/argo-rollouts/): Rollout CRD가 Deployment의 대체제로 canary / blueGreen 지원. AnalysisTemplate + Prometheus metric으로 자동 승격/롤백.
  • Flagger: Argo Rollouts의 대안, service-mesh 친화적 (Istio/Linkerd/App Mesh).
  • ArgoCD: sync wave (argocd.argoproj.io/sync-wave: "<int>"), sync phase hook (PreSync, Sync, PostSync, SyncFail, PostDelete).
  • Flux: Kustomization.spec.dependsOn 으로 순서 명시.
  • kubectl drain --ignore-daemonsets --delete-emptydir-data --grace-period=30 가 node maintenance 표준. PDB를 존중하므로 PDB 설계가 전제.
  • K3s System Upgrade Controller (https://docs.k3s.io/upgrades/automated): Plan CRD로 server-plan / agent-plan 분리, concurrency 제어, nodeSelector로 대상 제한.
  • Flyway validate, info, migrate — application rollout 과 분리.

기본 규칙

1. Source of truth = Git 의 Kustomize / Helm overlay

운영 변경은 Git에 있는 선언형 원본에서만 시작한다.

기본 금지:

  • 운영 노드에서 manifest 파일 직접 편집.
  • kubectl edit 로 live object 수정 후 문서 없음.
  • /var/lib/rancher/k3s/server/manifests 를 1차 원본처럼 사용.

2. 변경 절차는 render → diff → apply → status → post-check 로 고정

1. kubectl kustomize <overlay>        # render
2. kubectl diff -k <overlay>          # preview
3. kubectl apply -k <overlay>         # apply
4. kubectl rollout status ... --timeout=10m
5. post-check (smoke test, SLO check)

diff 없는 apply 는 프로덕션 금지.

3. rollingUpdate.maxSurge / maxUnavailable 는 워크로드별 튜닝

기본값 25% / 25%replica 수에 따라 틀릴 수 있다.

  • replica 2: default는 maxUnavailable 0, maxSurge 1 추천 → 항상 최소 2 유지 + 1 추가.
  • replica 3: maxSurge: 1, maxUnavailable: 0 → 가용성 우선.
  • replica 10+: maxSurge: 25%, maxUnavailable: 10% → 속도와 가용성 균형.
  • latency-sensitive: maxUnavailable: 0 고정.
  • cost-sensitive large fleet: maxSurge: 10%, maxUnavailable: 10%.

4. Recreate 전략은 singleton / 동시성 금지 워크로드에만

  • PVC ReadWriteOnce + 단일 pod 가 전제인 app (legacy MySQL single instance 등).
  • Old/New 동시 실행 시 데이터 부정합이 나는 앱.
  • 짧은 downtime이 허용되는 경우.

일반 stateless app은 절대 Recreate 쓰지 않는다.

5. kubectl rollout 명령 계열

  • kubectl rollout status deployment/<name> --timeout=10m: 타임아웃 필수.
  • kubectl rollout history deployment/<name>: revision 확인.
  • kubectl rollout undo deployment/<name> --to-revision=<N>: 이전 revision으로 되돌림.
  • kubectl rollout pause deployment/<name>: 롤아웃 중단 (부분 적용 뒤 관찰용).
  • kubectl rollout resume deployment/<name>: 재개.
  • kubectl rollout restart deployment/<name>: 이미지 변경 없이 Pod 재생성 (secret 갱신 후 등).

6. 진보된 배포 전략: Argo Rollouts (canary / blueGreen)

표준 Deployment 로는 부족한 경우 (자동화된 canary, metric-based 승격) 에는 Argo Rollouts 의 Rollout CRD 를 쓴다.

  • canary: steps: 로 traffic %, pause, analysis 순서 기술.
  • blueGreen: activeService / previewService 로 서비스 두 개 전환.
  • AnalysisTemplate: Prometheus query로 success rate / p99 latency 측정 → 자동 promote or abort.
  • 대안 Flagger: Istio / Linkerd / App Mesh + Flagger Canary CRD. service mesh 있는 플랫폼에서 선택.

7. Argo Rollouts 기본 canary 스텝

steps:
  - setWeight: 10
  - pause: { duration: 2m }
  - analysis: { templates: [{ templateName: success-rate }] }
  - setWeight: 25
  - pause: { duration: 5m }
  - analysis: { templates: [...] }
  - setWeight: 50
  - pause: { duration: 10m }
  - setWeight: 100

각 setWeight 사이에 pause + analysis 로 자동 abort gate.

8. blueGreen 은 traffic cutover 가 필요한 경우만

blueGreen은:

  • schema 변경이 양립 불가해서 instant cutover가 필요.
  • 외부 system 과 coordination 필요 (rollback도 instant).

일반 변경은 canary 가 우선. blueGreen 은 trade-off (리소스 2배, warm-up 부담) 때문에 default 가 아니다.

9. ArgoCD sync wave / hook

배포 순서는 sync wave annotation 으로 명시한다.

  • argocd.argoproj.io/sync-wave: "-2" → CRD.
  • argocd.argoproj.io/sync-wave: "-1" → namespace, secret store, operator.
  • argocd.argoproj.io/sync-wave: "0" → 본 리소스 (기본).
  • argocd.argoproj.io/sync-wave: "1" → Ingress, post-deploy job.

hook:

  • PreSync: schema migration job.
  • Sync: 본 리소스 (default).
  • PostSync: smoke test Job, cache warm.
  • SyncFail: 실패 시 알림 Job.
  • PostDelete: 삭제 후 cleanup.

10. Flux Kustomization dependsOn

Flux 플랫폼에서는 Kustomization.spec.dependsOn 으로 순서를 명시한다.

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: auth-server
  namespace: flux-system
spec:
  interval: 5m
  path: ./k8s/overlays/prod
  prune: true
  sourceRef:
    kind: GitRepository
    name: platform
  dependsOn:
    - name: cert-manager
    - name: postgres-operator

11. node 작업 (drain / cordon) 은 PDB 존중 흐름

1. kubectl cordon <node>
2. kubectl drain <node> \
     --ignore-daemonsets \
     --delete-emptydir-data \
     --grace-period=30 \
     --timeout=10m
3. 작업 수행
4. kubectl uncordon <node>

옵션 의미:

  • --ignore-daemonsets: DaemonSet pod는 evict 대상이 아님.
  • --delete-emptydir-data: ephemeral 데이터 수용.
  • --grace-period=30: preStop + terminationGracePeriod 존중.
  • --timeout=10m: PDB 로 인한 무한 대기 차단.

PDB 없는 critical workload 는 drain 실패 또는 downtime 유발. PDB 설계가 선결 조건.

12. K3s System Upgrade Controller

K3s 자동 업그레이드는 system-upgrade-controllerPlan CRD 를 쓴다.

구성:

  • server-plan: control-plane 먼저 업그레이드. concurrency: 1, nodeSelector: node-role.kubernetes.io/control-plane=true.
  • agent-plan: agent 노드. concurrency: 1~N (small cluster는 1), server-plan 완료 후.
  • cordon: true, drain.force: true, deleteEmptydirData: true, ignoreDaemonsets: true 표준.
  • version: 또는 channel: 로 target K3s version.
  • upgrade.image: rancher/k3s-upgrade + 버전 tag.

13. blue/green via two Services (수동 패턴)

Argo Rollouts 없이 간단 blue/green 이 필요하면:

  • Deployment A (blue), Deployment B (green) 각각.
  • Service selector 의 version label 만 전환 (blue → green).
  • rollback = selector 를 다시 blue 로.
  • canary 는 이 방식으로 구현하지 않는다 (Argo Rollouts 사용).

14. Rollback 은 DB rollback 이 아니다

가장 자주 오해되는 규칙. 반드시 내재화한다.

  • kubectl rollout undo 는 Deployment workload 만 되돌린다.
  • DB schema 변경 / migration 은 되돌아가지 않는다.
  • rollback 설계는 schema-forward-compatible 로 한다:
    • Expand (schema 추가 → 이전 코드도 호환) → Migrate (데이터 이전) → Contract (이전 코드용 schema 제거). Expand/Contract를 별도 릴리스로 분리.
  • 긴급 상황에서도 rollout undo 로 DB 를 되돌릴 수 없다. DB 는 별도 restore 절차 (PITR, snapshot).

15. Flyway validate → migrate 를 application rollout 과 분리

1. flyway validate         # checksum / 순서 확인
2. flyway info             # 대기 migration 확인
3. flyway migrate          # 실제 적용
4. kubectl apply -k ...    # app rollout (별도 단계)
5. kubectl rollout status  # 앱 기동 확인

application startup 안에 migration 을 숨기지 않는다 (rollout 실패와 migration 실패 섞임).

16. restore 와 rollout 구분

rollout (workload 변경 되돌리기):

  • kubectl rollout undo 또는 이전 Git revision apply.
  • Deployment / StatefulSet / DaemonSet 대상.

restore (상태 복구):

  • K3s control plane → etcd snapshot restore.
  • PostgreSQL → PITR / base backup + WAL.
  • Vault → raft snapshot restore.
  • MinIO → replication resync 또는 DR site cutover.

서로 다른 runbook 이다. "rollback" 이라는 한 단어로 뭉치지 않는다.

17. 긴급 변경도 runbook 을 벗어나지 않음

장애 대응 hot-fix 라도:

  • 어떤 overlay 를 바꿨는지 commit / PR.
  • 어떤 명령을 실행했는지 기록 (shell history / runbook log).
  • 사후 Git 반영 (live-cluster drift 제거).
  • 임시 조치의 만료 / 정리 시점 기록.

18. destructive 작업은 명시 승인 + 증거 보존

요구 작업:

  • namespace 삭제.
  • PVC 삭제.
  • StatefulSet 삭제 + PVC 정리.
  • K3s snapshot restore.
  • Vault raft snapshot restore.
  • DB restore overwrite.
  • MinIO bucket purge / replication cutover.

규칙:

  • 2-person approval.
  • 작업 전 full snapshot 확보.
  • dry-run / diff 선행.
  • post-mortem 작성.

권장 절차 템플릿

일반 app 변경

  1. PR 생성 + review
  2. kubectl kustomize <overlay> → 렌더 검증
  3. kubectl diff -k <overlay> → 변경 확인
  4. kubectl apply -k <overlay>
  5. kubectl rollout status deployment/<name> --timeout=10m
  6. smoke test + SLO dashboard 확인
  7. 결과 PR comment

DB migration 포함 변경

  1. migration SQL review
  2. flyway validateflyway infoflyway migrate
  3. app overlay apply
  4. kubectl rollout status
  5. post-check
  6. 실패 시 DB runbook 과 app rollback runbook 분리 적용

K3s control plane upgrade

  1. 해당 버전 release notes / caveat 확인
  2. etcd snapshot 확보
  3. Plan CRD apply (server-plan)
  4. control-plane 업그레이드 완료 확인
  5. Plan CRD apply (agent-plan)
  6. agent 업그레이드 완료 확인
  7. packaged component 영향 확인
  8. 실패 시 etcd restore runbook

node maintenance

  1. kubectl cordon <node>
  2. kubectl drain <node> --ignore-daemonsets --delete-emptydir-data --grace-period=30 --timeout=10m
  3. 작업 수행
  4. kubectl uncordon <node>
  5. kubectl get pods -o wide 로 재배치 확인

프로젝트 기준 요약

  • source of truth = Git Kustomize/Helm overlay, live-cluster 수정 금지.
  • render → diff → apply → rollout status → post-check 순서 고정.
  • rollingUpdate 파라미터는 워크로드별 튜닝, default 25%/25% 맹신 금지.
  • Argo Rollouts 로 canary + AnalysisTemplate 자동 gate, Flagger 는 mesh 환경 대안.
  • ArgoCD sync wave / hook, Flux dependsOn 으로 순서 명시.
  • node 작업은 PDB 존중 drain 흐름, PDB 설계가 선결.
  • K3s 업그레이드는 System Upgrade Controller Plan CRD (server → agent).
  • blue/green 은 cutover 필요 시, canary 가 default.
  • rollback 은 DB rollback 이 아니다 — schema-forward-compatible 로 설계.
  • Flyway validate/migrate 는 application rollout 과 분리.
  • restore 와 rollout 은 다른 runbook.
  • destructive 작업은 2-person approval + snapshot.