상세 컨텐츠

본문 제목

[kubernetes] Deployment 배포 전략 RollingUpdate 세부 설정하기

프로그래밍/kubernetes

by jisooo 2024. 1. 14. 17:09

본문

 

 

간만에 돌아온 개발 포스팅🤓

 

 

 

 

Deployment, ReplicaSet이란?
쿠버네티스에서 애플리케이션이 배포되는 과정

 

 

 

쿠버네티스에서 어플리케이션을 배포하려면 Deployment 오브젝트를 사용한다.

 

디플로이먼트의 하위 오브젝트인 Replicaset(레플리카셋)에

배포할 파드의 갯수 (replicas) 속성을 설정하고 배포하면,

 

번거롭게 직접 원하는 갯수의 파드와 레플리카셋을 직접 생성할 필요가 없이

kube-scheduler의 "스케줄링" 기능을 통해 각 워커 노드의 가용량 (cpu, memory)를 확인한 뒤

설정한 레플리카 갯수대로 워커 노드에 배치하여 배포한다.

 

그리고 레플리카셋에서 일정 개수의 파드가 유지되도록 하기 때문에,

중간에 파드가 장애로 다운되거나 워커 노드의 장애로 파드의 갯수가 줄어들어나 하면,

이를 지속적으로 모니터링한 뒤, 설정한 레플리카 갯수대로 파드를 다시 배포해준다.

 

 

그리고 보통 쿠버네티스에서 어플리케이션을 신규 이미지로 배포하려면,

기존에 생성된 애플리케이션을 삭제한 다음

새로운 버전의 애플리케이션을 배포해야할 수 도 있고,

 

신규 버전의 애플리케이션에서 버그가 있어서

이전 버전의 애플리케이션으로 롤백 해야 하는 상황이 있을 수 있다.

 

 

디플로이먼트는 레플리카를 이용한 파드 유지 기능, 롤백 기능, 무중단 배포 전략 등의 기능을 지원하여

애플리케이션의 업데이트와 배포를 더욱 편하게 만들어준다.

 

 

 

 

 

 

1) 롤백 기능

디플로이먼트는 수정된 이미지로 파드를 업데이트할 때,

새로운 레플리카셋과 파드를 생성했음에도 이전 버전의 레플리카셋을 삭제하지 않고 남겨둔다.

 

레플리카셋의 변경 사항을 저장하는 "리비전(Revision)"을 남겨

위와 같이 롤백이 필요한 상황에서 특정 리비전으로 파드가 돌아갈 수 있도록 한다.

 

$ kubectl apply -f deployment-v1.yaml --record 
deployment .apps/nginx-deployment created
// record 옵션을 추가하여 디플로미넡으의 변경 사항을 적용하면 이전에 사용하던 레플리카셋의 정보는 디플로이먼트의 히스토리에 기록됨.

$ kubectl get pods
NAME                                  READY  STATUS    RESTARTS   AGE
nginx-deployment-5f9fdfb85d-92bn7     1/1    Running    0         8s
nginx-deployment-5f9fdfb85d-dbhbw     1/1    Running    0         8s
nginx-deployment-5f9fdfb85d-gskjp     1/1    Running    0         8s

$ kubectl appply -f deployment-v2.yaml --record
deployment .apps/nginx-deployment configured
// 2번째 버전을 배포한다.

$ kubectl rollout history deployment nginx-deployment
deployment.extensions/nginx-deployment
REVISION    CHANGE-CAUSE
1            kubectl apply --filename-deployment-v1.yaml --record=true
2            kubectl apply --filename-deployment-v2.yaml --record=true

// 이전 버전(v1)의 레플리카셋 정보를 디플로이먼트 히스토리제 저장해두고 있음.
 

 

 

 

 

 

2) 무중단 배포

또한 신규 버전으로 배포를 할 때는,

기존 어플리케이션을 다 삭제한 뒤, 신규 버전을 배포해버리면

