基於Kubernetes的hpa實現pod實例數量的自動伸縮


Pod 是在 Kubernetes 體系中,承載用戶業務負載的一種資源。Pod 們運行的好壞,是用戶們最為關心的事情。在業務流量高峰時,手動快速擴展 Pod 的實例數量,算是玩轉 Kubernetes 的基本操作。實際上這個操作還可以更加自動化,運維人員可以事先設置好規則,讓 Pod 實例的數量,在指定情況下自動的調整實例的數量,這一操作依靠 Horizontal Pod Autoscaler 來實現。

場景描述

如果企業應用的最終用戶是人,那么它的訪問壓力情況,都會有潮汐特征。好比一款供企業內部人員使用的OA系統,工作日的流量遠比休息日高,工作時間的流量遠比下班時間高。那么可否讓這款 OA 系統根據流量的大小,自動調整實例的數量。令其忙時啟動足夠數量的實例抵御訪問壓力,閑時自動降低實例數量,將資源留給其他企業應用。

下圖是某個業務系統,在 24 小時內的性能監控曲線。其吞吐率和在線人數曲線都可以反映出一定的潮汐特性:

  • 午夜 0 點直到次日早上8 點,這個系統都處於無人使用的狀態。在這一段時間里,可以自動將業務系統的實例數量降下來,釋放一些計算資源。
  • 上午 9 點直到晚間 21 點為系統使用高峰期,最高在線人數達到 1600 人。在這一段時間里,業務系統的實例數量可以自動提升起來,滿足業務的需要。

image-20200213120547158

關於 hpa

Kubernetes 在 1.2 版本開始支持了 Horizontal Pod Autoscaler(hpa) ,來應對 Pod 實例的自動伸縮場景。它可以基於實例的 CPU 使用率來決定是否為 Pod 進行實例數量的擴容。我們知道 Pod 的副本數量是被其控制器的配置所決定的,比如 Deployment、StatefulSet、ReplicaSet 。所以,hpa 是在獲取了 Pod 實際 CPU 使用率這一指標,和擴展實例的目標指標對比后,操作了其控制器來實現副本數量的擴縮的。

了解了以上內容后,我們起碼可以知道,在使用 hpa 進行自動伸縮的設置之前,Kubernetes 集群和 Pod 的控制器都應該符合一定的先決條件。

  • 存在 Metrics-server。Metrics-server 是 Kubernetes 集群范圍資源用量數據的聚合器。Pod 的 CPU 使用率這一指標,是從 Metrics-server 中獲取 CPU 實際用量之后,與控制器中指定的 Pod 資源做比后所得。大多數 Kubernetes 發行版中都已經默認安裝了 Metrics-server ,它一般部署在 kube-system 命名空間中。
  • Pod 資源限額。既然使用的指標是 CPU 使用率,那么就必須存在一個 CPU 可用的上限作為分母。這個上限,實際上就是在控制器中規定的 Pod 資源限額 spec.resources.limits.cpu

創建 hpa

創建 hpa 之前, 我們需要確保 Pod 控制器中規定了CPU資源限額。我當前使用的案例,使用了 Deployment 控制器。其 Pod 的 CPU 資源限額給到 500m。

Kubernetes 體系中,CPU 是一種可以再分的資源,1000m = 1 Core

kubectl get deployment demo-java -n my-namespace -o yaml

返回的結果中,包含了事先設置的資源限額信息:

spec:
  resources:
    limits:
      cpu: 200m
      memory: 1Gi
    requests:
      cpu: 200m

最簡單的創建 hpa 的方式,是使用 kubectl autoscale 命令進行操作。下面的示例,意味着在 Pod 的 CPU 使用率超過 50% 之后,將會觸發自動伸縮,最多伸縮到 3 個實例。

kubectl autoscale deployment demo-java -n my-namespace --cpu-percent=50 --min=1 --max=3

返回結果:

horizontalpodautoscaler.autoscaling/demo-java autoscaled

創建完成后,我們可以查看 hpa 資源的狀態:

kubectl get hpa -n my-namespace

返回結果中,自動伸縮已經被觸發,所有實例的綜合 CPU 使用率,已經低於設定的值:

hpa 資源只需要被設定一次,就會始終監控 Pod 指標,並根據設定進行自動伸縮

NAME        REFERENCE              TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
demo-java   Deployment/demo-java   49%/50%   1         3         2          3m34s

查看 Pod 實際 CPU 使用量,可以得出相應的使用率計算值,和 hpa 中的顯示是相符的。

kubectl top pod -n my-namespace
NAME                         CPU(cores)   MEMORY(bytes)
demo-java-7d6d7d4c9c-lz8sw   197m         87Mi
demo-java-7d6d7d4c9c-52sdl   1m           90Mi

另一種創建 hpa 的方式,是通過 yaml 文件進行定義。我們可以將已存在的 hpa 資源導出,便可以了解這一資源的定義方式。

kubectl get hpa demo-java -n my-namespace -o yaml > hpa.yaml

其定義方式可以歸結如下:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: demo-java
  namespace: my-namespace
spec:
  maxReplicas: 3
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: demo-java
  targetCPUUtilizationPercentage: 50

通過命令,可以將這一yaml文件加載進 Kubernetes 集群:

kubectl apply -f hpa.yaml

更多的伸縮指標

在上一個章節,已經實現基於 Pod 的 CPU 使用率來進行自動伸縮。利用 CPU 使用率作為伸縮判定指標,是官方默認提供的方式。那么是否還有其他類型的指標可以作為伸縮判定指標呢?這需要 Kubernetes 用戶自行擴展。

我建議從兩個方向挑選更多的伸縮判定指標。第一個方向是資源的選擇,相較於 CPU 而言,內存也可以作為判定指標;第二個方向是維度,相較於使用率而言,使用量也可以作為判定指標。兩個方向彼此組合之后,除了 CPU 使用率,我們還得到了另外 3 種伸縮判定指標:

  • CPU 使用量,單位 m
  • 內存使用率,單位 %
  • 內存使用量,單位 MB

在 CPU 與內存之間,個人更建議使用內存作為伸縮指標,原因是資源的不可壓縮性。CPU 是一種可以壓縮的資源,而內存不是,資源可壓縮意味着當 Pod 的 CPU 用量無限接近於資源限額時,對 Pod 實例的影響很小,只是性能表現不佳而已。但是當 Pod 的內存用量無限接近於資源限額時, Kubernetes 會對 Pod 執行 OOM kill 操作,這對業務的影響很大。如果當內存用量/率達到一定程度,Pod 的實例數量得到了擴展,就有可能避免 Pod 被系統殺死重啟。

Kubernetes 官方提供了如何擴展指標的方案,但這對於一般的用戶而言並不好掌握。我的建議是選用市面上可見的基於 Kubernetes 實現的應用管理平台。它們往往已經將自動伸縮功能封裝成為簡單易用的功能,並且提供了上述幾種伸縮判斷指標。推薦使用北京好雨科技開源的 Rainbond 雲原生管理平台。

Rainbond 目前已經集成了開箱可用的自動伸縮功能,下面是功能截圖。

image-20211212233055816

功能界面已經將易用性做到了極致,即使不去關注之前章節所寫的純技術內容,也可以掌握相關的設置。

在這個功能界面的示例中,將 CPU 使用率和內存使用率同時設定了。在 Kubernetes 中,一旦出現同個 hpa 設定中,包含了多個判定條件時,會分別計算在每一種條件下,滿足條件的 Pod 實例數量,並在所有結果之中選擇最大值作為最終的實例數量。

更多需要了解的內容,可以參考 Kubernetes 官方手冊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM