티스토리 뷰

MSA 아키텍처를 많이 지향하고 있는 추세인데, 해당 트렌드에 맞춰서 무중단으로 안전하게 배포할 수 있는 전략이 많이 나오고 있습니다.

 

해당 포스팅에서 Rolling 배포 및 카나리 블루/그린 배포에 대해서 설명하고 kubernetes deployment에 업데이트 전략에 대해 다뤄보겠습니다.

 

보통 Rolling 업데이트, 카나리, 블루/그린 배포는 무중단으로 배포할 수 있는 기법입니다.

 

□ Rolling 배포

Rolling 배포의 정의는 사용중인 서비스 내에서 새 버전을 점진적(순차적)으로 교체하는 것을 말합니다. 관리가 편하지만, 배포 중 하나의 서비스 수가 감소되므로 서버 처리 용량을 미리 고려해야 합니다.

 

Rolling 배포는 사용 중인 Pod 내에서 새 버전으로 점진적으로 교체하는 것으로 무중단 배포의 가장 기본적인 방식입니다. deployment에서 정의해 사용하는 기본적인 방법이므로 yaml 파일을 예시로 같이 한번 살펴보겠습니다.

위에서 말은 Rolling 배포라고 말했지만 아래 설명은 정확히 Deployment 전략중 Recreate, RollingUpdate 전략을 설명합니다.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: stress-core-api
  namespace: dev-service
  labels:
    app: stress-core-api
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 100%
  selector:
    matchLabels:
      app: stress-core-api
  template:
    metadata:
      labels:
        app: stress-core-api
    spec:
      containers:
      - name: stress-core-api
        image: devops:1111

위의 yaml 기준으로 spec.strategy에 type이 RollingUpdate 라는것을 볼 수 있습니다. 그밑에 maxSurge, maxUnavailable 이라는 옵션이 있는데, RollingUpdate는 업데이트 중에 동시에 정지 가능한 최대 파드 수(maxUnavailable)와 업데이트 중에 동시에 생성할 수 있는 최대 파드 수(maxSurge)를 설정할 수 있습니다. 이 설정을 사용하면 추가 리소스를 사용하지 않도록 하거나 많은 리소스를 소비하지 않고 빠르게 전환하는 등 업데이트를 하면서 동작을 제어할 수 있습니다.  즉, 해당 기능을 통해서 전체 Pod을 한번에 중단/배포 하는것이 아니라 n개씩 Pod를 순차적으로 업데이트 할 수 있습니다.

 

조금 더 이해하기 쉽게 설명하자면

 

maxUnavailable: 업데이트 과정에서 spec.replicas 수 기준 최대 이용 불가능 파드 수

maxSurge: 업데이트 과정에서 spec.replicas 수 기준 최대 새로 추가되는 파드 수

 

추가적으로 위의 yaml 파일에서 strategy를 지정하지 않으면 Recreate 전략이 디폴트로 실행됩니다. 하지만 위의 yaml에서 RollingUpdate를 사용한다고 지정했지만.. maxUnavailable과 maxSurge값을 저렇게 주게되면 Recreate 전략과 비슷하게 실행되게 됩니다. 이유는 아래 설명을 통해서 더 자세하게 설명하도록 하겠습니다.

 

아래 test는 2가지 테스트를 진행합니다. 두개의 차이점을 살펴보겠습니다.

1. maxUnavailable: 100% / maxSurge: 50%

2. maxUnavailable: 25% / maxSurge: 25%

 

이제 위와 같이 하면 Pod가 어떤식으로 업데이트 되는지 상세하게 알아보겠습니다. 일단 그림1에는 지금 정상적으로 Pod가 3개 띄워져있습니다.

그림1

위와 같은 설정으로 maxUnavailable: 100%, maxSurge: 50%로 설정하게 되면 아래와같이 한번에 3개의 Pod가 d Terminating 되면서 배포가 됩니다. 그림2를 보면 최대 이용 불가능 Pod 수가 100%로 설정했기때문에 3개가 전부 Terminating 됩니다.

그림2

실제로 k6를 사용해 해당 Pod로 트래픽을 흘려보냈을때 아래 보시는것처럼 무중단으로 배포가 안되는것을 볼 수 있습니다.

