強大的自愈能力是 Kubernetes 這類容器編排引擎的一個重要特性。自愈的默認實現方式是自動重啓發生故障的容器。除此以外,用戶還能夠利用 Liveness 和 Readiness 探測機制設置更精細的健康檢查,進而實現以下需求:web
(1)零停機部署。docker
(2)避免部署無效的鏡像。數據庫
(3)更加安全的滾動升級。後端
每一個容器啓動時都會執行一個進程,此進程由 Dockerfile 的 CMD 或 ENTRYPOINT 指定。若是進程退出時返回碼非零,則認爲容器發生故障,Kubernetes 就會根據 restartPolicy 重啓容器。api
一、模擬一個容器發生故障的場景,Pod 配置文件以下:緩存
[root@ren7 yaml]# cat pod1.yaml apiVersion: v1 kind: Pod metadata: name: healthcheck labels: test: healthcheck spec: containers: - name: healthcheck image: reg.yunwei.com/learn/busybox:latest args: - /bin/sh - -c - sleep 10; exit 1 restartPolicy: OnFailure
Pod 的 restartPolicy 設置爲 OnFailure,默認爲 Always。安全
sleep 10; exit 1 模擬容器啓動 10 秒後發生故障。、服務器
二、執行 kubectl apply 建立 Pod,命名爲 healthcheck。app
[root@ren7 yaml]# kubectl apply -f pod1.yaml
pod/healthcheck created
三、過幾分鐘查看 Pod 的狀態:負載均衡
[root@ren7 yaml]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES healthcheck 0/1 CrashLoopBackOff 3 101s 172.20.72.142 192.168.11.5 <none> <none>
可看到容器當前已經重啓了 3次。
在上面的例子中,容器進程返回值非零,Kubernetes 則認爲容器發生故障,須要重啓。但有很多狀況是發生了故障,但進程並不會退出。好比訪問 Web 服務器時顯示 500 內部錯誤,多是系統超載,也多是資源死鎖,此時 httpd 進程並無異常退出,在這種狀況下重啓容器多是最直接最有效的解決方案,那咱們如何利用 Health Check 機制來處理這類場景呢?
Liveness 探測讓用戶能夠自定義判斷容器是否健康的條件。若是探測失敗,Kubernetes 就會重啓容器。
一、建立以下 Pod:
[root@ren7 yaml]# cat pod2.yaml apiVersion: v1 kind: Pod metadata: name: liveness labels: test: liveness spec: containers: - name: liveness image: reg.yunwei.com/learn/busybox:latest args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 livenessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 10 periodSeconds: 5 restartPolicy: OnFailure
啓動進程首先建立文件 /tmp/healthy,30 秒後刪除,在咱們的設定中,若是 /tmp/healthy 文件存在,則認爲容器處於正常狀態,反之則發生故障。
livenessProbe 部分定義如何執行 Liveness 探測:
探測的方法是:經過 cat 命令檢查 /tmp/healthy 文件是否存在。若是命令執行成功,返回值爲零,Kubernetes 則認爲本次 Liveness 探測成功;若是命令返回值非零,本次 Liveness 探測失敗。
initialDelaySeconds: 10 指定容器啓動 10 以後開始執行 Liveness 探測,咱們通常會根據應用啓動的準備時間來設置。好比某個應用正常啓動要花 30 秒,那麼 initialDelaySeconds 的值就應該大於 30。
periodSeconds: 5 指定每 5 秒執行一次 Liveness 探測。Kubernetes 若是連續執行 3 次 Liveness 探測均失敗,則會殺掉並重啓容器。
二、下面建立 Pod liveness:
[root@ren7 yaml]# kubectl apply -f pod2.yaml
pod/liveness created
從配置文件可知,最開始的 30 秒,/tmp/healthy 存在,cat 命令返回 0,Liveness 探測成功
三、這段時間 kubectl describe pod liveness 的 Events部分會顯示正常的日誌。
[root@ren7 yaml]# kubectl describe pod liveness Name: liveness Namespace: default Node: 192.168.11.5/192.168.11.5 Start Time: Sat, 26 Oct 2019 10:59:15 +0800 Labels: test=liveness Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"test":"liveness"},"name":"liveness","namespace":"default"},"spec":... Status: Running IP: 172.20.72.141 Containers: liveness: Container ID: docker://abcecd2fe5d291ac028d8eebbb59ef37b22a558d451b0c401da44c1bcd7962e0 Image: reg.yunwei.com/learn/busybox:latest Image ID: docker-pullable://reg.yunwei.com/learn/busybox@sha256:dd97a3fe6d721c5cf03abac0f50e2848dc583f7c4e41bf39102ceb42edfd1808 Port: <none> Host Port: <none> Args: /bin/sh -c touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 State: Running Started: Sat, 26 Oct 2019 10:59:17 +0800 Ready: True Restart Count: 0 Liveness: exec [cat /tmp/healthy] delay=10s timeout=1s period=5s #success=1 #failure=3 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-qvqql (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-qvqql: Type: Secret (a volume populated by a Secret) SecretName: default-token-qvqql Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 18s default-scheduler Successfully assigned default/liveness to 192.168.11.5 Normal Pulling 17s kubelet, 192.168.11.5 Pulling image "reg.yunwei.com/learn/busybox:latest" Normal Pulled 16s kubelet, 192.168.11.5 Successfully pulled image "reg.yunwei.com/learn/busybox:latest" Normal Created 16s kubelet, 192.168.11.5 Created container liveness Normal Started 16s kubelet, 192.168.11.5 Started container liveness
四、35秒後再次查看日誌
35 秒以後,日誌會顯示 /tmp/healthy 已經不存在,Liveness 探測失敗。再過幾十秒,幾回探測都失敗後,容器會被重啓。
[root@ren7 yaml]# kubectl describe pod liveness Name: liveness Namespace: default Node: 192.168.11.5/192.168.11.5 Start Time: Sat, 26 Oct 2019 10:59:15 +0800 Labels: test=liveness Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"test":"liveness"},"name":"liveness","namespace":"default"},"spec":... Status: Running IP: 172.20.72.141 Containers: liveness: Container ID: docker://abcecd2fe5d291ac028d8eebbb59ef37b22a558d451b0c401da44c1bcd7962e0 Image: reg.yunwei.com/learn/busybox:latest Image ID: docker-pullable://reg.yunwei.com/learn/busybox@sha256:dd97a3fe6d721c5cf03abac0f50e2848dc583f7c4e41bf39102ceb42edfd1808 Port: <none> Host Port: <none> Args: /bin/sh -c touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 State: Running Started: Sat, 26 Oct 2019 10:59:17 +0800 Ready: True Restart Count: 0 Liveness: exec [cat /tmp/healthy] delay=10s timeout=1s period=5s #success=1 #failure=3 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-qvqql (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-qvqql: Type: Secret (a volume populated by a Secret) SecretName: default-token-qvqql Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 63s default-scheduler Successfully assigned default/liveness to 192.168.11.5 Normal Pulling 62s kubelet, 192.168.11.5 Pulling image "reg.yunwei.com/learn/busybox:latest" Normal Pulled 61s kubelet, 192.168.11.5 Successfully pulled image "reg.yunwei.com/learn/busybox:latest" Normal Created 61s kubelet, 192.168.11.5 Created container liveness Normal Started 61s kubelet, 192.168.11.5 Started container liveness Warning Unhealthy 19s (x3 over 29s) kubelet, 192.168.11.5 Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory Normal Killing 19s kubelet, 192.168.11.5 Container liveness failed liveness probe, will be restarted
五、查看pod
能夠發現容器開始被重啓
[root@ren7 yaml]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES liveness 1/1 Running 1 76s 172.20.72.141 192.168.11.5 <none> <none>
除了 Liveness 探測,Kubernetes Health Check 機制還包括 Readiness 探測。
用戶經過 Liveness 探測能夠告訴 Kubernetes 何時經過重啓容器實現自愈;Readiness 探測則是告訴 Kubernetes 何時能夠將容器加入到 Service 負載均衡池中,對外提供服務。
一、Readiness 探測的配置語法與 Liveness 探測徹底同樣
[root@ren7 yaml]# cat pod-read.yaml apiVersion: v1 kind: Pod metadata: name: readiness labels: test: readiness spec: containers: - name: readiness image: reg.yunwei.com/learn/busybox:latest args: - /bin/sh - -c - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 10 periodSeconds: 5 restartPolicy: OnFailure
這個配置文件只是將前面例子中的 liveness 替換爲了 readiness,咱們看看有什麼不一樣的效果。
二、部署
[root@ren7 yaml]# kubectl get pod readiness NAME READY STATUS RESTARTS AGE readiness 0/1 Running 0 14s [root@ren7 yaml]# kubectl get pod readiness NAME READY STATUS RESTARTS AGE readiness 1/1 Running 0 26s [root@ren7 yaml]# kubectl get pod readiness NAME READY STATUS RESTARTS AGE readiness 0/1 Running 0 76s
Pod readiness 的 READY 狀態經歷了以下變化:
剛被建立時,READY 狀態爲不可用。
15 秒後(initialDelaySeconds + periodSeconds),第一次進行 Readiness 探測併成功返回,設置 READY 爲可用。
30 秒後,/tmp/healthy 被刪除,連續 3 次 Readiness 探測均失敗後,READY 被設置爲不可用。
三、經過 kubectl describe pod readiness 也能夠看到 Readiness 探測失敗的日誌。
[root@ren7 yaml]# kubectl describe pod readiness Name: readiness Namespace: default Node: 192.168.11.5/192.168.11.5 Start Time: Sat, 26 Oct 2019 11:10:24 +0800 Labels: test=readiness Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"test":"readiness"},"name":"readiness","namespace":"default"},"spec... Status: Running IP: 172.20.72.143 Containers: readiness: Container ID: docker://7fc2db813b612e71a82b27d7a63fe1860982f4c20fbc1e110a92f3118b08fa82 Image: reg.yunwei.com/learn/busybox:latest Image ID: docker-pullable://reg.yunwei.com/learn/busybox@sha256:dd97a3fe6d721c5cf03abac0f50e2848dc583f7c4e41bf39102ceb42edfd1808 Port: <none> Host Port: <none> Args: /bin/sh -c touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 State: Running Started: Sat, 26 Oct 2019 11:10:26 +0800 Ready: False Restart Count: 0 Readiness: exec [cat /tmp/healthy] delay=10s timeout=1s period=5s #success=1 #failure=3 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-qvqql (ro) Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: default-token-qvqql: Type: Secret (a volume populated by a Secret) SecretName: default-token-qvqql Optional: false QoS Class: BestEffort Node-Selectors: <none> Tolerations: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m18s default-scheduler Successfully assigned default/readiness to 192.168.11.5 Normal Pulling 2m17s kubelet, 192.168.11.5 Pulling image "reg.yunwei.com/learn/busybox:latest" Normal Pulled 2m16s kubelet, 192.168.11.5 Successfully pulled image "reg.yunwei.com/learn/busybox:latest" Normal Created 2m16s kubelet, 192.168.11.5 Created container readiness Normal Started 2m16s kubelet, 192.168.11.5 Started container readiness Warning Unhealthy 3s (x21 over 103s) kubelet, 192.168.11.5 Readiness probe failed: cat: can't open '/tmp/healthy': No such file or directory
下面對 Liveness 探測和 Readiness 探測作個比較:
Liveness 探測和 Readiness 探測是兩種 Health Check 機制,若是不特地配置,Kubernetes 將對兩種探測採起相同的默認行爲,即經過判斷容器啓動進程的返回值是否爲零來判斷探測是否成功。
兩種探測的配置方法徹底同樣,支持的配置參數也同樣。不一樣之處在於探測失敗後的行爲:Liveness 探測是重啓容器;Readiness 探測則是將容器設置爲不可用,不接收 Service 轉發的請求。
Liveness 探測和 Readiness 探測是獨立執行的,兩者之間沒有依賴,因此能夠單獨使用,也能夠同時使用。用 Liveness 探測判斷容器是否須要重啓以實現自愈;用 Readiness 探測判斷容器是否已經準備好對外提供服務。
對於多副本應用,當執行 Scale Up 操做時,新副本會做爲 backend 被添加到 Service 的負載均衡中,與已有副本一塊兒處理客戶的請求。考慮到應用啓動一般都須要一個準備階段,好比加載緩存數據,鏈接數據庫等,從容器啓動到真正可以提供服務是須要一段時間的。咱們能夠經過 Readiness 探測判斷容器是否就緒,避免將請求發送到尚未 ready 的 backend。
一、下面是示例應用的配置文件。
[root@ren7 yaml]# cat healthy.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: web spec: replicas: 2 template: metadata: labels: name: web run: web spec: containers: - name: web image: reg.yunwei.com/learn/httpd:latest ports: - containerPort: 80 readinessProbe: httpGet: scheme: HTTP path: /healthy port: 8080 initialDelaySeconds: 10 periodSeconds: 5 --- apiVersion: v1 kind: Service metadata: name: web-svc spec: ports: - port: 8080 targetPort: 80 protocol: TCP selector: run: web
重點關注 readinessProbe 部分。這裏咱們使用了不一樣於 exec 的另外一種探測方法 -- httpGet。Kubernetes 對於該方法探測成功的判斷條件是 http 請求的返回代碼在 200-400 之間。
schema 指定協議,支持 HTTP(默認值)和 HTTPS。
path 指定訪問路徑。
port 指定端口。
上面配置的做用是:
容器啓動 10 秒以後開始探測。
若是 http://[container_ip]:8080/healthy 返回代碼不是 200-400,表示容器沒有就緒,不接收 Service web-svc 的請求。
每隔 5 秒再探測一次。
直到返回代碼爲 200-400,代表容器已經就緒,而後將其加入到 web-svc 的負載均衡中,開始處理客戶請求。
探測會繼續以 5 秒的間隔執行,若是連續發生 3 次失敗,容器又會從負載均衡中移除,直到下次探測成功從新加入。
現有一個正常運行的多副本應用,接下來對應用進行更新(好比使用更高版本的 image),Kubernetes 會啓動新副本,而後發生了以下事件:
正常狀況下新副本須要 10 秒鐘完成準備工做,在此以前沒法響應業務請求。
但因爲人爲配置錯誤,副本始終沒法完成準備工做(好比沒法鏈接後端數據庫)。
思考一個問題:若是沒有配置 Health Check,會出現怎樣的狀況?
由於新副本自己沒有異常退出,默認的 Health Check 機制會認爲容器已經就緒,進而會逐步用新副本替換現有副本,其結果就是:當全部舊副本都被替換後,整個應用將沒法處理請求,沒法對外提供服務。若是這是發生在重要的生產系統上,後果會很是嚴重。
若是正確配置了 Health Check,新副本只有經過了 Readiness 探測,纔會被添加到 Service;若是沒有經過探測,現有副本不會被所有替換,業務仍然正常進行。
一、用以下配置文件 app.v1.yml 模擬一個 10 副本的應用:
[root@ren7 yaml]# cat app.v1.yml apiVersion: apps/v1beta1 kind: Deployment metadata: name: app spec: replicas: 10 template: metadata: labels: name: app run: app spec: containers: - name: app image: reg.yunwei.com/learn/busybox:latest args: - /bin/sh - -c - sleep 10; touch /tmp/healthy; sleep 30000 readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 10 periodSeconds: 5
10秒後副本可以經過readiness探測
二、執行部署操做
[root@ren7 yaml]# kubectl apply -f app.v1.yml deployment.apps/app created [root@ren7 yaml]# kubectl get deployment app NAME READY UP-TO-DATE AVAILABLE AGE app 10/10 10 10 39s [root@ren7 yaml]# kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES app-577d86d68d-2qb4c 1/1 Running 0 50s 172.20.72.147 192.168.11.5 <none> <none> app-577d86d68d-45fc2 1/1 Running 0 50s 172.20.72.149 192.168.11.5 <none> <none> app-577d86d68d-4mbdj 1/1 Running 0 50s 172.20.33.114 192.168.11.6 <none> <none> app-577d86d68d-8hvjx 1/1 Running 0 50s 172.20.33.111 192.168.11.6 <none> <none> app-577d86d68d-gnwkn 1/1 Running 0 50s 172.20.72.146 192.168.11.5 <none> <none> app-577d86d68d-gv64q 1/1 Running 0 50s 172.20.33.113 192.168.11.6 <none> <none> app-577d86d68d-mgvv9 1/1 Running 0 50s 172.20.72.145 192.168.11.5 <none> <none> app-577d86d68d-mlq22 1/1 Running 0 50s 172.20.33.115 192.168.11.6 <none> <none> app-577d86d68d-n9cxh 1/1 Running 0 50s 172.20.33.112 192.168.11.6 <none> <none> app-577d86d68d-qjj92 1/1 Running 0 50s 172.20.72.148 192.168.11.5 <none> <none>
三、接下來滾動更新應用,配置文件 app.v2.yml 以下:
[root@ren7 yaml]# cat app.v2.yml apiVersion: apps/v1beta1 kind: Deployment metadata: name: app spec: replicas: 10 template: metadata: labels: name: app run: app spec: containers: - name: app image: reg.yunwei.com/learn/busybox:latest args: - /bin/sh - -c - sleep 30000 readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 10 periodSeconds: 5
很顯然,因爲新副本中不存在 /tmp/healthy,是沒法經過 Readiness 探測的。
四、查看探測結果
[root@ren7 yaml]# kubectl apply -f app.v2.yml --record deployment.apps/app configured [root@ren7 yaml]# kubectl get deployment app NAME READY UP-TO-DATE AVAILABLE AGE app 8/10 5 8 3m57s [root@ren7 yaml]# kubectl get deployment app NAME READY UP-TO-DATE AVAILABLE AGE app 8/10 5 8 4m25s [root@ren7 yaml]# kubectl get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES app-577d86d68d-2qb4c 1/1 Running 0 4m31s 172.20.72.147 192.168.11.5 <none> <none> app-577d86d68d-4mbdj 1/1 Running 0 4m31s 172.20.33.114 192.168.11.6 <none> <none> app-577d86d68d-8hvjx 1/1 Running 0 4m31s 172.20.33.111 192.168.11.6 <none> <none> app-577d86d68d-gnwkn 1/1 Running 0 4m31s 172.20.72.146 192.168.11.5 <none> <none> app-577d86d68d-gv64q 1/1 Running 0 4m31s 172.20.33.113 192.168.11.6 <none> <none> app-577d86d68d-mgvv9 1/1 Running 0 4m31s 172.20.72.145 192.168.11.5 <none> <none> app-577d86d68d-n9cxh 1/1 Running 0 4m31s 172.20.33.112 192.168.11.6 <none> <none> app-577d86d68d-qjj92 1/1 Running 0 4m31s 172.20.72.148 192.168.11.5 <none> <none> app-58ccc746ff-44kz6 0/1 Running 0 45s 172.20.33.116 192.168.11.6 <none> <none> app-58ccc746ff-4ndkq 0/1 Running 0 45s 172.20.72.151 192.168.11.5 <none> <none> app-58ccc746ff-5jfvr 0/1 Running 0 46s 172.20.72.150 192.168.11.5 <none> <none> app-58ccc746ff-qz7pn 0/1 Running 0 46s 172.20.33.117 192.168.11.6 <none> <none> app-58ccc746ff-z4h94 0/1 Running 0 46s 172.20.72.152 192.168.11.5 <none> <none> [root@ren7 yaml]#
先關注 kubectl get pod 輸出:
從 Pod 的 AGE 欄可判斷,最後 5 個 Pod 是新副本,目前處於 NOT READY 狀態。
舊副本從最初 10 個減小到 8 個。
再來看 kubectl get deployment app 的輸出:
DESIRED 10 表示指望的狀態是 10 個 READY 的副本。
CURRENT 13 表示當前副本的總數:即 8 箇舊副本 + 5 個新副本。
UP-TO-DATE 5 表示當前已經完成更新的副本數:即 5 個新副本。
AVAILABLE 8 表示當前處於 READY 狀態的副本數:即 8箇舊副本。
在咱們的設定中,新副本始終都沒法經過 Readiness 探測,因此這個狀態會一直保持下去。
上面咱們模擬了一個滾動更新失敗的場景。不過幸運的是:Health Check 幫咱們屏蔽了有缺陷的副本,同時保留了大部分舊副本,業務沒有因更新失敗受到影響。
接下來咱們要回答:爲何新建立的副本數是 5 個,同時只銷毀了 2 箇舊副本?
緣由是:滾動更新經過參數 maxSurge 和 maxUnavailable 來控制副本替換的數量。
maxSurge
此參數控制滾動更新過程當中副本總數的超過 DESIRED 的上限。maxSurge 能夠是具體的整數(好比 3),也能夠是百分百,向上取整。maxSurge 默認值爲 25%。
在上面的例子中,DESIRED 爲 10,那麼副本總數的最大值爲:
roundUp(10 + 10 * 25%) = 13
因此咱們看到 CURRENT 就是 13。
maxUnavailable
此參數控制滾動更新過程當中,不可用的副本相佔 DESIRED 的最大比例。 maxUnavailable 能夠是具體的整數(好比 3),也能夠是百分百,向下取整。maxUnavailable 默認值爲 25%。
在上面的例子中,DESIRED 爲 10,那麼可用的副本數至少要爲:
10 - roundDown(10 * 25%) = 8
因此咱們看到 AVAILABLE 就是 8。
maxSurge 值越大,初始建立的新副本數量就越多;maxUnavailable 值越大,初始銷燬的舊副本數量就越多。
理想狀況下,咱們這個案例滾動更新的過程應該是這樣的:
首先建立 3 個新副本使副本總數達到 13 個。
而後銷燬 2 箇舊副本使可用的副本數降到 8 個。
當這 2 箇舊副本成功銷燬後,可再建立 2 個新副本,使副本總數保持爲 13 個。
當新副本經過 Readiness 探測後,會使可用副本數增長,超過 8。
進而能夠繼續銷燬更多的舊副本,使可用副本數回到 8。
舊副本的銷燬使副本總數低於 13,這樣就容許建立更多的新副本。
這個過程會持續進行,最終全部的舊副本都會被新副本替換,滾動更新完成。
[root@ren7 yaml]# kubectl rollout history deployment app deployment.extensions/app REVISION CHANGE-CAUSE 1 <none> 2 kubectl apply --filename=app.v2.yml --record=true [root@ren7 yaml]# kubectl get deployment app NAME READY UP-TO-DATE AVAILABLE AGE app 8/10 5 8 7m50s [root@ren7 yaml]# kubectl rollout undo deployment app --to-revision=1 deployment.extensions/app rolled back [root@ren7 yaml]# kubectl get deployment app NAME READY UP-TO-DATE AVAILABLE AGE app 10/10 10 10 8m53s
若是要定製 maxSurge 和 maxUnavailable,能夠以下配置:
[root@ren7 yaml]# cat app.v2.yml apiVersion: apps/v1beta1 kind: Deployment metadata: name: app spec: strategy: rollingUpdate: maxSurge: 35% maxUnavailable: 35% replicas: 10 template: metadata: labels: name: app run: app spec: containers: - name: app image: reg.yunwei.com/learn/busybox:latest args: - /bin/sh - -c - sleep 30000 readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 10 periodSeconds: 5