Kubernetes 리소스 Deployment에 대해 이해하고 실습해보기

Bakumando·2022년 5월 23일
1

Kubernetes

목록 보기
7/17

들어가기에 앞서...

  • 본 글은 쿠버네티스 시리즈 중의 하나로, kubernetes 실습을 위한 기본 환경 세팅이 이루어져 있지 않은 분은 시리즈 1편을 확인해주시길 바란다.
  • 쿠버네티스 실습 시리즈는 아래 학습 자료를 참고하고 있다.

0. 블로깅 목적

  • Deployment 정의, 주요 기능 및 배포전략을 이해한다.
  • Deployment의 기본적인 생성 및 조회 방법을 이해할 수 있다.
  • Deployment의 롤링 업데이트 적용 및 흐름을 이해할 수 있다.

1. Deployment 정의, 주요 기능 및 배포전략을 이해한다.

1) Deployment의 정의 및 주요 기능

(1) Deployment?

  • 서비스 버전이 업데이트 되어 Pod를 새로운 버전의 이미지 Pod로 교체해야 한다면? 새 버전에 이슈가 발견되어 롤백을 진행해야 한다면?
    => 즉, 업데이트와 롤백 2가지 과정에 관여하는 게 바로 Deployment라고 할 수 있다.

(2) Deployment 기능

  • Pod의 이미지 버전이 갱신될 때 배포 전략을 설정한다.
  • 배포 전략을 지원해주는 게 2가지가 있는데, Recreate 전략과 RollingUpdate 전략이다.
  • Deployment 오브젝트를 생성하면 이에 대응되는 ReplicaSet과 Pod는 자동으로 생성된다. (Deployment를 쓰는 것만으로 ReplicaSet과 Pod을 사용자가 직접 다룰 필요가 없는 것)
    => 사용자는 특수한 목적이 아니라면 Pod와 ReplicaSet이 아닌 Deployment로 워크로드를 관리한다.

2) Deployment 배포 전략

(1) Recreate 전략

  • 기존 ReplicaSet의 Pod를 모두 종료 후, 새 ReplicaSet의 Pod를 새로 생성한다.
  • 다만 운영환경에서는 배포된 서비스의 다운타임이 발생하기 때문에, 어지간하면 안 쓰는 게 좋다. (트래픽이 적으면 고려해볼 수 있을 것)

(2) RollingUpdate 전략

  • 주로 사용되는 전략이다.
  • 세부 설정에 따라 기존 ReplicaSet에서 새로운 ReplicaSet으로 점진적으로 이동하는 전략이다.
  • maxSurge: 업데이트 과정에서 spec.replicas 수 기준 최대 새로 추가되는 파드 수
  • maxUnavailable: 업데이트 과정에 spec.replicas 수 기준 최대 이용 불가능 파드 수

1. [새 파드 생성] => [기존 파드 삭제] 반복 전략:

  • 가령 spec.replicas가 10인데 maxSurge 옵션이 1이면 최대 Pod 수가 11개까지 가능하다는 것이다. 그럼 롤링 업데이트 시에 새로운 레플리카에 Pod를 1개 만든 이후에, 기존 레플리카의 Pod를 1개씩 지워가는 방식으로 이동하게 된다.
  • 참고로 maxUnavailable 옵션은 0으로 고정해야 가능한 전략이다.
  • 장점: 노드 자원의 수가 기본 spec 설정값 미만으로 떨어질 일이 없다.
  • 단점: 노드 자원의 수가 간혹 기본 spec 설정값을 초과하여 클러스터에 부담을 줄 수 있다.

2. [기존 파드 삭제] => [새 파드 생성] 반복 전략:

  • 가령 spec.replicas가 10인데 maxUnavailable이 1이면 최대 Pod 수가 9까지 가능하다는 것이다. 그럼 롤링 업데이트 시에 기존 레플리카의 Pod를 1개를 삭제한 이후에, 새로운 레플리카에 Pod를 1개씩 만드는 방식으로 이동하게 된다.
  • 참고로 maxSurge 옵션은 0으로 고정해야 가능한 전략이다.
  • 장점: 노드 자원의 수가 기본 spec 설정값을 초과할 일이 없다.
  • 단점: 노드 자원의 수가 간혹 기본 spec 설정값 미만으로 떨어져 트래픽 대응 레벨이 떨어질 수 있다.

2. Deployment의 기본적인 생성 및 조회 방법을 이해할 수 있다.

  • yml 파일을 준비하고 실습을 통해 이해해보자.

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      name: hello
      labels:
        app: hello
    spec:
      containers:
      - name: nginx
        image: nginxdemos/hello:plain-text
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
  • 이전 시리즈의 replicaSet.yml 파일과 kind 부분빼고는 다른 게 없다.

  • cat deployment.yml
    • 간단히 파일을 확인부터 시작해본다.

  • kubectl apply -f deployment.yml
    • 생성을 진행한다.

  • kubectl get deploy
    • 간단히 deployment를 조회해본다. deploy는 축약어이다.

  • kubectl get rs
    • rs(replicaSet의 축약어)을 조회하였다. hello 뒤에 prefix값이 랜덤으로 붙은 걸 볼 수 있다.

  • kubectl get pod
    • pod도 조회하였다. 모든 pod가 동일한 replicaSet prefix값이 붙고, 그뒤에 pod 각각의 식별값이 랜덤하게 붙은 걸 볼 수 있다. 이렇게 deployment를 생성하면 Pod와 ReplicarSet이 같이 생성이 된다.

  • watch kubectl get pod --show-labels
    • 새로운 터미널을 열고 watch 모드로도 관찰해보자.
    • 그리고 kubectl delete -f deployment.yml 한다.

