k8s自定义指标HPA实践(微服务基于自定义指标自动扩缩容的实践)附demo

先上demo代码仓库

https://github.com/wentjiang/prometheus-HPA-test

自动扩缩容的使用场景

在开发微服务时,我们会有一些请求量突增的场景,举个例子,快上下班的时候,大家都需要签到签退,那么签到考勤,那么对于考勤服务,在上下班的时候,会出现流量激增的情况,一种解决方法是,我们将服务的数量启动到能满足峰值的情况,这种情况会产生不必要的资源浪费,那么,怎么样才能解决该问题呢?作为云原生时代最重要的基础设施,k8s为我们提供了HPA(Horizontal Pod Autoscaler)自动扩缩容机制,这样我们就能够应对类似的流量突增的情况,按照配置好的扩缩容机制,进行自动的扩缩容;

HPA使用方式及实现原理

k8s原生的HPA使用方式为:

1.使用类似Deployment的方式部署微服务

2.为微服务添加HPA定义

完成以上配置之后,Metrics Server会根据从pod采集到的信息,使用HPA中定义的判断条件,对当前Deployment的副本数进行调整,以达到期望数值

 

 

常规的自动扩缩容的局限性

k8s原生的自动扩缩容,支持的指标只有cpu和内存,但我们业务的场景可能使用的不仅限于cpu和内存,或者,cpu和内存不能满足业务扩缩容的需求,这样的话,就需要使用自定义指标的HPA来进行实现,例如,客户端提交的计算任务,服务端使用生产者消费者模式,将客户端的计算任务放在队列中,这个时候,监听队列的积压,从而进行扩缩容是一个相对于cpu,内存来说更优的方案

HPA指标的分类

通过上述的介绍,想必大家已经明白了HPA的原理,和为什么使用自定义指标扩缩容,这里列出几种HPA指标:

HPA需要从metrics API获取到所需要进行HPA的值,默认使用的是metrics server提供的数据,只有cpu,内存的信息,如果要使用service相关的数据,如http get请求数之类的信息,需要查阅外部指标相关的API,k8s也同样支持,这里只关注custom metrics api指标,接下来,我们将详细的了解如何一步一步搭建自定义指标HPA,这里选取主流的prometheus作为采集指标的收集器,将数据上报给HPA

搭建自定义指标HPA环境

前置条件

 k8s集群,helm可用

整体的搭建流程

  1. 部署prometheus在k8s上
  2. 部署service
  3. 在prometheus上配置服务的serviceMonitor
  4. 部署prometheus adapter在k8s上
  5. 配置prometheus的采集规则rule
  6. 为service添加HPA配置
  7. 验证HPA是否生效

使用helm安装prometheus

将prometheus保存到本地,可根据需要修改prometheus配置

helm show values prometheus-community/kube-prometheus-stack > prometheus-config.yaml

这里使用默认的配置进行安装,安装时需要注意,如果之前集群通过helm安装过prometheus,需要将所有之前安装的信息删除掉(包括无状态,有状态,配置,自定义对象等),否则会导致安装失败

使用helm命令安装prometheus,完成之后会有以下输出

