Skip to main content

디플로이먼트 운영하기

Deployment

디플로이먼트는 쿠버네티스가 애플리케이션의 인스턴스를 어떻게 생성하고 업데이트해야 하는지를 지시한다. 디플로이먼트가 만들어지면, 쿠버네티스 컨트롤 플레인이 해당 디플로이먼트에 포함된 애플리케이션 인스턴스가 클러스터의 개별 노드에서 실행되도록 스케쥴한다.

애플리케이션 인스턴스가 생성되면, 쿠버네티스 디플로이먼트 컨트롤러는 지속적으로 이들 인스턴스를 모니터링한다. 인스턴스를 구동 중인 노드가 다운되거나 삭제되면, 디플로이먼트 컨트롤러가 인스턴스 클러스터 내부의 다른 노드의 인스턴스로 교체시켜준다. 이렇게 머신의 장애나 정비에 대응할 수 있는 자동 복구(self-healing) 메커니즘을 제공한다.

오케스트레이션이 없던 환경에서는 설치 스크립트가 애플리케이션을 시작하는데 종종 사용되곤 했지만, 머신의 장애가 발생한 경우 복구를 해주지는 않았다. 쿠버네티스 디플로이먼트는 애플리케이션 인스턴스를 생성해주고 여러 노드에 걸쳐서 지속적으로 인스턴스가 구동되도록 하는 두 가지를 모두 하기 때문에 애플리케이션 관리를 위한 접근법에서 근본적인 차이를 가져다준다.

  • 쿠버네티스 클러스터에서 애플리케이션을 배포하는 가장 일반적인 방식
  • ReplicaSet 컨트롤러를 통해 replica 수 보장 및 scaling 가능
  • Rolling update 또는 Rollback 지원
# vi deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment # 디플로이먼트 정의
metadata:
name: deploy-nginx # 디플로이먼트명
spec:
replicas: 2 # 생성하려는 파드의 개수만큼 지정
selector:
matchLabels:
app: webui
template:
metadata:
labels:
app: webui
spec:
containers:
- name: nginx-container
image: nginx:1.14

# 디플로이먼트 생성
kubectl apply -f deploy-nginx.yaml

# 생성된 두 개의 pod 확인
kubectl get pods
...
deploy-nginx-758f56d7-mxt5x
deploy-nginx-[controller명]-[pod명]

# 레플리카셋명: deploy-nginx-[controller명]
# 파드명: deploy-nginx-[controller명]-[pod명]

# 레플리카셋 확인
kubectl get replicaset
kubectl get rs

# 레이블 확인
kubectl get pods --show-labels

# 레플리카셋 상세 확인
kubectl get rs deploy-nginx-758f56d7 -o wide

# new command shell (파드 모니터링)
watch kubectl get pod -o wide

# 파드 삭제 테스트
# 삭제와 동시에 새로운 파드 자동 생성 확인
kubectl delete pod deploy-nginx-758f56d7-pssth

Deployment는 ReplicaSet 컨트롤러를 이용해 Pod Scaling을 지원

  • Scale-out: 애플리케이션 파드 수를 확장하여 처리능력을 향상
  • Scale-in: 애플리케이션 Pod 수를 줄여서 리소스 낭비 최소화
  • 스케일인의 경우 가장 최근에 만든 파드부터 삭제
# 파드 수를 5개로 증가
kubectl scale deployment deploy-nginx --replicas=5

# 파드 추가 생성 확인
kubectl get pods -o wide

# 2개로 스케일인
kubectl scale deployment deploy-nginx --replicas=2
note

webserver라는 이름으로 deployment를 생성하세요.

  • name: webserver
  • 2 replicas
  • label: app_env_stage=dev
  • container name: webserver
  • container image: nginx:1.14
  • 다음, webserver Deployment의 파드 수를 3개로 확장
# 디플로이먼트 yaml 파일 생성
kubectl create deployment webserver --image=nginx:1.14 --dry-run=client --replicas=2 -o yaml > webserver.yaml

# vi webserver.yaml 수정
apiVersion: apps/v1
kind: Deployment
metadata:
name: webserver
spec:
replicas: 2
selector:
matchLabels:
app_env_stage: dev
template:
metadata:
labels:
app_env_stage: dev
spec:
containers:
- image: nginx:1.14
name: webserver

# 디플로이먼트 생성
kubectl apply -f webserver.yaml

# 디플로이먼트 확인
kubectl get deployment.apps

# 레이블 확인
kubectl get pods --show-labels

# new command shell -> watch kubectl get pods -o wide
# 파드 개수 증가 확인
kubectl scale deployment webserver --replicas=3
note

