일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 도커 엔진
- 알고리즘
- java
- 쓰레드
- 스레드
- 도커
- 김영한
- 쿠버네티스
- Kubernetes
- container
- 시작하세요 도커 & 쿠버네티스
- 자바 입출력 스트림
- 리스트
- 컨테이너
- 인프런
- Thread
- 멀티 쓰레드
- 동시성
- java network
- 스레드 제어와 생명 주기
- java socket
- 자바
- filewriter filereader
- Java IO
- LIST
- 실전 자바 고급 1편
- 자료구조
- Docker
- Collection
- 자바 io 보조스트림
- Today
- Total
쌩로그
[Kubernetes] 쿠버네티스 디플로이먼트(Deployment) 본문
목록
- 포스팅 개요
- 본론
2-1. 디플로이먼트 사용하기
2-2. 디플로이먼트를 사용하는 이유 - 요약
1. 포스팅 개요
이 포스팅은 위키북스 출판사의 '시작하세요! 도커/쿠버네티스'의 제 6장 쿠버네티스 시작하기를 학습하며 기록한 포스팅이다.
그 중 레플리카셋, 파드의 배포를 관리하는 디플로이먼트(Deployment)에 대한 내용이다.
2-1. 디플로이먼트 사용하기
레플리카셋만 사용해도 충분히 마이크로서비스 구조의 컨테이너를 구성할 수 있을 것 같지만, 실제 쿠버네티스 운영 환경에서 레플리카셋을 YAML 파일에서 사용하는 경우는 거의 없다.
대부분은 레플리카셋과 파드의 정보를 정의하는 디플로이먼트(Deployment)라는 이름의 오브젝트를 YAML 파일에 정의해 사용하며, 디플로이먼트는 앞으로 파드와 함께 가장 많이 보게 될 오브젝트이다.
디플로이먼트는 레플리카셋의 상위 오브젝트이기 때문에 디플로이먼트를 생성하면 해당 디플로이먼트에 대응하는 레플리카셋도 함께 생성된다.
따라서 디플로이먼트를 사용하면 파드와 레플리카셋을 직접 생성할 필요가 없다.
간단한 예시를 통해 디플로이먼트를 직접 생성해 보도록 한다.
deployment-nginx.yaml
이라는 이름의 yaml 파일을 만들자.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-nginxkl
template:
metadata:
name: my-nginx-pod
labels:
app: my-nginx
spec:
containers:
- name: nginx
image: nginx:1.10
ports:
- containerPort: 80
위의 YAML 파일의 내용을 보면 단지 kind 항목이 Deployment
로 바뀌었을 뿐, 레플리카셋의 YAML 파일에서 변경된 부분은 거의 없어 보인다.
위의 YAML 파일로 디플로이먼트를 생성해보자.
$ kubectl apply -f deployment-nginx.yaml
deployment.apps/my-nginx-deployment created
생성된 디플로이먼트의 목록은 파드나 레플리카셋에서 목록을 출력했던 것과 동일하게 kubectl get deployment
명령어로 출력할 수 있다.
$ kubectl get deploy # ment를 생략한 이름으로도 사용 가능하다.
NAME READY UP-TO-DATE AVAILABLE AGE
my-nginx-deployment 3/3 3 3 72s
my-nginx-deployment
라는 이름의 디플로이먼트가 생성돼 있으며, READY 항목의 3/3이라는 출력을 통해 3개의 파드가 정상적으로 준비됐음을 알 수 있다.
그러나 이전에 설명했던 것처럼 일정 개수의 파드가 유지되도록 생성하는 것은 레플리카셋이기 때문에 실제로는 디플로이먼트와 함께 레플리카셋 또한 생성돼 있을 것이다.
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
my-nginx-deployment-6fdddc5dc8 3 3 3 2m8s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-deployment-6fdddc5dc8-2j8tx 1/1 Running 0 2m14s
my-nginx-deployment-6fdddc5dc8-g5758 1/1 Running 0 2m14s
my-nginx-deployment-6fdddc5dc8-wrml2 1/1 Running 0 2m14s
참고
디플로이먼트로부터 생성된 레플리카셋과 파드는 6fdddc5dc8
라는 특이한 해시값을 포함한 이름으로 생성됐다.
이 해시값은 파드를 정의하는 템플릿으로부터 생성된 것으로 이 해시값에 대해서는 아래의 디플로이먼트를 사용하는 이유에서 다시 다룬다.

이처럼 디플로이먼트를 생성함으로써 레플리카셋이 생성됐고, 레플리카셋이 파드를 생성한 것이다.
따라서 디플로이먼트를 삭제하면 레플리카셋과 파드 또한 함께 삭제된다.
2-2. 디플로이먼트를 사용하는 이유
쿠버네티스는 왜 레플리카셋을 그대로 사용하지 않고 굳이 상위 개념인 디플로이먼트를 다시 정의해 사용하는 것일까???
레플리카셋만으로도 동일한 개수의 파드를 충분히 유지할 수 있는데도, 디플로이먼트를 사용해 간접적으로 레플리카셋을 생성해야 할 이유가 있는지 궁금할 것이다.
디플로이먼트를 사용하는 핵심적인 이유 중 하나는 애플리케이션의 업데이트와 배포를 더욱 편하게 만들기 위해서이다.
디플로이먼트(Deployment)라는 이름의 Deploy 단어의 뜻이 나타내는 것처럼 디플로이먼트는 컨테이너 애플리케이션을 배포하고 관리하는 역할을 담당한다.
예를 들어 애플리케이션을 업데이트할 때 레플리카셋의 변경 사항을 저장하는 리비전(revision)을 남겨 롤백을 가능하게 해주고, 무중단 서비스를 위해 파드의 롤링 업데이트의 전락을 지정할 수도 있다.
좀 더 쉬운 이해를 위해 디플로이먼트를 이용해 애플리케이션의 버전을 업데이트해 배포하는 간단한 예시를 알아보자.
이전과 동일한 YAML 파일인 deployment-nginx.yaml
파일로 디플로이먼트를 생성하되, 이번에는 --record
라고 하는 조금 특수한 옵션을 추가하자.
## --record가 deprecated 되었다. 추후 삭제될 거라고 한다.
$ kubectl apply -f deployment-nginx.yaml --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/my-nginx-deployment created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-deployment-6fdddc5dc8-jrq2m 1/1 Running 0 4m33s
my-nginx-deployment-6fdddc5dc8-qjfhc 1/1 Running 0 4m33s
my-nginx-deployment-6fdddc5dc8-qnm7b 1/1 Running 0 4m33s
만약 컨테이너 애플리케이션의 버전이 업데이트되어 파드의 이미지를 변경해야 한다고 가정해 보자.
이때 디플로이먼트에서 생성된 파드의 이미지를 변경할 때는 kubectl set image
명령 어를 사용할 수 있다.
예를 들어 파드의 이미지의 버전을 nginx:1.11
로 변경하려면 다음과 같이 명령어를 입력하면 된다.nginx=nginx:1.11
은 파드 템플릿에 정의된 containers
항목에서 nginx라는 이름을 가지는 컨테이너의 이미지를 nginx:1.11
으로 변경한다.
$ kubectl set image deployment my-nginx-deployment nginx=nginx:1.11 --record
참고
kubectl set image
명령어 대신 YAML 파일에서 직접 image 항목을 nginx:1.11
으로 변경한 다음 kubectl apply -f
명령어로 적용해도 동일하게 변경된다.
또는 이전에 사용해 보았던 kubectl edit
명령어를 사용해도 된다.
다시 파드의 목록을 확인해 보면 방금 전에 이미지를 업데이트함으로써 새롭게 생성된 파드들이 존재할 것이다.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-deployment-6d48fb5b7-cdtdn 1/1 Running 0 4s
my-nginx-deployment-6d48fb5b7-dc8jz 1/1 Running 0 10s
my-nginx-deployment-6d48fb5b7-k2v47 1/1 Running 0 18s
그 뒤에 레플리카셋의 목록을 출력해보면 무엇이 출력될까요?
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
my-nginx-deployment-6d48fb5b7 3 3 3 40s
my-nginx-deployment-6fdddc5dc8 0 0 0 7m41s
이상하게도 두 개의 레플리카셋이 있다.DESIRED
, CURRENT
등의 항목이 3으로 표시된 my-nginx-deployment-67fff69f59
레플리카셋은 이미지를 업데이트하면서 방금 새롭게 생성된 레플리카셋이다.
다른 하나는 replicas
의 값이 0으로 설정돼 파드를 생성하지는 않고 있지만 6fdddc5dc8
라는 해시값으로 미루어보아 첫 번째에 생성했던 레플리카셋임을 알 수 있다.
디플로이먼트는 파드의 정보를 업데이트함으로써 새로운 레플리카셋과 파드를 생성했음에도 불구하고 이전 버전의 레플리카셋을 삭제하지 않고 남겨두고 있다.
즉, 디플로이먼트는 파드의 정보가 변경되어 업데이트가 발생했을 때, 이전의 정보를 리비전으로서 보존한다.
이러한 리비전 정보는 다음 명령어로 더욱 자세히 확인할 수 있다.
$ kubectl rollout history deployment my-nginx-deployment
deployment.apps/my-nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment-nginx.yaml --record=true
2 kubectl set image deployment my-nginx-deployment nginx=nginx:1.11 --
record=true
--record=true
옵션으로 디플로이먼트를 변경하면 변경 사항을 위와 같이 디플로이먼트에 기록함으로써 해당 버전의 레플리카셋을 보존한다.
만약 이전 버전의 레플리카셋으로 되돌리는 롤백을 하고 싶다면 다음 명령어를 사용할 수 있다. --to-revision
에는 되돌리려는 리비전의 번호를 입력하면 된다.
$ kubectl rollout undo deployment my-nginx-deployment --to-revision=1
deployment.apps/my-nginx-deployment rolled back
위 명령어를 실행한 뒤 다시 레플리카셋의 목록을 확인해 보면 처음에 생성했던 레플리카셋이 다시 3개의 파드를 생성하고 있는 것을 알 수 있다.
물론 방금 새롭게 생성됐던 레플리카셋의 파드 수는 0으로 줄어들어있다.
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
my-nginx-deployment-6d48fb5b7 0 0 0 8m13s
my-nginx-deployment-6fdddc5dc8 3 3 3 15m
참고
파드 템플릿으로부터 계산된 해시값은 각 레플리카셋의 라벨 셀렉터(matchLabels
)에서 pod-template-hash
라는 이름의 라벨값으로서 자동으로 설정된다.
따라서 여러 개의 레플리카셋은 겹치지 않는 라벨을 통해 파드를 생성하게 된다.
$ kubectl get replicasets --show-labels
NAME DESIRED CURRENT READY AGE LABELS
my-nginx-deployment-6d48fb5b7 0 0 0 9m28s app=my-nginx,pod-template-hash=6d48fb5b7
my-nginx-deployment-6fdddc5dc8 3 3 3 16m app=my-nginx,pod-template-hash=6fdddc5dc8
쿠버네티스 리소스의 자세한 정보를 출력하는 kubectl describe
명령어를 사용해 디플로이먼트의 정보를 출력해 보면 현재의 레플리카셋 리비전 정보와 활성화된 레플리카셋 이름을 확인할 수 있다.
$ kubectl describe deploy my-nginx-deployment
...
Annotations: deployment.kubernetes.io/revision: 3
...
OldReplicaSets: my-nginx-deployment-6d48fb5b7 (0/0 replicas created)
NewReplicaSet: my-nginx-deployment-6fdddc5dc8 (3/3 replicas created)
...

