[Kubernetes] 쿠버네티스 Deployment 란?
[Kubernetes] 쿠버네티스 Deployment 란?
안녕하세요? 정리하는 개발자 워니즈 입니다. 이번시간에는 kubernetes 의 Deployment
라는 개념에 대해서 알아보는 시간을 갖도록 하겠습니다. 지난 시간까지는 Service 의 개념에 대해서 알아봤었는데요. 이번에는 Pod의 배포가 어떻게 되는지 확인해보도록 하겠습니다.
지난 글들은 아래를 참고 해주시면 됩니다.
- 쿠버네티스 1편 : 설치 가이드
- 쿠버네티스 2편 : pod
- 쿠버네티스 3편 : service
- 쿠버네티스 4편 : deployment
- 쿠버네티스 5편 : pod 설정
- 쿠버네티스 6편 : 배포 전략
- 쿠버네티스 7편 : volume
- 쿠버네티스 8편 : daemonset
- 쿠버네티스 9편 : 테라폼을 통한 클러스터 구성
- 쿠버네티스 10편 : eks에서 volume 사용하기
- 쿠버네티스 11편 : helm
- 쿠버네티스 12편 : helm chart template
- 쿠버네티스 13편 : helm deploy
- 쿠버네티스 14편 : fluentd를 통한 log수집
- 쿠버네티스 15편 : chartmuseum
- 쿠버네티스 16편 : 배포툴(ArgoCD 설치방법/사용법)
- 쿠버네티스 17편 : 배포툴(ArgoCD 구성/알람)
- 쿠버네티스 18편 : 쿠버네티스 Autoscailing
- 쿠버네티스 19편 : 쿠버네티스 로깅 아키텍처
1. ReplicaSet
먼저 Deployment의 개념중에서 가장 중요한것은 ReplicaSet
입니다. Replication Controller의 새로운 버전으로 Label Selector를 통해 노드 상의 여러 Pod의 생성/복제/삭제 등의 라이프 싸이클을 관리합니다.
- 지정한 Replica의 숫자만큼 Pod 수 생성/유지
- Label Selector를 통한 Pod 타겟팅
2. Deployment
Kubernetes에서 어플리케이션 단위를 관리하는 Controller 이며 Kubernetes의 최소 유닛인 Pod에 대한 기준스펙을 정의한 Object이다.
Kubernetes에서는 각 Object를 독립적으로 생성하기 보다는 Deployment를 통해서 생성하는 것을 권장하고 있으며, Pod와 ReplicaSet의 기준정보를 지정할 수 있다.
이러한 Deployment는
- Pod의 scale in / out 되는 기준을 정의한다.
- Pod의 배포되고 update 되는 모든 버전을 추적할 수 있다.
- 배포된 Pod에 대한 rollback을 수행할 수 있다.
즉, 개념적으로 Deployment = ReplicaSet +Pod+history이며 ReplicaSet 을 만드는 것보다 더 윗 단계의 선언(추상표현)이다.
3. Templates
Deployment는 위에서 보았듯이 Deployment안에 ReplicaSet과 Pod를 담을 수 잇는 구조로 되어 있습니다.
apiVersion: apps/v1beta1
kind: Deployment
metadata:
# Deployment 객체의 Unique한 명칭
name: deployment-example
spec:
# Deployment label selector for pod
selector:
matchLabels:
app: nginx
# 3 Pods should exist at all times.
replicas: 3
template:
metadata:
labels:
# Pod의 라벨
app: nginx
spec:
containers:
- name: nginx
# Run this image
image: nginx:1.10
4. 실습예제
그럼 위의 개념들을 기반으로 Deployment
에 대한 실습을 진행해보도록 하겠습니다.
4-1. Deployment 파일 생성 및 배포
- Deployment yaml파일 생성
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deployment
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx-container
image: nginx
imagePullPolicy: Always
ports:
- containerPort: 80
- Deployment 생성
# kubectl apply -f /lab/deployment/nginx-deployment.yaml --record=true
- 결과확인
root@master:/k8s/metallb# kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
curl 1 1 1 1 110m
my-nginx-deployment 2 2 2 2 15s
root@master:/k8s/metallb# kubectl get rs
NAME DESIRED CURRENT READY AGE
curl-5cc7b478b6 1 1 1 111m
my-nginx-deployment-6877c7847d 2 2 2 65s
root@master:/k8s/metallb# kubectl get pod
NAME READY STATUS RESTARTS AGE
curl-5cc7b478b6-vwtmj 1/1 Running 2 111m
my-nginx-deployment-6877c7847d-j6nml 1/1 Running 0 71s
my-nginx-deployment-6877c7847d-wr7c9 1/1 Running 0 71s
DESIRED
displays the desired number of replicas of the application, which you define when you create the Deployment. This is the desired state.CURRENT
displays how many replicas are currently running.UP-TO-DATE
displays the number of replicas that have been updated to achieve the desired state.AVAILABLE
displays how many replicas of the application are available to your users.AGE
displays the amount of time that the application has been running.
4-2. Delete Pod (장애 상황 표현)
장애가 발생한 상황을 가정하여 Pod한개를 삭제해보자
root@master:/k8s/metallb# kubectl get pod
NAME READY STATUS RESTARTS AGE
curl-5cc7b478b6-vwtmj 1/1 Running 2 111m
my-nginx-deployment-6877c7847d-j6nml 1/1 Running 0 71s
my-nginx-deployment-6877c7847d-wr7c9 1/1 Running 0 71s
root@master:/k8s/metallb# kubectl delete pod my-nginx-deployment-6877c7847d-j6nml
pod "my-nginx-deployment-6877c7847d-j6nml" deleted
root@master:/k8s/metallb# kubectl get pod
NAME READY STATUS RESTARTS AGE
curl-5cc7b478b6-vwtmj 1/1 Running 2 114m
my-nginx-deployment-6877c7847d-7pm2c 1/1 Running 0 5s
my-nginx-deployment-6877c7847d-j6nml 0/1 Terminating 0 4m4s
my-nginx-deployment-6877c7847d-wr7c9 1/1 Running 0 4m4s
삭제를 하자마자 Deployment에서 선언한 replicas에 의해 신규로 1개의 pod가 생성었음을 알 수 있다.
4-3. Updating a Deployment
- ReplicaSet Edit
ReplicaSet의 replicas의 숫자를 2에서 4로 변경해봅시다.
# kubectl edit deployment my-nginx-deployment
spec:
progressDeadlineSeconds: 600
replicas: 4
결과확인 – 위에서 변경한 갯수대로 변경되었는지 확인합니다.
root@master:/k8s/metallb# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-deployment-6877c7847d-9vwwj 1/1 Running 0 22s
my-nginx-deployment-6877c7847d-gqp2g 1/1 Running 0 22s
my-nginx-deployment-6877c7847d-nx9zq 1/1 Running 0 22s
my-nginx-deployment-6877c7847d-sqg22 1/1 Running 0 22s
- Rolling Back a Deployment
이번에는 이미지를 다른 버전으로 업데이트하고 이전 버전의 이미지로 돌리는 과정을 실습해봅시다.
Pod의 이미지를 nginx:latest 에서 nginx:1.9.1으로 변경해봅니다.
변경에 대한 이력을 기록하기 위해 annotations에 change-cause을 추가할 수도 있습니다. 이것은 추후에 이력조회시 변경내용으로 조회되는 항목입니다.
# gedit /lab/deployment/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deployment
annotations:
kubernetes.io/change-cause: "set image nginx 1.9.1"
spec:
selector:
matchLabels:
run: my-nginx
replicas: 4
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx-container
image: nginx:1.9.1
imagePullPolicy: Always
ports:
- containerPort: 80
Deployment 생성
# kubectl apply -f /lab/deployment/nginx-deployment.yaml
결과확인
root@master:/k8s/metallb# kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
curl 1 1 1 1 110m
my-nginx-deployment 2 2 2 2 15s
root@master:/k8s/metallb# kubectl get rs
NAME DESIRED CURRENT READY AGE
curl-5cc7b478b6 1 1 1 111m
my-nginx-deployment-6877c7847d 2 2 2 65s
root@master:/k8s/metallb# kubectl get pod
NAME READY STATUS RESTARTS AGE
curl-5cc7b478b6-vwtmj 1/1 Running 2 111m
my-nginx-deployment-6877c7847d-j6nml 1/1 Running 0 71s
my-nginx-deployment-6877c7847d-wr7c9 1/1 Running 0 71s
Deployment이력조회
# kubectl rollout history deployment.v1.apps/my-nginx-deployment
deployment.apps/my-nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=/lab/deployment/nginx-deployment.yaml --record=true
2 set image nginx 1.9.1
상세조회를 위해서는 버전옵션을 추가할 수 있습니다.
# kubectl rollout history deployment.v1.apps/my-nginx-deployment --revision=2
deployment.apps/my-nginx-deployment with revision #2
Pod Template:
Labels: pod-template-hash=846f7cc5d6
run=my-nginx
Annotations: kubernetes.io/change-cause: set image nginx 1.9.1
Containers:
my-nginx-container:
Image: nginx:1.9.1
Port: 80/TCP
Host Port: 0/TCP
Environment:
Mounts:
Volumes:
그럼 이제 버전1로 롤백을 해봅시다.
# kubectl rollout undo deployment.v1.apps/my-nginx-deployment --to-revision=1
4-4. Delete Deployment
위에서 언급했지만 Deployment 는 하위의 ReplicaSet과 Pod를 관리하는 리소스입니다. 따라서 Deployment를 삭제하면 하위의 ReplicaSet과 Pod이 함께 삭제됩니다.
# kubectl delete deployment my-nginx-deployment
deployment.extensions "my-nginx-deployment" deleted
# kubectl get rs
No resources found.
# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-deployment-6877c7847d-sm4cs 0/1 Terminating 0 2m35s
my-nginx-deployment-6877c7847d-zbqxk 0/1 Terminating 0 2m38s
my-nginx-deployment-6877c7847d-zxhlq 0/1 Terminating 0 2m38s
5. 마치며..
이번시간에는 Pod의 ReplicaSet을 지정하며 배포를 해보고 해당 리비전으로 롤백해보고, 각 Deployment yaml 파일을 업데이트해서 재배포 해보는 내용을 정리해봤습니다. 확실히 쿠버네티스를 사용하면서 오케스트레이션의 강력함을 배우게 되는것 같습니다. 손쉽게 다수의 VM안에 docker container를 배포해주고 또 자동적으로 관리를 해주면서 해당 POD을 교체해주는 면에 있어서 정말로 편리한것 같습니다.
다음 이시간에는 Pod Configuration
에 대해서 알아보는 시간을 갖겠습니다.