[컨트롤러] Deployment 재배포 방식 4가지

3 minute read

본문은 인프런의 대세는 쿠버네티스 [초급~중급] 강의를 정리한 글입니다.

모든 본문의 내용과 이미지의 출처는 강의자료에 있습니다.


Deployment

  • 현재 한 서비스가 운영중인데 이 서비스를 업데이트해야 해서 재배포를 해야할 때 도와주는 컨트롤러

업그레이드 방식 4가지

일반적으로 사용되는 업그레이드 방식과 쿠버네티스에서 이 배포방식을 어떻게 응용해서 사용할 수 있는지 알아보자

image-20210407224055190

image-20210407224113318

ReCreate

  • Deployment를 만들면 V1에 Pod들이 만들어진다.
    • Pod 하나당 자원이 하나씩 사용된다고 가정

ReCreate 방식으로 업그레이드를 하면

  1. Deployment는 먼저 Pod들을 삭제한다.
  2. 서비스에 대한 Downtime이 발생, 자원 사용량도 없어지게 된다.
  3. V2에 대한 Pod 2 개를 만들어 준다.

단점

  • Downtime이 발생하기 때문에 일시적인 정지가 가능한 서비스일 경우에만 사용가능한 방법

Rolling Update

  • Deployment를 만들면 V1에 Pod들이 만들어진다.
    • Pod 하나당 자원이 하나씩 사용된다고 가정

Rolling Update 방식으로 업그레이드를 하면

  1. Deployment는 먼저 V2의 Pod 하나를 만들어준다.

  2. 그러면 자원 사용량이 그만큼 늘어난다.

    이 상태에서는 V1과 V2에서 모두 서비스가 되고 있다.

    누군가는 V1에 접속하고, 누군가는 V2에 접속하게 된다.

  3. Deployment는 V1의 Pod 하나를 삭제한다.

  4. 남은 V2 Pod를 하나 더 만든다.

  5. 남은 V1 Pod를 마저 삭제한다.

특징

  • 배포 중간에 추가적인 자원을 요구하지만, 큰 장점은 Downtime이 없다.

Blue/Green

  • Deployment 자체에서 제공되는 기능은 아니다.
  • Deployment를 사용해서 할 수도 있지만
  • ReplicaSet과 같이 Replicas를 관리하는 모든 컨트롤러를 이용해서 할 수 있다.

예시

  1. 컨트롤러를 만들어서 Pod가 생성되면, Pod에는 Label이 있기 때문에 Service에 있는 Selector와 연결된다.

이렇게 운영이 되고 있는 상태에서

  1. 컨트롤러를 하나 더 만드는데, V2 버전에 대한 Pod를 만들고, Label도 V2 버전이다.

    이 때 자원 사용량은 기존의 2배가 된다.

  2. 그리고 Service에 있는 라벨만 V2로 변경해준다.

    기존 pod와의 관계는 끊어버리고, V2버전의 새로운 Pod와 연결이 된다.

특징

  • 순간적으로 변경되기 때문에 서비스에 대한 Downtime은 없다.
  • 만약 V2에 문제가 발생하면, 다시 Service의 Label만 V1으로 변경해주면 기존 서비스로 전환돼서 문제시 롤백이 쉽다는 장점이 있다.
  • 문제가 없으면 기존 버전은 삭제를 하면된다.
  • 상당히 많이 사용되고 안정적인 배포 방식이다.

단점

  • 자원이 두배 필요하다.

Canary

  • 실험체를 통해서 위험을 검증하고 위험이 없다는게 확인되면 정식으로 배포를 하는 방식

image-20210407224811388

방식 1

예시

  1. V1에 대한 Pod가 있고, Label이 붙어져있는 상태에서 Service를 만든다.
    • 이 때, V1이 아닌 ty:app 이라는 Label을 달아서 연결해둔다.

이렇게 운영중인 상태에서

  1. 테스트용으로 컨트롤러를 만들 때, Replicas1로 해서 V2에 대한 Pod를 만들고,

    Pod에 똑같이 ty:app 이라고 라벨을 달면, Service에 연결이 된다.

그러면, 이 Service로 들어오는 트래픽 중에서 일부는 V2로 접근이 될 것이고, 그러면 새 버전에 대한 Test가 이루어진다.

그러다 문제가 발생하면,

  • V2 컨트롤러의 replicas만 0으로 만들면 된다.

특징

  • 불특정 다수에 대한 테스팅을 할 때 사용하는 방식

