日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Kubernetes 的 HPA 原理详解

發(fā)布時間:2024/3/12 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kubernetes 的 HPA 原理详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. HPA解決的問題

HPA全稱是 Horizontal Pod Autoscaler,也就是對k8s的workload的副本數(shù)進(jìn)行自動水平擴縮容(scale)機制,也是k8s里使用需求最廣泛的一種Autoscaler機制,在開始詳細(xì)介紹HPA之前,先簡單梳理下k8s autoscale的整個大背景。

k8s被譽為新一代數(shù)據(jù)中心操作系統(tǒng)(DCOS),說到操作系統(tǒng)我們自然想到其定義:管理計算機的軟硬件資源的系統(tǒng),k8s也一樣其核心工作也是管理整個集群的計算資源,并按需合理分配給系統(tǒng)里的程序(以Pod為基礎(chǔ)的各種workload)。

其本質(zhì)是解決資源與業(yè)務(wù)負(fù)載之間供需平衡的問題,隨著業(yè)務(wù)需求和部署規(guī)模的增大,k8s集群就要相應(yīng)擴容計算資源,集群擴容的最直接的辦法是新增資源,一般單機器很難垂直擴展(k8s node也不支持),所以一般都是直接增加節(jié)點。但是隨著機器的不斷增加成本也不斷加大,而實際上大量服務(wù)大部分時間負(fù)載很低導(dǎo)致機器的整體使用率很低,一方面業(yè)務(wù)為了應(yīng)對每日隨機流量高峰會把副本數(shù)盡量擴得很高,另一方面業(yè)務(wù)方并不能準(zhǔn)確評估服務(wù)實際需要的CPU等資源,也出現(xiàn)大量浪費。

為了解決業(yè)務(wù)服務(wù)負(fù)載時刻存在的巨大波動和資源實際使用與預(yù)估之間差距,就有了針對業(yè)務(wù)本身的“擴縮容”解決方案: Horizontal Pod Autoscaler(HPA)和 Vertical Pod Autoscaler(VPA)。

為了充分利用集群現(xiàn)有資源優(yōu)化成本,當(dāng)一個資源占用已經(jīng)很大的業(yè)務(wù)需要擴容時,其實可以先嘗試優(yōu)化業(yè)務(wù)負(fù)載自身的資源需求配置(request與實際的差距),只有當(dāng)集群的資源池確實已經(jīng)無法滿足負(fù)載的實際的資源需求時,再調(diào)整資源池的總量保證資源的可用性,這樣可以將資源用到極致。