- 이처럼 디플로이먼트는 여러 개의 레플리카셋을 관리하기 위한 상위 오브젝트다.
- 디플로이먼트를 사용하면 이러한 레플리카셋의 리비전 관리뿐만 아니라 다양한 파드의 롤링 업데이트 정책을 사용할 수도 있다는 장점이 있다.
- 따라서 쿠버네티스에서도 공식적으로 디플로이먼트를 사용할 것을 권장하고 있다.
지금 당장 레플리카셋의 리비전 및 롤링 업데이트와 관련된 명령어를 기억할 필요는 없다.
디플로이먼트의 기능을 이용한 롤링 업데이트 전략은 후에 다시 설명한다.
지금은 디플로이먼트는 레플리카셋의 상위 수준의 오브젝트이며, 일반적으로 디플로이먼트를 통해 파드를 생성한다
라는 것만 알고 넘어가면 된다.
리소스 정리
해당 명령어로 남아있는 리소스를 한 번에 삭제할 수 있다.
$ kubectl delete deployment,pod,rx -all
3. 요약
- 디플로이먼트는 레플리카셋의 상위 오브젝트이기 때문에 디플로이먼트를 생성하면 해당 디플로이먼트에 대응하는 레플리카셋도 함께 생성된다.
- 디플로이먼트를 사용하면 파드와 레플리카셋을 직접 생성할 필요가 없다.
- 디플로이먼트를 사용하는 핵심적인 이유 중 하나는 애플리케이션의 업데이트와 배포를 더욱 편하게 만들기 위해서이다.
- 디플로이먼트(Deployment)라는 이름의 Deploy 단어의 뜻이 나타내는 것처럼 디플로이먼트는 컨테이너 애플리케이션을 배포하고 관리하는 역할을 담당한다.
'Deploy > Kubernetes' 카테고리의 다른 글
[Kubernetes] 쿠버네티스 서비스(Service) (0) | 2025.03.05 |
---|---|
[Kubernetes] 쿠버네티스 레플리카셋(ReplicaSet) (14) | 2025.02.25 |
[Kubernetes] 쿠버네티스 파드(Pod) (4) | 2025.02.25 |
[Kubernetes] 쿠버네티스 설치 (1) | 2025.02.25 |
[Kubernetes] 쿠버네티스 시작 전 알고가기 (1) | 2025.02.25 |