이제 무중단으로 배포하기 위해 maxUnavailable: 25% , maxSurge:25%로 설정해서 진행해보겠습니다.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: stress-core-api
  namespace: dev-service
  labels:
    app: stress-core-api
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  selector:
    matchLabels:
      app: stress-core-api
  template:
    metadata:
      labels:
        app: stress-core-api
    spec:
      containers:
      - name: stress-core-api
        image: devops:1111

 

그렇다면 replicas가 3이므로 아래와같은 형식으로 롤링 업데이트가 될것입니다. 3개의 25%는 1이므로 replicas 개수로 카운팅을 해보자면

1. 이전 replicas 3 > 신규 replicas 0

2. 이전 replicas 2 > 신규 replicas 0

3. 이전 replicas 2 > 신규 replicas 1

4. 이전 replicas 1 > 신규 replicas 1

5. 이전 replicas 1 > 신규 replicas 2

6. 이전 replicas 0 > 신규 replicas 3 

 

실제 Pod가 배포될때 과정을 담아보았습니다. 왼쪽 부터 시계방향으로 순서대로 보자면 처음에 신규 Pod를 생성하고 해당 Pod가 Running 상태이면 기존에 있던 Pod 하나를 Terminating하고 이과정을 동일하게 3번 반복해 배포하게 됩니다.

해당 배포 과정을 진행할때 동일하게 k6로 test를 진행했을때는 아래와같이 모두 response가 성공한 모습을 확인할 수 있습니다.

 

이제 위에서 말씀드린것처럼 처음에 maxUnavailable 값을 100% maxSurge 값을 50%로 주었을때 왜 Recreate 전략과 비슷하다고 했는지 이유를 알아보겠습니다.

 

deployment에서 배포전략은 크게 RollingUpdate와 Recreate 전략이 있습니다. Recreate 업데이트 전략은 모든 Pod를 한 번 삭제하고 다시 Pod를 생성하기 때문에 다운타임이 발생합니다. 위에서도 첫번째 테스트에서는 실제로 다운타임이 발생한것을 볼 수 있습니. 하지만 Recreate 업데이트 전략을 사용하면 추가 리소스를 사용하지 않고 전환이 빠르다는 장점이 있습니다. 상용환경에서 해당 전략을 사용하면 클일나겠죠. 

Recreate의 경우에는 기존 replicaset의 replicas를 0으로 하고 이후 신규 replicaset을 생성하고 replicas 수를 늘려나갑니다.

 

마지막으로 아래 yaml에 revisionHistoryLimit 값이 있는데 해당 파라미터는 Recreate나 RollingUpdate를 사용할 때 다른 파라미터를 설정하여 사용할 수 있습니다. 해당 옵션값은 수정 버전 기록을 제한하는 옵션이어서 디플로이먼트가 유지할 replicaset 수 즉, 롤백이 가능한 이력 수라고 생각하시면 됩니다.

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: stress-core-api
  namespace: dev-service
  labels:
    app: stress-core-api
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 100%
  revisionHistoryLimit: 3      
  selector:
    matchLabels:
      app: stress-core-api
  template:
    metadata:
      labels:
        app: stress-core-api
    spec:
      containers:
      - name: stress-core-api
        image: devops:1111

 

□ Blue / Green

이전버전의 서비스를 Blue, 신규버전의 서비스를 Green이라고 칭했을때 Blue와 Green 서비스를 동일하게 두고 라우팅을 순간적으로 바꿔서 신규 버전의 서비스로 트래픽을 흘려보내는 배포 방법입니다. 구버전과 신규버전이 동일하게 있으므로 빠른 롤백과 운영환경에 영향을 주지 않고 실제 서비스 환경으로 신규 버전의 테스트 가능하지만 자원이 두배로 필요하여 비용 측면을 고려해야합니다.

 

□ Canary

Canary 배포는 위험을 빠르게 감지할 수 있는 배포 전략입니다. 구버전 서비스중에 하나를 신규 버전으로 업데이트하고 트래픽을 신규 버전으로 조금씩 점진적으로 옮겨가며 테스트를 진행할 수 있습니다. 만약 테스트 중에 신규 버전이 잘 동작하면 다음 구버전을 신규버전으로 올리고 이렇게 차근차근 배포를 진행할 수 있습니다. 보통 kubernetes에 istio를 활용해 많이 사용하는 배포 전략입니다.

 

 

댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31