[Kubernetes] 무중단 배포 방식 알아보기 (Rolling Update, Canary Deployment, Blue-Green Deployment)
무중단 배포(Heterogeneous deployments)란
무중단 배포란 두 개 이상의 인프라 환경을 사용해 애플리케이션을 배포하는 것
Heterogeneous deployments를 구축하는 방법에는 2가지의 종류가 있습니다.
1. 멀티 클라우드: 여러 클라우드 환경을 사용하기
2. 하이브리드(public-private 클라우드): 온프레미스 환경과 클라우드 환경을 함께 사용하기
이번 게시글에서는 쿠버네티스를 활용하여 Heterogeneous deployments를 구축할 예정입니다 :)
우리가 이번 글에서 사용할 deployment 객체를 먼저 자세히 살펴보도록 하겠습니다.
kubectl explain
해당 쿠버네티스 객체의 내부 구조와 그에 대한 설명을 확인할 수 있습니다.
- -- recursive 옵션: 객체의 모든 필드를 확인할 수 있습니다.
kubectl explain deployment
kubectl explain deployment.metadata.name # deployment의 세부 필드에 대한 설명을 확인할 수 있습니다.
Rolling Update
기본적으로 쿠버네티스의 Deployment를 수정하면 실행 중인 이미지들은 롤링 업데이트 방식으로 자동 업데이트됩니다.
Rolling Update의 동작 방식은 다음과 같습니다.
1. Deployment를 새 버전으로 업데이트합니다.
2. 새로운 ReplicaSet이 만들어지기 시작합니다.
3. 점점 기존 ReplicaSet은 줄어들고, 그 빈 자리를 새로운 ReplicaSet이 대체합니다.
쿠버네티스에서 Deployment를 수정하면 자동으로 롤링 업데이트가 실행됩니다.
kubectl edit deployment hello
롤링 업데이트가 적용되고 있는지 직접 pod으로 확인해보고 싶다면 아래 명령어를 사용해보세요.
kubectl get pods -o jsonpath --template='{range .items[*]}{.metadata.name}{"\t"}{"\t"}{.spec.containers[0].image}{"\n"}{end}'
아래 명령어들을 통해 Rolling Update를 세부적으로 관리할 수 있습니다.
kubectl get replicaset
생성되는 ReplicaSet들을 확인할 수 있습니다.
kubectl get replicaset
kubectl rollout history
deployment의 rollout 이력을 확인할 수 있습니다.
kubectl rollout history deployment/hello
kubectl rollout pause
rollout을 중지하는 명령어입니다.
kubectl rollout pause deployment/hello
kubectl rollout resume
중지된 rollout을 재실행하는 명령어입니다.
kubectl rollout resume deployment/hello
kubectl rollout status
rollout의 상태를 확인할 때 사용하는 명령어입니다.
kubectl rollout status deployment/hello
kubectl rollout undo
현재 rollout을 이전 버전으로 되돌릴 때 사용하는 명령어입니다.
kubectl rollout undo deployment/hello
Canary deployments
Canary deployment는 새로운 버전을 테스트하기 위해 몇몇 서비스 유저들만을 대상으로 버전을 업데이트하는 것을 말합니다. 사전 테스트를 통해 새로운 버전을 배포했을 때 발생할 수 있는 문제점들을 미연에 방지할 수 있습니다.
위의 퀵랩을 따라 쿠버네티스에서 Canary Deployment을 직접 실습해보겠습니다.
1. 먼저 주어진 yaml 파일을 이용해 canary용 deployment를 생성합니다.
kubectl create -f deployments/hello-canary.yaml
여기서 사용하는 yaml 파일의 코드는 다음과 같습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-canary
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
track: canary
# Use ver 2.0.0 so it matches version on service selector
version: 2.0.0
spec:
containers:
- name: hello
image: kelseyhightower/hello:2.0.0
ports:
- name: http
containerPort: 80
- name: health
containerPort: 81
...
2. 만들어진 deployment에게 계속 요청을 전송해봅시다.
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
위 명령어를 계속 실행하면 4분의 1 확률로 deployment의 1.0.0이 아닌 2.0.0 버전이 실행되는 것을 확인할 수 있습니다.
근데 유저에게 보이는 UI가 계속 바뀌네요?
Canary deployment를 사용하면 랜덤으로 유저에게 제공되는 서비스의 버전이 달라집니다. 이 때, Canary deployment가 제공하는 서비스가 프론트엔드 서비스라고 가정해봅시다. 그럼 유저에게 제공하는 서비스의 버전에 따라 프론트엔드 UI가 계속 달라질 수도 있습니다.
이 문제점을 해결하기 위해서는 동일한 유저에게 동일한 버전의 deployment만 제공해야 합니다. Session affinity란 이렇듯 동일한 IP의 유저에게 동일한 버전의 deployment만 제공하는 기법을 말합니다.
Blue-Green Deployments
어떤 서비스는 롤링 업데이트보다는 새로운 버전의 배포가 완벽히 완료된 이후에 로드 밸런서가 새로운 버전을 제공하는 것이 더 유용할 수도 있습니다. 이런 경우에는 Rolling Update 대신 Blue-Green Deployment를 사용하는 것이 좋습니다.
Blue-Green Deployment에서는 deployment를 기존의 "blue" 버전과 새로운 "green" 버전 두 가지로 분리해 관리합니다. 유저는 서비스를 통해 기존의 blue 버전 deployment에만 접근할 수 있습니다. 새로운 green 버전의 배포가 끝나면 이제 유저는서비스를 통해 green 버전으로만 접속할 수 있게 됩니다.
이번에도 퀵랩을 따라 Blue-Green Deployment를 실습해보겠습니다.
1. 처음에는 blue 버전의 service를 적용합니다.
kubectl apply -f services/hello-blue.yaml
2. green 버전의 service를 생성해 적용해봅시다.
kubectl create -f deployments/hello-green.yaml
kubectl apply -f services/hello-green.yaml
3. Rolling Update와 달리 green 버전을 적용하자마자 즉시 green 버전의 deployment가 사용됩니다.
curl -ks https://`kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}"`/version
만일 이전 버전으로 되돌리고 싶다면 kubectl apply 명령어로 blue 버전 서비스를 다시 적용하면 됩니다.
kubectl apply -f services/hello-blue.yaml
여기까지 쿠버네티스에서 제공하는 3가지 무중단 배포 방식에 대해 알아보았습니다.