안녕하세요! 👋 오늘은 쿠버네티스(Kubernetes)를 다루는 개발자, 운영자라면 누구나 한 번쯤은 들어봤을 배포 전략, 블루/그린(Blue/Green)과 카나리아(Canary)에 대해 이야기해보려고 합니다.
"Istio나 Linkerd 같은 서비스 메시(Service Mesh)를 써야만 가능한 거 아니야?" 라고 생각하실 수도 있지만, 천만에요! 🙅♂️ 쿠버네티스의 가장 기본적인 리소스인 Deployment와 Service만으로도 이 멋진 배포 전략들을 충분히 구현할 수 있습니다. CKAD(Certified Kubernetes Application Developer) 시험에도 괜히 나오는 단골 주제가 아니랍니다.
자, 지금부터 쿠버네티스 기본기를 활용해 어떻게 안전하고 효율적인 무중단 배포를 할 수 있는지 아주 상세하게 파헤쳐 보겠습니다!

🔵🟢 블루/그린 (Blue/Green) 배포: 가장 안전하게 신호등을 건너는 법
블루/그린 배포는 마치 신호등 없는 횡단보도에 새로운 길(Green)을 하나 더 만들고, 모든 준비가 끝나면 사람들을 한 번에 그 길로 안내하는 것과 같습니다. 기존에 운영 중인 환경을 블루(Blue), 새로 배포할 환경을 그린(Green)이라고 부릅니다. 두 환경을 동시에 구축해두고, 트래픽을 한 번의 클릭으로 휙! 전환하는 전략이죠.
가장 큰 장점은 혹시라도 새 버전에 문제가 생겼을 때, 다시 트래픽을 기존 블루 환경으로 돌리기만 하면 되니 롤백이 아주 빠르고 안전하다는 것입니다. 👍
핵심 아이디어 💡
Service의 selector를 바꿔치기해서 트래픽의 목적지를 한 번에 변경한다!
구현 단계별 상세 가이드
1️⃣ 단계: 현재 운영 환경 (블루 🔵)
먼저, 현재 서비스되고 있는 v1 애플리케이션(블루)이 있다고 가정해 봅시다.
- Deployment는 version: blue 라는 라벨을 가진 Pod들을 관리합니다.
- Service는 selector를 통해 version: blue 라벨이 붙은 Pod들에게만 트래픽을 전달하고 있습니다.
blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-blue
spec:
replicas: 3
selector:
matchLabels:
app: my-app
version: blue
template:
metadata:
labels:
app: my-app
version: blue
spec:
containers:
- name: my-app
image: my-app:v1.0.0
ports:
- containerPort: 80
service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app
version: blue # <--- 현재는 블루를 가리킴
ports:
- protocol: TCP
port: 80
targetPort: 80
이 상태에서는 모든 사용자 트래픽이 my-app:v1.0.0 버전을 사용하는 Pod으로 향하게 됩니다.
2️⃣ 단계: 새로운 버전 배포 (그린 🟢)
이제 새로운 v2 애플리케이션(그린)을 배포할 차례입니다. 블루 환경과 완전히 동일한 구성으로, 라벨만 version: green으로 변경하여 배포합니다.
green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-green
spec:
replicas: 3
selector:
matchLabels:
app: my-app
version: green
template:
metadata:
labels:
app: my-app
version: green
spec:
containers:
- name: my-app
image: my-app:v2.0.0 # 새로운 버전의 이미지
ports:
- containerPort: 80
이 Deployment를 배포해도 사용자 트래픽에는 아무런 영향이 없습니다. 왜냐하면 my-app-service는 여전히 version: blue만 바라보고 있기 때문이죠. 이 시간 동안 우리는 그린 환경이 정말 문제없이 잘 동작하는지 충분히 테스트할 수 있습니다. 🧪
3️⃣ 단계: 트래픽 전환! 🚦
그린 환경의 테스트가 모두 끝나고 "이제 배포해도 되겠다!" 확신이 서면, 마법을 부릴 시간입니다. Service의 selector 값을 blue에서 green으로 변경해 주기만 하면 됩니다.
가장 간단한 방법은 kubectl patch 명령어를 사용하는 것입니다.
kubectl patch service my-app-service -p '{"spec":{"selector":{"version":"green"}}}'
이 명령어가 실행되는 즉시! my-app-service로 들어오는 모든 트래픽은 version: green 라벨을 가진 Pod, 즉 신규 버전으로 향하게 됩니다. 사용자는 다운타임을 전혀 느끼지 못합니다. ✨
4️⃣ 단계: 기존 버전 정리 🧹
신규 버전(그린)이 안정적으로 잘 서비스되는 것을 확인했다면, 이제 구 버전(블루) Deployment는 삭제하거나, 만약을 대비해 레플리카 수를 0으로 줄여 리소스를 확보합니다.
# 옵션 1: 완전히 삭제
kubectl delete deployment my-app-blue
# 옵션 2: Pod만 제거 (롤백 대비)
kubectl scale deployment my-app-blue --replicas=0
🐦 카나리아 (Canary) 배포: 위험은 미리, 조금씩 맛보기
카나리아 배포는 과거 광부들이 유독가스를 탐지하기 위해 카나리아 새를 데리고 탄광에 들어갔던 것에서 유래했습니다. 즉, 새로운 버전의 위험을 먼저 감지하기 위해 일부 사용자에게만 살짝 공개해보는 전략입니다.
전체 트래픽의 10%를 신규 버전으로 보내보고, 모니터링 후 괜찮으면 30%, 50%... 점진적으로 늘려나가다가 최종적으로 100% 전환하는 방식입니다. 위험을 최소화하고 싶을 때 아주 유용합니다.
핵심 아이디어 💡
버전별로 Deployment를 2개 운영하고, replicas(Pod 수) 비율을 조절해 트래픽을 점진적으로 이전한다!
구현 단계별 상세 가이드
1️⃣ 단계: 안정적인 현재 버전
현재 v1 버전의 애플리케이션이 10개의 Pod으로 안정적으로 운영되고 있다고 가정해 봅시다. 여기서 중요한 점은 Service가 version 라벨이 아닌, 앱 전체를 나타내는 app: my-app 라벨을 바라보게 설정하는 것입니다.
v1-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v1
spec:
replicas: 10
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
version: v1 # 버전 구분을 위한 라벨
spec:
containers:
- name: my-app
image: my-app:v1.0.0
ports:
- containerPort: 80
service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector:
app: my-app # <--- 버전에 상관없이 'my-app' 전체를 선택
ports:
- protocol: TCP
port: 80
targetPort: 80
현재는 app: my-app 라벨을 가진 Pod이 v1 Deployment에 속한 10개뿐이므로, 모든 트래픽은 v1으로 갑니다.
2️⃣ 단계: 카나리아 릴리즈 🕊️
이제 신규 버전인 v2를 아주 작은 규모로 배포해 봅시다. 예를 들어, 전체 트래픽의 약 10% 정도만 받도록 replicas: 1로 설정하여 배포합니다.
v2-canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v2
spec:
replicas: 1 # <--- 아주 작은 수의 Pod로 시작
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
version: v2 # 새로운 버전 라벨
spec:
containers:
- name: my-app
image: my-app:v2.0.0 # 새로운 버전 이미지
ports:
- containerPort: 80
이 Deployment를 배포하면, Service가 바라보는 app: my-app 라벨을 가진 Pod는 총 11개(v1 10개 + v2 1개)가 됩니다. 쿠버네티스 Service는 기본적으로 라운드 로빈 방식으로 트래픽을 분배하므로, 약 1/11 (대략 9%)의 트래픽이 신규 버전 v2로 흐르게 됩니다.
3️⃣ 단계: 점진적인 트래픽 확대 📈
이제 모니터링 대시보드를 켜고 v2 버전에서 에러율이나 응답 시간 등에 문제가 없는지 면밀히 관찰합니다.
문제가 없다고 판단되면, v2의 Pod 수를 늘리는 동시에 v1의 Pod 수를 점진적으로 줄여나갑니다.
# v2 트래픽을 30%로 확대
kubectl scale deployment my-app-v2 --replicas=3
kubectl scale deployment my-app-v1 --replicas=7
# v2 트래픽을 50%로 확대
kubectl scale deployment my-app-v2 --replicas=5
kubectl scale deployment my-app-v1 --replicas=5
# ...
# v2 트래픽을 100%로 전환
kubectl scale deployment my-app-v2 --replicas=10
kubectl scale deployment my-app-v1 --replicas=0
4️⃣ 단계: 배포 완료 및 정리 🏁
v1 Deployment의 Pod 수가 0이 되고 모든 트래픽이 v2로 안정적으로 넘어갔다면 카나리아 배포가 성공적으로 완료된 것입니다. 이제 더 이상 필요 없는 v1 Deployment를 깔끔하게 삭제해 줍니다.
kubectl delete deployment my-app-v1
결론: 기본기가 가장 강력하다!
어떠신가요? 복잡한 툴 없이도 쿠버네티스의 Deployment와 Service가 가진 라벨링과 셀렉터 기능만 잘 이해하고 활용하면, 이렇게 정교하고 안정적인 배포 전략을 구사할 수 있습니다.
- 블루/그린은 리소스를 2배로 사용하지만, 가장 빠르고 안전한 롤백을 보장합니다.
- 카나리아는 배포 과정이 조금 더 길고 복잡하지만, 위험을 최소화하며 점진적으로 신규 버전을 도입할 수 있습니다.
여러분의 서비스와 팀의 상황에 맞는 배포 전략을 선택하여, 더 이상 배포 때문에 밤새우는 일이 없으시길 바랍니다! 😊
태그: 쿠버네티스, 무중단 배포, 블루그린, 카나리아, DevOps, CKAD, Deployment, Service, Kubernetes
'클라우드 > 쿠버네티스' 카테고리의 다른 글
| 쿠버네티스 고수되기: Source IP 보존과 트래픽 관리를 위한 최종 아키텍처 🚀 (0) | 2025.09.10 |
|---|---|
| 🚀 알아두면 쓸모있는 쿠버네티스 배포 전략: 롤링, 블루/그린, 카나리 완벽 정복! (0) | 2025.09.10 |
| 쿠버네티스 Secret, 정말 메모리에만 마운트될까? 🧠 완벽 분석! (0) | 2025.09.09 |
| 🔭 Kubelet & API 서버 트레이싱: OpenTelemetry로 커널 심층 분석하기! 🚀 (1) | 2025.09.09 |
| 📝 YAML의 진화: 쿠버네티스 사용자를 위한 KYAML 톺아보기! ✨ (1) | 2025.09.09 |