Kubernetes/따라하면서 배우는 쿠버네티스

[쿠버네티스] 6-3. Rolling Update를 위한 Deployment

맨날화남 2023. 8. 1. 17:46

 

 

https://youtu.be/L5LDBWrP6QU

 

 

Deployment란?

Deplotyment는 ReplicaSet을 관리하고 ReplicaSet는 Pod를 관리한다.

  • ReplicaSet을 제어해 주는 부모 역할
    • ReplicaSet을 컨트롤해서 pod 수를 조절
  • Deloyment의 목적: Rolling Update & Rolling Back
    • pod를 점진적으로 새로운 것으로 업데이트하여 Deloyment Update가 서비스 중단 없이 이루어질 수 있도록 해준다.

 

 

Deployment definition

ReplicaSet definition Deployment definition
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14
  • kind만 다르고 Replicaset을 쓰듯이 쓸 수 있다.
  • Rolling Update만 쓰지 않는다면 두 개는 완전히 똑같은 컨트롤러다

 

Deployment example

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14
  • label이 app: webui인 Pod를 3개 유지하는 deploy-nginx.yaml 파일 생성

 

TEST

yaml 실행 후 pod 3개 생성된 것을 확인
deploy를 통해 replicaset이 만들어지고 replicaset이 pod를 생성했다.

  • deploy name: deploy-nginx
  • replicaset name: deploy-nginx-6d75c5dd9b
  • pod name: deploy-nginx-6d75c5dd9b-2t2sw
  • deploy의 이름으로 rc의 이름이 정해지고 그 rc의 이름으로 pod의 이름이 정해진다.
  • 그래서 pod의 이름만으로도 rc와 deploy의 이름을 파악할 수 있음

rs를 지워 rs와 pod를 날려도 rs를 관리하는 deploy가 rs를 재생성하여 pod 또한 재생성 된다.

 

 

Rolling Update

  • 서비스를 운영중에 버전을 업데이트 하는 기능
  • kubectl set : 여러가지 리소스들을 업데이트 해줄 때 사용
    • env, image, resources, selector, serviceaccount, subject를 업데이트 할 수 있음
  • Rolling Update
    • kubectl set image deployment <deploy_name> <container_name>=<new_version_image>

  • app이라는 Deployment로 nginx:1.14를 3개 운영중이다. 이걸 1.15로 업데이트 해보자
  • kebuctl set image deployment app-deploy app=nginx:1.15 --record
    • 1.15로 업데이트 하면서 --record로 업데이트 내역을 기록

  • 명령어 실행 후 Deployment는 새로운 ReplicaSet을 하나 새로 생성한다.
    • 새로 생성된 ReplicaSet에서 1.15 pod를 생성하고 생성이 완료되면 1.14의 ReplicaSet에서 pod를 하나 제거
    • 이걸 반복하여 서비스 중단 없이 버전을 업데이트 한다.

 

Deployment example(1)

$cat deployment-exam1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deploy
spec:
  selector:
    matchLabels:
      app: webui
  replicas: 3
  template:
    metadata:
      labels:
        app: webui
    spec:
      containers:
      - image: nginx:1.14
        name: web
        ports:
        - containerPort: 80

TEST

  • 추후 버전 관리를 위해 --record로 history를 기록했으나 해당 옵션은 추후 삭제 예정이라는 알람이 떴다.

kubectl describe pod <pod-name>으로 확인해보면 버전은 1.14

  • 이제 kebuctl set image deployment app-deploy app=nginx:1.15 --record 이 명령으로 업데이트를 해보자

Rolling Update를 실행하면 pod가 차례차례 바뀌는걸 볼 수 있다.
버전 업데이트 확인

  • kubectl rollout status deployment <deployment-name> : 현재상태 확인
  • kubectl rollout pause deployment <deployment-name> : 업데이트 일시정지
  • kubectl rollout resume deployment <deployment-name> : 재시작
  • kubectl rollout history deployment <deployment-name> : 업데이트 내역 확인

update 실행 후 바로 kubectl rollout status deployment <deployment-name>를 실행하면 현재 상태 정보를 실시간으로 확인할 수 있다.
업데이트 도중 일시정지, 일시정지로 인해 구버전 2개와 신버전 2개가 돌아가고 있다.
재실행하면 업데이트가 완료된다.
지금까지 업데이트한 내역도 확인

 

 

Rolling Back

  • 서비스를 운영중에 버전을 롤백하는 기능
  • Rolling Back
    • kubectl rollout undo deploy <deploy_name> : 바로 History 전 단계로 돌아감
    • kubectl rollout undo deploy <deploy_name> --to-revision=<revision-number> : 원하는 revision number로 돌아감

TEST

