본문 바로가기

Container/Kubernetes

[K8S] Deployment - RollingUpdate

Deployment : Rolling update를 위해 만들어진 API resource

  • ReplicaSet을 컨트롤해서 Pod수 조절
  • Rolling update & Rollling Back

 

rolling update allows a Deployment update to take place with zero downtime. It does this by incrementally replacing the current Pods with new ones. The new Pods are scheduled on Nodes with available resources, and Kubernetes waits for those new Pods to start before removing the old Pods.

=> 서비스 중단없이 파드의 버전을 업그레이드 시키는 것.

 

Deployment Strategy

# create
$ kubectl create -f deployment-definition.yaml
# update
$ kubectl apply -f deployment-definition.yaml
$ kubectl set image deployment/myapp-deployment nginx=nginx:1.9.1
# status
$ kubectl rollout status deployment/myapp-deployment
$ kubectl rollout history deployment/myapp-deployment
# rollback
$ kubectl rollout undo deployment/myapp-deployment

 

 


* Rolling Update
kubectl set image deployment <deploy_name> <container_name>=<new_version_image>
ex, kubectl set image deployment app-deploy app=nginx:1.15 --record
* Rollback
kubectl rollout history deployment <deploy_name>
kubectl rollout undo deploy <deploy_name>

 

# kubectl set 명령어

[master ~]$ kubectl set --help
Configure application resources.

 These commands help you make changes to existing application resources.

Available Commands:
  env              Update environment variables on a pod template
  image            Update the image of a pod template
  resources        Update resource requests/limits on objects with pod templates
  selector         Set the selector on a resource
  serviceaccount   Update the service account of a resource
  subject          Update the user, group, or service account in a role binding or cluster role
binding

Usage:
  kubectl set SUBCOMMAND [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

# kubectl set image deployment
# 롤링 업데이트 커멘드

[master ~]$  kubectl set image --help
Update existing container image(s) of resources.

 Possible resources include (case insensitive):

        pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), statefulset (sts), cronjob (cj),
replicaset (rs)

Examples:
  # Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'
  kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
  
  # Update all deployments' and rc's nginx container's image to 'nginx:1.9.1'
  kubectl set image deployments,rc nginx=nginx:1.9.1 --all
  
  # Update image of all containers of daemonset abc to 'nginx:1.9.1'
  kubectl set image daemonset abc *=nginx:1.9.1
  
  # Print result (in yaml format) of updating nginx container image from local file, without hitting the server
  kubectl set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml

 

[실습]

 

[master ~]$ 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



[master ~]$ kubectl create -f deployment-exam1.yaml 
deployment.apps/app-deploy created

# 이전 업데이트 기록 출력
## kubectl rollout history
[master ~]$ kubectl rollout history deployment app-deploy 
deployment.apps/app-deploy 
REVISION  CHANGE-CAUSE
1         <none>
# 아무것도 기록되지 않았다. --record 옵션 넣어줘야 한다.
## --record : 업데이트 과정 history로 기록
### 지우고 다시 만들기
[master ~]$kubectl delete -f deployment-exam1.yaml 
deployment.apps "app-deploy" deleted

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

[master ~]$ kubectl get pods -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
app-deploy-c95d6f7d4-fjtnm   1/1     Running   0          63s   10.5.2.3   node3   <none>           <none>
app-deploy-c95d6f7d4-gqzwg   1/1     Running   0          63s   10.5.1.4   node2   <none>           <none>
app-deploy-c95d6f7d4-ndbm9   1/1     Running   0          63s   10.5.1.5   node2   <none>           <none>

[master ~]$ kubectl describe pod app-deploy-c95d6f7d4-fjtnm 
Name:             app-deploy-c95d6f7d4-fjtnm
Namespace:        default
Priority:         0
Service Account:  default
Node:             node3/192.168.0.6
Start Time:       Wed, 21 Feb 2024 08:35:47 +0000
Labels:           app=webui
                  pod-template-hash=c95d6f7d4
Annotations:      <none>
Status:           Running
IP:               10.5.2.3
IPs:
  IP:           10.5.2.3
Controlled By:  ReplicaSet/app-deploy-c95d6f7d4
Containers:
  web:
    Container ID:   containerd://39f5f1427cbe048ceee83c1aecbc94e7d0a6443c03e8f92699f4befbc36b2f8a
    Image:          nginx:1.14    # check
    Image ID:       docker.io/library/nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
    
[master ~]$ kubectl rollout history deployment app-deploy 
deployment.apps/app-deploy 
REVISION  CHANGE-CAUSE
1         kubectl create --filename=deployment-exam1.yaml --record=true

[master ~]$ 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


