做者:Sandor Magyarigit
譯者:張成github
審校:羅廣明spring
原文:https://banzaicloud.com/blog/k8s-hpa-prom-istio/api
本文來自Banzai Cloud,經過一個spring-boot應用示例演示如何經過Istio operator來實現pod水平擴展。服務器
Pipeline的核心功能之一,Banzai Cloud的應用程序和devops容器管理平臺,是多維的並能夠基於默認和自定義指標進行自動調節。 在咱們引入自定義指標後,咱們選擇了經過Prometheus適配器從Prometheus收集指標。 從那時起,咱們的許多客戶開始使用Hoizontal Pod Autoscaling,他們中的大多數人只對基本的CPU和內存指標感到滿意。網絡
咱們一直都知道這不是一個理想的解決方案,咱們一直在努力尋求更靈活的解決方案,以便:app
隨着咱們的開源Istio operator的發佈以及在Pipeline平臺上普遍引入基於Istio的服務網格,咱們也提供了根據自定義的Istio指標的自動縮放功能。 Prometheus如今提供網絡指標,延遲,故障率以及更多指標(默認狀況下從Istio中刪除)。 咱們的HPA operator根據這些指標決定是否擴展。less
可是,在使用Prometheus Adapter時,咱們的方法已再也不可行,所以咱們決定探索替代方案。ide
若是您錯過了咱們關於Pipeline平臺所支持和自動化不一樣類型的自動縮放功能的系列博客,請查看這些早先的帖子:spring-boot
因爲上面列出的緣由,咱們決定使用另外一個自定義指標適配器,kube-metrics-adapter。
kube-metrics-adapter 是一種通用指標適配器,能夠從多個來源收集和提供指標。對於每一個源,都有一個Collector
實現;目前,咱們對其Prometheus收集器最感興趣。
Prometheus Collector
是一個通用收集器。它將Prometheus 查詢映射到可由HPA 控制器用於部署自動擴展的度量標準。它的方法不一樣於Prometheus Adapter ,它具備預約義的規則集 - 包含針對Prometheus 運行的查詢,用於將指標轉換爲自定義指標 - 按期執行。獲取全部匹配的指標標準(由於這些查詢必須是通用的而且定位全部pod和部署),並做爲自定義指標進行轉換和公開。相比之下,「Prometheus collector」僅收集自定義查詢返回的指標結果,其定義因部署而異,而且僅針對單個部署/ pod或服務,從而減小了存儲的指標總數。該解決方案的一個缺點是,目前,用戶應該避免執行性能不佳的查詢。
我選擇了流行的spotguides
,基於MySQL的Sprint Boot 應用,以便在MySQL服務器旁,快速啓動一個輕量級Web應用程序容器。 我使用Banzai Pipeline Beta,它支持在六個雲提供商中或在本地快速啓動Kubernetes集羣。 Prometheus & Grafana Monitoring以及Istio是默認功能,能夠經過UI開關輕鬆打開(Pipeline處理其他部分)。 在這個例子中,我將在Google Cloud上啓動一個Kubernetes集羣,並打開Monitoring and Service Mesh,並在其上部署Spring Boot Spotguide。 羣集建立是咱們的spotguide
嚮導的一部分,可是,由於Service Mesh
是Pipeline中的一個相對較新的功能,咱們不能(迄今爲止)從spotguide
的流程中啓用它, 因此咱們必須事先建立集羣。
我在這個視頻中記錄了這些步驟:
一旦你的Spring Boot容器
和MySQL
服務器啓動並運行,你就能夠從Spotguid 總覽打開演示程序。這是一個演示應用程序,是典型的Spring Web
應用程序。咱們已經建立了一個GitHub
代碼庫,你能夠在裏面找到示意代碼(就像咱們的其餘spotguides
同樣)。默認狀況下,應用程序URL將僅返回運行情況檢查狀態,該狀態鏈接到Kubernetes
活動和準備狀況檢查。而後,JVM指標將暴露給Prometheus,而且repo將集成到咱們的CI/CD流中,所以,一旦您提交業務邏輯,它將自動部署到集羣。在這裏閱讀更多關於咱們的spotguides。
您能夠從羣集列表或詳細信息頁面下載Kubernetes
配置,以便稍後從本地計算機獲取對羣集的kubectl
訪問權限。
我正在使用hey
工具(go get -u github.com/rakyll/hey
)來生成針對Spring應用程序的負載;下面的命令將每秒發出50個請求
,總計10000
個請求:
hey -n 10000 -q 50 https://spring-boot-custom-metrics-demo.sancyx5g25.sancyx.beta.banzaicloud.io/actuator/health/kubernetes複製代碼
如今,打開監控(咱們的Spotguide摘要或羣集詳細信息頁面中提供的連接)以查看可用的指標並肯定您的Prometheus 查詢。 由於咱們啓用了Service Mesh,全部網絡通訊都將經過Envoy代理,將指標發送到Istio遙測服務,該服務由Prometheus抓取。
我將基於個人示例,查詢基於istiorequeststotal指標,該指標與Spring容器相關:
sum(rate(istio_requests_total{destination_service="spring-boot-custom-metrics-demo-spotguide-spring-boot.default.svc.cluster.local",destination_service_name="spring-boot-custom-metrics-demo-spotguide-spring-boot",destination_service_namespace="default",destination_workload="spring-boot-custom-metrics-demo-spotguide-spring-boot"}[1m]))複製代碼
請務必添加相應的標籤過濾器,以便專門選擇與您的pod/部署相關的指標。
從部署列表頁面上的Horizontal Pod Autoscaler菜單中選擇spring-boot-custom-metrics-demo-spotguide-spring-boot部署,以訪問HPA Edit頁面。 在那裏,您能夠經過輸入自定義指標或查詢的名稱來設置cpu,內存和自定義指標。
如今,若是您在更長的時間內生成另外一個負載(50個請求/秒),則應在屬於部署的HPA中增長副本計數:
hey -n 50000 -q 50 https://spring-boot-custom-metrics-demo.sancyx5g25.sancyx.beta.banzaicloud.io/actuator/health/kubernetes
...
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
spring-boot-custom-metrics-demo-spotguide-spring-boot Deployment/spring-boot-custom-metrics-demo-spotguide-spring-boot 245866m/40 1 10 7 80s複製代碼
加載結束後,副本數將慢慢減小到默認的最小值:
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
spring-boot-custom-metrics-demo-spotguide-spring-boot Deployment/spring-boot-custom-metrics-demo-spotguide-spring-boot 266m/40 1 10 1 32m複製代碼
讓咱們深刻了解使用Pipeline UI向部署添加自定義指標時幕後發生的狀況。 這個流程很是相似於資源指標,您可能會從以前的一系列帖子中熟悉這些指標,可是如今,讓咱們關注與自定義指標相關的API。
Pipeline UI使用HPA API建立/更新指標:
PUT {{pipeline_url}}/api/v1/orgs/:orgId/clusters/:clusterId/hpa
{
"scaleTarget": "example-deployment-name",
"minReplicas": 1,
"maxReplicas": 10,
"customMetrics": {
"customMetricName": {
"query": "sum({kubernetes_pod_name=~\"^example-deployment-name-pod.*\",__name__=~\"example-metric-name\"})",
"targetAverageValue": "100"
}
}
}複製代碼
若是要指定絕對值,可使用targetValue
而不是targetAverageValue
。 不一樣之處在於,targetAverageValue
使用當前pod副本計數對獲取的度量值進行平均。
Pipeline實際上作的是爲您的部署添加如下注釋:
hpa.autoscaling.banzaicloud.io/maxReplicas=10
hpa.autoscaling.banzaicloud.io/minReplicas=1
prometheus.customMetricName.hpa.autoscaling.banzaicloud.io/query=sum({kubernetes_pod_name=~\"^example-deployment-name-pod.*\",__name__=~\"example-metric-name\"})複製代碼
全部這些都是經過HPA operator實現的,它根據部署註釋管理HPA資源。 Pipeline在羣集建立完成後,經過一個post hook,部署HPA operator,而後,若是metrics.api
還沒有註冊,則部署kube-metrics-adapter
和metrics-server
。 此過程可能會有所不一樣,具體取決於您的雲提供商和K8s版本,這些版本可能已安裝了某些功能。在咱們的例子中,新建立的HPA對象將以下所示:
apiVersion: v1
items:
- apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
annotations:
...
autoscaling.alpha.kubernetes.io/current-metrics: '[{"type":"Object","object":{"target":{"kind":"Pod","name":"example-deployment-name-customMetricName","apiVersion":"v1"},"metricName":"customMetricName","currentValue":"222m"}}]'
autoscaling.alpha.kubernetes.io/metrics: '[{"type":"Object","object":{"target":{"kind":"Pod","name":"example-deployment-name-customMetricName","apiVersion":"v1"},"metricName":"customMetricName","targetValue":"40"}}]'
metric-config.object.customMetricName.prometheus/per-replica: "true"
metric-config.object.customMetricName.prometheus/query: sum({kubernetes_pod_name=~\"^example-deployment-name-pod.*\",__name__=~\"example-metric-name\"})
...
spec:
maxReplicas: 10
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: example-deployment-name
status:
currentReplicas: 1
desiredReplicas: 1
kind: List
metadata:
resourceVersion: ""
selfLink: ""複製代碼
請注意,自定義度量標準是Object
類型,並綁定到名爲example-deployment-name-customMetricName
的Pod資源。 Kube-metrics-adapter
也使用註釋查詢來獲取度量值,該值在如下端點公開/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/example-deployment-name -customMetricName/customMetricName
,而且它正是HPA控制器將要查找的位置:
$ kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/customMetricName" | jq .
{
"kind": "MetricValueList",
"apiVersion": "custom.metrics.k8s.io/v1beta1",
"metadata": {
"selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/customMetricName"
},
"items": [
{
"describedObject": {
"kind": "Pod",
"namespace": "default",
"name": "example-deployment-name-customMetricName",
"apiVersion": "v1"
},
"metricName": "customMetricName",
"timestamp": "2019-03-13T20:23:32Z",
"value": "222m"
}
]
}複製代碼
很高興你閱讀本文,但願你有一個關於自動縮放愉快的實踐體驗!
ServiceMesher 社區是由一羣擁有相同價值觀和理念的志願者們共同發起,於 2018 年 4 月正式成立。
社區關注領域有:容器、微服務、Service Mesh、Serverless,擁抱開源和雲原生,致力於推進 Service Mesh 在中國的蓬勃發展。
社區官網:https://www.servicemesher.com