kubectl rollout history deployment app-deploy로 update history 확인
revision 3를 지정해 1.16버전으로 롤백 해보자
kubectl describe pod으로 1.16버전 확인
3번에 있던 1.1.6이 빠지고 마지막 7에 추가되었다. 이 상태로 undo만 실행하면 어떻게 될까?
전 단계인 6번의 1.19로 돌아가면서 8번에 추가되었다.

 

Rolling Update(2)

  • kubectl set image deployment app-deploy web=nginx:1.15 --record=true
  • 명령어가 너무 길고 복잡하다. 이걸 짧고 간단하게 사용해보자

Deployment example(2)

$cat deployment-exam2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  annotations:
    kubernetes.io/change-cause: version 1.14
spec:
  progressDeadlineSeconds: 600
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      labels:
        app: webui
    spec:
      containers:
      - image: nginx:1.14
        name: web
        ports:
        - containerPort: 80
  • annotations
    • kubernetes.io/change-cause: version 1.14 이렇게 추가하고 이미지도 1.14로 맞춰주고 실행
    • version 1.14라는 이름으로 history가 넘겨진다.
    • 업데이트 할 때는 kubernetes.io/change-cause: version 1.14와 이미지에서 버전을 변경 후 apply
    • kubectl apply -f deployment-exam2.yaml
  • revisionHistoryLimit : kubectl rollout history deployment에서 나오는 revision을 몇개까지 유지할 것인가
  • progressDeadlineSeconds : 600(초) 10분안에 업데이트가 끝나지 않으면 업데이트를 취소
  • maxSurge
    • 업데이트 하면서 running 중인걸 몇개까지 유지할 것인지를 정하는 것
    • 현재 replicas는 3, 3의 25%는 0.75고 반올림하면 1, 3+1 = 4
    • 높일수록 한번에 여러개를 업데이트 하므로 업데이트가 빨라짐
  • maxUnavailable
    • 업데이트중 사용할 수 없는 pod의 수를 정한다. 
    • Terminating 개수를 조절
  • type: “Recreate” or “RollingUpdate”를 설정가능. 기본값은 “RollingUpdate”, Recreate의 경우 Pod가 삭제된 후 재생성

TEST

  • yaml 실행 후 history를 보면 kubernetes.io/change-cause: version 1.14 대로 1.14 들어간거 확인
  • create 말고 apply를 사용했는데 이 둘의 차이는
    • create : 생성만
    • apply : 생성+변경을 같이

yaml을 열어 change-cause와 이미지의 버전을 변경하고 저장
apply 하면 업데이트가 진행된다.
history에도 1.15가 추가됐다.

 

QUESTION

  1. 다음의 조건으로 Deployment를 사용하는 dep-lab.yaml 파일을 생성하고 apply 명령으로 동작시킵니다.
    • labels ( neme: apache, app: main, rel: stable )를 가지는 httpd:2.2 버전의 pod를 2개 히스토리를 기록하며 운영합니다.
    • annotations ( kubernetes.io/change-cause: version 2.2 )를 추가로 설정합니다.
    • deploymene name: dep-mainui
    • container: httpd:2.2
  2. 동작되는 dep-lab.yaml의 이미지를 httpd:2.4버전으로 Rolling update 합니다.
    • 단, apply 명령을 통해 Rolling update 진행합니다.
  3. 현재의 dep-maunui history를 확인하고 rollback 시킵니다.
  4. 현재 동작중인 pod의 httpd 이미지 버전은 어떻게 되는지 확인합니다.

 

ANSWER

1. 다음의 조건으로 Deployment를 사용하는 dep-lab.yaml 파일을 생성하고 apply 명령으로 동작시킵니다.

$cat dep-lab.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dep-mainui
  annotations:
    kubernetes.io/change-cause: version 2.2
spec:
  progressDeadlineSeconds: 600
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 2
  selector:
    matchLabels:
      app: main
  template:
    metadata:
      labels:
        app: main
        name: apache
        rel: stable
    spec:
      containers:
      - image: httpd:2.2
        name: httpd
        ports:
        - containerPort: 80
        
 $kubectl apply -f dep-lab.yaml

 

2. 동작되는 dep-lab.yaml의 이미지를 httpd:2.4버전으로 Rolling update 합니다.

  • 단,  apply 명령을 통해 Rolling update 진행합니다.
$vi dep-lab.yaml

  annotations:
    kubernetes.io/change-cause: version 2.4
...
    spec:
      containers:
      - image: httpd:2.4
...

 $kubectl apply -f dep-lab.yaml

 

3. 현재의 dep-maunui history를 확인하고 rollback 시킵니다.

 

4. 현재 동작중인 pod의 httpd 이미지 버전은 어떻게 되는지 확인합니다.

kubectl describe pod <pod-name>