[master ~]$ kubectl get pods -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
app-deploy-7499444785-5ljkz   1/1     Running   0          6s    10.5.2.8   node3   <none>           <none>
app-deploy-7499444785-f9trw   1/1     Running   0          19s   10.5.1.8   node2   <none>           <none>
app-deploy-7499444785-pccmm   1/1     Running   0          12s   10.5.2.7   node3   <none>           <none>

[master ~]$ kubectl describe pod app-deploy-7499444785-5ljkz 
Name:             app-deploy-7499444785-5ljkz
Namespace:        default
Priority:         0
Service Account:  default
Node:             node3/192.168.0.6
Start Time:       Wed, 21 Feb 2024 08:49:26 +0000
Labels:           app=webui
                  pod-template-hash=7499444785
Annotations:      <none>
Status:           Running
IP:               10.5.2.8
IPs:
  IP:           10.5.2.8
Controlled By:  ReplicaSet/app-deploy-7499444785
Containers:
  web:
    Container ID:   containerd://b70e169c09b8869b4c9cde7ac734db3c2ad9f9ce1c6303ecfba368b8bf52b584
    Image:          nginx:1.15
    Image ID:       docker.io/library/nginx@sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
    
[master ~]$ 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

[master ~]$ 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
[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)
## 업데이트 일시정지 / 재시작

[master ~]$ kubectl rollout --help
Manage the rollout of one or many resources.
  
 Valid resource types include:

  *  deployments
  *  daemonsets
  *  statefulsets

Examples:
  # Rollback to the previous deployment
  kubectl rollout undo deployment/abc
  
  # Check the rollout status of a daemonset
  kubectl rollout status daemonset/foo
  
  # Restart a deployment
  kubectl rollout restart deployment/abc
  
  # Restart deployments with the app=nginx label
  kubectl rollout restart deployment --selector=app=nginx

Available Commands:
  history       View rollout history
  pause         Mark the provided resource as paused
  restart       Restart a resource
  resume        Resume a paused resource
  status        Show the status of the rollout
  undo          Undo a previous rollout

Usage:
  kubectl rollout SUBCOMMAND [options]
  
  
[master ~]$ kubectl rollout resume deployment app-deploy
deployment.apps/app-deploy resumed

[master ~]$ kubectl rollout pause deployment app-deploy
deployment.apps/app-deploy paused

# 바로 전 단계로 돌아가고 싶을 때 (kubectl rollout undo)
[master ~]$ kubectl rollout undo deployment app-deploy

# --to-revision=[REVISION 값] 옵션 : [REVISION 값]으로 롤백
[master ~]$ kubectl rollout undo deployment app-deploy --to-revision=3
deployment.apps/app-deploy rolled back
maxSurge: 50%
replicas=3 50%=1.5 ==> 3+2(반올림) = 5

maxSurge: 25%
replicas=3 25%=0.75 ==> 3+1 =4
숫자가 올라갈 수록 update 속도가 빨라진다.

maxUnavailable : Terminating 갯수 조절

 

# annotations

# yaml 로 롤링 업데이트 시키기
[master ~]$ cat > deployment-exam2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  annotations:
    kubernetes.io/change-cause: version 1.14
spec:
  progressDeadlineSeconds: 600 # 10분동안 update 진행하지 못하면 update 취소
  revisionHistoryLimit: 10 # revision 갯수 보존
  strategy:
    rollingUpdate:
      maxSurge: 25%			# running 중인걸 최대 몇개까지 운영하는지
      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
        
[master ~]$ kubectl apply -f deployment-exam2.yaml 
deployment.apps/deploy-nginx created
[master ~]$ kubectl get pods -o wide
NAME                           READY   STATUS              RESTARTS   AGE   IP       NODE    NOMINATED NODE   READINESS GATES
deploy-nginx-c95d6f7d4-9kskb   0/1     ContainerCreating   0          3s    <none>   node2   <none>           <none>
deploy-nginx-c95d6f7d4-dc4zf   0/1     ContainerCreating   0          3s    <none>   node4   <none>           <none>
deploy-nginx-c95d6f7d4-s84xs   0/1     ContainerCreating   0          3s    <none>   node3   <none>           <none>

[master ~]$ kubectl describe pod deploy-nginx-c95d6f7d4-9kskb
Name:             deploy-nginx-c95d6f7d4-9kskb
Namespace:        default
Priority:         0
Service Account:  default
Node:             node2/192.168.0.17
Start Time:       Mon, 26 Feb 2024 05:58:43 +0000
Labels:           app=webui
                  pod-template-hash=c95d6f7d4
Annotations:      <none>
Status:           Running
IP:               10.5.1.3
IPs:
  IP:           10.5.1.3