방식 2

  1. V1은 V1의 Service를 만들고, V2는 V2의 Service를 만든다.

  2. Ingress Controller를 둔다.

    • 유입되는 트래픽을 Url Path에 따라서 Service에 연결을 해주는 역할의 컨트롤러

    • Path 앞에 /v2를 추가한 사람들은 새로운 버전의 서비스를 사용하게 된다.

문제가 없으면,

  1. V2에 대한 Pod를 증가시킨다.
  2. Ingress Controller의 설정을 /v2/app/app 으로 변경 후,
  3. 기존 V1의 내용을 삭제하면 된다.

예시

  • 글로벌한 서비스를 운영할 때, 새로 배포될 서비스는 미국을 테스트 지역으로 설정한다고 정한다면
  • url 앞에 미국에서 접근했으면 앞에 /v2 를 붙이도록 변경한다.
  • 그러면 Ingress Controller가 V2에 대한 서비스로 연결해준다.

특징

  • 특정 Target을 정해서 테스트 할 수 있는 방식

  • DownTime이 없다.
  • 자원 사용량은 테스트를 할 Pod의 수나 V2 Pod를 얼마나 만들어 놓고, V1의 Pod를 다운 시키느냐에 따라서 필요한 자원의 양은 증가하게 된다.

Deployment - ReCreate

  1. Deployment를 만들 때, (Replica에는 없었던) selector와 replicas, template 값을 넣게 된다.

    • 이 값은 직접 Deployment가 pod를 만들어서 관리하기위한 값들이 아니다.

    • Deployment가 ReplicaSet을 만들고, 여기에 값을 지정하기 위한 용도이다.

  2. 그래서 만들어진 ReplicaSet은 내용에 맞게 Pod를 만들게 된다.
  3. 그리고 Service를 만들어서 Pod의 Label에 연결하면 이 Service를 통해서 Pod에 접근할 수 있게 된다.

image-20210407231306564

ReCreate 업그레이드

  1. Deployment의 template을 V1 → V2 로 업데이트 해준다.
  2. Deployment는 V1용 ReplicaSet의 replicas를 0으로 변경한다.
  3. ReplicaSet은 연결된 Pod들을 제거한다.
  4. Service도 연결대상이 없어지게 되기 때문에, 이 때 Downtime이 발생하게 된다.

image-20210407231539182

  1. 새로운 ReplicaSet을 만들면서 template에는 변경된 V2의 Pod 정보를 넣게 된다.
  2. V2 버전의 Pod들이 생성된다.
  3. 기존과 같은 type:app Label이 있어서 Service와 Pod들이 연결된다.
  • revisionHistoryLimit : 기존에 사용되다가 replicas가 0이 된 ReplicaSet을 몇개 남길지 지정 (default : 10)
  • replicas 0인 ReplicaSet은 기존 버전으로 되돌아가고 싶을 때 사용된다.

image-20210407225851743

Rolling Update(default)

  1. 서비스 운영 상태

image-20210407232010163

  1. 새로운 버전 V2로 template을 update 하면서 Rolling Update 시작
  2. 먼저 replicas가 1인 ReplicaSet을 하나 만든다.
  3. V2 pod 하나가 만들어 진다.
  4. 이 때, V1 Label과 똑같은 Label로 만들어지므로 기존 Service와 연결된다.

이 때, V1와 V2 Pod 들에게 트래픽이 분산되어 보내지게 된다.

image-20210407232232515

  1. V1의 ReplicaSet의 replicas를 1로 변경하면서 V1 Pod가 1개만 남는다.
  2. Pod의 삭제가 완료되면 V2의 ReplicaSet의 replicas를 2로 만들어서 V2 Pod를 하나 더 늘린다.

image-20210407232434711

이 과정에서 V2의 ReplicaSet은 Selector(type:app)과 Pod의 Label(type:app)으로 연결이 되는데, Rolling Update에서 지금 순간인 경우 V2의 ReplicaSet이 V1 Pod의 Label(type:app)과 매칭되어 연결될 수 있지 않았나?

⇒ 연결되지 않는 이유

Deployment가 V2 ReplicaSet을 만들 때, 여기에 준 Selector 값만 가지고 ReplicaSet과 Pod의 Label 관계를 매칭하지 않고, 추가적인 Lable과 Selotor를 만들어 준다.

  1. 마지막으로 V1의 replicas를 0으로 만들면서 V1 Pod를 모두 삭제한다.
  • 마찬가지로 ReplicaSet을 지우지 않고 배포를 종료한다.

image-20210407232411955