实际生产环境中,通过CPU和内存的监控指标弹性伸缩不能很好的反映应用真实的状态,所以我们需要根据应用本身自定义一些监控指标来进行弹性伸缩,如web应用,根据当前QPS来进行弹性,在这里Kubernetes HPA本身也支持自定义监控指标。
自定义监控指标收集过程:
pod 内置一个metrics 或者挂一个sidecar 当作exporter对外暴露。
Prometheus收集对应的监控指标。
Prometheus-adapter定期从prometheus收集指标对抓取的监控指标进行过滤和晒算,通过custom-metrics-apiserver将指标对外暴露。
HPA控制器从custom-metrics-apiserver获取数据。
部署prometheus
clone代码
1 | git clone https://github.com/stefanprodan/k8s-prom-hpa |
切换到k8s-prom-hpa目录
1 | kubectl create namespace monitoring |
查看prometheus
1 | kubectl get pod -n monitoring |
访问prometheus
http://node_ip:31190
prometheus内prometheus-cfg.yaml 配置了自动发生规则,会自动将组件注册。
监控指标被prometheus收集 –>Prometheus adapter变换指标格式–>custom metrics apiserver–>k8s hpa
部署kubernetes-prometheus-adapter
进入k8s-prom-hpa目录
生成Prometheus-adapter所需的TLS证书:
1 | make certs |
custom-metrics-api/custom-metrics-apiservice.yaml中配置了
insecureSkipTLSVerify: true选项,所以生成的证书是否受信任都无所谓。
查看output文件夹有以下文件
1 | ls output/ |
部署k8s-prometheus-adapter
1 | kubectl create -f ./custom-metrics-api |
prometheus-adapter配置文件查看
custom-metrics-apiserver-deployment.yaml文件
1 | args: |
custom-metrics-config-map.yaml文件
custom-metrics-config-map.yaml文件主要定义的是prometheus-adapter去prometheus获取指标的规则,因为prometheus的指标不能直接拿来用,需要通过prometheus-adapter进行一层中转和修改,然后将重新组装的指标通过自己接口暴露给custom-metrics-apiserver。
所以这个文件内的值,实际上定义的就是从prometheus抓取规则的语句。
1 | - seriesQuery: '{namespace!="",__name__!~"^container_.*"}' |
这个文件内容分为两部分第一个部分是 rules,用于 custom metrics;第二部分是 resourceRules,用于 metrics。
Prometheus adapter,可以将 Prometheus 中的任何一个指标都用于 HPA,但需要在prometheus-adapter内定义查询语句将它拿到。如果只需要使用一个指标做 HPA,可以只写一条查询,而不需要像这里面使用了多个查询。
字段解释:
- seriesQuery:prometheus的查询语句
- seriesFilters:指标过滤
- is:需要筛选保留下来的。
- isNot:需要过滤掉的。
- resource:将指标中的标签和k8s资源对应起来有两种方式一种是用overrides方式
- name:用来给对应的指重命名的,有些指标是递增的http_request但采集的原始指标是http_request_total,需要进行一层计算然后过滤掉_total
- matches:通过正则表达式来匹配指标名,可以进行分组;
- as:默认值为 $1,也就是第一个分组。as 为空就是使用默认值的意思,也就是去
.*
对应的值。 - metricsQuery: metricsQuery字段是一个Go模板,对调用出来的prometheus指标进行特定的处理。
- Series:指标名称
- LabelMatchers:标签匹配列表。
- 1md:定义时间范围
总体来说就是获取多次http_request_total指标,然后进行处理计算过去1分钟内每秒http_request,最后结果返回为http_request指标。
查看k8s-prometheus-adapter部署情况
1 | kubectl get pod -n monitoring |
查看创建的api组
1 | kubectl api-versions | grep metrics |
获取自定义监控指标
1 | yum install jq -y |
1 | kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq . |
1 | { |
部署Podinfo应用测试custom-metric autoscale
1 | kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.yaml |
prometheus配置了自动发现规则,在podinfo-dep.yaml里面配置了对应的规则
1 | annotations: |
kubectl get –raw “/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests” | jq .
{
“kind”: “MetricValueList”,
“apiVersion”: “custom.metrics.k8s.io/v1beta1”,
“metadata”: {
“selfLink”: “/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/http_requests”
},
“items”: [
{
“describedObject”: {
“kind”: “Pod”,
“namespace”: “default”,
“name”: “podinfo-58b68656c9-b9cmg”,
“apiVersion”: “/v1”
},
“metricName”: “http_requests”,
“timestamp”: “2019-11-09T09:00:09Z”,
“value”: “888m”
},
{
“describedObject”: {
“kind”: “Pod”,
“namespace”: “default”,
“name”: “podinfo-58b68656c9-mr265”,
“apiVersion”: “/v1”
},
“metricName”: “http_requests”,
“timestamp”: “2019-11-09T09:00:09Z”,
“value”: “911m”
}
]
}
1 |
|
kubectl create -f ./podinfo/podinfo-hpa-custom.yaml
1 | ``` |
这里10指的是每秒10个请求,按照定义的规则metricsQuery中的时间范围1分钟,这就意味着过去1分钟内每秒如果达到10个请求则会进行扩容。
1 | kubectl get hpa |
713m是什么意思?
自定义API SERVER收到请求后会从Prometheus里面查询http_requests_total的值,然后把这个值换算成一个以时间为单位的请求率。713m的m就是milli-requests,按照定义的规则metricsQuery中的时间范围1分钟,大概每秒为0.71个请求
使用webbench进行压测
1 | webbench -c 100 http://172.31.48.86:31198/ |
查看hpa,可以看见请求数暴涨
1 | kubectl get hpa |
查看HPA事件
1 | kubectl describe hpa/podinfo |