本文介绍使用基于prometheus的自定义metric进行HPA。一般来说,前文介绍的根据CPU和内存做metric进行HPA就已经满足了绝大多数应用场景。
现在主流公有云产商的弹性伸缩服务支持的metric类型也较为丰富。以华为云的弹性伸缩服务为例,指标主要涵盖:CPU、内存、网络、磁盘这些资源层面。针对应用级别的就比较少见了,因此本文将介绍基于http请求访问次数的HPA。

K8S集群使用自定义metrics指标HPA测试

一、创建pormetheus

# cd k8s-prom-hpa/
# kubectl create -f namespaces.yaml 
# kubectl create -f ./prometheus 

K8S集群使用自定义metrics指标HPA测试
由于apiserver的端口配置限制问题,这里修改了service的监听端口,其余的配置和github上下载的一致

# cat prometheus/prometheus-svc.yaml   
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitoring
  labels:
    app: prometheus
spec:
  type: NodePort
  ports:
    - port: 9090
      targetPort: 9090
      nodePort: 8500
      protocol: TCP
  selector:
app: prometheus

二、创建证书

# yum -y install go
# make certs

K8S集群使用自定义metrics指标HPA测试

三、创建custom-metrics api

需要对custom-metrics-apiserver-deployment.yaml文件添加 --client-ca-file参数

# grep 'client-ca-file'  custom-metrics-apiserver-deployment.yaml                 
        - --client-ca-file=/etc/ssl/kubernetes/front-proxy-ca.pem
# kubectl create -f ./custom-metrics-api

K8S集群使用自定义metrics指标HPA测试

四、查看metrics状态

# kubectl get pod,svc -n monitoring

K8S集群使用自定义metrics指标HPA测试

# kubectl get apiservice v1beta1.custom.metrics.k8s.io -o yaml  

K8S集群使用自定义metrics指标HPA测试

# kubectl get --raw /apis/custom.metrics.k8s.io/ |jq
# kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 |jq

K8S集群使用自定义metrics指标HPA测试

# kubectl get --raw  \
"/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/fs_usage_bytes" | jq .

K8S集群使用自定义metrics指标HPA测试

五、创建pod、hpa

由于apiserver的端口配置限制问题,这里修改了service的监听端口,其余的配置和github上下载的一致

# kubectl create -f ./podinfo/podinfo-svc.yaml,./podinfo/podinfo-dep.yaml  
# kubectl get --raw  \
"/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests" | jq .

K8S集群使用自定义metrics指标HPA测试

# kubectl create -f ./podinfo/podinfo-hpa-custom.yaml

K8S集群使用自定义metrics指标HPA测试

六、测试

1、科学上网方式获取hey

# cat proxy.conf 
export http_proxy=http://192.168.115.2:1080
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export rsync_proxy=$http_proxy
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"
# source  proxy.conf              
# go get -u github.com/rakyll/hey 

K8S集群使用自定义metrics指标HPA测试
2、开启一个会话,使用hey产生访问请求,总共10万个请求,每秒中25个qps

# /root/go/bin/hey -n 10000 -q 5 -c 5 http://192.168.115.6:8491/healthz 

3、观察 kube-controller-manager的日志和hpa情况

# journalctl -u kube-controller-manager -f

K8S集群使用自定义metrics指标HPA测试
K8S集群使用自定义metrics指标HPA测试

七、排错

# kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .
error: You must be logged in to the server (Unauthorized)

出现上述问题的原因是未添加--client-ca-file参数

# grep 'client-ca-file'  \
k8s-prom-hpa/custom-metrics-api/custom-metrics-apiserver-deployment.yaml                 
        - --client-ca-file=/etc/ssl/kubernetes/front-proxy-ca.pem

K8S集群使用自定义metrics指标HPA测试

# kubectl get --raw  \
"/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/fs_usage_bytes" | jq .
Error from server (Forbidden): pods.custom.metrics.k8s.io "*" is forbidden: User "front-proxy-client" cannot get pods.custom.metrics.k8s.io/http_requests in the namespace "default"

K8S集群使用自定义metrics指标HPA测试
出现上述错误的原因主要是未对front-proxy-client这个sa进行rbac授权
偷懒的解决方案,直接将这个sa和cluster-admin进行绑定,但不符合最小权限原则。

# kubectl create clusterrolebinding  custom-metric-with-cluster-admin  \
--clusterrole=cluster-admin --user=front-proxy-client

参考文档:
https://github.com/stefanprodan/k8s-prom-hpa
注意:使用http请求访问次数metrics来配置hpa需要对pod配置liveness探针。