3. Deployment의 롤링 업데이트 적용 및 흐름을 이해할 수 있다

  • yml 파일을 준비하고 실습을 통해 이해해보자.

rolling-update.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rolling
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  minReadySeconds: 5
  revisionHistoryLimit: 5
  replicas: 5
  selector:
    matchLabels:
      app: rolling
  template:
    metadata:
      name: rolling
      labels:
        app: rolling
    spec:
      containers:
      - name: nginx
        image: nginxdemos/hello:plain-text
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
  • deployment.yml에서 전반적인 이름이 hello -> rolling으로 바뀌고, spec 부분의 strategy ~ revisionHistoryLimit이 새로 추가된 파일이다.
  • strategy가 없으면 Recreate 전략이 디폴트로 실행된다. RollingUpdate 전략을 적용하려면 strategy.type에 RollingUpdate를 추가해야 한다.
  • 앞서 설명했듯이 rollingUpdate 옵션도 줄 수 있다. 옵션은 maxSurgemaxUnavailable을 잘 사용한다.
  • minReadySeconds는 새로운 Pod를 생성한 뒤의 최소 대기 시간을 설정하는 옵션이다.
  • revisionHistoryLimit은 이미지 버전이 업데이트 될때마다 revision을 만든다. 그 revision을 몇개까지 가지고 있을 건지를 설정하는 옵션이다.

  • cat rolling-update.yml
    • 간단히 파일을 확인부터 시작해본다.

  • kubectl apply -f rolling-update.yml
    • 생성이 잘 되었다.

  • kubectl rollout history deployment rolling
    • 기본적으로는 kubectl이 어떤 CHANGE-CAUSE 명령어로 발생한 revision인지 기록하지 않는다.
    • record 옵션을 통해서 만들면 기록을 남길 수 있다.
    • 아래 명령어를 순서대로 입력하면
    • kubectl delete -f rolling-update.yml
    • kubectl apply -f rolling-update.yml --record
    • kubectl rollout history deployment rolling
      • revision 1이 만들어 질때 사용됐던 CHANGE-CAUSE가 확인됨을 알 수 있다.

  • 이제 새로운 터미널을 열어 watch 모드를 실행시키고 아래 과정을 진행해보자.
  • kubectl set image deployment rolling nginx=nginxdemos/hello:latest --record
    • 롤링 업데이트 입력을 진행하기 전의 출력 상태다.
    • 새로운 rs에 새로운 Pod를 만들고, 기존 rs의 Pod를 삭제하는 모습이다. 이와 같은 과정이 한바퀴 돌때까지 반복된다.
    • 마지막엔 이렇게 종료만 이루어진다.
    • 롤링 업데이트 완료 후 상태이다. 롤링 업데이트 전과 비교하면 Pod 식별값이 전부 바뀐 것을 알 수 있다.

  • kubectl rollout history -f rolling-update.yml
    • 2번 revision과 CHANGE-CAUSE가 기록되어 있음을 알 수 있다.
    • kubectl rollout history deployment rolling도 되지만 이렇게 yml을 통해 history를 볼수도 있다.

  • kubectl rollout undo deployment rolling --to-revision=1
    • undo 를 통해 이전 revision 시점으로 돌아가는 방법이다.
    • 과정은 생략했지만 이것도 롤링 업데이트 처럼 점진적으로 돌아간다.

  • kubectl rollout status deployment rolling
    • 동시에 해당 롤링 업데이트 중에 rollout status를 입력하면, 상태를 확인할 수도 있다. 1 -> 2 -> 3 몇번째 replica가 새롭게 만들어지고 있는 지 보인다.

  • kubectl rollout history -f rolling-update.yml
    • 완료 후 마지막으로 한번더 확인해보자.
    • revision 1은 사라지고 revision 3가 revision 1의 구문을 동일하게 대체하여 만들어졌음을 알 수 있다.
    • 즉, 당연히 복구라고는 해도 Pod를 새롭게 만들면서 돌아간 것이기 때문에 식별자는 처음 revision 1의 Pod들과는 다르며 새로운 revision이 만들어진 것이나 다름 없는 것이다.
    • 다만 undo로 이전 시점과 완전히 동일한 구문을 실행한거나 다름 없으므로, 중복되는 revision 1은 필요가 없어져 삭제된 것이다.
profile
그렇게 바쿠만도는 개발에 퐁당 빠지고 말았답니다.

0개의 댓글