Kubernetes:應用自動擴容、收縮與穩定更新

痴者工良發表於2021-12-07

在前面我們已經學習到了 Pod 的擴容、滾動更新等知識,我們可以手動為 Deployment 等設定 Pod 副本的數量,而這裡會繼續學習 關於 Pod 擴容、收縮 的規則,讓 Pod 根據節點伺服器的資源自動增加或減少 Pod 數量。

本文為作者的 Kubernetes 系列電子書的一部分,電子書已經開源,歡迎關注,電子書瀏覽地址:

https://k8s.whuanle.cn【適合國內訪問】

https://ek8s.whuanle.cn 【gitbook】

縮放 Deployment

設定副本數量

很簡單,使用 kubectl scale 命令直接設定:

kubectl scale deployment nginx --replicas=10

其它方式前面的章節已經提到過了,還有通過修改 YAML 檔案的方式。

水平自動縮放

K8S 有個 Pod 水平自動擴縮(Horizontal Pod Autoscaler) 可以基於 CPU 利用率自動擴縮 ReplicationController、Deployment、ReplicaSet 和 StatefulSet 中的 Pod 數量。Pod 自動擴縮不適用於無法擴縮的物件,比如 DaemonSet。

除了 CPU 利用率,也可以基於其他應程式提供的自定義度量指標 來執行自動擴縮。

參考資料:https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale/

命令:

kubectl autoscale deployment nginx --min=10 --max=15 --cpu-percent=80

表示目標 CPU 使用率為 80%(期望指標),副本數量配置應該為 10 到 15 之間,CPU 是動態縮放 pod 的指標,會根據具體的 CPU 使用率計算副本數量,其計算公式如下。

期望副本數 = ceil[當前副本數 * (當前指標 / 期望指標)]

因為筆者這裡只有一個 Worker 節點,不能控制 CPU 使用率模擬場景,所以不方便演示,讀者只需要瞭解這個命令即可。

按照演算法計算,加入當前副本數量為 12,且 CPU 使用率達到 90%,則期望副本數為 12*(90%/80%) = 13.5,那麼理論上會部署 14 個 Pod,但是 CPU 再繼續增加的話,最多 15 個副本數量。如果在機器管夠的情況下,可以去掉 min 和 max 引數。

演算法細節請檢視:https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale/#algorithm-details

比例縮放

比例縮放指的是在上線 Deployment 時,臨時執行著應用程式的多個版本(共存),比例縮放是控制上線時多個 Pod 服務可用數量的方式。

水平縮放只關心最終的期望 Pod 數量,直接修改副本數和水平縮放,決定最終 Pod 數量有多少個。

而比例縮放是控制物件上線過程中,新的 Pod 建立速度和 舊的 Pod 銷燬速度、 Pod 的可用程度,跟上線過程中新舊版本的 Pod 替換數量有關。

檢視上一章中建立的 Deployment 的部分 YAML 如下:

spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate

strategy 可以配置 Pod 是怎麼更新的。

當我們設定.spec.strategy.type==RollingUpdate時,便會採取滾動更新的方式更新 Pods,此時可以指定 maxUnavailable 和 maxSurge 來控制滾動更新 過程。這個我們之前提到過,就是 Deployment 預設會保證一直有 75% 的 pod處於可用狀態,在完成更新前可能有多個版本的 pod 共存。

  • maxUnavailable

    最大不可用數量或比例,舊的 Pod 會以這個數量或比例逐漸減少。

  • maxSurge

    最大峰值,新的 Pod 會按照這個數量或比例逐漸建立。

3.5 章已經使用到了這兩者,這裡就不細說了,讀者請參考:https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/#max-unavailable

我們檢視之前的 Deployment,執行命令 kubectl get deployment nginx -o yaml

... ...
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
... ...

配置表示,每次只有 1/4 的 Pod 被更新、替換。

這個是所有 Deployment 的預設配置,在更新映象版本時,舊的 Pod 會被新的 Pod 替換,但是不是一下子完成的,每次處理 25% 的 Pod,在更新過程中,我們必須保證我們的服務依然可用,即還有舊版本的 Pod 在執行。這個配置設定了更新過程中至少保證 75% 的 Pod 還可以使用,這個就是比例縮放。

下面我們來進行實驗。

首先建立新的 Deployment ,設定副本數量為 10:

kubectl create deployment nginx --image=nginx:1.19.0 --replicas=10
# kubectl scale deployment nginx --replicas=10

我們執行 kubectl edit deployment nginx 修改縮放個數:

  strategy:
    rollingUpdate:
      maxSurge: 3
      maxUnavailable: 2
    type: RollingUpdate

除了可用百分比表示,也可以使用個數表示。

舊的 Pod 按照最大 2 個的速度不斷減少;新的 Pod 按照最大 3 個的速度不斷增加;

比例縮放的配置處理好了,它會在我們上線新版本的時候生效,我們可以觀察到這個過程,但是需要快一點執行命令檢視狀態。

快速執行以下命令:

kubectl set image deployment nginx nginx=nginx:1.20.0
kubectl get replicaset
root@instance-1:~# kubectl set image deployment nginx nginx=nginx:1.20.0
deployment.apps/nginx image updated
root@instance-1:~# kubectl get replicaset
NAME               DESIRED   CURRENT   READY   AGE
nginx-7b87485749   5         5         0       93m
nginx-85b45874d9   0         0         0       93m
nginx-bb957bbb5    8         8         8       35m

因為允許新的 Pod 建立較快(3個),所以最終可能新的 Pod 數量達到 10 個了,舊的 Pod 還有很多,總數量大於 10。

最終:

NAME               DESIRED   CURRENT   READY   AGE
nginx-7b87485749   10        10        10      99m
nginx-85b45874d9   0         0         0       99m
nginx-bb957bbb5    0         0         0       41m

如果想新版本的 Pod 上線速度更快,則可以把 maxSurge 數量或比例設定大一些;為了保證上線過程穩定、服務可用程度高,可以把 maxUnavailable 設定小一些。

相關文章