Deployment RollingUpdate를 설명하기에 앞서 무중단 배포에 대해서 얘기 좀 해보겠다
무중단 배포
DevOps에서 말하는 CI&CD 지속적 통합 지속적 배포이다 예를 들자면 쇼핑몰의 서비스를 진행 중인데 고객 관련 로직을 수정을 해서
WAS를 업데이트 즉 새로운 버전으로 배포를 해야 한다 하지만 업데이트 시점에 구 버전을 다운시키고 신 버전을 업 시키게 되면 그 중간에 트래픽 전송을 못하는 시점이 생겨버린다 이 시간에 만약에 쇼핑몰을 이용한다면 어떻게 될까 쇼핑몰을 이용하는 사용자는 원활하게 서비스를
이용하지 못하며 서비스 운영자는 그 시간에 거래가 불가능하기에 금전적 손실이 어마어마하게 발생할 것이다
위의 예시는 조금 최악의 상황을 가정하여 들은 예시지만, 충분히 있을 법한 예시이다. 실제로 이전에는 이와 같이 배포 자체가 하나의 거대한 일이었고, 이를 위해 따로 편성된 팀이 존재했으며 새벽에 배포하는 일이 잦았다. 하지만 최근 무중단 배포 기술을 가진 deploy 자동화 툴들이 개발되며 개발자들이 배포와 운영까지 담당하는 DevOps의 역할을 하게 되었다. 그렇다면 무중단 배포란 무엇인지 다시 풀어 설명해 보자면
무중단 배포란 서비스하는 웹 애플리케이션을 내리지 않으며 새로운 웹 애플리케이션을 올린 후 만약 그 서버가 정상적으로 작동한다면, 그제야 트래픽을 새로운 버전의 애플리케이션으로 보내는 것이다.
RollingUpdate
쿠버네티스에서는 이와 같은 무중단 배포를 지원하게 되는데 대표적인 3가지 방법으로 블루/그린 방법, 롤링 업데이트 방법, 카나리 배포 방법이 있다. 그중 이번 쿠버네티스에서 가장 많이 사용되는 배포 방식 중 하나인 Rolling Update에 대해서 알아보겠다. 롤링 업데이트란 새 버전을 배포하면서, 새 버전 인스턴스를 하나씩 늘려가고 기존 버전의 인스턴스를 하나식 줄여나가는 방식이다. 이러한 경우 새 버전의 인스턴스로 트래픽이 이전되기 전까지 이전 버전과 새 버전의 인스턴스가 동시에 존재할 수 있다는 단점이 있지만, 시스템을 무중단으로 업데이트할 수 있다는 장점이 있다.
이번에 실습할 RollingUpdate의 스펙이다.
먼저 Deployment 템플릿 필드에 대해 자세하게 설명해 보겠다
. spec.strategy 는 이전 파드를 새로운 파드로 대체하는 전략을 명시한다
Recreate
이렇게 하면 업그레이드를 생성하기 전에 파드 종료를 보장할 수 있다. 디플로이먼트를 업그레이드하면, 이전 버전의 모든 파드가 즉시 종료된다.
RollingUpdate
새로운 파드가 점진적으로 추가되고 이전 파드가 중지된다.
여기서 사용할 RollingUpdate는 배포를 했을 때 maxUnavailable와 maxSurge를 명시해서 롤링 업데이트 프로세스를 제어할 수 있다.
공통적으로 업데이트 프로세스 중에 사용할 수 없는 최대 파드의 수를 지정하는 선택적 필드이다. 이 값은 절대 숫자(예: 5) 또는 의도한 파드 비율(예: 10%)이 될 수 있다. 절대 값은 내림해서 백분율로 계산한다.
- maxUnavailable: 이 값을 30%로 설정하면 롤링업데이트 시작 시 즉각 이전 레플리카셋의 크기를 의도한 파드 중 70%를 스케일 다운할 수 있다. 새 파드가 준비되면 기존 레플리카셋을 스케일 다운할 수 있으며, 업데이트 중에 항상 사용 가능한 전체 파드의 수는 의도한 파드의 수의 70% 이상이 되도록 새 레플리카셋을 스케일 업할 수 있다.
- maxSurge: 이 값을 30%로 설정하면 롤링업데이트 시작 시 새 레플리카셋의 크기를 즉시 조정해서 기존 및 새 파드의 전체 개수를 의도한 파드의 130%를 넘지 않도록 한다. 기존 파드가 죽으면 새로운 레플리카셋은 스케일 업할 수 있으며, 업데이트하는 동안 항상 실행하는 총 파드의 수는 최대 의도한 파드의 수의 130%가 되도록 보장한다.
쉽게 얘기하자면 replicas가 3일 때 maxUnavailable이 1이라면 바로 삭제되는 파드의 개수는 1이며 즉
replicas - maxUnavailable = 2이기 때문에 파드를 삭제했을 때 유지되어야 하는 파드의 개수는 2개이다
maxSurge가 1일 때는 RS의 값보다 1개 더 생성되기 때문에
replicas + maxSurge = 4 이므로 최대 파드의 개수는 4개를 넘을 수 없다.
그림으로 나타내보면
직접 배포를 해보면서 어떤 식으로 배포가 되는지 살펴보겠다(이미지는 준비되어 있다)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 5 # 배포할 Pod의 개수
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate # 배포 전략은 RollingUpdate
rollingUpdate:
maxUnavailable: 2 # 즉시 삭제할 수 있는 Pod의 개수는 2개이다
maxSurge: 1 # 최대 Rollout 가능한 Pod의 개수는 6이다
template:
metadata:
labels:
app: my-app
env: production
version: v1
spec:
containers:
- name: my-app
image: nginx:latest
ports:
- containerPort: 80
resources:
limits:
memory: "64Mi"
cpu: "50m"
베포를 하고 Pod를 조화하면 5개의 Pod가 잘 생성된 걸 확인할 수 있고 rollout으로 배포가능한 상태인 것도 확인했다
이번에는 컨테이너의 이미지를 수정해보고 확인해 보겠다.
# 배포하기전에 watch 모드로 RS가 어떻게 상태가 변환이되어 배포되는지 확인해보자
$ kubectl get rs -w
제 배포를 하는 순간 신규 RS의 Pod 1개가 desired 되며 구버전의 RS는 Pod 2개가 즉시 종료되면서
신버전의 RS는 순차적으로 배포되는 걸 확인할 수 있으며 구버전의 RS는 순차적으로 삭제되는 걸 확인할 수 있다.
구버전의 RS 이벤트를 확인해보면 Pod가 삭제된 걸 확인할 수 있다. 신버전의 RS 이벤트를 확인해보면 새롭게 배포된 걸 확인할 수 있다.