devops 네임스페이스를 통해 eshop-order 애플리케이션이 배포되었습니다. 서비스 트래픽 증가로 eshop-order에서 동작되는 파드 수를 scale-out 해야 합니다. 파드 수를 5개로 확장하고, 동작 중인 5개의 파드 이름을 /opt/REPORT/2022/eshop-order-pod-list에 기록하세요.

  • Rolling Update: 동작중인 애플리케이션을 서비스 중단 없이 점진적으로 파드 업데이트
# 파드 3개 스케일 아웃
$ kubectl scale deployment deploy-nginx --replicas=3

# nginx-container의 현재 nginx 이미지를 nginx:1.15로 업그레이드
# rollback을 위한 히스토리를 남기기 위해 --record 플래그 추가
# kubectl set image deployment [디플로이먼트] [컨테이너]:[이미지]:[태그] --record
# deprecated
# kubectl set image deployment deploy-nginx nginx-container=nginx:1.15 --record
$ kubectl set image deployment deploy-nginx nginx-container=nginx:1.15
$ kubectl set image deployment deploy-nginx nginx-container=nginx:1.14
$ kubectl annotate deployment/deploy-nginx kubernetes.io/change-cause='downgrade image 1.15 to 1.14'
deployment.apps/deploy-nginx annotated


# 새로운 버전의 레플리카셋 생성 확인
$ kubectl get rs
...
NAME DESIRED CURRENT READY AGE
deploy-nginx-758f56d7 0 0 0 36m
deploy-nginx-7876fbb99b 3 3 3 37s ✅
front-end-5b76b7ff75 0 0 0 39h
front-end-6f49fd5bf9 2 2 2 18h
webserver-57bd8745d8 3 3 3 17m

# rollback 전 히스토리 확인
# 위에서 보는 것처럼 전 버전의 레플리카셋이 남아있기 때문에 리비전 가능
$ kubectl rollout history deployment deploy-nginx

# 전 단계로 롤백
$ kubectl rollout undo deployment deploy-nginx

# 첫 번째 버전으로 롤백
$ kubectl rollout undo deployment deploy-nginx --to-revision 1

# nginx 버전 확인
$ kubectl describe pod deploy-nginx-758f56d7-w2mqk

# 히스토리 확인
$ kubectl rollout history deployment deploy-nginx

# 디플로이먼트 삭제
$ kubectl delete deployments.apps deploy-nginx
note

Deployment를 이용해 nginx 파드를 3개 배포한 다음 컨테이너 이미지 버전을 rolling update하고 update record를 기록합니다. 마지막으로 컨테이너 이미지를 previous version으로 롤백합니다.

  • name: eshop-payment
  • image: nginx
  • image version: 1.16
  • update image version: 1.17
  • label: app=payment, environment=production
# 디플로이먼트 yaml 파일 생성
kubectl create deployment eshop-payment --image=nginx:1.16 --replicas=3 --dry-run=client -o yaml > 3-5.yaml

# vi 3-5.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: eshop-payment
spec:
replicas: 3
selector:
matchLabels:
app: payment
environment: production
template:
metadata:
labels:
app: payment
environment: production
spec:
containers:
- image: nginx:1.16
name: nginx

# 디플로이먼트 생성 / history 기록
# --record flags [deprecated]
# kubectl apply -f 3-5.yaml --record

$ k apply -f 3-5.yaml
deployment.apps/eshop-payment created

$ kubectl annotate deployment/eshop-payment kubernetes.io/change-cause='created deployment eshop-payment'
deployment.apps/eshop-payment annotated

$ k rollout history deployment eshop-payment
deployment.apps/eshop-payment
REVISION CHANGE-CAUSE
1 created deployment eshop-payment

# 1.17 이미지 업그레이드
# kubectl set image deployment eshop-payment nginx=nginx:1.17 --record
$ kubectl annotate deployments.apps/eshop-payment kubernetes.io/change-cause='upgrade image to 1.17'
deployment.apps/eshop-payment annotated

# history 확인
$ kubectl rollout history deployment eshop-payment
deployment.apps/eshop-payment
REVISION CHANGE-CAUSE
1 created deployment eshop-payment
2 upgrade image to 1.17

# 롤백
$ kubectl rollout undo deployment eshop-payment
deployment.apps/eshop-payment rolled back

# history 확인
$ k rollout history deployment eshop-payment
deployment.apps/eshop-payment
REVISION CHANGE-CAUSE
2 upgrade image to 1.17
3 created deployment eshop-payment