신규 버전을 배포 하는 동안 서비스는 중단되게 된다.

 

일반적인 운영 환경에서는 위와 같은 상황에서 무중단 배포가 필요하다.

또한 무중단 서비스를 위해 파드의 롤링 업데이트 전략을 지정할 수 있다.

 

 

 

 


 

 

Deployment의 배포 전략

 

 

 

 

 

 

1) Recreate 배포 전략

기존 버전의 파드를 모두 삭제 한 뒤, 새로운 버전의 파드를 생성하는 방식이다.

파드를 신규 버전으로 배포하는 동안에는,

즉 위 그림에서 step2 ~ step3의 단계에서는

서비스 가능한 파드가 없으므로 일시적으로 서비스가 중단된다.

 

따라서 어플리케이션 트래픽이 계속 인입되는 운영 환경에서는

해당 배포 전략을 사용하지 않는다.

 

 

 

 

 

 

2) RollingUpdate 배포 전략

 

 
 
 
 

파드를 조금씩 삭제하고 생성하는 롤링 업데이트 배포 전략이다.

디플로이먼트를 업데이트하는 도중에도 사용자의 요청을 처리 할 수 있는 파드가 계속 존재한다.

따라서 무중단 배포가 가능하다.

 

위 이미지처럼 0.1버전에서 0.2버전으로 파드를 배포한다고 가정해보자.

rollingUpdate 전략을 사용하면,

0.1버전의 파드에서 0.2버전의 파드로 점진적으로 옮겨간다.

 

배포 과정에서 0.1버전의 파드를 일정 갯수대로 지우고,

0.1버전의 파드가 지워진 갯수에

0.2버전의 파드를 점진적으로 메꾸어가며

전체 파드를 0.2버전으로 배포해가는 과정이 이루어진다.

 

점진적으로 파드가 배포되는 만큼,

배포 과정에서 일시적으로 v1 버전과 v2 버전이 공존 할 수 있다.

따라서 애플리케이션과 통신하는 다른 컴포넌트들은

기존 버전과 새로운 버전 어떤 버전과 통신에도

전체 시스템에 문제가 발생하지 않도록 유의해야 한다.

 

만약 배포 과정에서 두 버전이 공존하는 케이스를 막고자 한다면,

블루 그린 배포를 사용해야 한다.

 

 

 

 

 

 

 

 

 

 

 

참고: 블루 그린 (blue-green) 배포란?

 

 

블루 그린 배포는 기존 버전의 포드를 그대로 놔둔 상태에서,

새로운 버전의 파드들을 미리 replicas 갯수만큼 생성해둔 뒤,

서비스 라우팅만 신규 버전으로 변경하는 배포 방식을 의미한다.

 

rollingUpdate와 달리 배포 특정 순간에 두 버전의 애플리케이션이 공존하지 않으며,

Recreate 전략처럼 서비스 중단 시간이 발생하지 않는다.

 

하지만 위 그림에서 step2, step3와 같은 시점에는

v1 파드 N개와, v2 파드 N개가 워커 노드에 공존하게 된다.

따라서 해당 시점에는 디플로이먼트에 설정된 replicas 갯수의 두 배에 해당하는 파드가 노드에 올라가있기 때문에

일시적으로 전체 자원을 많이 소모할 수 있다.

 

본 포스팅은 rollingUpdate 배포 전략에 관한 내용을 다루므로 블루 그린 배포는 자세히 다루지 않을 것!

 

 

 

 

 

 

 

 

암튼간에!!!

이렇게 점진적 배포 과정중 파드를 갈아끼우는 과정에서,

파드가 replicas 갯수보다 일시적으로 늘어나거나 줄어들 수 있는데

해당 설정을 할 수 있는 옵션이 maxSurge, maxUnavailable 2가지가 있다.

 

spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
        maxSurge: 2
        maxUnuvailable: 2
 

 

 

 

 

 

