본문 바로가기

Kubernetes

[Kubernetes] RollingUpdate를 위한 Deployment

반응형

Deployment

 - ReplicaSet을 컨트롤해서 Pod 수를 조절

 - Rolling Update & Rolling Back

 

※ Rolliing Update 란?

- 서비스 중단 없이 버전이 업데이트 되어 고객에게 서비스 제공

 

deploy-nginx.yaml 예제

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

 

deploy-nginx.yaml 실행 후 deploy, replicaset, pod 정보 확인

# kubectl create -f deploy-nginx.yaml 
deployment.apps/deploy-nginx created

# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
deploy-nginx-5cfbcf5f65-7nc55   1/1     Running   0          55s   10.44.0.2   node2.example.com   <none>           <none>
deploy-nginx-5cfbcf5f65-8jwzz   1/1     Running   0          55s   10.36.0.1   node1.example.com   <none>           <none>
deploy-nginx-5cfbcf5f65-hmk6q   1/1     Running   0          55s   10.44.0.1   node2.example.com   <none>           <none>

# kubectl get deploy,rs,pod
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-nginx   3/3     3            3           91s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/deploy-nginx-5cfbcf5f65   3         3         3       91s

NAME                                READY   STATUS    RESTARTS   AGE
pod/deploy-nginx-5cfbcf5f65-7nc55   1/1     Running   0          91s
pod/deploy-nginx-5cfbcf5f65-8jwzz   1/1     Running   0          91s
pod/deploy-nginx-5cfbcf5f65-hmk6q   1/1     Running   0          91s

 

pod, replicaset는 deployment 하위 개념이기 때문에 삭제해도 replicas 3개를 유지하며 deployment 삭제시 모든 자원 삭제 

# kubectl delete pod deploy-nginx-5cfbcf5f65-hmk6q
pod "deploy-nginx-5cfbcf5f65-hmk6q" deleted

# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP          NODE                NOMINATED NODE   READINESS GATES
deploy-nginx-5cfbcf5f65-7nc55   1/1     Running   0          4m19s   10.44.0.2   node2.example.com   <none>           <none>
deploy-nginx-5cfbcf5f65-8jwzz   1/1     Running   0          4m19s   10.36.0.1   node1.example.com   <none>           <none>
deploy-nginx-5cfbcf5f65-lsl6r   1/1     Running   0          3s      10.36.0.2   node1.example.com   <none>           <none>

# kubectl delete rs deploy-nginx-5cfbcf5f65
replicaset.apps "deploy-nginx-5cfbcf5f65" deleted
# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
deploy-nginx-5cfbcf5f65-cmcjg   1/1     Running   0          6s    10.44.0.1   node2.example.com   <none>           <none>
deploy-nginx-5cfbcf5f65-nngzm   1/1     Running   0          6s    10.36.0.3   node1.example.com   <none>           <none>
deploy-nginx-5cfbcf5f65-nv4kc   1/1     Running   0          6s    10.44.0.3   node2.example.com   <none>           <none>

# kubectl delete deployments.apps deploy-nginx 
deployment.apps "deploy-nginx" deleted
# kubectl get pods -o wide
No resources found in default namespace.

 

Deployment Rolling Update & Rolliing Back

 - Rolling Update

    kubectl set image deployment <deploy_name> <container_name>=<new_version_image)

 - RollBack

    kubectl rollout history deployment <deploy_name>

    kubectl rollout undo deploy <deploy_name>  

 

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

 

deployment-exam1.yaml 실행 후 describe 를 통해 컨테이너 이미지 버전 확인

# kubectl create -f deployment-exam1.yaml
deployment.apps/app-deploy created

# kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
app-deploy-86c8cbb88-4hbxh   1/1     Running   0          13s   10.44.0.1   node2.example.com   <none>           <none>
app-deploy-86c8cbb88-ln5cg   1/1     Running   0          13s   10.36.0.2   node1.example.com   <none>           <none>
app-deploy-86c8cbb88-x76dw   1/1     Running   0          13s   10.36.0.1   node1.example.com   <none>           <none>

# kubectl describe pod app-deploy-86c8cbb88-4hbxh 
Name:             app-deploy-86c8cbb88-4hbxh
Namespace:        default
Priority:         0
Service Account:  default
Node:             node2.example.com/10.100.0.102
Start Time:       Sun, 11 Dec 2022 21:41:48 +0900
Labels:           app=webui
                  pod-template-hash=86c8cbb88
Annotations:      <none>
Status:           Running
IP:               10.44.0.1
IPs:
  IP:           10.44.0.1
Controlled By:  ReplicaSet/app-deploy-86c8cbb88
Containers:
  web:
    Container ID:   containerd://f8bcf0259c0242ea568934ac9d5fd2e65856e8dcf9eeb17943022b1ddfd741d7
    Image:          nginx:1.14
    Image ID:       docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 11 Dec 2022 21:41:51 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-gmcr7 (ro)

 

kubectl rollout history : 이전 업데이트 기록 출력 (record 옵션을 추가하지 않고 실행하면 기록이 남지 않음)

# kubectl rollout history deployment app-deploy 
deployment.apps/app-deploy 
REVISION  CHANGE-CAUSE
1         <none>

 

--record 옵션 : 업데이트 과정을 history로 기록

# kubectl create -f deployment-exam1.yaml --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/app-deploy created

# kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
app-deploy-86c8cbb88-r66mh   1/1     Running   0          17s   10.36.0.1   node1.example.com   <none>           <none>
app-deploy-86c8cbb88-tnn67   1/1     Running   0          17s   10.36.0.2   node1.example.com   <none>           <none>
app-deploy-86c8cbb88-z7jkx   1/1     Running   0          17s   10.44.0.1   node2.example.com   <none>           <none>

 

ngingx 1.15 버전으로 rolling update 진행 후 확인

# kubectl set image deployment app-deploy web=nginx:1.15 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/app-deploy image updated

# kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE    IP          NODE                NOMINATED NODE   READINESS GATES
app-deploy-cf8c7477c-8pwlh   1/1     Running   0          101s   10.44.0.1   node2.example.com   <none>           <none>
app-deploy-cf8c7477c-bmrdj   1/1     Running   0          116s   10.36.0.3   node1.example.com   <none>           <none>
app-deploy-cf8c7477c-lwtts   1/1     Running   0          119s   10.44.0.2   node2.example.com   <none>           <none>

# kubectl describe pod app-deploy-cf8c7477c-lwtts 
Name:             app-deploy-cf8c7477c-lwtts
Namespace:        default
Priority:         0
Service Account:  default
Node:             node2.example.com/10.100.0.102
Start Time:       Sun, 11 Dec 2022 21:48:46 +0900
Labels:           app=webui
                  pod-template-hash=cf8c7477c
Annotations:      <none>
Status:           Running
IP:               10.44.0.2
IPs:
  IP:           10.44.0.2
Controlled By:  ReplicaSet/app-deploy-cf8c7477c
Containers:
  web:
    Container ID:   containerd://2c8a5a17e12ded0cc7fb2de112b7336cb721e83f11e9bff37f7d5be5042f8833
    Image:          nginx:1.15
    Image ID:       docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 11 Dec 2022 21:48:48 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8rdl4 (ro)

 

nginx 1.16 버전으로 rolling update 진행 후 status 명령어를 통해 확인

# kubectl set image deployment app-deploy web=nginx:1.16 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/app-deploy image updated

# kubectl rollout status deployment app-deploy 
deployment "app-deploy" successfully rolled out
root@master:~# kubectl rollout status deployment app-deploy 
Waiting for deployment "app-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "app-deploy" rollout to finish: 1 old replicas are pending termination...
deployment "app-deploy" successfully rolled out

 

kubectl rollout pause/resume (중지/재시작)

# kubectl set image deployment app-deploy web=nginx:1.17 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/app-deploy image updated

# kubectl rollout pause deployment app-deploy 
deployment.apps/app-deploy paused

# kubectl rollout status deployment app-deploy 
Waiting for deployment "app-deploy" rollout to finish: 1 out of 3 new replicas have been updated...

# kubectl rollout resume deployment app-deploy 
deployment.apps/app-deploy resumed

# kubectl rollout status deployment app-deploy 
Waiting for deployment "app-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment spec update to be observed...
Waiting for deployment spec update to be observed...
Waiting for deployment "app-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "app-deploy" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "app-deploy" rollout to finish: 1 old replicas are pending termination...
deployment "app-deploy" successfully rolled out

 

history 확인

# kubectl rollout history deployment app-deploy 
deployment.apps/app-deploy 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=deployment-exam1.yaml --record=true
2         kubectl set image deployment app-deploy web=nginx:1.15 --record=true
3         kubectl set image deployment app-deploy web=nginx:1.16 --record=true
4         kubectl set image deployment app-deploy web=nginx:1.17 --record=true

 

kubectl rollout undo : 업데이트 롤백 커맨드(history 기준 한 단계 전)

--to-revision=[REVISION 값] 옵션 : [REVISION 값] 으로 롤백

# kubectl rollout history deployment app-deploy 
deployment.apps/app-deploy 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=deployment-exam1.yaml --record=true
2         kubectl set image deployment app-deploy web=nginx:1.15 --record=true
3         kubectl set image deployment app-deploy web=nginx:1.16 --record=true
4         kubectl set image deployment app-deploy web=nginx:1.17 --record=true

# kubectl rollout undo deployment app-deploy --to-revision=3 
deployment.apps/app-deploy rolled back

# kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
app-deploy-85ddb89cc8-spjck   1/1     Running   0          47s   10.44.0.2   node2.example.com   <none>           <none>
app-deploy-85ddb89cc8-tp4l2   1/1     Running   0          42s   10.36.0.1   node1.example.com   <none>           <none>
app-deploy-85ddb89cc8-vv7jl   1/1     Running   0          45s   10.36.0.2   node1.example.com   <none>           <none>