Controlled By:  ReplicaSet/deploy-nginx-c95d6f7d4
  ...
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m58s  default-scheduler  Successfully assigned default/deploy-nginx-c95d6f7d4-9kskb to node2
  Normal  Pulling    4m57s  kubelet            Pulling image "nginx:1.14"
  Normal  Pulled     4m52s  kubelet            Successfully pulled image "nginx:1.14" in 4.985074038s (4.985101539s including waiting)
  Normal  Created    4m52s  kubelet            Created container web
  Normal  Started    4m52s  kubelet            Started container web
  
# yaml 1.15로 수정
[master ~]$ vi deployment-exam2.yaml 
[master ~]$ kubectl apply -f deployment-exam2.yaml 
deployment.apps/deploy-nginx configured
# 정리되는 것 확인
[master ~]$ kubectl get pods -o wide
NAME                            READY   STATUS              RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
deploy-nginx-7499444785-2cdbs   1/1     Running             0          2s    10.5.3.4   node4   <none>           <none>
deploy-nginx-7499444785-5h4n7   0/1     ContainerCreating   0          0s    <none>     node2   <none>           <none>
deploy-nginx-7499444785-mzcp8   1/1     Running             0          4s    10.5.2.4   node3   <none>           <none>
deploy-nginx-c95d6f7d4-9kskb    1/1     Running             0          15m   10.5.1.3   node2   <none>           <none>
deploy-nginx-c95d6f7d4-dc4zf    1/1     Terminating         0          15m   10.5.3.3   node4   <none>           <none>
[master ~]$ kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
deploy-nginx-7499444785-2cdbs   1/1     Running   0          7s    10.5.3.4   node4   <none>           <none>
deploy-nginx-7499444785-5h4n7   1/1     Running   0          5s    10.5.1.4   node2   <none>           <none>
deploy-nginx-7499444785-mzcp8   1/1     Running   0          9s    10.5.2.4   node3   <none>           <none>
[master ~]$ kubectl describe pod deploy-nginx-7499444785-2cdbs
Name:             deploy-nginx-7499444785-2cdbs
Namespace:        default
Priority:         0
Service Account:  default
Node:             node4/192.168.0.15
Start Time:       Mon, 26 Feb 2024 06:14:28 +0000
Labels:           app=webui
                  pod-template-hash=7499444785
Annotations:      <none>
Status:           Running
IP:               10.5.3.4
....
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  31s   default-scheduler  Successfully assigned default/deploy-nginx-7499444785-2cdbs to node4
  Normal  Pulled     30s   kubelet            Container image "nginx:1.15" already present on machine
  Normal  Created    30s   kubelet            Created container web
  Normal  Started    30s   kubelet            Started container web
[master ~]$ kubectl rollout history deployment deploy-nginx 
deployment.apps/deploy-nginx 
REVISION  CHANGE-CAUSE
1         version 1.14
2         version 1.15

 


# [실습]

Strategy : RollingUpdate에서 Recreate으로 바꾸기

Recreate에서는 관련  파라미터들을 사용하지 않으니 전부 지운다.

controlplane ~ ➜  kubectl edit deployments frontend
deployment.apps/frontend edited

 

controlplane ~ ➜  kubectl describe deployments.apps frontend 
Name:               frontend
Namespace:          default
CreationTimestamp:  Sat, 27 Apr 2024 10:10:58 +0000
Labels:             <none>
Annotations:        deployment.kubernetes.io/revision: 2
Selector:           name=webapp
Replicas:           4 desired | 4 updated | 4 total | 4 available | 0 unavailable
StrategyType:       Recreate # 여기
...


# v3로 바꿔서 확인하기
controlplane ~ ➜  kubectl set image deploy frontend simple-webapp=kodekloud/webapp-color:v3
deployment.apps/frontend image updated


controlplane ~ ➜  ./curl-test.sh
Failed

Failed

Failed

Hello, Application Version: v3 ; Color: red OK

Hello, Application Version: v3 ; Color: red OK

Hello, Application Version: v3 ; Color: red OK

Hello, Application Version: v3 ; Color: red OK

Hello, Application Version: v3 ; Color: red OK

Hello, Application Version: v3 ; Color: red OK

Hello, Application Version: v3 ; Color: red OK

# 전부 down되었다가 올라오기 때문에 처음에는 Failed가 된다.

 

반응형

'Container > Kubernetes' 카테고리의 다른 글

[K8S] Statefulset  (0) 2024.02.26
[K8S] DaemonSet  (0) 2024.02.26
[K8S] ReplicaSet  (0) 2024.02.21
[K8S] ReplicationController  (0) 2024.02.19
[K8S] Pod 환경 변수 설정  (0) 2024.02.19