이러한 속성은 노드의 자원을 관리해야 할 때 유용하게 쓰이는데,

예를 들어 배포중 일시적으로 파드의 갯수가 n개 늘어날 수 있는데,

n개의 파드를 워커 노드에 추가 배치해야하는 상황에서

만약 워커 노드의 용량이 적절하지 않으면 배포에 실패하게 된다.

 

워커 노드의 용량을 애초에 넉넉히 설정하면 걱정할 케이스는 아니지만,

자원의 효율적인 사용을 위해서

아래 2가지 속성을 상황에 따라 맞게 설정해서 사용하는 것이 좋다.

 

 

rollingUpdate 배포 전략 속성인 2가지

maxSurge, maxUnavailable 옵션에 대해 자세히 알아보자.

 

 

 


 

 

maxSurge

 

롤링 업데이트 도중 전체 파드의 갯수가 디플로이먼트의 replicas로 설정된 값보다

얼마나 더 많이 존재할 수 있는지 설정한다.

단위는 % 또는 파드 갯수로 설정할 수 있으며, 기본값은 25%로 설정된다.

 

case 1) replica 갯수가 10개이고, maxSurge값이 25% 기본값으로 설정되어있다면,

롤링 업데이트 도중 파드는 최대 125%인 12개까지 늘어날 수 있다.

 

case 2) replica 갯수가 10개이고, maxSurge값이 2로 설정되어있다면,

롤링 업데이트 도중 파드는 최대 10 + 2인 12개까지 늘어날 수 있다.

 

 

 

 

maxUnavailable

 

롤링 업데이트 도중 사용 불가능한 상태가 되는 포드의 갯수를 설정한다.

즉 롤링 업데이트 도중에도 사용자의 요청이 처리될 수 있도록

실행중인 파드의 갯수가 일정 값 이하로 내려가지 않도록 유지해준다.

 

maxSurge와 똑같이 단위는 % 또는 파드 갯수로 설정할 수 있으며, 기본값은 25%로 설정된다.

 

case 1) replica 갯수가 10개이고, maxUnavailable값이 25% 기본값으로 설정되어있다면,

롤링 업데이트 도중 적어도 75%의 파드는 사용자의 요청을 처리할 수 있는 상태로 유지된다.

즉 25%인 2개의 파드가 줄어들어 일시적으로 서비스 가능한 파드가 8개로 유지될 수 있다.

 

case 2) replica 갯수가 10개이고, maxSurge값이 2로 설정되어있다면,

롤링 업데이트 도중 서비스 가능한 파드는 최대 10 - 2인 8개로 일시적으로 줄어들 수 있다.

 

 

 

이제 아래에서 위 maxUnavailable, maxSurge 설정 별로

파드가 배포가 되는 과정을 좀 더 자세히 분석해보자!

 

 

 

 


 

 

 

 

 

기존 파드 삭제 + 새 파드 배포 전략 (maxSurge + maxUnavailable 설정)

 

replicas가 4개,

maxUnavailable이 1개,

maxSurge가 2개로 설정되어있을 때

롤링 업데이트 배포가 진행되는 과정을 그려보자.

 

maxUnvailable이 1개면, 배포 과정에서 전체 파드 갯수가 (4 -1) 3개보다 더 떨어지지 않는다.

또한 maxSurge가 2개면, 배포 과정에서 전체 파드 갯수가 (4 + 2) 6개를 초과하지 않는다.

 

 

 

 

 

 

step1)

기존에는 v1 파드가 4개가 워커 노드에 떠있는 상태이다.

(v1 전체 파드 4개 유지)

 

step2)

maxUnavailable 갯수(1) 만큼 v1 파드를 삭제 한다.

(v1 전체 파드 3개 유지, v1 파드 1개 삭제)

 

step3)

maxSurge 갯수를 더한 가능한 전체 파드 갯수(4 + 2 = 6)개가 상한선이 될 수 있도록

v2 파드를 3개 배포한다.

(v1 전체 파드 3개 유지, v2 전체 파드 3개 유지)

 

step4)

다시 maxUnavailable 갯수(1) 만큼 전체 파드 하한선을 (4 - 1)3개로 설정하여

v1 파드를 삭제 한다.

(v1 파드 3개 삭제, v2 전체 파드 3개 유지)

 

step 5)

전체 replicas 설정인 4개가 유지되도록 v2 파드를 1개 추가 배포하여 롤링 업데이트를 마무리한다.

(v2 전체 파드 4개 유지)

 

 

 

 

 

새 파드 배포 => 기존 파드 삭제 전략 (maxSurge만 설정)

 

 

전체 파드의 수가 replicas 갯수보다 줄어들지 않게 하는 설정으로,

maxSurge 값을 N개 (또는 %)로 설정하고

maxUnavailable을 0으로 설정하는 전략이다.

 

이 전략의 특징은, replicas 갯수대로 무조건 유지되고,

롤링 업데이트 배포 과정 동안 오히려 파드가 일시적으로 늘어날 수 있다.

 

만약 파드에 배포하려는 서비스가 트래픽에 엄청 예민한 서비스라면,

파드가 일시적으로 갯수가 줄어드는 타이밍이 전혀 없으므로,

즉 트래픽을 받을 파드가 줄어드는 타이밍이 없으므로 이렇게 설정하는 것이 좋다.

 

단점은 N개 만큼 배포도중 파드가 늘어나기 때문에,

N개의 가용량 (cpu, memory)이 워커 노드에 충분히 있어야 하여 리소스가 그만큼 많이 필요하다.

 

 

아래 이미지는

replicas가 2개로 설정되어있고, maxSurge가 1, maxUnavailable이 0로 설정되었을 때

rollingUpdate가 진행되는 과정이다.

 

 

 

 

 

 

 

 

기존 파드 삭제 => 새 파드 배포 전략 (maxUnavailAble만 설정)

 

이 전략은 전체 파드의 갯수는 파드의 replicas 갯수를 초과하지 않도록 하는 설정이며,

maxUnavailable을 N개 (또는 %),

maxSurge를 0으로 설정하는 전략이다.

 

 

위 전략과 반대로, maxUnavailable 갯수를 설정하기 때문에,

점진적 배포 과정에서 파드가 N개만큼 배포 과정 동안 줄어들 수 있다.

 

파드가 replicas 갯수보다 N개 만큼 적어지는 케이스가 배포 과정에서 생기기 때문에,

그만큼 트래픽에 민감한 서비스라면 해당 전략보다는 위의 전략을 사용하는 것이 안전하다.

파드가 기존의 트래픽에 대응하던 수보다 줄어들어 더 적은 수의 파드에 트래픽이 분배되기 때문이다.

 

서비스 중인 애플리케이션의 트래픽이 민감하지 않고,

워커 노드의 리소스를 효율적(경제적?)으로 사용하고 싶다면 해당 전략을 사용해도 괜찮다.

 

 

아래 이미지는

replicas가 2개로 설정되어있고, maxSurge가 0, maxUnavailable이 1로 설정되었을 때

rollingUpdate가 진행되는 과정이다.

 

 

 

 

 

 

 

 

이렇게 쿠버네티스 환경에서 어플리케이션을 배포할 때는

어플리케이션의 트래픽 민감도나,

워커 노드의 잔여 cpu, memory와 같은 리소스 현황,

v1, v2 버전의 공존 가능 여부 등을 고려하여

위와 같이 적절한 배포 전략과 설정을 상황에 맞게 사용해야 한다!

 

 

 

 

#쿠버네티스 #k8s #deployment #replicaset #배포전략 #recreate #rollingUpdate

 

관련글 더보기

댓글 영역