# kubectl describe pod app-deploy-85ddb89cc8-vv7jl
Name:             app-deploy-85ddb89cc8-vv7jl
Namespace:        default
Priority:         0
Service Account:  default
Node:             node1.example.com/10.100.0.101
Start Time:       Sun, 11 Dec 2022 22:04:43 +0900
Labels:           app=webui
                  pod-template-hash=85ddb89cc8
Annotations:      <none>
Status:           Running
IP:               10.36.0.2
IPs:
  IP:           10.36.0.2
Controlled By:  ReplicaSet/app-deploy-85ddb89cc8
Containers:
  web:
    Container ID:   containerd://02b0e1cb4d17f0254e955a1a6bed69f0c3500f22fe5afec1bd6667ca50737def
    Image:          nginx:1.16
    Image ID:       docker.io/library/nginx@sha256:d20aa6d1cae56fd17cd458f4807e0de462caf2336f0b70b5eeb69fcaaf30dd9c
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 11 Dec 2022 22:04:45 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-x42p7 (ro)

 

--to-revision 없이 롤백하면 이전 단계로 롤백함

# kubectl rollout history deployment app-deploy 
deployment.apps/app-deploy 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=deployment-exam1.yaml --record=true
2         kubectl set image deployment app-deploy web=nginx:1.15 --record=true
4         kubectl set image deployment app-deploy web=nginx:1.17 --record=true
5         kubectl set image deployment app-deploy web=nginx:1.16 --record=true

# kubectl rollout undo deployment app-deploy 
deployment.apps/app-deploy rolled back

# kubectl rollout history deployment app-deploy 
deployment.apps/app-deploy 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=deployment-exam1.yaml --record=true
2         kubectl set image deployment app-deploy web=nginx:1.15 --record=true
5         kubectl set image deployment app-deploy web=nginx:1.16 --record=true
6         kubectl set image deployment app-deploy web=nginx:1.17 --record=true

 

history  확인시 CHANGE-CAUSE 값이 복잡하게 나오기 때문에 간단하게 나올 수 있는 방법 확인

annotations 라는 이름을 이용하여 쿠버네티스 동작 방식을 컨트롤할 수 있도록 서포트 해줌

change-cause 이름에 버전 이름 및 이미지 버전을 추가하면 해당 버전으로 history에 남겨짐

다음번에 실행시 똑같은 파일을 버전 이름을 변경하고 실행하면 새로운 버전으로 실행됨

 

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:
      - name: web
        image: nginx:1.14
        ports:
        - containerPort: 80

 

deployment-exam2.yaml 실행 후 nginx 1.14 버전 확인

기존 yaml 실행시에는 create를 사용했지만 이번에는 apply 명령어를 통해 실행을 하였다.

※ create와 apply 차이

create 명령어는 yaml 파일안에 모든 것을 기술해야 하는 반면 apply 명령어는 부분적인 spec만 주어져도 업데이트가 잘 진행 된다.

 

# kubectl apply -f deployment-exam2.yaml
deployment.apps/deploy-nginx created

# kubectl get pods -o wide
NAME                           READY   STATUS    RESTARTS   AGE   IP          NODE                NOMINATED NODE   READINESS GATES
deploy-nginx-86c8cbb88-dzlb7   1/1     Running   0          22s   10.36.0.1   node1.example.com   <none>           <none>
deploy-nginx-86c8cbb88-ms4kt   1/1     Running   0          22s   10.44.0.2   node2.example.com   <none>           <none>
deploy-nginx-86c8cbb88-zjbql   1/1     Running   0          22s   10.44.0.1   node2.example.com   <none>           <none>

# kubectl describe pod deploy-nginx-86c8cbb88-zjbql
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m12s  default-scheduler  Successfully assigned default/deploy-nginx-86c8cbb88-zjbql to node2.example.com
  Normal  Pulled     2m10s  kubelet            Container image "nginx:1.14" already present on machine
  Normal  Created    2m10s  kubelet            Created container web
  Normal  Started    2m10s  kubelet            Started container web

 

change-cause: version 1.14 → 1.15 변경

image: nginx:1.14 → 1.15 변경

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  annotations:
    kubernetes.io/change-cause: version 1.15
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:
      - name: web
        image: nginx:1.15
        ports:
        - containerPort: 80

 

버전이 변경된 deployment-exam2.ymal 을 실행한 후 history를 확인한다.

# kubectl apply -f deployment-exam2.yaml
deployment.apps/deploy-nginx configured

# kubectl describe pod deploy-nginx-cf8c7477c-wftnp 
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  18s   default-scheduler  Successfully assigned default/deploy-nginx-cf8c7477c-wftnp to node2.example.com
  Normal  Pulled     16s   kubelet            Container image "nginx:1.15" already present on machine
  Normal  Created    16s   kubelet            Created container web
  Normal  Started    15s   kubelet            Started container web
  
  # kubectl rollout history deployment deploy-nginx
deployment.apps/deploy-nginx 
REVISION  CHANGE-CAUSE
1         version 1.14
2         version 1.15

 

 

[참고]

- https://www.youtube.com/watch?v=L5LDBWrP6QU&list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&index=19

반응형