벌써 에이블스쿨 7기 14주차에 접어든 요즘, 11주차부터 Cloud Native Application 교육이 진행되고 있다.
도메인 주도 설계(DDD)부터 마이크로서비스 아키텍처(MSA), 그리고 이를 효과적으로 운영하기 위한 쿠버네티스까지 배우고 있다.
이번 포스팅에서는 MSA에서 자주 활용하는 Canary 배포에 대해 쿠버네티스 환경에서 Argo Rollout를 기반으로 어떻게 적용하는지 다뤄보겠다.
Canary 배포란, 새 버전을 모든 사용자에게 한번에 배포하지 않고 먼저 일부 사용자에게만 점진적으로 배포해서 문제가 없는지 확인하고, 점차 모든 사용자에게 배포를 확장하는 전략이다.
글로 읽는 것보다는 직접 해보는 게 더 이해가 빠르니까 바로 실습으로 넘어가보자!
실습은 azure의 쿠버네티스 클러스터가 프로젝트에 붙어있어 kubectl을 사용할 수 있는 환경에서 진행되었습니다.
Argo Rollout이란, 쿠버네티스에는 없는 배포전략을 쉽게 할 수 있도록 도와주는 쿠버내티스 컨트롤러(배포 도구)이다. 기본 쿠버네티스는 롤링 업데이트(Rolling Update) 방식만 지원하는데, Argo Rollout을 쓰면 canary 배포, blue-green 배포, 단계별 트래픽 분할, 배포 상태 시각화 대시보드 등 다양한 기능을 쉽게 사용할 수 있다는 장점이 있다.
kubectl create ns argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
위의 내용을 터미널에 입력한다.
내용에 대해 설명하자면, 쿠버네티스 클러스터에 argo-rollouts라는 새로운 네임스페이스를 만들고, 해당 네임스페이스 안에 원격에 있는 yaml 파일을 실행해서 Argo Rollouts 컨트롤러를 설치하는 것이다.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: example-rollout
spec:
replicas: 10 # Pod를 10개로 유지
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19.10
ports:
- containerPort: 80
minReadySeconds: 30
revisionHistoryLimit: 3
strategy:
canary: # Canary 배포 전략 적용
maxSurge: "25%" # 원래 Pod 10개에서 최대 25%만큼 더 띄울 수 있음
maxUnavailable: 0 # 기존 Pod는 항상 유지, 중단 없음
steps:
- setWeight: 10 # 트래픽 10%만 신규 Pod로 전달
- pause:
duration: 10s # 10초 동안 현 상태 유지
- setWeight: 20
- pause:
duration: 10s
- setWeight: 30
- pause:
duration: 10s
- setWeight: 40
- pause:
duration: 10s
---
# service 리소스
apiVersion: "v1"
kind: "Service"
metadata:
name: "nginx"
labels:
app: "nginx"
spec:
ports:
-
port: 80
targetPort: 80
selector:
app: "nginx"
type: "LoadBalancer"
이 yaml파일에서는 2가지 작업을 한다.
1. Rollout 객체 생성 (Deployment 대신)
2. Service 객체 생성
Rollout 객체는 nginx 이미지로 Pod를 띄우고 Canary 배포 전략으로는 총 4단계가 있다. 새 버전을 가지는 Pod의 비율이 10% -> 20% -> 30% -> 40%로 점진적으로 늘어나며, 각 단계 후 10초동안 멈추고 다음 단계로 넘어간다. (보통 실제로는 더 긴 시간을 멈춰서 오류가 있는지 확인하고 다음 단계로 넘어간다.)
Service 객체는 nginx 라벨이 붙은 Pod를 연결하며, LoadBalancer 타입으로 지정되어서 퍼플릭 IP를 할당받는다.
이 yaml파일을 프로젝트의 rollout.yaml 파일에 저장하고, 다음 명령어를 터미널에 입력해서 Rollout을 배포한다.
kubectl apply -f rollout.yaml
Argo Rollouts를 쓸 때 배포 상태를 단계별로 보기 쉽고 편하게 관리하기 위해 Argo CLI/Dashboard를 사용할 수 있습니다.
curl -LO https://github.com/argoproj/argo-rollouts/releases/latest/download/kubectl-argo-rollouts-linux-amd64
chmod +x ./kubectl-argo-rollouts-linux-amd64
sudo mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts
이 명령어를 터미널에 입력해서 설치합니다.
kubectl argo rollouts dashboard
이 명령어를 터미널에 입력하면, 3100번 포트에 argo dashboard 서비스가 실행된다.
3100번 포트를 public으로 설정하고 브라우저에서 접속한다.
kubectl argo rollouts set image example-rollout nginx=jinyoung/app:blue
위 명령어를 터미널에 입력하면 rollout.yaml에 우리가 설정했던 것대로 canary배포가 일어난다.
그리고 Argo 웹사이트에 가면 실시간으로 배포 과정을 확인할 수 있다.
pod가 점점 revision1에서 revision2로 점진적으로 옮겨가는 걸 확인할 수 있다.



전에 카나리 배포에 대해 몰랐을 당시에, 친구와 카카오톡 업데이트에 대해 이야기를 나눈 적이 있었다.
내 핸드폰에 있는 카카오톡 앱이 앱스토어에서는 더이상 업데이트할 버전이 없다고 나오지만, 나한테는 카카오톡의 신규 기능이 보이지 않았고 친구한테는 신규 기능이 보였었다.
이때 친구가 "처음에는 랜덤으로 새로운 기능 이용하는 거래"라고 말해줬는데, 그 당시에는 그냥 신기하다~ 하고 넘겼는데, canary 배포를 배우고 나니 그게 이거였구나~ 싶다!😁