2 분 소요

디플로이먼트(Deployment) 란?

디플로이먼트는 레플리카셋의 상위 개념으로 볼 수도 있습니다. 레플리카셋을 생성하는 디플로이먼트를 정의할 수 있고, 배포 작업을 좀 더 세분화(롤링 업데이트, 롤 백 등) 하여 조작할 수 있는 기능을 가지고 있습니다.

롤링 기능을 빼면 ReplicaSet과 똑같다.

롤아웃(roll-out)

신제품 또는 정책의 ‘출시’ 또는 ‘릴리즈’라고 할 수 있다.

deployment

Deployment 구성

# /root/test/deployment/test-deployment.yaml

apiVersion: apps/v1
kind: Deployment # ReplicaSet과 Object name만 빼고 다 같은 구성
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
  • apiVersion→ 쿠버네티스의 apps/v1 API를 사용 합니다.
  • kind → 해당 파일을 Deployment의 작업공간 으로 명시 합니다.
  • metadata.name → Deployment의 이름을 설정 합니다.
  • metadata.labels.app → Deployment의 레이블을 설정 합니다.
  • spec.replicas → 파드의 개수를 몇개 유지할 것 인지 설정 합니다. 기본값은 1 입니다.
  • spec.selector → 어떤 레이블의 파드를 선택하여 관리할지에 대한 설정 입니다. 앱 컨테이너의 test-deployment 레이블을 식별하여 해당되는 파드들을 관리하며, 이 필드가 없을 경우 spec.template.metadata.labels에 설정된 내용들을 기본값으로 사용 합니다.
  • spec.template.metadata → 어떤 파드를 실행할지에 대한 정보를 하위에 설정 합니다.
  • spec.template.metadata.name → 생성될 파드의 이름을 지정 합니다.
  • spec.template.metadata.labels.app: → 식별할 레이블
  • spec.spec → 이 하위의 옵션들은 컨테이너에 대한 설정을 합니다. 위 코드에선 컨테이너 명, 이미지, 포트를 지정 했습니다.

Deployment 생성

$ kubectl apply -f /root/test/deployment/test-deployment.yaml
# deployment, replicaset, pods 정보 확인
$ kubectl get deployment,replicaset,pods

# replicaset은 rs로 쓸 수 있다.
$ kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-75675f5897   3         3         3       18s

# 각 파드에 자동으로 생성된 레이블을 보려면
$ kubectl get pods --show-labels
NAME                                READY     STATUS    RESTARTS   AGE       LABELS
nginx-deployment-75675f5897-7ci7o   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-kzszj   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-qqcnn   1/1       Running   0          18s       app=nginx,pod-template-hash=3123191453

'''해당 레이블은 변경하면 안된다!'''

Deployment 세부정보

$ kubectl describe deployments

Deployment 업데이트

$ kubectl set image deployment [디플로이먼트이름] [컨테이너이름]=[이미지]:[버전]

예시 : nginx:1.14.2 이미지 대신 nginx:1.16.1 이미지를 사용하도록 nginx 파드를 업데이트 한다.

$ kubectl set image deployment nginx-deployment nginx=nginx:1.16.1 --record
# --record 커멘드에 의해 history를 기록하게 된다. 안써도 동작은 됌.

roll-out 상태 확인

  • history 조회
$ kubectl rollout history deployment [디플로이먼트 이름]
  • status 확인
$ kubectl rollout status deployment nginx-deployment
deployment "nginx-deployment" successfully rolled out
  • replica set을 확인해 보면 디플로이먼트가 새 레플리카셋을 생성해서 파드를 업데이트 했는지 볼 수 있고, 새 레플리카셋을 최대 3개의 레플리카로 스케일 업, 이전 레플리카셋을 0개의 레플리카로 스케일 다운한다.
$ kubectl get rs
NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-1564180365   3         3         3       6s
nginx-deployment-2035384211   0         0         0       36s

roll-back

때때로 디플로이먼트의 롤백을 원할 수도 있다. 예를 들어 디플로이먼트가 지속적인 충돌로 안정적이지 않은 경우. 또는 오타로 인해 잘못된 버전으로 롤아웃을 했을 경우. 기본적으로 모든 디플로이먼트의 롤아웃 기록은 시스템에 남아있어 언제든지 원할 때 롤백이 가능하다.

예를 들어,

아래와 같이 실수로 nginx:1.161 버전을 롤아웃 했을 경우 히스토리를 살펴보면

$ kubectl rollout history deployment.v1.apps nginx-deployment
deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1           kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true
2           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true
3           kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true

3 번 revision이 잘못된 버전이므로,

롤백 하려면

# 현재 history 기준 바로 한 단계 전으로 롤백
$ kubectl rollout undo deployment.v1.apps nginx-deployment

# 지정한 revision으로 롤백
$ kubectl rollout undo deployment.v1.apps nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back

Deployment 일시 중지, 시작, 재시작

  • 배포 일시 중지 : kubectl rollout pause deployment [디플로이먼트 이름]
$ kubectl rollout pause deployment.v1.apps nginx-deployment
  • 배포 재시작 : kubectl rollout resume deployment [디플로이먼트 이름]
$ kubectl rollout resume deployment.v1.apps nginx-deployment

그 이후 과정

  1. 새로운 레플리카셋 생성
  2. 새로운 파드 생성
  3. 기존 파드 종료
  4. 기존 레플리카셋 비활성화

Deployment Spec Setting

apiVersion: app/v1
kind: Deployment
metadata:
  ...
spec:
  progressDeadlineSeconds: 600 # 디플로이먼트 진행 실패 시, 600초 이후부터 실패로 간주하고 원인을 파악
  revisionHistoryLimit: 10 # 유지해야 하는 레플리카셋의 수
  strategy:
    rollingUpdate:
      maxSurge: 25% # 업데이트 동안 최대로 유지되는 pod의 수 = 높게 설정하면 update가 빠름
                    # replicas가 4개인 경우, maxSurge: 50%인 경우 replicaSet을 4 x 50% = 6개 까지 유지 가능하므로 동시에 2개씩 update가 가능, rollout 속도 조절할 때 사용
      maxUnavailable: 25% # terminating pod 개수를 조절
    type: RollingUpdate # 롤링업데이트 방식을 이용
  replicas:4
  selector:
    ...

Deployment 업데이트

yaml 파일을 이용해서 업데이트 할 수도 있다.

# deployment-test.yaml

apiVersion: app/v1
kind: Deployment
metadata:
  name: deploy-nginx
  annotations:
    kubernetes.io/change-cause: version 1.15 # kubernetes.io/change-cause에 업데이트 하고자 하는 버전을 지정해 줌
  spec:
    ...
  template:
    ...
    spec:
      containers:
      - name: web
        image: nginx:1.15 # 업데이트 하고자 하는 버전을 지정해 줌
        ...

복잡한 set image 커맨드를 쓰지 않고, 아래 커맨드를 통해 롤아웃이 가능하다.

$ kubectl apply -f deployment-test.yaml

난,, 개인적으로 set image가 더 편해보인다..


참고

https://kubernetes.io/ko/docs/concepts/workloads/controllers/deployment/

댓글남기기