所以總的來說彈性伸縮應(yīng)該包括:

  • Cluster-Autoscale: 集群容量(node數(shù)量)自動伸縮,跟自動化部署相關(guān)的,依賴iaas的彈性伸縮,主要用于虛擬機容器集群
  • Vertical Pod Autoscaler: 工作負(fù)載Pod垂直(資源配置)自動伸縮,如自動計算或調(diào)整deployment的Pod模板limit/request,依賴業(yè)務(wù)歷史負(fù)載指標(biāo)
  • Horizontal-Pod-Autoscaler: 工作負(fù)載Pod水平自動伸縮,如自動scale deployment的replicas,依賴業(yè)務(wù)實時負(fù)載指標(biāo)
  • 其中VPA和HPA都是從業(yè)務(wù)負(fù)載角度從發(fā)的優(yōu)化,VPA是解決資源配額(Pod的CPU、內(nèi)存的limit/request)評估不準(zhǔn)的問題,HPA則要解決的是業(yè)務(wù)負(fù)載壓力波動很大,需要人工根據(jù)監(jiān)控報警來不斷調(diào)整副本數(shù)的問題,有了HPA后,被關(guān)聯(lián)上HPA的deployment,后續(xù)副本數(shù)修改就不用人工管理,HPA controller將會根據(jù)業(yè)務(wù)忙閑情況自動幫你動態(tài)調(diào)整。當(dāng)然還有一種固定策略的特殊HPA: cronHPA,也就是直接按照cron的格式設(shè)定擴容和縮容時間及對應(yīng)副本數(shù),這種不需要動態(tài)識別業(yè)務(wù)繁忙度屬于靜態(tài)HPA,適用于業(yè)務(wù)流量變化有固定時間周期規(guī)律的情況,這種比較簡單可以算做HPA的一種簡單特例。

    2. 原理架構(gòu)

    既然是自動根據(jù)業(yè)務(wù)忙閑來調(diào)整業(yè)務(wù)工作負(fù)載的副本數(shù),其實HPA的實現(xiàn)思路很容易想到:通過監(jiān)控業(yè)務(wù)繁忙情況,在業(yè)務(wù)忙時,就要對workload擴容副本數(shù);等到業(yè)務(wù)閑下來時,自然又要把副本數(shù)再縮下去。所以實現(xiàn)水平擴縮容的關(guān)鍵就在于:

    • 如何識別業(yè)務(wù)的忙閑程度
    • 使用什么樣的副本調(diào)整策略

    kubernetes提供了一種標(biāo)準(zhǔn)metrics接口(整個HPA及metrics架構(gòu)如下圖所示),HPA controller通過這個統(tǒng)一metrics接口可以查詢到任意一個HPA對象關(guān)聯(lián)的deployment業(yè)務(wù)的繁忙指標(biāo)metrics數(shù)據(jù),不同的業(yè)務(wù)的繁忙指標(biāo)均可以自定義,只需要在對應(yīng)的HPA里定義關(guān)聯(lián)deployment對應(yīng)的metrics即可。

    標(biāo)準(zhǔn)的metrics查詢接口有了,還需要實現(xiàn)metrics API的服務(wù)端,并提供各種metrics數(shù)據(jù),我們知道k8s的所有核心組件之間都是通過apiserver進(jìn)行通信,所以作為k8s API的擴展,metrics APIserver自然選擇了基于API Aggregation聚合層,這樣HPA controller的metrics查詢請求就自動通過apiserver的聚合層轉(zhuǎn)發(fā)到后端真實的metrics API的服務(wù)端(對應(yīng)下圖的Promesheus adapter和Metrics server)。

    最早的metrics數(shù)據(jù)是由metrics-server提供的,只支持CPU和內(nèi)存的使用指標(biāo),metrics-serve通過將各node端kubelet提供的metrics接口采集到的數(shù)據(jù)匯總到本地,因為metrics-server是沒有持久模塊的,數(shù)據(jù)全在內(nèi)存中所以也沒有保留歷史數(shù)據(jù),只提供當(dāng)前最新采集的數(shù)據(jù)查詢,這個版本的metrics對應(yīng)HPA的版本是autoscaling/v1(HPA v1只支持CPU指標(biāo))。

    后來為了適應(yīng)更靈活的需求,metrics API開始擴展支持用戶自定義metrics指標(biāo)(custom metrics),自定義數(shù)據(jù)則需要用戶自行開發(fā)custom metrics server,社區(qū)有提供專門的custom adpater框架 custom-metrics-apiserver ,該框架定義了Custom和External的MetricsProvider接口(如下所示),需要自行實現(xiàn)對應(yīng)的接口。

    type MetricsProvider interface {CustomMetricsProviderExternalMetricsProvider }type CustomMetricsProvider interface {// GetMetricByName fetches a particular metric for a particular object.// The namespace will be empty if the metric is root-scoped.GetMetricByName(name types.NamespacedName, info CustomMetricInfo, metricSelector labels.Selector) (*custom_metrics.MetricValue, error)// GetMetricBySelector fetches a particular metric for a set of objects matching// the given label selector. The namespace will be empty if the metric is root-scoped.GetMetricBySelector(namespace string, selector labels.Selector, info CustomMetricInfo, metricSelector labels.Selector) (*custom_metrics.MetricValueList, error)// ListAllMetrics provides a list of all available metrics at// the current time. Note that this is not allowed to return// an error, so it is reccomended that implementors cache and// periodically update this list, instead of querying every time.ListAllMetrics() []CustomMetricInfo }type ExternalMetricsProvider interface {GetExternalMetric(namespace string, metricSelector labels.Selector, info ExternalMetricInfo) (*external_metrics.ExternalMetricValueList, error)ListAllExternalMetrics() []ExternalMetricInfo }

    目前社區(qū)已經(jīng)有人基于promethus server的監(jiān)控數(shù)據(jù)源,實現(xiàn)看一個promethus adapter來提供 custom metrics server服務(wù),如果需要的自定義指標(biāo)數(shù)據(jù)已經(jīng)在promesheus里有了,可以直接對接使用,否則要先把自定義的指標(biāo)數(shù)據(jù)注入到promesheus server里才行。因為HPA的負(fù)載一般來源于監(jiān)控數(shù)據(jù),而promesheus又是CNCF標(biāo)準(zhǔn)的監(jiān)控服務(wù),所以這個promesheus adapter基本也可以滿足我們所有自定義metrics的HPA的擴展需求。

    講清楚了metrics,也就解決了識別業(yè)務(wù)的忙閑程度的問題,那么HPA Controller是怎么利用metrics數(shù)據(jù)進(jìn)行擴縮容控制的呢,也就是使用什么樣的副本調(diào)整機制呢?

    如上圖右邊所示,用戶需要在HPA里設(shè)置的metrics類型和期望的目標(biāo)metrics數(shù)值,HPA Controller會定期(horizontal-pod-autoscaler-sync-period配置,默認(rèn)15s)reconcile每個HPA對像,reconcile里面又通過metrics的API獲取該HPA的metrics實時最新數(shù)值(在當(dāng)前副本數(shù)服務(wù)情況下),并將它與目標(biāo)期望值比較,首先根據(jù)比較的大小結(jié)果確定是要擴縮容方向:擴容、縮容還是不變,若不需要要進(jìn)行擴縮容調(diào)整就直接返回當(dāng)前副本數(shù),否則才使用HPA metrics 目標(biāo)類型對應(yīng)的算法來計算出deployment的目標(biāo)副本數(shù),最后調(diào)用deployment的scale接口調(diào)整當(dāng)前副本數(shù),最終實現(xiàn)盡可能將deployment下的每個pod的最終metrics指標(biāo)(平均值)基本維持到用戶期望的水平。注意HPA的目標(biāo)metrics是一個確定值,而不是一個范圍。

    3. HPA的metrics的分類

    要支持最新的custom(包括external)的metrics,也需要使用新版本的HPA:autoscaling/v2beta1,里面增加四種類型的Metrics:Resource、Pods、Object、External,每種資源對應(yīng)不同的場景,下面分別說明:

    • Resource支持k8s里Pod的所有系統(tǒng)資源(包括cpu、memory等),但是一般只會用cpu,memory因為不太敏感而且跟語言相關(guān):大多數(shù)語言都有內(nèi)存池及內(nèi)置GC機制導(dǎo)致進(jìn)程內(nèi)存監(jiān)控不準(zhǔn)確。

    • Pods類型的metrics表示cpu,memory等系統(tǒng)資源之外且是由Pod自身提供的自定義metrics數(shù)據(jù),比如用戶可以在web服務(wù)的pod里提供一個promesheus metrics的自定義接口,里面暴露了本pod的實時QPS監(jiān)控指標(biāo),這種情況下就應(yīng)該在HPA里直接使用Pods類型的metrics。

    • Object類型的metrics表示監(jiān)控指標(biāo)不是由Pod本身的服務(wù)提供,但是可以通過k8s的其他資源Object提供metrics查詢,比如ingress等,一般Object是需要匯聚關(guān)聯(lián)的Deployment下的所有的pods總的指標(biāo)。

    • External類型的metrics也屬于自定義指標(biāo),與Pods和Object不同的是,其監(jiān)控指標(biāo)的來源跟k8s本身無關(guān),metrics的數(shù)據(jù)完全取自外部的系統(tǒng)。

    在HPA最新的版本 autoscaling/v2beta2 中又對metrics的配置和HPA擴縮容的策略做了完善,特別是對 metrics 數(shù)據(jù)的目標(biāo)指標(biāo)值的類型定義更通用靈活:包括AverageUtilization、AverageValue和Value,但是不是所有的類型的Metrics都支持三種目標(biāo)值的,具體對應(yīng)關(guān)系如下表。

    HPA里的各種類型的Metrics和Metrics Target Type的對應(yīng)支持關(guān)系表

    Metrics Type \ Target TypeAverageUtilizationAverageValueValue備注(query metrics)
    Resource(pod’s cpu/memory etc.)YesYesNopods metrics list
    Pods(pod’s other metrics)NoYesNopods metrics list
    Object(k8s object)NoYesYesobject metrics
    External(not k8s object)NoYesYesexternal metrics list

    4. HPA的使用說明

    先看個最簡單的HPA的定義的例子

    apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata:name: php-apache spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: php-apacheminReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 50

    從上面的例子可以看出,HPA的spec定義由三個必填部分組成:

  • HPA控制的目標(biāo)workload,即scaleTargetRef,理論上HPA可以對任意支持scale子接口( sub-resource )的workload做彈性伸縮,不過statefulset一般代表有狀態(tài)服務(wù),副本不可隨便修改,而Job一般代表短生命周期的,所以基本可以認(rèn)為HPA目前是專門控制deployment的擴縮容的(不建議直接控制RS,否則將無法滾動升級)。

  • 彈性擴縮容的上下邊界,minReplicas和maxReplicas,也就是說HPA的擴縮容也不能是漫無邊際,如果計算出的副本數(shù)超過max則統(tǒng)一取maxReplicas,maxReplicas是為了保護(hù)k8s集群的資源被耗盡,minReplicas則相反,而且minReplicas必須不大于maxReplicas,但是也要大于0(k8s v1.16之后才放開允許Objetct和External類型的metrics的minReplicas為0,需要apiserver開啟–feature-gates mapStringBool HPAScaleToZero=true),兩者相等就相當(dāng)于關(guān)閉了自動伸縮功能了,總的來說minReplicas和maxReplicas邊界機制避免metrics數(shù)據(jù)異常導(dǎo)致的副本數(shù)不受控,特別是HPA在k8s最新的v1.18版本也依然是alpha特性,強烈建議大家謹(jǐn)慎設(shè)置這兩個邊界。

  • metrics指標(biāo)類型和目標(biāo)值,在autoscaling/v1里只有targetCPUUtilizationPercentage,autoscaling/v2beta1開始就擴展為metrics數(shù)組了,也就是說一個HPA可以同時設(shè)置多個類型維度的metrics目標(biāo)指標(biāo),如果有多個HPA 將會依次考量各個指標(biāo),然后最終HPA Controller選擇一個會選擇擴縮幅度最大的那個為最終擴容副本數(shù)。在最新的autoscaling/v2beta2版本的HPA中,metrics type共有4種類型:Resource、Pods、Object、External,target里則定義了metrics的目標(biāo)期望值,這里target的type也有三種類型Utilization,AverageValue和 Value,不同的metrics type都只能支持部分target type(詳見上面表格)

  • 此外,在autoscaling/v2beta2的HPA的spec里還新增了一個Behavior可選結(jié)構(gòu),它是用來精確控制HPA的擴容和縮容的速度,下面會專門講。

  • 完整的HPA的定義可參考k8s的官方API文檔。

    默認(rèn)HPA spec里不配置任何metrics的話k8s會默認(rèn)設(shè)置cpu的Resouce,且目標(biāo)類型是AverageUtilization value為80%。

    5. HPA擴縮容算法具體實現(xiàn)

    算法模型

    在HPA控制器里,針對不同類型的metrics和不同metrics下的target 類型,都有獨立的計算算法,雖然有很多細(xì)節(jié)差異,但是總的來說,計算公式可以抽象為:

    desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]

    例如如果配置 target value 是100m,當(dāng)前從metrics接口讀取到的 metrics value 是 200m,說明最新的副本數(shù)應(yīng)該是當(dāng)前的 200m/100m=2.0倍, 如果當(dāng)前副本數(shù)為 2,則HPA計算后的期望副本數(shù)是2*2.0=4;
    而如果當(dāng)前從metrics接口讀取到的 metrics value是 50m,說明最新的副本數(shù)應(yīng)該是 當(dāng)前的 50m/100m=0.5倍,也就是最終scale的副本數(shù)將為1。
    當(dāng)然實際上當(dāng)前的metrics value并不一定就只有一個值,如果是 Resource或者Pods類型的metrics,實際上 GetMetrics 會返回一批關(guān)聯(lián)的Pods對應(yīng)的metrics數(shù)據(jù),一般需要做一個平均后再與target的metrics的做比較。

    此外,為了保證結(jié)果盡量精確,metrics的計算都是浮點數(shù)計算,但是最終的副本數(shù)肯定要是整數(shù),為了統(tǒng)一HPA控制器在最后,都會對計算出的浮點數(shù)副本數(shù)向上取整,也就是上面公式里最外層的ceil函數(shù)。

    擴縮容threshold控制

    當(dāng)然上面的公式也只是純數(shù)學(xué)模型,實際工程實現(xiàn)還要考慮很多現(xiàn)實細(xì)節(jié)問題:比如監(jiān)控數(shù)據(jù)可能會有一定的誤差,如果GetMetrics里讀到數(shù)據(jù)不穩(wěn)定就會造成算出的期望副本數(shù)不穩(wěn)定,導(dǎo)致deployment一會擴縮1個副本,一會又?jǐn)U容1副本。所以為了避免這種問題kube-controller-manager里有個HPA的專屬參數(shù) horizontal-pod-autoscaler-tolerance 表示HPA可容忍的最小副本數(shù)變化比例,默認(rèn)是0.1,如果期望變化的副本倍數(shù)在[0.9, 1.1] 之間就直接停止計算返回。那么如果相反,某個時間點開始metrics數(shù)據(jù)大幅增長,導(dǎo)致最后計算的副本數(shù)變化倍數(shù)很大,是否HPA控制器會一步擴容到位呢? 事實上HPA控制器為了避免副本倍增過快還加了個約束:單次倍增的倍數(shù)不能超過2倍,而如果原副本數(shù)小于2,則可以一次性擴容到4副本,注意這里的速率是代碼寫死不可用配置的。(這個也是HPA controller默認(rèn)的擴縮容速率控制,autoscaling/v2beta2的HPA Behavior屬性可以覆蓋這里的全局默認(rèn)速率)

    縮容冷卻機制(cooldown delay)

    雖然HPA同時支持?jǐn)U容和縮容,但是在生產(chǎn)環(huán)境上擴容一般來說重要性更高,特別是流量突增的時候,能否快速擴容決定了系統(tǒng)的穩(wěn)定性,所以HPA的算法里對擴容的時機是沒有額外限制的,只要達(dá)到擴容條件就會在reconcile里執(zhí)行擴容(當(dāng)前一次至少擴容到原來的1.1倍)。但是為了避免過早縮導(dǎo)致來回波動(thrashing ),而容影響服務(wù)穩(wěn)定性甚,HPA的算法對縮容的要求比較嚴(yán)格,通過設(shè)置一個默認(rèn)5min(可配置horizontal-pod-autoscaler-downscale-stabilization)的滑動窗口,來記錄過去5分鐘的期望副本數(shù),只有連續(xù)5分鐘計算出的期望副本數(shù)都比當(dāng)前副本數(shù)小,才執(zhí)行scale縮容操作,縮容的目標(biāo)副本數(shù)取5分鐘窗口的最大值。

    總的來說k8s HPA算法的默認(rèn)擴縮容原則是:快速擴容,謹(jǐn)慎縮容。

    Pod的metrics數(shù)據(jù)過濾檢查機制

    一般情況下HPA的數(shù)據(jù)指標(biāo)都來自k8s的Pod里,但是實際上每次創(chuàng)建deployment、對deployment做擴縮容,Pod的副本數(shù)和狀態(tài)都會不斷變化,這就導(dǎo)致HPA controller在reconcile里獲取到的metrics的指標(biāo)肯定會有一定的異常,比如Pod還沒有Running、Pod剛剛啟動還在預(yù)熱期、或者Pod中間臨時OOM恰逢采集時刻、或者Pod正處在刪除中,這些都可能導(dǎo)致metrics指標(biāo)缺失。如果有任何 pod 的指標(biāo)缺失,HPA控制器會采取最保守的方式重新計算平均值, 在需要縮小時假設(shè)這些 pod 消耗了目標(biāo)值的 100%, 在需要放大時假設(shè)這些 pod 消耗了0%目標(biāo)值, 這可以在一定程度上抑制伸縮的幅度。

    具體來說,HPA算法里把deployment下的所有Pod的metrics的指標(biāo)數(shù)據(jù)分為三類:

    • ready pods list, deployment下處于Running狀態(tài)的Pod且HPA controller成功通過GetMetrics獲取的pod metrics的列表

    • ignore pods list, deployment下處于pending狀態(tài)的Pods或者(僅對Resouce類似的cpu metrics有效)雖然pod running了但controller成功通過GetMetrics獲取的pod metrics,但是pod的啟動時間在配置的initial-readiness-delay和cpu-initialization-period 保護(hù)期內(nèi)。

    • missing pods list,deployment下處于running狀態(tài)的pod(非pending、非failed、非deleted狀態(tài))但是HPA controller通過GetMetrics無法獲取的pod metrics的列表

    在計算pod的平均metrics值的時候,統(tǒng)一把 ignore pods的metrics設(shè)置為最小值0,如果HPA擴縮容的方向是擴容,把missing pods的metrics也設(shè)置為最小值0,如果是縮容方向則把missing pods的metrics也設(shè)置為最大值(如果是Resouce類型,最大值是Pod的request值,否則最大值就是target value)。

    6. HPA的scale速度控制

    講解完HPA的原理及具體算法后,最后再重點介紹HPA在擴縮容的速率控制機制。在前面講過HPA controller里默認(rèn)擴縮容總原則是:快速擴容,謹(jǐn)慎縮容,擴容上雖然強調(diào)快,但是速度卻是固定的最大于當(dāng)前副本數(shù)的2倍速度,對于想設(shè)置其他倍數(shù)或者說想精確控制副本數(shù)增量的方式的需求都是不行的;縮容上則僅僅只是靠設(shè)置一個集群全局的窗口時間,窗口期過后也就失去控制能力。

    為了能更精準(zhǔn)靈活地控制HPA的autoscale速度,從k8s v1.18(依賴HPA autoscaling/v2beta2)開始HPA的spec里新增了behavior結(jié)構(gòu)(如下定義)擴展了HPA的scale速度控制策略,該結(jié)構(gòu)支持每個HPA實例獨立配置擴縮容的速度,而且還可以單獨配置擴容scaleUp和縮容scaleDown使用不同的策略。

    在擴容策略ScalingRules里,有個StabilizationWindowSeconds用來記錄最近計算的期望副本數(shù),效果跟上面縮容的cooldown delay機制一樣,每次都會選擇窗口里所有推薦值的最大值,保證結(jié)果的穩(wěn)定性。

    Policies是一個HPAScalingPolicy數(shù)組,每個HPAScalingPolicy才是真正控制速度的部分:擴縮容計算周期和周期內(nèi)擴縮容變化的最大幅度,PeriodSeconds周期單位是秒,Percent是設(shè)置副本數(shù)每次變化的百分比,擴容后副本數(shù)是:(1+PercentValue%)* currentReplicas,縮容后副本數(shù)是:(1-PercentValue%)* currentReplicas; Pods則是設(shè)置每次副本數(shù)變化的絕對值。

    次外,每個方向還可以設(shè)置多個策略,多個策略會同時計算最終副本數(shù),最后結(jié)果則是通過SelectPolicy:Max/Min/Disabled做聚合,注意在縮容時Max會選擇計算副本數(shù)最小的那個,Min會選擇計算的副本數(shù)最大的那個,Disabled表示禁止這個方向的擴縮容。

    type HorizontalPodAutoscalerBehavior struct {// scaleUp is scaling policy for scaling Up.// If not set, the default value is the higher of:// * increase no more than 4 pods per 60 seconds// * double the number of pods per 60 secondsScaleUp *HPAScalingRules// scaleDown is scaling policy for scaling Down.// If not set, the default value is to allow to scale down to minReplicas pods, with a// 300 second stabilization window (i.e., the highest recommendation for// the last 300sec is used).ScaleDown *HPAScalingRules }type HPAScalingRules struct {// StabilizationWindowSeconds is the number of seconds for which past recommendations should be// considered while scaling up or scaling down.StabilizationWindowSeconds *int32// selectPolicy is used to specify which policy should be used.// If not set, the default value MaxPolicySelect is used.SelectPolicy *ScalingPolicySelect// policies is a list of potential scaling polices which can used during scaling.// At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalidPolicies []HPAScalingPolicy }// HPAScalingPolicyType is the type of the policy which could be used while making scaling decisions. type HPAScalingPolicyType string const (// PodsScalingPolicy is a policy used to specify a change in absolute number of pods.PodsScalingPolicy HPAScalingPolicyType = "Pods"// PercentScalingPolicy is a policy used to specify a relative amount of change with respect to// the current number of pods.PercentScalingPolicy HPAScalingPolicyType = "Percent" )// HPAScalingPolicy is a single policy which must hold true for a specified past interval. type HPAScalingPolicy struct {// Type is used to specify the scaling policy.Type HPAScalingPolicyType// Value contains the amount of change which is permitted by the policy.Value int32// PeriodSeconds specifies the window of time for which the policy should hold true.// PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).PeriodSeconds int32 }

    HPA的Behavior如果不設(shè)置,k8s會自動設(shè)置擴縮容的默認(rèn)配置, 具體內(nèi)容如下:

    behavior:scaleDown:stabilizationWindowSeconds: 300policies:- type: Percentvalue: 100periodSeconds: 15scaleUp:stabilizationWindowSeconds: 0policies:- type: Percentvalue: 100periodSeconds: 15- type: Podsvalue: 4periodSeconds: 15selectPolicy: Max

    默認(rèn)配置里分別定義了擴容和縮容的速率策略,縮容按照百分比,每15秒最多減少currentReplicas*100%個副本(但最終不可小于minReplicas),且縮容后的最終副本不得低于過去300s內(nèi)計算的歷史副本數(shù)的最大值;擴容則采用快速擴容,不考慮歷史計算值(窗口時間為0),每15秒副本翻倍或者每15秒新增4個副本(取最大值),即:max(2*currentReplicas,4)。這個默認(rèn)Behavior的默認(rèn)配置是否有點似曾相似的感覺,沒錯它跟HPA沒有Behavior時的默認(rèn)快速擴容,縮容的策略是完全一致的。

    不同擴縮容速率需求場景下的behavior用法舉例

    場景1:擴容越快越好

    如果業(yè)務(wù)希望能盡快的擴容,可以配置大的 percent值,可以按照如下配置:

    behavior:scaleUp:policies:- type: Percentvalue: 900periodSeconds: 60

    假如 deployment的副本數(shù)最開始是1,那么每隔60s的的極限擴容副本數(shù)的變化如下:

    1 -> 10 -> 100 -> 1000

    也就是每個擴容period都是(1+900%)=10倍的速度,不過最大副本數(shù)依然不可用超過HPA 的 maxReplicas上界,縮容則使用默認(rèn)行為。當(dāng)然Percent類型可能對資源消耗波動特別大,如果希望資源消耗可控,可以按絕對副本數(shù)來Pods類型來配置。

    場景 2: 擴容越快越好但要逐步縮容

    當(dāng)業(yè)務(wù)希望能盡快的擴容,但是縮容需要緩慢一些時,可以使用如下配置:

    behavior:scaleUp:policies:- type: Percentvalue: 900periodSeconds: 60scaleDown:policies:- type: Podsvalue: 1periodSeconds: 600

    假如 pod 最開始數(shù)量為 1,那么擴容路徑如下:

    1 -> 10 -> 100 -> 1000

    同時,縮容路徑如下 (每 10 分鐘縮容一次,每次減少一個 pod):

    1000 -> 1000 -> 1000 -> … (another 7 min) -> 999 (最小不低于minReplicas)

    場景 3: 逐步擴容、正常的縮容

    當(dāng)希望緩慢的擴容、正常的縮容,可以使用如下配置:

    behavior:scaleUp:policies:- type: Podsvalue: 1periodSeconds: 600

    假如 pod 最開始數(shù)量為 1,那么擴容路徑如下:

    1 -> 2 -> 3 -> 4

    場景 4: 正常擴容、不要縮容

    如果希望能正常的擴容,但是不要自動縮容,可以使用如下配置:

    behavior:scaleDown:policies:- type: Percent 或 Podsvalue: 0periodSeconds: 600

    把縮容的百分比或者pod 都置為 0,那么就永遠(yuǎn)不會縮容。
    或者直接設(shè)置 selectPolicy: Disabled。

    behavior:scaleDown:selectPolicy: Disabled

    場景 5: 延后縮容

    一般在流量激增時,都希望快速擴容應(yīng)對,那么發(fā)現(xiàn)流量降低是否應(yīng)該立馬縮容呢,加入只是臨時的流量降低呢,這樣就可能導(dǎo)致短時間反復(fù)的擴縮容,為了避免這種情況,縮容時應(yīng)該更謹(jǐn)慎些,可以使用延遲縮容機制:delaySeconds(這個跟 kube-controller-manager 的 horizontal-pod-autoscaler-downscale-stabilization 非常類似,但是這個參數(shù)是全局的,如果HPA有配置優(yōu)先使用delaySeconds),配置如下:

    behavior:scaleDown:policies:- type: Podsvalue: 5periodSeconds: 600

    那么,每次縮容最多減少 5 個 pod,同時每次縮容,至少要往前看 600s 窗口期的所有推薦值,每次都從窗口期中選擇最大的值。這樣,除非連續(xù)600s的推薦值都比之前的最大副本數(shù)小,才開始縮容。

    7. 總結(jié)

    總的來說,從k8s v1.18開始HPA的機制已經(jīng)算比較靈活了,在擴縮容識別指標(biāo)上可以使用Pod的系統(tǒng)cpu、內(nèi)存指標(biāo),也可以Pods自身暴露的自定義metrics指標(biāo),還可以支持外部的業(yè)務(wù)指標(biāo);在具體自定義實現(xiàn)上也提供了標(biāo)準(zhǔn)的擴展框架,還有社區(qū)其他人貢獻(xiàn)的promesheus adapter。在擴縮容速度上也通過相對百分比和絕對 Pods數(shù)變化,可以獨立控制單位時間內(nèi)最大的擴容和縮容,此外還通過自定義窗口時間機制保證副本變化的穩(wěn)定性。

    需要說明下,HPA特性還依然處于非正式GA版本,社區(qū)相關(guān)的issue有些沒有解決,包括HPA縮容的最小副本不允許為0(Resouce和Pods類型的metrics如果在pod副本為0時,將采集不到metrics,需要依賴額外的流量激活機制,Knative集成了service mesh有對流量的劫持所以可以直接實現(xiàn)0副本),參數(shù)控制粒度還不夠靈活,而且HPA controller的reconcile循環(huán)不支持多線程并發(fā),所以也一定程度上影響了一個k8s集群內(nèi)HPA的對象數(shù)過多的時效性,隨著k8s HPA關(guān)注和使用人數(shù)的增多,相信這些問題也都會逐步優(yōu)化掉。

    網(wǎng)易輕舟之前就已經(jīng)集成了基于業(yè)務(wù)容器的CPU、內(nèi)存指標(biāo)的HPA,網(wǎng)易傳媒業(yè)務(wù)很早就開始在生產(chǎn)環(huán)境使用這個特性,不過隨著離線業(yè)務(wù)的容器化遷移和離在線混部的廣泛使用,傳媒業(yè)務(wù)團(tuán)隊也提出了希望根據(jù)任務(wù)隊列的大小這樣的外部指標(biāo)來進(jìn)行彈性伸縮,所以輕舟也開始支持自定義metrics的HPA的功能,目前相關(guān)配套已經(jīng)開發(fā)完畢,正逐步應(yīng)用在網(wǎng)易內(nèi)部業(yè)務(wù)中,未來也將會跟隨輕舟新版本對外發(fā)布。

    作者:婁超,網(wǎng)易數(shù)帆輕舟事業(yè)部資深工程師

    總結(jié)

    以上是生活随笔為你收集整理的Kubernetes 的 HPA 原理详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。