Kubernetes/Kubernetes Best Practices

[Scenario Playbook Ep.7] 🚀 Deployment 편 #2 | Canary & Blue-Green 배포

ygtoken 2025. 3. 15. 13:39
728x90

 

쿠버네티스에서 무중단 배포 전략은 애플리케이션의 안정성을 유지하는 핵심 요소입니다.

이번 글에서는 Canary 배포와 Blue-Green 배포 전략을 적용하는 방법을 다룹니다.

 


📌 글에서 다루는 상황들

 

1️⃣ Canary 배포 전략 적용

2️⃣ Blue-Green 배포 전략 적용

 

각 문제를 실무에서 바로 활용할 수 있도록 Manifest 템플릿과 예상 결과 값을 제공합니다.

 


1️⃣ Canary 배포 전략 적용

 

📍 상황 설명

 

운영팀에서 새로운 애플리케이션 버전을 전체 배포 전에 일부 트래픽을 대상으로 테스트하려 합니다.

이를 위해 Canary 배포 전략을 사용하여 새로운 버전의 애플리케이션을 점진적으로 배포해야 합니다.

기존 nginx:1.21.6 이미지를 실행 중인 web-deployment가 있습니다.

새로운 버전 nginx:1.22.0을 배포하되, 트래픽의 20%만 Canary 버전으로 전달해야 합니다.

 


🛠️ 해결 방법

 

1. Deployment를 두 개로 분리하여 Canary 트래픽을 제어해야 합니다.

기존 버전(nginx:1.21.6)을 실행하는 Stable Deployment

새로운 버전(nginx:1.22.0)을 실행하는 Canary Deployment

2. 트래픽 분배를 위해 서비스(LoadBalancer 또는 Ingress)를 사용해야 합니다.

Canary Pod이 전체 트래픽의 20%만 받을 수 있도록 설정

 


✅ 정답 Manifest (Canary 배포 적용)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-stable  # 기존 안정적인 버전의 Deployment
spec:
  replicas: 4  # 80% 트래픽을 담당
  selector:
    matchLabels:
      app: web
      version: stable
  template:
    metadata:
      labels:
        app: web
        version: stable
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.6  # 기존 안정적인 버전
        ports:
        - containerPort: 80

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-canary  # 새로운 Canary 버전의 Deployment
spec:
  replicas: 1  # 20% 트래픽을 담당
  selector:
    matchLabels:
      app: web
      version: canary
  template:
    metadata:
      labels:
        app: web
        version: canary
    spec:
      containers:
      - name: nginx
        image: nginx:1.22.0  # 새로운 Canary 버전
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: web-service  # 트래픽을 Canary 및 Stable로 분배하는 서비스
spec:
  selector:
    app: web  # 동일한 app 레이블을 가진 Pod을 대상으로 서비스 제공
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

 

 


📌 적용 후 예상 결과 값

 

1. Deployment 및 Service 생성 확인

kubectl get deployments,svc

 

💡 예상 출력 값

NAME             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web-stable   4/4     4            4          5s
deployment.apps/web-canary   1/1     1            1          5s

NAME           TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/web-service   LoadBalancer   10.96.0.1      <pending>     80/TCP        5s

 

2. 트래픽이 Canary 및 Stable로 분배되는지 확인

watch -n 1 curl http://<EXTERNAL-IP>

 

💡 예상 출력 값 (랜덤 요청 결과)

Welcome to nginx 1.21.6
Welcome to nginx 1.21.6
Welcome to nginx 1.22.0  # 일부 요청이 Canary 버전으로 전달됨
Welcome to nginx 1.21.6

 

 


2️⃣ Blue-Green 배포 전략 적용

 

📍 상황 설명

 

운영팀에서 현재 실행 중인 애플리케이션을 즉시 새로운 버전으로 전환해야 합니다.

배포 후 문제가 발생하면 즉시 이전 버전으로 롤백할 수 있어야 합니다.

현재 nginx:1.21.6이 실행 중입니다.

새로운 버전 nginx:1.22.0을 배포하지만, 완전히 준비될 때까지 기존 버전과 트래픽을 공유하지 않습니다.

새 버전 배포 후 서비스의 트래픽을 기존 버전에서 새로운 버전으로 전환해야 합니다.

 


🛠️ 해결 방법

 

1. Deployment를 두 개로 나누어 서로 다른 버전을 실행해야 합니다.

web-blue: 현재 운영 중인 버전

web-green: 새롭게 배포될 버전

2. Service의 Selector를 변경하여 트래픽을 전환해야 합니다.

기존 web-blue에서 web-green으로 서비스의 selector를 업데이트

 


✅ 정답 Manifest (Blue-Green 배포 적용)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-blue  # 기존 운영 중인 버전
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      version: blue
  template:
    metadata:
      labels:
        app: web
        version: blue
    spec:
      containers:
      - name: nginx
        image: nginx:1.21.6  # 기존 운영 중인 버전
        ports:
        - containerPort: 80

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-green  # 새로운 배포 버전
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
      version: green
  template:
    metadata:
      labels:
        app: web
        version: green
    spec:
      containers:
      - name: nginx
        image: nginx:1.22.0  # 새로운 배포 버전
        ports:
        - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
    version: blue  # 최초에는 기존 버전(blue)으로 설정
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer

 

 


📌 적용 후 예상 결과 값

 

1. Deployment 및 Service 생성 확인

kubectl get deployments,svc

 

💡 예상 출력 값

NAME             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web-blue   3/3     3            3          5s
deployment.apps/web-green  3/3     3            3          5s

NAME           TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
service/web-service   LoadBalancer   10.96.0.1      <pending>     80/TCP        5s

 

2. 트래픽을 새 버전으로 전환

kubectl patch service web-service -p '{"spec":{"selector":{"app":"web", "version":"green"}}}'

 

💡 예상 출력 값

service/web-service patched

 

3. 새 버전이 정상적으로 서비스되고 있는지 확인

curl http://<EXTERNAL-IP>

 

💡 예상 출력 값

Welcome to nginx 1.22.0
728x90