만자의 개발일지

[Kubernetes] Deployment란 본문

Kubernetes

[Kubernetes] Deployment란

박만자 2022. 12. 18. 01:04

Deployment

Deployment는 ReplicaSet의 상위 개념으로, Pod와 ReplicaSet에 대한 배포를 관리합니다. 운영 중에 어플리케이션의 새 버전을 배포해야하거나 부하가 증가하면서 Pod를 추가하는 등 여러 가지 동작을 Deployment로 관리할 수 있습니다.

또한 Deployment는 배포에 대한 이력을 관리하는데 만약 배포한 새버전의 문제가 생긴 경우 Deployment를 통해 쉽게 이전 버전으로 롤백할 수 있습니다. 쿠버네티스로 서비스를 운영하는 상황이라면 ReplicaSet만으로 운영하기 보다는  대부분 Deployment단위로 Pod와 ReplicaSet을 관리하여 운영합니다.

 

 

Deployment 구성

Deployment를 구성합니다. 기본적인 구성은 다음과 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: demo-container
          image: nginx:latest
  • .spec.replicas
    • 생성할 Pod의 수를 지정해줍니다.
  • .spec.selector
    • 식별할 Pod를 지정해줍니다.
    • .spec.selector.matchLables를 통해 식별할 Pod의 라벨을 지정해줍니다.
  • .spec.template
    • Pod의 구성을 정의합니다.

 

Deployment 생성

YAML 파일을 구성한 후 다음 명령어를 통해 Deployment를 생성합니다.

$ kubectl apply -f deployment.yaml
deployment.apps/demo-deployment created

 

다음 명령어를 통해 생성된 Deployment를 확인할 수 있습니다.

$ kubectl get deploy
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
demo-deployment   2/2     2            2           4m5s

 

Deployment를 생성하게 되면 Deployment의 이름을 포함하고있는 ReplicaSet이 생성되는 것을 확인할 수 있습니다.

$ kubectl get replicaset
NAME                         DESIRED   CURRENT   READY   AGE
demo-deployment-5dd594bdcb   2         2         2       10s

 

그리고 Deployment에 의해 생성된 Pod는 ReplicaSet의 이름을 가지고 있는 것을 확인할 수 있습니다.

$ kubectl get pod
NAME                               READY   STATUS    RESTARTS   AGE
demo-deployment-5dd594bdcb-7h8tg   1/1     Running   0          31s
demo-deployment-5dd594bdcb-rjrx2   1/1     Running   0          31s

 

Deployment 업데이트

Deployment의 업데이트 전략에는 크게 두 가지가 있습니다.

  • RollingUpdate
  • Recreate

RollingUpdate

RollingUpdate 배포 전략은 무중단 배포 전략으로 기존 버전의 Pod를 하나씩 삭제하고 새 버전의 Pod를 생성하면서 순차적으로 교체하는 방법입니다. Pod가 순차적으로 교체되기 때문에 다운타임이 발생하지 않는다는 장점이 있지만, 이전 버전의 Pod와 새 버전의 Pod가 공존하는 시간이 발생하게됩니다.

 

다음과 같이 Rolling Update를 구성합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate # .spec.strategy.type을 RollingUpdate로 지정 생략시 기본값으로 RollingUpdate로 지정됨
    rollingUpdate:
      maxSurge: 3 
      maxUnavailable: 2
  minReadySeconds: 10 # Pod의 Status가 Ready가 될때까지의 최소대기시간, Pod의 변화를 관찰하기위해 지정해줌
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: demo-container
          image: nginx:latest

RollingUpdate 방식을 사용할 때 maxSurgemaxUnavailable을 명시하여 Rolling Update의 프로세스를 제어할 수 있습니다.

  • maxSurge
    • Rolling Update 시 동시에 생성할 수 있는 Pod의 최대 개수 지정, 개수 혹은 비율(%)로 지정 가능, 기본값 25%
    • 개수로 지정하게 되는 경우 백분율로 올림하여 계산합니다.
    • maxUnavailable이 0일 경우 0이될 수 없습니다.
    • 만약 maxSurge의 값이 30% 라면 업데이트하는 동안 항상 실행(Running) 중인 파드의 수가 최대 replicas의 130%가 되도록 보장합니다.
  • maxUnavailable
    • Rolling Update 시 동시에 삭제할 수 있는 Pod의 최대 개수 지정, 개수 혹은 비율(%)로 지정 가능, 기본값 25%
    • 개수로 지정하게 되는 경우 백분율로 내림하여 계산합니다.
    • maxSurge가 0일 경우 0이될 수 없습니다.
    • 만약 maxUnavailable의 값이 30% 라면 업데이트 하는 동안 항상 사용가능(Available)한 파드의 수가 최소 replicas의 70% 이상이 되도록 보장합니다.

 

다음 명령어를 통해 Deployment를 생성합니다.

$ kubectl apply -f deployment.yaml

 

Deployment의 이미지 부분을 변경합니다.

    spec:
      containers:
        - name: demo-container
          image: httpd:latest

 

다음 명령어를 통해 변경된 내용을 적용합니다.

$ kubectl apply -f deployment.yaml

 

다음 명령어를 통해 Pod의 변화를 관찰하실 수 있습니다.

$ while true;do kubectl describe rs | grep Replicas && kubectl describe rs | grep "Pods Status" && kubectl get deploy; sleep 1; done

 

Rolling Update의 동작 과정은 다음과 같습니다.

  1. v2 버전의 ReplicaSet을 생성한다. 이때 replicas는 (maxSurge + maxUnavailable)이 되고 해당 수치 만큼 Pod를 생성한다.
  2. v1 버전의 ReplicaSet의 replicas가 (replicas - maxUnavailable)로 변경되고, 해당 수치 만큼 Pod를 제거한다.
  3. 배포가 진행되는 동안 v1 버전과 v2 버전에 트래픽이 분산된다.
  4. v2 버전의 replicas를 1 증가시키고, v1 버전의 replicas를 1 감소시킨다. (v2 버전의 replicas가 템플릿에 정의된 replicas와 일치할때까지 반복)
  5. v1 버전의 replicas를 0으로 변경한 후 남은 Pod를 삭제한다.

 

Recreate

Recreate 배포 전략은 가장 단순한 배포 전략으로, 기존 버전의 Pod를 모두 삭제한 후 새 버전의 Pod를 생성하는 방법입니다. Recreate 배포 전략은 단순하지만 위 그림처럼 새 버전의 ReplicaSet이 생성되기 전까지 다운타임이 발생할 수 있다는 단점이 있습니다.

 

다음과 같이 Recreate를 구성합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment
spec:
  replicas: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: Recreate # .spec.strategy.type을 Recreate로 지정
  minReadySeconds: 10 
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: demo-container
          image: nginx:latest

 

 

RollingUpdate와 마찬가지로 Deployment를 배포한 뒤 다음과 같이 Deployment의 이미지 부분을 변경합니다.

    spec:
      containers:
        - name: demo-container
          image: httpd:latest

 

다음 명령어를 통해 변경된 내용을 적용합니다.

$ kubectl apply -f deployment.yaml

Recreate의 동작 원리는 다음과 같습니다. 

  • v1 버전의 ReplicaSet의 replicas를 0으로 변경한다.
  • v1 버전의 Pod가 제거 된다.
  • v2 버전의 ReplicaSet이 생성된다.
  • v2 버전의 Pod가 생성된다.

 

참고

Comments