天天看點

Kubernetes 灰階/滾動釋出 滾動更新速率控制解讀 maxUnavailable,maxSurge

Kubernetes 灰階/滾動釋出 滾動更新速率控制解讀 maxUnavailable,maxSurge

利用kubernetes的滾動更新時,可能經常遇到釋出“太快不穩定”或“太慢體驗差”的情況。本文将介紹kubernetes滾動更新控制速率的特性。

金絲雀釋出

金絲雀釋出這個術語源自20世紀初期,當時英國的煤礦勞工在下井采礦之前,會把籠養的金絲雀攜帶到礦井中,如果礦井中一氧化碳等有毒氣體的濃度過高,在影響礦工之前,金絲雀相比人類表現的更加敏感快速,金絲雀中毒之後,煤礦勞工就知道該立刻撤離。金絲雀釋出是在将整個軟體的新版本釋出給所有使用者之前,先釋出給部分使用者,用真實的客戶流量來測試,以保證軟體不會出現嚴重問題,降低釋出風險。

在實踐中,金絲雀釋出一般會先釋出到一個小比例的機器,比如 2% 的伺服器做流量驗證,然後從中快速獲得回報,根據回報決定是擴大釋出還是復原。金絲雀釋出通常會結合監控系統,通過監控名額,觀察金絲雀機器的健康狀況。如果金絲雀測試通過,則把剩餘的機器全部更新成新版本,否則復原代碼。

Kubernetes 灰階/滾動釋出 滾動更新速率控制解讀 maxUnavailable,maxSurge

 優勢:

  1. 對使用者體驗影響較小,在金絲雀釋出過程中,隻有少量使用者會受影響
  2. 釋出安全能夠得到保障

劣勢:

  1. 金絲雀的機器數量比較少, 有一些問題并不能夠暴露出來

适用場景:

  1. 監控比較完備且與釋出系統內建

灰階/滾動釋出

灰階釋出是金絲雀釋出的延伸,是将釋出分成不同的階段/批次,每個階段/批次的使用者數量逐級增加。如果新版本在目前階段沒有發現問題,就再增加使用者數量進入下一個階段,直至擴充到全部使用者。

灰階釋出可以減小釋出風險,是一種零當機時間的釋出政策。它通過切換線上并存版本之間的路由權重,逐漸從一個版本切換為另一個版本。整個釋出過程會持續比較長的時間, 在這段時間内,新舊代碼共存,是以在開發過程中,需要考慮版本之間的相容性,新舊代碼共存不能影響功能可用性和使用者體驗。當新版本代碼出現問題時,灰階釋出能夠比較快的復原到老版本的代碼上。

結合特性開關等技術,灰階釋出可以實作更複雜靈活的釋出政策。

Kubernetes 灰階/滾動釋出 滾動更新速率控制解讀 maxUnavailable,maxSurge

優勢:

  1. 使用者體驗影響比較小, 不需要停機釋出
  2. 能夠控制釋出風險

劣勢:

  1. 釋出時間會比較長
  2. 需要複雜的釋出系統和負載均衡器
  3. 需要考慮新舊版本共存時的相容性

适用場景:

  1. 适合可用性較高的生産環境釋出

滾動釋出

kubernetes預設的更新政策也就是主流釋出方案是滾動更新。

每次隻更新一個或多個服務,更新完成後加入生産環境, 不斷執行這個過程,直到叢集中的全部舊版更新新版本。

Kubernetes的預設釋出政策。

特點:

  • 使用者無感覺,平滑過渡

缺點:

  • 部署周期長(需要健康檢查,等它準備就緒,然後更新下一個,健康檢查還是需要花費一些時間的)
  • 釋出政策較複雜
  • 不易復原
  • 有影響範圍較大
Kubernetes 灰階/滾動釋出 滾動更新速率控制解讀 maxUnavailable,maxSurge

含義

服務在滾動更新時,deployment控制器的目的是:給舊版本(old_rs)副本數減少至0、給新版本(new_rs)副本數量增至期望值(replicas)。大家在使用時,通常容易忽視控制速率的特性,以下是kubernetes提供的兩個參數:

  • maxUnavailable:和期望ready的副本數比,不可用副本數最大比例(或最大值),這個值越小,越能保證服務穩定,更新越平滑;
  • maxSurge:和期望ready的副本數比,超過期望副本數最大比例(或最大值),這個值調的越大,副本更新速度越快。

取值範圍

數值

1. maxUnavailable: [0, 副本數]

2. maxSurge: [0, 副本數]

注意:兩者不能同時為0。

比例

1. maxUnavailable: [0%, 100%] 向下取整,比如10個副本,5%的話==0.5個,但計算按照0個;

2. maxSurge: [0%, 100%] 向上取整,比如10個副本,5%的話==0.5個,但計算按照1個;

注意:兩者不能同時為0。

建議配置

1. maxUnavailable == 0

2. maxSurge == 1

這是我們生産環境提供給使用者的預設配置。即“一上一下,先上後下”最平滑原則:1個新版本pod ready(結合readiness)後,才銷毀舊版本pod。此配置适用場景是平滑更新、保證服務平穩,但也有缺點,就是“太慢”了。

自定義政策

Deployment controller調整replicaset數量時,嚴格通過以下公式來控制釋出節奏。是以,如需快速釋出,可根據實際情況去調整這兩個值:

(目标副本數-maxUnavailable) <= 線上實際Ready副本數 <= (目标副本數+maxSurge)      

舉例:如果期望副本數是10,期望能有至少80%數量的副本能穩定工作,是以:maxUnavailable = 2,maxSurge = 2 (可自定義,建議與maxUnavailable保持一緻)

8 <= 線上實際Ready副本數 <= 12      

這樣,更新過程中,線上能夠正常提供服務的pod數總會保持在這個區間内。

現象(maxUnavailable = 1,maxSurge = 1)

#我這裡跟新了鏡像然後應用,也就是滾動更新
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1      
[root@k8s-master ~]# kubectl get ep -w
NAME         ENDPOINTS                                             AGE
kubernetes   192.168.179.102:6443                                  29d
web          10.244.169.141:80,10.244.169.142:80,10.244.36.78:80   8m8s


web          10.244.169.141:80,10.244.36.78:80                     8m58s
web          10.244.169.141:80,10.244.36.78:80                     10m
web          10.244.169.141:80,10.244.169.143:80,10.244.36.78:80   10m
web          10.244.169.143:80,10.244.36.78:80                     10m
web          10.244.169.143:80,10.244.36.78:80                     10m
web          10.244.169.143:80,10.244.169.144:80,10.244.36.78:80   10m
web          10.244.169.143:80,10.244.169.144:80                   10m
web          10.244.169.143:80,10.244.169.144:80                   11m
web          10.244.169.143:80,10.244.169.144:80,10.244.36.79:80   11m


[root@k8s-master ~]# kubectl get pod -w
NAME                   READY   STATUS    RESTARTS   AGE
web-655569c6d8-96kmp   1/1     Running   0          15m
web-655569c6d8-n8nvk   1/1     Running   0          15m
web-655569c6d8-vmnj6   1/1     Running   0          15m



web-7cf4f6bf9f-kktpq   0/1     Pending   0          0s
web-7cf4f6bf9f-kktpq   0/1     Pending   0          0s
web-655569c6d8-n8nvk   1/1     Terminating   0          15m
web-7cf4f6bf9f-bbchz   0/1     Pending       0          0s
web-7cf4f6bf9f-bbchz   0/1     Pending       0          1s
web-655569c6d8-n8nvk   1/1     Terminating   0          15m
web-655569c6d8-n8nvk   0/1     Terminating   0          15m
web-655569c6d8-n8nvk   0/1     Terminating   0          15m
web-655569c6d8-n8nvk   0/1     Terminating   0          15m
web-7cf4f6bf9f-bbchz   0/1     Pending       0          15s
web-7cf4f6bf9f-bbchz   0/1     ContainerCreating   0          15s
web-7cf4f6bf9f-bbchz   0/1     ContainerCreating   0          18s
web-7cf4f6bf9f-bbchz   0/1     Running             0          63s
web-7cf4f6bf9f-bbchz   1/1     Running             0          75s
web-655569c6d8-vmnj6   1/1     Terminating         0          16m
web-7cf4f6bf9f-rgq9w   0/1     Pending             0          0s
web-7cf4f6bf9f-rgq9w   0/1     Pending             0          0s
web-655569c6d8-vmnj6   1/1     Terminating         0          16m
web-655569c6d8-vmnj6   0/1     Terminating         0          16m
web-655569c6d8-vmnj6   0/1     Terminating         0          16m
web-655569c6d8-vmnj6   0/1     Terminating         0          16m
web-7cf4f6bf9f-kktpq   0/1     Pending             0          79s
web-7cf4f6bf9f-kktpq   0/1     ContainerCreating   0          80s
web-7cf4f6bf9f-kktpq   0/1     ContainerCreating   0          81s
web-7cf4f6bf9f-kktpq   0/1     Running             0          82s
web-7cf4f6bf9f-kktpq   1/1     Running             0          92s
web-655569c6d8-96kmp   1/1     Terminating         0          17m
web-655569c6d8-96kmp   1/1     Terminating         0          17m
web-655569c6d8-96kmp   0/1     Terminating         0          17m
web-655569c6d8-96kmp   0/1     Terminating         0          17m
web-655569c6d8-96kmp   0/1     Terminating         0          17m
web-7cf4f6bf9f-rgq9w   0/1     Pending             0          19s
web-7cf4f6bf9f-rgq9w   0/1     ContainerCreating   0          19s
web-7cf4f6bf9f-rgq9w   0/1     ContainerCreating   0          21s
web-7cf4f6bf9f-rgq9w   0/1     Running             0          59s
web-7cf4f6bf9f-rgq9w   1/1     Running             0          68s      

總結

## 檢視曆史
kubectl rollout history deployment/anyops-devopsdocker-ui

## 檢視具體某一個曆史版本資訊
kubectl rollout history deployment/anyops-devopsdocker-ui --revision=2

## 復原上個版本 
kubectl rollout undo deployment/anyops-devopsdocker-ui -n anyops

## 復原指定版本
kubectl rollout undo deployment/nginx --to-revision=2      

繼續閱讀