<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Kubernetes HPA:基于 Prometheus 自定義指標(biāo)的可控彈性伸縮

          共 8412字,需瀏覽 17分鐘

           ·

          2022-01-20 08:25

          《Kubernetes 的自動(dòng)伸縮你用對(duì)了嗎?》?一文中詳細(xì)說(shuō)明了如何使用 Kubernetes 的自動(dòng)伸縮。在 Kubernetes 中彈性伸縮主要有三種:HPA、VPA、CA。本文不再詳細(xì)說(shuō)明,有興趣的可以看那篇文章。這里主要來(lái)說(shuō)下 Pod 水平縮放 HPA。

          隨著 Kubernetes v1.23 的發(fā)布,HPA 的 API 來(lái)到了穩(wěn)定版?autoscaling/v2

          • 基于自定義指標(biāo)的伸縮
          • 基于多項(xiàng)指標(biāo)的伸縮
          • 可配置的伸縮行為

          從最初的 v1 版本 HPA 只支持 CPU、內(nèi)存利用率的伸縮,到后來(lái)的自定義指標(biāo)、聚合層 API 的支持,到了 v1.18 版本又加入了配置伸縮行為的支持,HPA 也越來(lái)越好用、可靠。

          依靠 CPU 或者內(nèi)存指標(biāo)的擴(kuò)容并非使用所有系統(tǒng),看起來(lái)也沒(méi)那么可靠。對(duì)大部分的 web 后端系統(tǒng)來(lái)說(shuō),基于 RPS(每秒請(qǐng)求數(shù))的彈性伸縮來(lái)處理突發(fā)的流量則會(huì)更加靠譜。

          Prometheus 也是當(dāng)下流行開(kāi)源監(jiān)控系統(tǒng),通過(guò) Prometheus 可以獲取到系統(tǒng)的實(shí)時(shí)流量負(fù)載指標(biāo),今天我們就來(lái)嘗試下基于 Prometheus 的自定義指標(biāo)進(jìn)行彈性伸縮。

          注:目前 HPA 的縮容到0 (scale to 0),則需要在 feature gate 打開(kāi) alpha 版本的?HPAScaleToZero?以及配置一個(gè)對(duì)象或者外部指標(biāo)。即使是打開(kāi)了,從 0 到 1 的擴(kuò)容需要調(diào)度、IP 分配、鏡像拉取等過(guò)程,存在一定的開(kāi)銷(xiāo)。如果降低這部分開(kāi)銷(xiāo),這里先賣(mài)個(gè)關(guān)子,后續(xù)的文章進(jìn)行補(bǔ)充。

          文章中使用的所有代碼都可以從這里下載。

          整體架構(gòu)

          HPA 要獲取 Prometheus 的指標(biāo)數(shù)據(jù),這里引入 Prometheus Adapter 組件。Prometheus Adapter 實(shí)現(xiàn)了 resource metrics、custom metrics 和 external metrics APIs API,支持?autoscaling/v2?的 HPA。

          獲取到指標(biāo)數(shù)據(jù)后,根據(jù)預(yù)定義的規(guī)則對(duì)工作負(fù)載的示例數(shù)進(jìn)行調(diào)整。

          環(huán)境搭建

          K3s

          我們使用最新 1.23 版本的 K3s 作為 Kubernetes 環(huán)境。

          export?INSTALL_K3S_VERSION=v1.23.1+k3s2
          curl?-sfL?https://get.k3s.io?|?sh?-s?-?--write-kubeconfig-mode?644?--write-kubeconfig?~/.kube/config

          示例應(yīng)用

          我們準(zhǔn)備一個(gè)簡(jiǎn)單的 web 應(yīng)用,可以記錄請(qǐng)求次數(shù)并通過(guò)?/metrics?端點(diǎn)輸出 Prometheus 格式的指標(biāo)?http_requests_total

          func?main()?{
          ?metrics?:=?prometheus.NewCounterVec(
          ??prometheus.CounterOpts{
          ???Name:????????"http_requests_total",
          ???Help:????????"Number?of?total?http?requests",
          ??},
          ??[]string{"status"},
          ?)
          ?prometheus.MustRegister(metrics)

          ?http.HandleFunc("/",?func(w?http.ResponseWriter,?r?*http.Request)?{
          ??path?:=?r.URL.Path
          ??statusCode?:=?200
          ??switch?path?{
          ??case?"/metrics":
          ???promhttp.Handler().ServeHTTP(w,?r)
          ??default:
          ???w.WriteHeader(statusCode)
          ???w.Write([]byte("Hello?World!"))
          ??}
          ??metrics.WithLabelValues(strconv.Itoa(statusCode)).Inc()
          ?})
          ?http.ListenAndServe(":3000",?nil)
          }

          將應(yīng)用部署到集群:

          kubectl?apply?-f?kubernetes/sample-httpserver-deployment.yaml

          Prometheus

          使用 Helm 安裝 Prometheus,先添加 prometheus 的 chart 倉(cāng)庫(kù):

          helm?repo?add?prometheus-community?https://prometheus-community.github.io/helm-charts

          這里的測(cè)試只需要用到 prometheus-server,安裝時(shí)禁用其他組件。同時(shí)為了演示效果的實(shí)效性,將指標(biāo)的拉取間隔設(shè)置為?10s。

          #?install?prometheus?with?some?components?disabled
          #?set?scrape?interval?to?10s
          helm?install?prometheus?prometheus-community/prometheus?-n?default?--set?alertmanager.enabled=false,pushgateway.enabled=false,nodeExporter.enabled=false,kubeStateMetrics.enabled=false,server.global.scrape_interval=10s

          通過(guò)端口轉(zhuǎn)發(fā),可以在瀏覽器中訪(fǎng)問(wèn) web 頁(yè)面。

          #?port?forward
          kubectl?port-forward?svc/prometheus-server?9090:80?-n?prometheus

          這里查詢(xún) Pod 的 RPS 使用?sum(rate(http_requests_total[30s])) by (pod)?語(yǔ)句查詢(xún):

          Prometheus Adapter

          同樣使用 Helm 安裝 Produmetheus Adapter,這里要進(jìn)行額外的配置。

          helm?install?prometheus-adapter?prometheus-community/prometheus-adapter?-n?default?-f?kubernetes/values-adapter.yaml

          除了要配置 Prometheus server 的訪(fǎng)問(wèn)方式外,還要配置自定義指標(biāo)的計(jì)算規(guī)則,告訴 adapter 如何從 Prometheus 獲取指標(biāo)并計(jì)算出我們需要的指標(biāo):

          rules:
          ??default:?false
          ??custom:
          ???-?seriesQuery:?'{__name__=~"^http_requests.*_total$",container!="POD",namespace!="",pod!=""}'
          ?????resources:
          ???????overrides:
          ?????????namespace:?{?resource:?"namespace"?}
          ?????????pod:?{?resource:?"pod"?}
          ?????name:
          ???????matches:?"(.*)_total"
          ???????as:?"${1}_qps"
          ?????metricsQuery:?sum(rate(<<.Series>>{<<.LabelMatchers>>}[30s]))?by?(<<.GroupBy>>)

          可以參考詳細(xì)的 Adapter 配置。

          待 promethues-adapter pod 成功運(yùn)行后,可以執(zhí)行?custom.metrics.k8s.io?請(qǐng)求:

          kubectl?get?--raw?'/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests_qps'?|?jq?.
          {
          ??"kind":?"MetricValueList",
          ??"apiVersion":?"custom.metrics.k8s.io/v1beta1",
          ??"metadata":?{
          ????"selfLink":?"/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/http_requests_qps"
          ??},
          ??"items":?[
          ????{
          ??????"describedObject":?{
          ????????"kind":?"Pod",
          ????????"namespace":?"default",
          ????????"name":?"sample-httpserver-64c495844f-b58pl",
          ????????"apiVersion":?"/v1"
          ??????},
          ??????"metricName":?"http_requests_qps",
          ??????"timestamp":?"2022-01-18T03:32:51Z",
          ??????"value":?"100m",
          ??????"selector":?null
          ????}
          ??]
          }

          注意:這里的?value: 100m,值的后綴“m” 標(biāo)識(shí)?milli-requests per seconds,所以這里的 100m 的意思是 0.1/s 每秒0.1 個(gè)請(qǐng)求。

          HPA

          最后就是 HPA 的配置了:

          1. 最小最大的副本數(shù)分別設(shè)置 1、10
          2. 為了測(cè)試效果的實(shí)效性,設(shè)置擴(kuò)縮容的行為?behavior
          3. 指定指標(biāo)?http_requests_qps、類(lèi)型?Pods?以及目標(biāo)值?50000m:表示平均每個(gè) pod 的 RPS ?50?。比如以 300 的 RPS 訪(fǎng)問(wèn),副本數(shù)就是 300/50=6 。
          kind:?HorizontalPodAutoscaler
          apiVersion:?autoscaling/v2
          metadata:
          ??name:?sample-httpserver
          spec:
          ??scaleTargetRef:
          ????apiVersion:?apps/v1
          ????kind:?Deployment
          ????name:?sample-httpserver
          ??minReplicas:?1
          ??maxReplicas:?10
          ??behavior:
          ????scaleDown:
          ??????stabilizationWindowSeconds:?30
          ??????policies:
          ????????-?type:?Percent
          ??????????value:?100
          ??????????periodSeconds:?15
          ????scaleUp:
          ??????stabilizationWindowSeconds:?0
          ??????policies:
          ????????-?type:?Percent
          ??????????value:?100
          ??????????periodSeconds:?15
          ??metrics:
          ????-?type:?Pods
          ??????pods:
          ????????metric:
          ??????????name:?http_requests_qps
          ????????target:
          ??????????type:?AverageValue
          ??????????averageValue:?50000m

          測(cè)試

          測(cè)試工具選用?vegeta,因?yàn)槠淇梢灾付?RPS。

          先為應(yīng)用創(chuàng)建 NodePort service:

          kubectl?expose?deploy?sample-httpserver?--name?sample-httpserver-host?--type?NodePort?--target-port?3000

          kubectl?get?svc?sample-httpserver-host
          NAME?????????????????????TYPE???????CLUSTER-IP?????EXTERNAL-IP???PORT(S)??????????AGE
          sample-httpserver-host???NodePort???10.43.66.206???????????3000:31617/TCP???12h

          分別使用?240120、40?的 RPS 發(fā)起請(qǐng)求:

          #?240
          echo?"GET?http://192.168.1.92:31617"?|?vegeta?attack?-duration?60s?-connections?10?-rate?240?|?vegeta?report
          #?120
          echo?"GET?http://192.168.1.92:31617"?|?vegeta?attack?-duration?60s?-connections?10?-rate?120?|?vegeta?report
          #?40
          echo?"GET?http://192.168.1.92:31617"?|?vegeta?attack?-duration?60s?-connections?10?-rate?40?|?vegeta?report

          從 Prometheus 的 web 界面上觀察請(qǐng)求量與示例數(shù)的變化:

          kubectl?describe?hpa?sample-httpserver
          Warning:?autoscaling/v2beta2?HorizontalPodAutoscaler?is?deprecated?in?v1.23+,?unavailable?in?v1.26+;?use?autoscaling/v2?HorizontalPodAutoscaler
          Name:???????????????????????????sample-httpserver
          Namespace:??????????????????????default
          Labels:?????????????????????????
          Annotations:????????????????????
          CreationTimestamp:??????????????Mon,?17?Jan?2022?23:18:46?+0800
          Reference:??????????????????????Deployment/sample-httpserver
          Metrics:????????????????????????(?current?/?target?)
          ??"http_requests_qps"?on?pods:??100m?/?50
          Min?replicas:???????????????????1
          Max?replicas:???????????????????10
          Behavior:
          ??Scale?Up:
          ????Stabilization?Window:?0?seconds
          ????Select?Policy:?Max
          ????Policies:
          ??????-?Type:?Percent??Value:?100??Period:?15?seconds
          ??Scale?Down:
          ????Stabilization?Window:?30?seconds
          ????Select?Policy:?Max
          ????Policies:
          ??????-?Type:?Percent??Value:?100??Period:?15?seconds
          Deployment?pods:???????1?current?/?1?desired
          Conditions:
          ??Type????????????Status??Reason??????????????Message
          ??----????????????------??------??????????????-------
          ??AbleToScale?????True????ReadyForNewScale????recommended?size?matches?current?size
          ??ScalingActive???True????ValidMetricFound????the?HPA?was?able?to?successfully?calculate?a?replica?count?from?pods?metric?http_requests_qps
          ??ScalingLimited??False???DesiredWithinRange??the?desired?count?is?within?the?acceptable?range
          Events:
          ??Type????Reason?????????????Age??????????????????From???????????????????????Message
          ??----????------?????????????----?????????????????----???????????????????????-------
          ??Normal??SuccessfulRescale??25m??????????????????horizontal-pod-autoscaler??New?size:?6;?reason:?pods?metric?http_requests_qps?above?target
          ??Normal??SuccessfulRescale??19m??????????????????horizontal-pod-autoscaler??New?size:?4;?reason:?All?metrics?below?target
          ??Normal??SuccessfulRescale??12m?(x2?over?9h)?????horizontal-pod-autoscaler??New?size:?4;?reason:?pods?metric?http_requests_qps?above?target
          ??Normal??SuccessfulRescale??11m??????????????????horizontal-pod-autoscaler??New?size:?5;?reason:?pods?metric?http_requests_qps?above?target
          ??Normal??SuccessfulRescale??9m40s?(x2?over?12m)??horizontal-pod-autoscaler??New?size:?2;?reason:?pods?metric?http_requests_qps?above?target
          ??Normal??SuccessfulRescale??9m24s?(x4?over?10h)??horizontal-pod-autoscaler??New?size:?3;?reason:?pods?metric?http_requests_qps?above?target
          ??Normal??SuccessfulRescale??7m54s?(x3?over?9h)???horizontal-pod-autoscaler??New?size:?2;?reason:?All?metrics?below?target
          ??Normal??SuccessfulRescale??7m39s?(x4?over?9h)???horizontal-pod-autoscaler??New?size:?1;?reason:?All?metrics?below?target

          總結(jié)

          基于自定義指標(biāo)比如每秒請(qǐng)求量進(jìn)行應(yīng)用的水平擴(kuò)容相比 CPU/內(nèi)存 作為依據(jù)更加靠譜,適用于大部分的 web 系統(tǒng)。在突發(fā)流量時(shí)可以進(jìn)行快速擴(kuò)容,通過(guò)對(duì)伸縮行為的控制,可以減少副本數(shù)的抖動(dòng)。Promeheus 作為流行應(yīng)用的監(jiān)控系統(tǒng),在 Adapter 和 Aggregate API 的支持下,可以作為伸縮的指標(biāo)。

          目前 HPA 的?scale to 0?還在 alpha 的階段,還需要關(guān)注副本從 0 到 N 的實(shí)效性。如果最小副本數(shù)大于0 ,對(duì)某些服務(wù)來(lái)說(shuō)又會(huì)占用資源。接下來(lái),我們會(huì)為嘗試解決 0 到 N 的性能,以及資源占用的問(wèn)題。


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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本人妻の乱孕妇 | 欧美专区在线观看 | 内射肉丝内射在线播放 | 亚洲精品国产精品乱码桃花 | 丁香六月婷婷五月 |