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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

优化Kubernetes横向扩缩HPA

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

Pod水平自動擴縮(Horizontal Pod Autoscaler, 簡稱HPA)可以基于 CPU/MEM 利用率自動擴縮Deployment、StatefulSet 中的 Pod 數量,同時也可以基于其他應程序提供的自定義度量指標來執(zhí)行自動擴縮。默認HPA可以滿足一些簡單場景,對于生產環(huán)境并不一定適合,本文主要分析HPA的不足與優(yōu)化方式。

HPA Resource類型不足

默認HPA提供了Resource類型,通過CPU/MEM使用率指標(由metrics-server提供原始指標)來擴縮應用。

使用率計算方式

在Resource類型中,使用率計算是通過request而不是limit,源碼如下:

// 獲取Pod resource request func calculatePodRequests(pods []*v1.Pod, resource v1.ResourceName) (map[string]int64, error) {requests := make(map[string]int64, len(pods))for _, pod := range pods {podSum := int64(0)for _, container := range pod.Spec.Containers {if containerRequest, ok := container.Resources.Requests[resource]; ok {podSum += containerRequest.MilliValue()} else {return nil, fmt.Errorf("missing request for %s", resource)}}requests[pod.Name] = podSum}return requests, nil } // 計算使用率 func GetResourceUtilizationRatio(metrics PodMetricsInfo, requests map[string]int64, targetUtilization int32) (utilizationRatio float64, currentUtilization int32, rawAverageValue int64, err error) {metricsTotal := int64(0)requestsTotal := int64(0)numEntries := 0for podName, metric := range metrics {request, hasRequest := requests[podName]if !hasRequest {// we check for missing requests elsewhere, so assuming missing requests == extraneous metricscontinue}metricsTotal += metric.ValuerequestsTotal += requestnumEntries++}currentUtilization = int32((metricsTotal * 100) / requestsTotal)return float64(currentUtilization) / float64(targetUtilization), currentUtilization, metricsTotal / int64(numEntries), nil }

通常在Paas平臺中會對資源進行超配,limit即用戶請求資源,request即實際分配資源,如果按照request來計算使用率(會超過100%)是不符合預期的。相關issue見72811,目前還存在爭論。可以修改源碼,或者使用自定義指標來代替。

多容器Pod使用率問題

默認提供的Resource類型的HPA,通過上述方式計算資源使用率,核心方式如下:

metricsTotal = sum(pod.container.metricValue) requestsTotal = sum(pod.container.Request) currentUtilization = int32((metricsTotal * 100) / requestsTotal)

計算出所有container的資源使用量再比總的申請量,對于單容器Pod這沒影響。但對于多容器Pod,比如Pod包含多個容器con1、con2(request都為1cpu),con1使用率10%,con2使用率100%,HPA目標使用率60%,按照目前方式得到使用率為55%不會進行擴容,但實際con2已經達到資源瓶頸,勢必會影響服務質量。當前系統(tǒng)中,多容器Pod通常都是1個主容器與多個sidecar,依賴主容器的指標更合適點。

好在1.20版本中已經支持了ContainerResource可以配置基于某個容器的資源使用率來進行擴縮,如果是之前的版本建議使用自定義指標替換。

性能問題

單線程架構

默認的hpa-controller是單個Goroutine執(zhí)行的,隨著集群規(guī)模的增多,勢必會成為性能瓶頸,目前默認hpa資源同步周期會15s,假設每個metric請求延時為100ms,當前架構只能支持150個HPA資源(保證在15s內同步一次)

func (a *HorizontalController) Run(stopCh <-chan struct{}) {// ...// start a single worker (we may wish to start more in the future)go wait.Until(a.worker, time.Second, stopCh)<-stopCh }

可以通過調整worker數量來橫向擴展,已提交PR。

調用鏈路

在hpa controller中一次hpa資源同步,需要調用多次apiserver接口,主要鏈路如下

  • 通過scaleForResourceMappings得到scale資源
  • 調用computeReplicasForMetrics獲取metrics value
  • 調用Scales().Update更新計算出的副本數
  • 尤其在獲取metrics value時,需要先調用apiserver,apiserver調用metrics-server/custom-metrics-server,當集群內存在大量hpa時可能會對apiserver性能產生一定影響。

    其他

    對于自定義指標用戶需要實現custom.metrics.k8s.io或external.metrics.k8s.io,目前已經有部分開源實現見custom-metrics-api。

    另外,hpa核心的擴縮算法根據當前指標和期望指標來計算擴縮比例,并不適合所有場景,只使用線性增長的指標。

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

    watermarkpodautoscaler提供了更靈活的擴縮算法,比如平均值、水位線等,可以作為參考。

    總結

    Kubernetes提供原生的HPA只能滿足一部分場景,如果要上生產環(huán)境,必須對其做一些優(yōu)化,本文總結了當前HPA存在的不足,例如在性能、使用率計算方面,并提供了解決思路。

    總結

    以上是生活随笔為你收集整理的优化Kubernetes横向扩缩HPA的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。