배포에서 프로젝트 카나리 전략
Source: Dev.to
위에 제공된 소스 링크 아래에 번역하고자 하는 텍스트를 알려주시면, 해당 내용을 한국어로 번역해 드리겠습니다. (코드 블록, URL 및 마크다운 형식은 그대로 유지됩니다.)
삽화
![]() | ![]() |
이 프로젝트가 보여주는 것
- 카나리 배포 – 실제 의미
- 버전 간 트래픽 분할 방법
- 카나리가 존재하는 이유 (실제 운영상의 이유)
DevOps 엔지니어가 주의 깊게 살펴야 할 사항
- 카나리를 잘못 수행하면 프로덕션에서 깨질 수 있는 것
1️⃣ Canary란? (일반적인 DevOps 설명)
Canary 배포 = 새로운 버전을 소수의 사용자에게 먼저 릴리스한다.
대신에:
- 한 번에 모두 교체 (Rolling)
- 두 개의 전체 스택을 운영 (Blue/Green)
당신은:
- **v1 (stable)**을 계속 실행한다.
- **v2 (canary)**를 복제본 수를 줄여 추가한다.
- Kubernetes가 자연스럽게 트래픽을 분산하도록 한다.
- 문제가 발생하면 → Canary를 즉시 삭제한다.
- 모든 것이 정상이면 → Canary를 확장하고, v1을 축소한다.
DevOps 목표: 블라스트 반경을 줄인다.
2️⃣ DevOps가 카나리를 사용할 때 (실제 사례)
카나리를 사용할 경우 새로운 기능이 다음에 영향을 미칠 때:
- 결제, 인증, Kafka 소비자
- 위험한 스키마 또는 설정 변경
- 테스트 트래픽이 아닌 실제 사용자 트래픽이 필요할 때
모니터링 및 롤백은 즉시 이루어져야 합니다.
카나리를 사용하면 안 되는 경우:
- 애플리케이션이 무상태이며 규모가 작을 때
- 모니터링이 구축되지 않았을 때
- 롤백 프로세스가 없을 때
- 작은 내부 도구일 때
3️⃣ Canary Demo Project (what you will build)
You will deploy:
| Version | Response |
|---|---|
| v1 | VERSION 1 |
| v2 (canary) | VERSION 2 |
- One Service
- Traffic split via replica count
4️⃣ 단계별 구현 (가능한 가장 작은 YAML)
단계 1 – 안정 버전 (v1)
File: deploy-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-v1
spec:
replicas: 3
selector:
matchLabels:
app: demo
version: v1
template:
metadata:
labels:
app: demo
version: v1
spec:
containers:
- name: app
image: hashicorp/http-echo
args:
- "-listen=:8080"
- "-text=VERSION 1"
ports:
- containerPort: 8080
적용:
kubectl apply -f deploy-v1.yaml
단계 2 – 카나리 버전 (v2)
File: deploy-v2-canary.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-v2-canary
spec:
replicas: 1 # 🔑 THIS is the canary
selector:
matchLabels:
app: demo
version: v2
template:
metadata:
labels:
app: demo
version: v2
spec:
containers:
- name: app
image: hashicorp/http-echo
args:
- "-listen=:8080"
- "-text=VERSION 2 (CANARY)"
ports:
- containerPort: 8080
적용:
kubectl apply -f deploy-v2-canary.yaml
단계 3 – 단일 서비스 (트래픽 분할이 여기서 발생)
File: service.yaml
apiVersion: v1
kind: Service
metadata:
name: demo-svc
spec:
selector:
app: demo
ports:
- port: 80
targetPort: 8080
적용:
kubectl apply -f service.yaml
5️⃣ 실시간 트래픽 관찰 (가장 중요한 부분)
서비스 노출:
minikube service demo-svc
노출된 URL에 대해 지속적으로 트래픽을 발생시킵니다:
while true; do
date +"%H:%M:%S"
curl -s $URL
echo
sleep 0.3
done
보게 될 내용
VERSION 1
VERSION 1
VERSION 1
VERSION 2 (CANARY)
VERSION 1
VERSION 1
이것이 카나리 실제 동작입니다.
6️⃣ 트래픽 분할이 실제로 작동하는 방식 (DevOps 현실)
Kubernetes 퍼센트로 분할하지 않으며 – Pod 수로 분할합니다.
- v1 = 3개의 pod
- v2 = 1개의 pod
≈ 25 %의 트래픽이 카나리로 흐릅니다.
7️⃣ Canary 동안 DevOps 책임 (핵심 부분)
🔍 Metrics
- Error rate (5xx) → 오류 비율 (5xx)
- Latency increase → 지연 시간 증가
- Pod restarts → Pod 재시작
- CPU / memory spikes → CPU / 메모리 급증
📜 Logs
- Application exceptions → 애플리케이션 예외
- Kafka lag → Kafka 지연
- DB connection failures → DB 연결 실패
🚦 Health
- Readiness probe failures → Readiness 프로브 실패
- CrashLoopBackOff → CrashLoopBackOff
- Partial availability → 부분 가용성
8️⃣ 실패 시뮬레이션 (중요 데모)
Canary를 즉시 삭제합니다:
kubectl delete deployment app-v2-canary
2‑Canary
트래픽이 즉시 복귀하는 대상
VERSION 1
VERSION 1
VERSION 1
- 👉 롤백이 필요 없음
- 👉 다운타임 없음
- 👉 이것이 Canary가 존재하는 이유입니다
9️⃣ Canary를 전체 릴리스로 승격
모든 것이 정상이라면:
kubectl scale deployment app-v2-canary --replicas=3
kubectl scale deployment app-v1 --replicas=0
Result:
- v2가 메인이 됩니다
- v1이 사라집니다
- 사용자는 전혀 눈치채지 못했습니다
🔟 일반적인 카나리 실수 (실제 운영 이슈)
- ❌ 모니터링 없음
- ❌ 카나리에는
readinessProbe가 없음 - ❌ v1과 v2에 동일한 DB 마이그레이션 적용
- ❌ 카나리 실행 시간이 필요 이상으로 길어짐
- ❌ 즉시 삭제 계획 없음
최종 DevOps 요점 (중요)
Canary는 YAML이 아닙니다.
Canary는 리스크 관리입니다.
당신의 실제 업무:
- 노출을 제어한다
- 실패를 조기에 감지한다
- 문제 있는 릴리스를 빠르게 차단한다
- 사용자와 비즈니스를 보호한다

