Deployment

이전 포스팅에서는 ReplicaSet에 대해 알아보았다.
ReplicaSet만 있어도 애플리케이션을 배포할 수 있지만, Deployment는 좀 더 많은 기능을 제공한다.
Deployment는 Pod + ReplicaSet의 조합이라고 이해하면 된다.
보통 Pod를 배포할 때 Deployment를 사용해서 배포한다.
그리고 대체로 MSA 환경에서 하나의 서비스를 Deployment라고 생각하면 된다.
Deployment는 무엇을 해주나
그래서 Deployment는 우리를 위해 무엇을 해줄까?
이름에서 알 수 있듯이 애플리케이션의 업데이트와 배포를 좀 더 용이하게 해준다.
애플리케이션을 운영하다보면 업데이트는 필수이다.
버그 발견, 기능 추가, 삭제등등 하루에 몇번이고 업데이트가 일어날 수 있다.
Deployment는 업데이트가 일어날때마다 레플리카셋의 변경 사항을 저장하는 리비전(revision)을 남긴다.
또한 업데이트마다 서비스가 다운되면 안되므로 롤링 업데이트 형식의 무중단 배포를 지원한다.
Deployment를 정의하는 YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: de-nginx
spec:
replicas: 4
selector:
matchLabels:
app: my-nginx
template:
metadata:
name: my-nginx-pod
labels:
app: my-nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
음,,, ReplicaSet과 비교해서 달라진건 kind뿐이다.
바로 Deployment를 생성해보자.
YAML파일로 Deployment 생성하기
kubectl apply -f de-nginx.yaml

Deployment가 생성됐다. 한번 살펴보자.

Deployment는 ReplicaSet + Pod의 조합이라 했으니, ReplicaSet도 살펴보자.

이름이 이상한 ReplicaSet이 생겼지만, Deployment가 생성한것이란걸 알 수 있다.
또 ReplicaSet의 Selector 부분에 pod-template이라는 것이 생겼다.
Pod도 내친김에 살펴보자.

Pod들의 이름을 잘 보면 ReplicaSet의 이름을 그대로 가져와서 끝에 5글자만 다른것을 볼 수 있다.
그리고 7f8cb4999d 이 부분이 pod-template-hash와 일치하는것을 볼 수 있다.
이는 Deployment가 지원하는 기능인 리비전(revision)에서 사용하는 hash값으로, 좀 더 자세히 알아보자.
Revision
앞에서 리비전 기능은 상용 서비스에서 자주 일어나는 업데이트의 기록을 남겨준다고 했었다.
Deployment는 업데이트마다 일종의 커밋을 남겨 변경사항을 저장해준다.
다만, Revision 기능을 사용하려면 Deployment를 생성할 때 --record 옵션을 주어야 한다.
kubectl apply -f de-nginx.yaml --record
기존의 Deployment를 삭제하고 위의 명령어로 다시 만들어보자.

그런다음에, 업데이트를 진행해보자.
현재 PodSpec을 보면 nginx의 이미지에 태그가 없이 latest로 생성되고 있다.
yaml 파일을 수정해보자.
apiVersion: apps/v1
kind: Deployment
metadata:
name: de-nginx
spec:
replicas: 4
selector:
matchLabels:
app: my-nginx
template:
metadata:
name: my-nginx-pod
labels:
app: my-nginx
spec:
containers:
- name: nginx
image: nginx:1.11 # 1.11버전으로 수정
ports:
- containerPort: 80
다시 apply를 해보자.
kubectl apply -f de-nginx.yaml

그런다음 ReplicaSet의 목록을 조회해보면

이제는 ReplicaSet이 2개가 되었다.
아니, 그럼 Pod가 8개가 된건가? 그렇지 않다.

ReplicaSet의 이름을 잘 살펴보면, 7f8cb4999d 라는 이름이 보인다.
이는 이전에 nginx:latest를 컨테이너로 가지는 Deployment를 생성할 때 보았다.
Deployment는 리비전을 위해 이전 버전의 ReplicaSet을 삭제하지 않고, 거기에 속한 Pod만 삭제한다.
그리고 새로운 버전의 ReplicaSet을 생성하고, Pod를 다시 생성한다.
547cd85fbc라는 hash값을 가지는 ReplicaSet이 새롭게 생성됐고, Pod들이 생성된것을 확인할 수 있다.
Revision 정보 확인하기
그동안의 업데이트 기록 즉, Revision 정보를 확인하려면 다음과 같은 명령어를 사용하면 된다.
kubectl rollout history deploy de-nginx

우리는 yaml 파일 수정을 통해 업데이트를 진행했으므로 리비전1과 리비전2의 자세한 업데이트 내역을 확인할 수 없다.
보다 정확한 리비전 정보를 남기고 싶다면,
kubectl set image deploy de-nginx nginx=nginx:1.11 --record
와 같이 CLI 환경에서 바로 수정하는 방법도 있다.
Revision 되돌리기
nginx:latest 버전을 사용하는 이전 리비전으로 돌아가고 싶다면 어떻게 해야할까?
kubectl rollout undo deploy de-nginx --to-revison=1
바로 적용해보자.

ReplicaSet을 확인해보자.

nginx:latest가 적용된 버전으로 돌아왔다!

이런식으로 리비전을 이용해서 마치 git checkout처럼 여러 버전을 넘나들 수 있다.
Deployment 업데이트 전략
리비전을 통해서 업데이트 기록을 관리할 수 있다는것을 알았다.
그렇다면 실제 업데이트는 어떻게 일어날까?
이번에는 nginx:1.12버전으로 업데이트 하면서 중간에 수시로 Pod의 목록을 확인해보자.
kubectl set image deploy de-nginx nginx=nginx:1.12 --record

잘 보이진 않지만, 해쉬값으로 구별하자면 7f8c가 1.11 버전, 74d5가 1.12 버전인것 같다.
Deployment는 기본적으로 업데이트 전략으로 롤링 업데이트 방식을 제공한다.
롤링 업데이트
무중단 배포 방법중 하나로, v1 버전의 Pod를 죽이면서 동시에 v2 버전의 Pod를 생성하는것이다.

롤링 업데이트를 통해서 무중단 배포를 할 수 있지만, v1과 v2 버전의 Pod의 요청을 모두 처리할 수 있어야 한다.
Recreate
롤링 업데이트 이외에도 Recreate 전략을 사용할수도 있다.
v1 버전의 Pod들을 한번에 죽이고 v2 버전의 Pod들을 한번에 생성한다.
그림으로 보자.

Recreate 전략을 사용하려면, YAML파일에 따로 다음과 같이 명시해주어야 한다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: de-nginx
spec:
replicas: 4
strategy: # 전략 명시
type: Recreate
...
이외에도 서비스 오브젝트를 통해 Blue-Green 배포를 할 수 있다.
'Infra > Kubernetes' 카테고리의 다른 글
[Kubernetes] 쿠버네티스 오브젝트 [Namespace] (0) | 2023.07.05 |
---|---|
[Kubernetes] 쿠버네티스 오브젝트 [Service] (0) | 2023.07.05 |
[Kubernetes] 쿠버네티스 오브젝트 [ReplicaSet] (0) | 2023.07.03 |
[Kubernetes] 쿠버네티스 오브젝트 [Pod] (0) | 2023.07.03 |
[Kubernetes] 쿠버네티스 구성 요소 (0) | 2023.07.03 |