Step 1 運行基本環境
準備用來部署的yaml檔案如下,為設置 4個持續運行nginx的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx labels: app: my-nginx spec: replicas: 4 minReadySeconds: 1 progressDeadlineSeconds: 60 revisionHistoryLimit: 5 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 1 selector: matchLabels: app: my-nginx template: metadata: labels: app: my-nginx spec: containers: - name: my-nginx image: nginx:1.16.1-alpine ports: - containerPort: 80 resources: limits: memory: "128Mi" cpu: "200m"
定義nginx的service
nginx.service.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 kind: Service apiVersion: v1 metadata: name: nginx-service labels: app: my-nginx spec: type: LoadBalancer selector: app: my-nginx ports: - port: 80 targetPort: 80
接著執行運行指令
1 2 3 4 5 6 $ kubectl create -f nginx.deployment.yml --save -config --record $ kubectl create -f nginx.service.yml --save -config --record service/nginx-service created
--record
可以紀錄rollout的過程紀錄,方便後續執行rolling back動作
可以看到4個nginx的容器正在同一個pod運行中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ kubectl get all NAME READY STATUS RESTARTS AGE pod/my-nginx-75bbd45cb9-2k7gg 1 /1 Running 0 15m pod/my-nginx-75bbd45cb9-4j5zn 1 /1 Running 0 15m pod/my-nginx-75bbd45cb9-5glbj 1 /1 Running 0 15m pod/my-nginx-75bbd45cb9-nhxpx 1 /1 Running 0 15m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96 .0 .1 <none> 443 /TCP 4d11h service/nginx-service LoadBalancer 10.104 .214 .7 localhost 80 :31533/TCP 4m25s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-nginx 4 /4 4 4 15m NAME DESIRED CURRENT READY AGE replicaset.apps/my-nginx-75bbd45cb9 4 4 4 15m
這時準備一個測試是否是可執行 zero downtime的腳本
確認nginx服務是否能夠回傳首頁
1 2 3 4 5 for ((i=1;i<=100;i++)); do curl -s "http://localhost" | grep "<title>.*</title>" sleep 2s done
這時可看到nginx服務正在運作中
1 2 3 4 5 $ bash curl-loop.sh <title> Welcome to nginx!</title><title> Welcome to nginx!</title><title> Welcome to nginx!</title><title> Welcome to nginx!</title>
Step 2. 更換版本並移轉
若要更換 nginx版本 從 nginx:1.16.1-alpine
到 nginx:1.17.8-alpine
更改nginx.deployment.yml
檔案,並使用 kubectl apply -f nginx.deployment.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx labels: app: my-nginx spec: replicas: 4 minReadySeconds: 1 # Default 0 progressDeadlineSeconds: 60 # Default 600s revisionHistoryLimit: 5 #Default 10 strategy: type: RollingUpdate # This is the default rollingUpdate: maxSurge: 1 #Default 25% maxUnavailable: 1 # Default 25% selector: matchLabels: app: my-nginx template: metadata: labels: app: my-nginx spec: containers: - name: my-nginx image: nginx:1.17.8-alpine (更換成新版的nginx) .. .
接著快速的執行 kubectl get all
查看目前Rolling Update狀況
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 $ kubectl get all NAME READY STATUS RESTARTS AGE pod/my-nginx-6b8f7cd7cc-2vk7g 0 /1 ContainerCreating 0 6s pod/my-nginx-6b8f7cd7cc-596cv 0 /1 ContainerCreating 0 5s pod/my-nginx-75bbd45cb9-2k7gg 1 /1 Running 0 36h pod/my-nginx-75bbd45cb9-4j5zn 0 /1 Terminating 0 36h pod/my-nginx-75bbd45cb9-5glbj 1 /1 Running 0 36h pod/my-nginx-75bbd45cb9-nhxpx 1 /1 Running 0 36h NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96 .0 .1 <none> 443 /TCP 5d22h service/nginx-service LoadBalancer 10.104 .214 .7 localhost 80 :31533/TCP 35h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-nginx 3 /4 2 3 36h NAME DESIRED CURRENT READY AGE replicaset.apps/my-nginx-6b8f7cd7cc 2 2 0 6s replicaset.apps/my-nginx-75bbd45cb9 3 3 3 36h
再過一會兒,可看到目前的Pod一樣維持4個nginx服務
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ kubectl get all NAME READY STATUS RESTARTS AGE pod/my-nginx-6b8f7cd7cc-2vk7g 1 /1 Running 0 56s pod/my-nginx-6b8f7cd7cc-596cv 1 /1 Running 0 55s pod/my-nginx-6b8f7cd7cc-5wn5d 1 /1 Running 0 41s pod/my-nginx-6b8f7cd7cc-j9zzk 1 /1 Running 0 36s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96 .0 .1 <none> 443 /TCP 5d22h service/nginx-service LoadBalancer 10.104 .214 .7 localhost 80 :31533/TCP 35h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/my-nginx 4 /4 4 4 36h NAME DESIRED CURRENT READY AGE replicaset.apps/my-nginx-6b8f7cd7cc 4 4 4 56s replicaset.apps/my-nginx-75bbd45cb9 0 0 0 36h
可看到版本移轉完畢後有兩個replicaSets
1 2 3 NAME DESIRED CURRENT READY AGE replicaset.apps/my-nginx-6 b8f7cd7cc 4 4 4 56 s replicaset.apps/my-nginx-75 bbd45cb9 0 0 0 36 h
Step 3:查看移轉狀態
使用 kubectl rollout status deployment <name>
查看rollout狀態
1 2 $ kubectl rollout status deployment my-nginx deployment "my-nginx" successfully rolled out
再次查看 curl-loop.sh
腳本的運作,可看到移轉過程中,都沒有中斷!
1 2 3 4 5 6 7 8 9 10 $ bash curl-loop.sh <title> Welcome to nginx!</title><title> Welcome to nginx!</title><title> Welcome to nginx!</title><title> Welcome to nginx!</title>... <title> Welcome to nginx!</title><title> Welcome to nginx!</title><title> Welcome to nginx!</title>
Step 4:執行回滾 (rollback)
使用 kubectl rollout history deployment [name]
查看移轉歷史紀錄
查看一下移轉後的歷史紀錄revision=2
的內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl rollout history deployment my-nginx --revision=2 deployment.apps/my-nginx with revision Pod Template: Labels: app=my-nginx pod-template-hash=6b8f7cd7cc Annotations: kubernetes.io/change-cause: kubectl create --filename=nginx.deployment.yml --save-config=true --record=true Containers: my-nginx: Image: nginx:1.17.8-alpine Port: 80 /TCP Host Port: 0 /TCP Limits: cpu: 200m memory: 128Mi Environment: <none> Mounts: <none> Volumes: <none>
若要回滾到先前的版本,使用 kubectl rollout undo deployment my-nginx --to-revision=1
1 2 $ kubectl rollout undo deployment my -nginx deployment.apps/my -nginx rolled back
再次查看history,可看到revision為3的回滾紀錄
1 2 3 4 5 6 $ kubectl rollout history deployment my-nginx deployment.apps/my-nginx REVISION CHANGE-CAUSE 2 kubectl create --filename =nginx.deployment.yml --save-config =true --record =true 3 kubectl create --filename =nginx.deployment.yml --save-config =true --record =true
回滾完畢後,使用 kubectl describe deploy [name]
查看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 $ kubectl describe deploy my-nginx Name: my-nginx Namespace: default CreationTimestamp: Thu, 29 Oct 2020 22 :10:47 +0800 Labels: app=my-nginx Annotations: deployment.kubernetes.io/revision: 3 kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"my-nginx"},"name":"my-nginx","namespace":"defaul... kubernetes.io/change-cause: kubectl create --filename=nginx.deployment.yml --save-config=true --record=true Selector: app=my-nginx Replicas: 4 desired | 4 updated | 4 total | 4 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 1 RollingUpdateStrategy: 1 max unavailable, 1 max surge Pod Template: Labels: app=my-nginx Containers: my-nginx: Image: nginx:1.16.1-alpine Port: 80 /TCP Host Port: 0 /TCP Limits: cpu: 200m memory: 128Mi Environment: <none> Mounts: <none> Volumes: <none> ...
參考
Pluralsight: Kubernetes for Developers: Deploying Your Code
https://app.pluralsight.com/library/courses/kubernetes-developers-deploying-code/table-of-contents