$ helm install ops-prometheus prometheus-community/kube-prometheus-stack -n ops
NAME: ops-prometheus
LAST DEPLOYED: Tue Nov  3 16:26:10 2020
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl --namespace monitoring get pods -l "release=ops-prometheus"

Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.
prometheus相关文档(https://github.com/prometheus-operator/kube-prometheus)
验证prometheus是否部署成功
$ kubectl --namespace ops get pods -l "release=ops-prometheus"
NAME                                                   READY   STATUS    RESTARTS   AGE
ops-prometheus-kube-promet-operator-6d44cfccfb-72xv2   2/2     Running   0          52d
ops-prometheus-prometheus-node-exporter-n6fg4          1/1     Running   0          52d

# wentao.jiang @ wentjiang in ~/Downloads/temp on git:master x [23:23:03]
$ kubectl get pods -n ops
NAME                                                     READY   STATUS    RESTARTS   AGE
alertmanager-ops-prometheus-kube-promet-alertmanager-0   2/2     Running   0          52d
ops-prometheus-adapter-8ff46679d-c52ch                   1/1     Running   0          51d
ops-prometheus-grafana-f4875b756-zvn6m                   2/2     Running   0          52d
ops-prometheus-kube-promet-operator-6d44cfccfb-72xv2     2/2     Running   0          52d
ops-prometheus-kube-state-metrics-7bdbdb4559-z4dlf       1/1     Running   0          52d
ops-prometheus-prometheus-node-exporter-n6fg4            1/1     Running   0          52d
prometheus-ops-prometheus-kube-promet-prometheus-0       3/3     Running   1          52d
如果所有node中的exporter 都为running状态,并包含以下组件:
- alertmanager-ops-prometheus-kube-promet-alertmanager
- ops-prometheus-grafana
- ops-prometheus-kube-promet-operator
- ops-prometheus-kube-state-metrics
- ops-prometheus-prometheus-node-exporter
- prometheus-ops-prometheus-kube-promet-prometheus
则部署成功

部署demo service

将我们已经写好的demo程序部署到k8s集群中

将代码clone到本地,保证本地环境中有gradle,docker,执行./build.sh 会自动构建出prometheus-test:1.1的镜像,也可以直接使用上传好的docker hub的镜像

docker pull wentjiang/prometheus-test:1.1

启动service,

在项目目录下执行

kubectl create -f ./k8s/service.yaml -n local

分别查看pod 和 service状态

请求以下接口,验证服务启动成功

$ curl http://localhost:8080/prometheus-test/1.0/test
ok%
 

配置prometheus serviceMonitor

配置serviceMonitor的目的是让prometheus能够采集到服务的监控指标

按照代码中的serviceMonitor.yaml的配置,启动serviceMonitor

使用kubectl create -f ./k8s/serviceMonitor.yaml -n local启动

查看serviceMonitor创建成功

部署prometheus adapter

prometheus adapter的作用是让k8s的custome api能够采集到prometheus的监控数据

安装过程中使用该文档     prometheus-adapter参考链接

a.添加adapter仓库

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

b.查找prometheus对应的ip,记录下来,adapter配置中需要使用

 c.修改adapter的配置项

helm show values prometheus-community/prometheus-adapter > prometheus-adapter.yaml
修改prometheus.url为上边查到的url 

prometheus:
  url: http://10.106.240.218
  port: 9090
  path: ""

d.安装prometheus adapter chart

helm repo update
helm install [RELEASE_NAME] prometheus-community/prometheus-adapter --values prometheus-adapter.yaml --namespace ops
NAME: prometheus-adapter
LAST DEPLOYED: Wed Nov  4 09:22:09 2020
NAMESPACE: ops
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
prometheus-adapter has been deployed.
In a few minutes you should be able to list metrics using the following command(s):

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

e.验证是否部署成功

等待几分钟adapter相关配置安装完成

$ kubectl_local get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/local/pods/*/custom_value"
{"kind":"MetricValueList","apiVersion":"custom.metrics.k8s.io/v1beta1","metadata":{"selfLink":"/apis/custom.metrics.k8s.io/v1beta1/namespaces/local/pods/%2A/custom_value"},"items":[{"describedObject":{"kind":"Pod","namespace":"local","name":"prometheus-test-796fcd758d-5c7fc","apiVersion":"/v1"},"metricName":"custom_value","timestamp":"2020-12-25T13:46:59Z","value":"0","selector":null}]}

看到服务的custom_value已经成功的注册到了k8s的api server上,至此,已经成功的将微服务的自定义指标注册到了k8s集群的api Server上

配置prometheus的采集规则rule

这里的rule是添加adapter采集prometheus数据的规则,需要修改adapter对应的配置

a.找到adapter对应的configmap

$ kubectl_local get configmap -n ops |grep prometheus-adapter
ops-prometheus-adapter                                         1      52d

执行命令进行修改

kubectl edit configmap ops-prometheus-adapter -n ops 

在rule的数组中添加以下规则

    - metricsQuery: avg(rate(<<.Series>>{<<.LabelMatchers>>}[10s])) by (<<.GroupBy>>)
      name:
        as: ""
        matches: custom_value
      resources:
        overrides:
          namespace:
            resource: namespace
          pod_name:
            resource: pod
      seriesQuery: custom_value{namespace!="",pod_name!=""}

保存之后 adapter会热更新该配置项

为service添加HPA配置

kubectl create ./k8s/hpa.yaml -n local

可以看到配置已经成功提交

验证HPA是否生效

kubectl describe hpa prometheus-test-hpa -n local 可以查看当前hpa的状态

可以看到,当前hpa的状态一切良好, 最小副本数为1,最大副本数为3,当前custom_value的值为 0,目标平均值为10

现在我们修改custom_value的值,使其大于hpa中设置的值,就会看到副本数根据规则增加

调用服务的修改custom_value的接口

持续观察hpa的状态,可以发现,下图中,hpa已经开始工作了,拉起新的节点

已经成功的创建出了第二个节点,图中的5500m实际含义为5500/1000的数值,即为5.5,当前custom_value 11/2=5.5

至此,我们所有的操作都已经完成了

参考资料

k8s官网对于自定义指标支持的文档

https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-custom-metrics

支持自定义指标的适配器

https://github.com/kubernetes/metrics/blob/master/IMPLEMENTATIONS.md#custom-metrics-api

 

https://www.padok.fr/en/blog/scaling-prometheus-rabbitmq

https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack

https://artifacthub.io/packages/helm/prometheus-community/prometheus-adapter

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值