GitOps & Progressive Delivery
Git 저장소를 인프라의 단일 진실 공급원(SSOT)으로 삼아 자동으로 동기화하고, 트래픽을 점진적으로 노출하며 리스크를 수치적으로 통제하는 현대적 배포 공학을 다루는 학습 노드입니다.
Article
M
Me
hyunyoun's Blog
software-engineering-devopssoftware-engineeringdev-opsreliabilitycdgit-opsprogressive-deliverydelivery11 min read
1. Overview
GitOps와 점진적 배포(GitOps & Progressive Delivery)는 배포 파이프라인(Jenkins)이 서버에 코드를 밀어 넣는(Push) 폭력적인 방식을 버리고, 서버가 직접 Git 저장소를 감시하다가 코드가 바뀌면 스스로 자신의 상태를 동기화(Pull)하는 자율 주행 인프라의 물리학을 해부합니다.
학습자는 누가 언제 AWS 콘솔을 건드렸는지 모르는 깜깜이 인프라를 타파하고, 오직 Git 커밋(Commit)만이 인프라를 변경하는 유일한 합법적 수단이 되는 GitOps의 단일 진실 원천(Single Source of Truth)을 뜯어봅니다. 나아가 Kubernetes 안에서 작동하는 ArgoCD 같은 에이전트(Agent)가 어떻게 Git 상태와 현재 서버 상태의 오차(Drift)를 실시간으로 교정(Reconciliation)하는지 장악합니다. 마지막으로, 트래픽을 1%, 10%, 100%로 쪼개며 에러율이 치솟으면 기계가 0.1초 만에 배포를 롤백해 버리는 점진적 배포(Progressive Delivery) 역량을 확보합니다.
2. Scope & Boundaries
In-Scope
- GitOps Principles: 선언적(Declarative), 버전 관리됨(Versioned), 자동 승인(Pulled), 지속적 조정(Reconciliation).
- Push vs Pull Deployment: CI 서버가 클러스터를 직접 찌르는 구조(Push)와 클러스터 내부의 봇이 Git을 쳐다보는 구조(Pull)의 차이 및 보안.
- Progressive Delivery: 카나리아 배포(Canary), A/B 테스팅, 피처 플래그(Feature Flags)를 통한 런타임 통제.
- Reconciliation Loop: Git 저장소의 매니페스트(Desired State)와 쿠버네티스의 현재 상태(Actual State) 간의 오차를 0으로 맞추는 무한 루프.
Out-of-Scope
- 쿠버네티스(Kubernetes) 컴포넌트 심층 구조: Pod, Deployment, Service의 구체적 YAML 작성법 07. Cloud & System Architecture 계층이나 K8s 전문 모듈로 위임.
- ArgoCD / Flux 설치 및 CLI 명령어: 특정 툴의 설치법 툴 종속적 내용이므로 본 문서에서는 'Reconciliation'이라는 공학적 매커니즘에 집중함.
Boundaries
- CI/CD vs GitOps: 전통적인 CI/CD는 젠킨스(Jenkins) 신(God)이 모든 권력을 쥡니다. 빌드도 하고(CI), 실서버 DB 비밀번호를 들고 100대의 서버에
ssh로 찔러 넣기도(CD) 합니다. 해커가 젠킨스를 털면 회사가 망합니다. 반면 GitOps는 젠킨스의 손발을 자릅니다. 젠킨스는 도커 이미지(Artifact)만 굽고 퇴근합니다. 배포(CD)는 쿠버네티스 '안에' 숨어있는 요원(ArgoCD)이 Git(선언서)을 읽고 '스스로' 다운받아 적용합니다. 외부망에서 내부망을 찌를 수 없는 완벽한 방화벽(Security Boundary)의 역전에 명확한 선을 긋습니다.
3. Counterexample
- 드리프트(Drift)의 공포: 금요일 밤, 서버 하나가 자꾸 죽어서 급한 마음에 시니어 개발자가
kubectl edit명령어로 쿠버네티스 메모리 제한을 1GB에서 4GB로 늘려놨습니다(수동 조작). 문제는 해결됐지만, 아무도 이걸 문서에 안 적었습니다. 다음 주, 주니어 개발자가 Git에 있는 원래 YAML 코드(1GB)를 배포 파이프라인에 태워 배포했습니다. 서버 메모리가 다시 1GB로 덮어씌워지며 월요일 아침 서비스가 대폭발합니다. Git 저장소와 실서버의 상태가 엇갈리는(State Drift) 야만적인 수동 조작의 결말입니다. - 무지성 빅뱅 배포 (All-or-Nothing): 새 추천 알고리즘을 배포합니다. 한방에 100% 유저에게 오픈했습니다(빅뱅). 그런데 알고리즘에 메모리 누수 버그가 있어 5분 만에 서버 전체가 OOM(Out of Memory)으로 죽었습니다. 점진적 배포(Canary)를 써서 단 1%의 유저(탄광 속 카나리아)에게만 먼저 오픈하고, 에러율(500 Http Code)이 치솟을 때 기계가 자동으로 배포를 중단(Auto-Rollback)하게 만들지 않은, 오만의 대가입니다.
4. Prerequisites
- IaC와 선언형 상태 (Basic): 멱등성과 드리프트 방어 개념. (09-05-01-03 IaC)
- 도커와 불변 아티팩트 (Basic): 배포 이미지는 절대 런타임에 변하지 않음. (09-05-01-02 Artifacts)
5. Learning Map
6. Learning Topics
Basic
Core Topic 01: 단일 진실 공급원의 4대 헌법 (The 4 Principles of GitOps)
- Why to Learn: "현재 우리 서버에 배포된 버전이 뭐지? 설정 파일은 어디 있지?"라며 퇴사자 자리를 뒤지는 수사 극을 끝내고, 오직 Git 리포지토리 하나만 보면 서버의 100% 진실을 알 수 있게 하기 위함입니다.
- What to Learn:
- Concepts: GitOps 4원칙 (Declarative, Versioned/Immutable, Pulled Automatically, Continuously Reconciled), Single Source of Truth (단일 진실 원천).
- Skills: 시스템의 모든 껍데기(아키텍처, 네트워크, 리소스 제한)를
yaml파일로 작성(Declarative)하여 Git에 올리고(Versioned), 어떤 변경이든 오직git commit과PR(Pull Request)을 통해서만 이루어지는 거버넌스 구축하기.
- How to Learn:
- 1단계: 선언 (Declarative): 스크립트(
sh)가 아닙니다. "DB 1대, 웹 2대"라는 최종 상태(yaml)입니다. - 2단계: 버전 (Versioned): 이 선언문은 반드시 Git에 올라가야 합니다. 누가, 언제, 왜 인프라를 바꿨는지
git log에 영원히 박제됩니다. - 3단계: 자동 당기기 (Pulled): 서버가 알아서 Git을 보고 당겨옵니다.
- 4단계: 지속적 교정 (Reconciled): 서버가 1초마다 Git과 자신을 비교하며 똑같은 상태를 유지하려 발악합니다. 이 4박자가 맞아떨어질 때, Git이 곧 "인프라의 신(God)"이자 유일한 진실(Truth)로 등극하는 아키텍처를 해부합니다.
- 1단계: 선언 (Declarative): 스크립트(
- Implement: 인프라 복구(Disaster Recovery) 시뮬레이터.
상황: AWS 도쿄 리전(Region) 전체가 지진으로 폭발. 수백 대의 서버 완전 증발.GitOps 복구: 싱가포르 리전에 빈 쿠버네티스 클러스터를 띄움 ArgoCD 에이전트 설치 Git 리포지토리 URL 1개 던져줌.결과: 에이전트가 Git을 읽고 단 10분 만에 도쿄 리전과 100% 똑같은 DB, 네트워크, 권한 설정을 자동 렌더링(복구). 완벽한 재난 복구(DR) 시각화.
Recommended
Core Topic 02: 방화벽을 뚫지 마라, Push vs Pull (Security Inversion)
- Why to Learn: 만능 열쇠(클러스터 Admin 권한)를 쥔 젠킨스(Jenkins) 서버가 해킹당했을 때, 회사 내부망 전체가 해커의 놀이터가 되는 끔찍한 단일 장애점(SPOF)을 제거하기 위함입니다.
- What to Learn:
- Concepts: Push Deployment (전통적 CI/CD), Pull Deployment (GitOps), Control Plane Security, Least Privilege (최소 권한의 원칙).
- Skills: Jenkins가 쿠버네티스를 향해
kubectl apply를 쏘게 놔두는 멍청한 파이프라인(Push)을 버리고, 쿠버네티스 안쪽에 위치한 ArgoCD가 외부 인터넷(GitHub)을 쳐다보며 코드를 훔쳐 오게(Pull) 아키텍처 뒤집기.
- How to Learn:
- 1단계: Push 모델의 치명상: 사내 CI 서버(Jenkins)가 실서버에 코드를 쏘려면(Push), 실서버의 방화벽에 구멍을 뚫어줘야 하고, 실서버를 조작할 수 있는 '최고 관리자 인증서'를 CI 서버에 쥐여줘야 합니다. CI 서버는 해커의 1순위 타겟이 됩니다.
- 2단계: Pull 모델의 헥사고날(Hexagonal) 방어: 권력을 뒤집습니다. CI 서버의 권한을 박탈합니다(이미지 빌드만 함). 대신 실서버 내부(안전지대)에 요원(Agent)을 심습니다. 이 요원이 "밖(GitHub)"을 쳐다보다가 변경 사항이 생기면 안으로 코드를 들고 들어옵니다(Pull).
- 3단계: 보안의 극대화: 밖에서 안으로 찌르는 방화벽 구멍이 0개가 됩니다. 해커가 GitHub 코드를 바꿔치기하려 해도 PR 리뷰어 승인 없이는 불가능합니다. 배포 파이프라인의 물리적 벡터를 반대로 꺾어버리는 보안의 전복을 뜯어봅니다.
- Implement: 배포 벡터(Deployment Vector) 공격 표면(Attack Surface) 차트화.
Push 아키텍처: [인터넷] (방화벽 인바운드 개방) [실서버]. 해커 침투 경로(Vector) 존재.Pull 아키텍처: [실서버 봇] (아웃바운드로만 나감) [GitHub]. 인바운드 포트(0개). 아웃바운드 트래픽만 허용하여 공격 표면을 수학적0으로 만드는 아키텍처 렌더링.
Practical
Core Topic 03: 불침번의 무한 루프, 지속적 교정 (The Reconciliation Loop)
- Why to Learn: "인프라 코드를 수정하고 까먹고 배포(Apply)를 안 눌렀다"는 휴먼 에러를 방지하고, 누군가 실서버를 몰래 수동 조작해도 1초 만에 기계가 원상 복구시키는 강제력을 갖기 위함입니다.
- What to Learn:
- Concepts: Reconciliation Loop (조정 루프), Desired State (원하는 상태), Actual State (현재 상태), State Drift (상태 오차).
- Skills: Git에 저장된
replicas: 3(원하는 상태)과, 현재 쿠버네티스에 떠 있는서버 4대(실제 상태)를 지속적으로 비교(Diff)하여, 넘치는 1대를 기계가 가차 없이 죽여버리도록(Kill) 통제망 구축하기.
- How to Learn:
- 1단계: 원하는 상태 vs 실제 상태: 보일러 온도조절기(Thermostat)와 같습니다. 내가 25도(Desired)로 세팅했는데 방 온도가 20도(Actual)면, 보일러는 불을 때서(Reconciliation) 온도를 맞춥니다.
- 2단계: 인프라의 온도조절기: GitOps 봇이 이 짓을 무한 반복합니다. Git에는 "메모리 1GB짜리 앱 3대"라고 적혀 있습니다.
- 3단계: 자가 치유 (Self-Healing): 서버 1대가 터져서 2대가 됐습니다(오차 발생). 봇이 즉각 1대를 살려냅니다. 반대로 관리자가 쉘에 접속해 수동으로 서버를 5대로 늘렸습니다(오차 발생). 봇이 "누가 감히 내 허락 없이(Git 없이) 서버를 늘렸냐"며 2대를 즉시 죽여버립니다. 절대적인 독재자(Git)의 룰을 강제하는 봇의 끈질긴 루프를 해부합니다.
- Implement: State Reconciliation (상태 조정) 콘솔 시뮬레이터.
State [Git]:image: v1.0State [K8s]:image: v1.0(Sync OK).Event: 해커가 K8s 내부에 침투하여kubectl set image v9.9(비트코인 마이너)강제 실행.Action: 1초 뒤 ArgoCD 봇 루프 기동Diff 감지 (v1.0 != v9.9)해커의 이미지를 죽이고v1.0재배포 강제 실행. 해커의 런타임 조작을 무한 루프로 짓뭉개는 자가 치유(Self-Healing) 시각화.
Advanced
Core Topic 04: 카나리아와 기계의 심판, 점진적 배포 (Progressive Delivery & Auto-Rollback)
- Why to Learn: "제가 짠 코드 완벽합니다! 배포하시죠!"라는 인간의 호언장담을 절대 믿지 않고, 트래픽을 찔끔찔끔 보내면서 실시간 에러율 수치(Data)로만 배포 확정 여부를 심판하기 위함입니다.
- What to Learn:
- Concepts: Progressive Delivery, Canary Release, Feature Flags, Automated Rollback, APM (Application Performance Monitoring) Metrics.
- Skills: 새 버전을 띄우고 유저 트래픽의 5%만 쏟아부은 뒤, 프로메테우스(Prometheus) 모니터링 봇에게 "에러율이 1% 넘거나 응답 속도가 2초 넘으면 즉시 배포 취소(Rollback)해라"라고 수학적 심판관 세팅하기.
- How to Learn:
- 1단계: 카나리아의 투입: v2.0(새 코드)을 띄우고 유저 100명 중 딱 5명(5%)만 이쪽으로 보냅니다. 나머지 95명은 v1.0(안전망)을 씁니다.
- 2단계: 지표 기반 심판 (Metrics-driven): 사람이 모니터를 뚫어지게 쳐다보지 않습니다. 분석 봇(Flagger/Argo Rollouts)이 v2.0 서버의 CPU, 메모리, HTTP 500 에러율을 초 단위로 감시합니다.
- 3단계: 기계의 무자비한 롤백: 5분 동안 지켜봤는데 500 에러율이 기준치(1%)를 넘어 3%를 찍었습니다. 봇은 슬랙(Slack)에 "v2.0 불합격" 알림을 쏘고, 단 0.1초 만에 유저 트래픽을 다시 100% v1.0으로 롤백해 버립니다. 반대로 지표가 완벽하면 10%, 50%, 100%로 밸브를 천천히 엽니다. 인간의 '느낌'이 아니라 '통계와 기계'가 배포의 목줄을 쥐는 진정한 CI/CD의 최종 진화 형태를 뜯어봅니다.
- Implement: 점진적 배포 자동 롤백 매트릭스 도출.
T=0: Canary 배포 시작 (Traffic 5%).T=3m: Metric 분석Latency: 150ms < 기준(200ms)(Pass) Traffic 20%로 증가.T=6m: Metric 분석Error Rate: 2.5% > 기준(1%)(Fail).Action: 즉각 Traffic 0% (v1.0으로 전면 롤백). 인간의 인지 속도(최소 수십 분)를 기계의 속도(초 단위)로 압도하여 비즈니스 손실(Blast Radius)을 막아내는 렌더링.
7. Terminology
8. References
Primary
- [P1] CS2023 - Software Engineering (SE) - Software Evolution (DevOps and GitOps)
- [P5] SFIA - Release and Deployment (RELM) - Automated deployment and GitOps
Secondary
- [Continuous Delivery] Jez Humble, David Farley - Advanced Deployment Strategies
- [GitOps and Kubernetes] Billy Yuen, et al. - Core principles of GitOps (Reconciliation, Pull model)
Industry
- [Weaveworks] - Guide To GitOps (The original creator of the term GitOps)
- [ArgoCD Documentation] - Architecture (Pull-based vs Push-based deployments)
9. Final Checklist
Primary
- 장애 발생 시 누군가
kubectl edit으로 클러스터를 수동 조작하여 Git 코드와 실서버 상태가 달라지는 '상태 드리프트(State Drift)' 현상을, GitOps의 조정 루프(Reconciliation Loop)가 어떻게 원상 복구(Self-Healing)하는지 증명할 수 있는가? - 젠킨스(Jenkins)가 클러스터의 관리자(Admin) 권한을 들고 직접 배포(Push)하는 기존 아키텍처의 치명적 보안 취약점(SPOF)을 지적하고, 클러스터 내부의 에이전트가 Git을 쳐다보는(Pull) 아키텍처로 방화벽 인바운드를 틀어막을 수 있는가?
Secondary
- 모든 인프라 변경 사항(스케일 아웃, 환경 변수 변경)을 오직 PR(Pull Request) 리뷰와 머지(Merge)를 통해서만 수행하게 함으로써, "누가 언제 왜" 바꿨는지
git log가 완벽한 감사 트레일(Audit Trail) 역할을 수행함을 논증할 수 있는가? - 쿠버네티스 클러스터 전체가 날아가는 최악의 재난(Disaster) 상황에서, 비어 있는 새 클러스터를 띄우고 Git 저장소 주소 하나만 연결해 주면 단 몇 분 만에 수백 개의 인프라가 100% 동일하게 부활하는 GitOps 기반 복구(DR) 시나리오를 설계할 수 있는가?
Industry
- 새로운 결제 로직을 배포할 때, 전체 유저에게 한방에 오픈하는 빅뱅 배포 대신 점진적 배포(Progressive Delivery)를 적용하여 트래픽 5%만 카나리아(Canary)로 라우팅하고 에러율 메트릭을 수집하는 파이프라인을 구축할 수 있는가?
- 카나리아 배포 진행 중 프로메테우스(Prometheus) 모니터링 시스템이 500 Http Status 에러율 스파이크(1% 초과)를 감지했을 때, 인간의 개입(승인) 없이 기계(Argo Rollouts 등)가 즉각 트래픽 밸브를 잠그고 0.1초 만에 구버전으로 롤백(Auto-Rollback)시키는 심판관 로직을 구현할 수 있는가?