在kubernetes集群中使用prometheus实现对SpringCloud的HPA

在kubernetes集群中使用prometheus实现对SpringCloud的HPA

在kubernetes集群中需要实现对微服务(spring cloud)的弹性伸缩,也就是HPA (Horizontal Pod Autoscaler)。通过在微服务上暴露一个 prometheus 的模块,使用 HPA v2beta2 加入的 metrics 的 pod 类型的 type ,就可以基于 prometheus 的参数,实现对微服务弹性伸缩。

SpringCloud 微服务配置prometheus

这里提供了micrometer.io提供的prometheus模块

micrometer.io官方文档 可以查看如何在SpringCloud 中加入依赖和配置

然后就可以通过 /prometheus 访问得到jvm、tomcat、堆栈等信息

详细信息可以参考这篇博文 SpringBoot2.0 Actuator 监控参数说明

在kubernetes集群安装k8s-prom-hpa

这里提供了一个安装方法

github仓库和英文文档: https://github.com/stefanprodan/k8s-prom-hpa

翻译的中文文档:https://zhuanlan.zhihu.com/p/34555654

介绍了原有的 Resource Metrics API 提供的参数(就是hpa里使用的cpu和内存)获取的原理 ,以及通过添加一个 Metrics Server ,让hpa能够接受 prometheus 提供的参数

按照 Setting up the Metrics Server 提供的步骤依照顺序执行命令,就可以在 kubernetes 集群中安装好 k8s-prom-hpa

Deployment 加入prometheus注解

安装好 k8s-prom-hpa 还有一个问题,就是需要让 k8s-prom-hpa 在命名空间monitoring 中 pull 到微服务暴露在 /prometheus 的参数。

很简单,在 微服务的Deployment 加入prometheus注解就可以了。

deployment.yaml 的 spec.template.metadata.annotations 加注解

spec:
  template:
    metadata:
      annotations:
        prometheus.io/path: /prometheus
        # prometheus.io/port: "8080"
        prometheus.io/scrape: "true"

其中 port 不需要配置,自动地就是微服务暴露的端口

通过 deployment 部署好微服务

如果通过 prometheus web页面的 Status 的 Targets 的 kubernetes-pods 看到微服务,就说明成功了

avatar

通过 get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_server_requests_seconds_count" | jq .

就可以看到json格式的通过微服务/prometheus pull到的实时参数

其中 default 是命名空间,如果在不同的命名空间,需要改成命名空间

http_server_requests_seconds_count就是参数名,也就是 hpa 能够获取到的值,其他参数可以参考上面那篇博文

shell输出的json

{
  "kind": "MetricValueList",
  "apiVersion": "custom.metrics.k8s.io/v1beta1",
  "metadata": {
    "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/%2A/http_server_requests_seconds_count"
  },
  "items": [
    {
      "describedObject": {
        "kind": "Pod",
        "namespace": "default",
        "name": "health-checker-c7cb8dfdd-fj84m",
        "apiVersion": "/__internal"
      },
      "metricName": "http_server_requests_seconds_count",
      "timestamp": "2019-01-03T03:49:44Z",
      "value": "213"
    },
    {
      "describedObject": {
        "kind": "Pod",
        "namespace": "default",
        "name": "health-checker-c7cb8dfdd-q5d5l",
        "apiVersion": "/__internal"
      },
      "metricName": "http_server_requests_seconds_count",
      "timestamp": "2019-01-03T03:49:44Z",
      "value": "396"
    }
  ]
}

配置HPA

使用 prometheus 的参数,就可以配置HPA,实现对微服务的自动扩容/缩容

hpa.yaml

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: health-checker
  labels:
    app: health-checker
spec:
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: health-checker
  minReplicas: 1
  maxReplicas: 3
  metrics:
#  - type: Resource
#    resource:
#      name: cpu
#      target:
#        type: Utilization
#        averageUtilization: 80
#  - type: Resource
#    resource:
#      name: memory
#      target:
#        type: Utilization
#        averageUtilization: 90
  - type: Pods
    pods:
      metricName: http_server_requests_seconds_count
      targetAverageValue: 100

查看hpa

[root@service1 ~]# kubectl get hpa
NAME                         REFERENCE                   TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
mqtt-broker-health-checker   Deployment/health-checker   5020/100   1         3         3          4d18h

如果配置多个metrics,hpa会根据第一个达到阈值的 metrics 进行扩容

思考:

了解了HPA基本原理,考虑到 micrometer.io 的一些参数不适合作为扩容/缩容的参考参数,可以考虑加入一些自己的参数作为扩容/缩容的参考值,这里就不展开了

参考

micrometer.io官方文档

SpringBoot2.0 Actuator 监控参数说明

通过自定义prometheus数据实现k8s hpa

官方文档Horizontal Pod Autoscaler