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>

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

        共 8412字,需瀏覽 17分鐘

         ·

        2022-01-20 08:25

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

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

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

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

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

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

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

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

        整體架構(gòu)

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

        獲取到指標(biāo)數(shù)據(jù)后,根據(jù)預(yù)定義的規(guī)則對工作負(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)備一個簡單的 web 應(yīng)用,可以記錄請求次數(shù)并通過?/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 倉庫:

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

        這里的測試只需要用到 prometheus-server,安裝時禁用其他組件。同時為了演示效果的實效性,將指標(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

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

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

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

        Prometheus Adapter

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

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

        除了要配置 Prometheus server 的訪問方式外,還要配置自定義指標(biāo)的計算規(guī)則,告訴 adapter 如何從 Prometheus 獲取指標(biāo)并計算出我們需要的指標(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?請求:

        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)識?milli-requests per seconds,所以這里的 100m 的意思是 0.1/s 每秒0.1 個請求。

        HPA

        最后就是 HPA 的配置了:

        1. 最小最大的副本數(shù)分別設(shè)置 1、10
        2. 為了測試效果的實效性,設(shè)置擴(kuò)縮容的行為?behavior
        3. 指定指標(biāo)?http_requests_qps、類型?Pods?以及目標(biāo)值?50000m:表示平均每個 pod 的 RPS ?50?。比如以 300 的 RPS 訪問,副本數(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

        測試

        測試工具選用?vegeta,因為其可以指定 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

        分別使用?240、12040?的 RPS 發(fā)起請求:

        #?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 界面上觀察請求量與示例數(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)比如每秒請求量進(jìn)行應(yīng)用的水平擴(kuò)容相比 CPU/內(nèi)存 作為依據(jù)更加靠譜,適用于大部分的 web 系統(tǒng)。在突發(fā)流量時可以進(jìn)行快速擴(kuò)容,通過對伸縮行為的控制,可以減少副本數(shù)的抖動。Promeheus 作為流行應(yīng)用的監(jiān)控系統(tǒng),在 Adapter 和 Aggregate API 的支持下,可以作為伸縮的指標(biāo)。

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


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

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        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>
            美女色色网站 | 好湿好紧好多水..嗯 | 啊啊啊好大好舒服视频 | 军人粗野h-军人受军人h 国产一级片免费 | 黄片毛片在线观看 | 日韩AV一区二区在线观看 | 日韩三级免费看 | 十八毛片18女人18毛片免费观看 | 开心激情网深爱五月天 | 绫川ふみ授乳奶水 |