1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        優(yōu)化 Kubernetes 橫向擴(kuò)縮容 HPA

        共 4364字,需瀏覽 9分鐘

         ·

        2021-06-03 23:10

        圖片來源: instagram.com/febin_raj

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

        HPA Resource類型不足

        默認(rèn)HPA提供了Resource類型,通過CPU/MEM使用率指標(biāo)(由metrics-server提供原始指標(biāo))來擴(kuò)縮應(yīng)用。

        使用率計(jì)算方式

        在Resource類型中,使用率計(jì)算是通過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
        }
        // 計(jì)算使用率
        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 := 0

         for podName, metric := range metrics {
          request, hasRequest := requests[podName]
          if !hasRequest {
           // we check for missing requests elsewhere, so assuming missing requests == extraneous metrics
           continue
          }

          metricsTotal += metric.Value
          requestsTotal += request
          numEntries++
         }


         currentUtilization = int32((metricsTotal * 100) / requestsTotal)

         return float64(currentUtilization) / float64(targetUtilization), currentUtilization, metricsTotal / int64(numEntries), nil
        }

        通常在Paas平臺(tái)中會(huì)對(duì)資源進(jìn)行超配,limit即用戶請(qǐng)求資源,request即實(shí)際分配資源,如果按照request來計(jì)算使用率(會(huì)超過100%)是不符合預(yù)期的。相關(guān)issue見72811,目前還存在爭(zhēng)論??梢孕薷脑创a,或者使用自定義指標(biāo)來代替。

        多容器Pod使用率問題

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

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

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

        好在1.20版本中已經(jīng)支持了ContainerResource可以配置基于某個(gè)容器的資源使用率來進(jìn)行擴(kuò)縮,如果是之前的版本建議使用自定義指標(biāo)替換。

        性能問題

        單線程架構(gòu)

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

        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
        }

        可以通過調(diào)整worker數(shù)量來橫向擴(kuò)展,已提交PR。

        調(diào)用鏈路

        hpa controller中一次hpa資源同步,需要調(diào)用多次apiserver接口,主要鏈路如下

        1. 通過scaleForResourceMappings得到scale資源
        2. 調(diào)用computeReplicasForMetrics獲取metrics value
        3. 調(diào)用Scales().Update更新計(jì)算出的副本數(shù)

        尤其在獲取metrics value時(shí),需要先調(diào)用apiserver,apiserver調(diào)用metrics-server/custom-metrics-server,當(dāng)集群內(nèi)存在大量hpa時(shí)可能會(huì)對(duì)apiserver性能產(chǎn)生一定影響。

        其他

        對(duì)于自定義指標(biāo)用戶需要實(shí)現(xiàn)custom.metrics.k8s.ioexternal.metrics.k8s.io,目前已經(jīng)有部分開源實(shí)現(xiàn)見custom-metrics-api。

        另外,hpa核心的擴(kuò)縮算法根據(jù)當(dāng)前指標(biāo)和期望指標(biāo)來計(jì)算擴(kuò)縮比例,并不適合所有場(chǎng)景,只使用線性增長(zhǎng)的指標(biāo)。

        期望副本數(shù) = ceil[當(dāng)前副本數(shù) * (當(dāng)前指標(biāo) / 期望指標(biāo))]

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

        總結(jié)

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

        ?

        本文鏈接: https://qingwave.github.io/k8s-hpa-enchance/

        ?


        瀏覽 114
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            在线看片毛片无码永久免费 | 麻豆久久久久久 | 波多野结衣无码一区二区三区久在线视频 | 亚洲中文娱乐 | 51毛片 | 秋霞影院一区二区三区 | 天天躁夜夜躁av天天爽 | 国产69精品久久极品美女夜本色 | 夜夜夜夜夜夜爽 | 操碰视频在线观看 |