마지막으로 deployment 이벤트까지 확인한다면 구버전은 scaled down 신버전으로 scaled up 된 걸 확인할 수 있다

maxUnavailable, maxSurge가 필요한 이유
- 기존에 실행 중인 Pod를 일시에 제거하면 새로운 Pod가 생성되기까지 서비스 중단이 발생할 수 있다
- 모든 OldPod를 NewPod로 전환하는데 시간을 최소화할 수 있다
- 새로운 Pod를 replicas수만큼 미리 배포한다면 리소스가 부족할 수 있다(약2배 리소스 확보 필요)
- 그래서 maxUnavailable을 이용해서 최소 서비스 운영에 영향을 주지 않을 만큼 유지해야 하는 Pod 수를 선언할 수 있다
- maxSurge로 어떤 시점에 동시에 존재할 수 있는 최 대Pod 수를 선언하여 배포 속도를 조절함과 동시에 리소스를 제어할 수 있다
- 유지해야할 Pod수의 상한선과 하한선을 쿠버네티스에게 알리기 위한 옵션이다.
'DevOps > K8s' 카테고리의 다른 글
[K8s] 쿠버네티스 livenessProbe로 파드 헬스 체크 (0) | 2023.02.14 |
---|---|
[K8s] 쿠버네티스 Service 개념 (0) | 2022.12.30 |
[K8s] 쿠버네티스 Deployment의 개념 (2) | 2022.12.22 |
[K8s] 쿠버네티스 ReplicaSet의 개념 (0) | 2022.12.22 |
[K8s] 쿠버네티스 Label과 Selector (0) | 2022.12.21 |