[컨트롤러] Deployment 재배포 방식 4가지
본문은 인프런의 대세는 쿠버네티스 [초급~중급] 강의를 정리한 글입니다.
모든 본문의 내용과 이미지의 출처는 강의자료에 있습니다.
Deployment
- 현재 한 서비스가 운영중인데 이 서비스를 업데이트해야 해서 재배포를 해야할 때 도와주는 컨트롤러
업그레이드 방식 4가지
일반적으로 사용되는 업그레이드 방식과 쿠버네티스에서 이 배포방식을 어떻게 응용해서 사용할 수 있는지 알아보자
ReCreate
- Deployment를 만들면 V1에 Pod들이 만들어진다.
- Pod 하나당 자원이 하나씩 사용된다고 가정
ReCreate 방식으로 업그레이드를 하면
- Deployment는 먼저 Pod들을 삭제한다.
- 서비스에 대한 Downtime이 발생, 자원 사용량도 없어지게 된다.
- V2에 대한 Pod 2 개를 만들어 준다.
단점
- Downtime이 발생하기 때문에 일시적인 정지가 가능한 서비스일 경우에만 사용가능한 방법
Rolling Update
- Deployment를 만들면 V1에 Pod들이 만들어진다.
- Pod 하나당 자원이 하나씩 사용된다고 가정
Rolling Update 방식으로 업그레이드를 하면
-
Deployment는 먼저 V2의 Pod 하나를 만들어준다.
-
그러면 자원 사용량이 그만큼 늘어난다.
이 상태에서는 V1과 V2에서 모두 서비스가 되고 있다.
누군가는 V1에 접속하고, 누군가는 V2에 접속하게 된다.
-
Deployment는 V1의 Pod 하나를 삭제한다.
-
남은 V2 Pod를 하나 더 만든다.
-
남은 V1 Pod를 마저 삭제한다.
특징
- 배포 중간에 추가적인 자원을 요구하지만, 큰 장점은 Downtime이 없다.
Blue/Green
- Deployment 자체에서 제공되는 기능은 아니다.
- Deployment를 사용해서 할 수도 있지만
- ReplicaSet과 같이 Replicas를 관리하는 모든 컨트롤러를 이용해서 할 수 있다.
예시
- 컨트롤러를 만들어서 Pod가 생성되면, Pod에는 Label이 있기 때문에 Service에 있는 Selector와 연결된다.
이렇게 운영이 되고 있는 상태에서
-
컨트롤러를 하나 더 만드는데, V2 버전에 대한 Pod를 만들고, Label도 V2 버전이다.
이 때 자원 사용량은 기존의 2배가 된다.
-
그리고 Service에 있는 라벨만 V2로 변경해준다.
기존 pod와의 관계는 끊어버리고, V2버전의 새로운 Pod와 연결이 된다.
특징
- 순간적으로 변경되기 때문에 서비스에 대한 Downtime은 없다.
- 만약 V2에 문제가 발생하면, 다시 Service의 Label만 V1으로 변경해주면 기존 서비스로 전환돼서 문제시 롤백이 쉽다는 장점이 있다.
- 문제가 없으면 기존 버전은 삭제를 하면된다.
- 상당히 많이 사용되고 안정적인 배포 방식이다.
단점
- 자원이 두배 필요하다.
Canary
- 실험체를 통해서 위험을 검증하고 위험이 없다는게 확인되면 정식으로 배포를 하는 방식
방식 1
예시
- V1에 대한 Pod가 있고, Label이 붙어져있는 상태에서 Service를 만든다.
- 이 때, V1이 아닌
ty:app
이라는 Label을 달아서 연결해둔다.
- 이 때, V1이 아닌
이렇게 운영중인 상태에서
-
테스트용으로 컨트롤러를 만들 때,
Replicas
를1
로 해서 V2에 대한 Pod를 만들고,Pod에 똑같이
ty:app
이라고 라벨을 달면, Service에 연결이 된다.
그러면, 이 Service로 들어오는 트래픽 중에서 일부는 V2로 접근이 될 것이고, 그러면 새 버전에 대한 Test가 이루어진다.
그러다 문제가 발생하면,
- V2 컨트롤러의 replicas만 0으로 만들면 된다.
특징
- 불특정 다수에 대한 테스팅을 할 때 사용하는 방식
방식 2
-
V1은 V1의 Service를 만들고, V2는 V2의 Service를 만든다.
-
Ingress Controller를 둔다.
-
유입되는 트래픽을 Url Path에 따라서 Service에 연결을 해주는 역할의 컨트롤러
-
Path 앞에
/v2
를 추가한 사람들은 새로운 버전의 서비스를 사용하게 된다.
-
문제가 없으면,
- V2에 대한 Pod를 증가시킨다.
- Ingress Controller의 설정을
/v2/app
→/app
으로 변경 후, - 기존 V1의 내용을 삭제하면 된다.
예시
- 글로벌한 서비스를 운영할 때, 새로 배포될 서비스는 미국을 테스트 지역으로 설정한다고 정한다면
- url 앞에 미국에서 접근했으면 앞에
/v2
를 붙이도록 변경한다. - 그러면 Ingress Controller가 V2에 대한 서비스로 연결해준다.
특징
-
특정 Target을 정해서 테스트 할 수 있는 방식
- DownTime이 없다.
- 자원 사용량은 테스트를 할 Pod의 수나 V2 Pod를 얼마나 만들어 놓고, V1의 Pod를 다운 시키느냐에 따라서 필요한 자원의 양은 증가하게 된다.
Deployment - ReCreate
-
Deployment를 만들 때, (Replica에는 없었던) selector와 replicas, template 값을 넣게 된다.
-
이 값은 직접 Deployment가 pod를 만들어서 관리하기위한 값들이 아니다.
-
Deployment가 ReplicaSet을 만들고, 여기에 값을 지정하기 위한 용도이다.
-
- 그래서 만들어진 ReplicaSet은 내용에 맞게 Pod를 만들게 된다.
- 그리고 Service를 만들어서 Pod의 Label에 연결하면 이 Service를 통해서 Pod에 접근할 수 있게 된다.
ReCreate 업그레이드
- Deployment의 template을 V1 →
V2
로 업데이트 해준다. - Deployment는 V1용 ReplicaSet의 replicas를 0으로 변경한다.
- ReplicaSet은 연결된 Pod들을 제거한다.
- Service도 연결대상이 없어지게 되기 때문에, 이 때 Downtime이 발생하게 된다.
- 새로운 ReplicaSet을 만들면서 template에는 변경된 V2의 Pod 정보를 넣게 된다.
- V2 버전의 Pod들이 생성된다.
- 기존과 같은
type:app
Label이 있어서 Service와 Pod들이 연결된다.
revisionHistoryLimit
: 기존에 사용되다가 replicas가 0이 된 ReplicaSet을 몇개 남길지 지정 (default : 10)- replicas 0인 ReplicaSet은 기존 버전으로 되돌아가고 싶을 때 사용된다.
Rolling Update(default)
- 서비스 운영 상태
- 새로운 버전 V2로 template을 update 하면서 Rolling Update 시작
- 먼저 replicas가
1
인 ReplicaSet을 하나 만든다. - V2 pod 하나가 만들어 진다.
- 이 때, V1 Label과 똑같은 Label로 만들어지므로 기존 Service와 연결된다.
이 때, V1와 V2 Pod 들에게 트래픽이 분산되어 보내지게 된다.
- V1의 ReplicaSet의 replicas를 1로 변경하면서 V1 Pod가 1개만 남는다.
- Pod의 삭제가 완료되면 V2의 ReplicaSet의 replicas를 2로 만들어서 V2 Pod를 하나 더 늘린다.
이 과정에서 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를 만들어 준다.
- 마지막으로 V1의 replicas를 0으로 만들면서 V1 Pod를 모두 삭제한다.
- 마찬가지로 ReplicaSet을 지우지 않고 배포를 종료한다.