资讯专栏INFORMATION COLUMN

k8s集群应用基于Prometheus实现HPA

IT那活儿 / 578人阅读
k8s集群应用基于Prometheus实现HPA

点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!


01

在k8s集群中,我们希望当应用负载过大的时候,可以对应用进行自动扩容,提升pod的副本数来应对大量的流量,当负载小的时候可以对应用进行自动缩容,以避免资源浪费,这个时候就需要给应用做一个HPA
但是并非所有系统应用都可以通过多带带依靠CPU/内存使用量度来满足其SLA。有时候,我们希望除了CPU/内存指标外有更多的指标能用于实现HPA。这样不仅能保证实现HPA指标的多样性,还可以通过多指标对系统应用做HPA,以更好地处理突发事件并确保高可用性。 

02

HPA原理

对k8s比较熟悉的人,都知道k8s集群里的应用在调度和扩缩容的时候都有自己的一套算法,自动弹性伸缩的原理是怎样的呢,下面举一个实际例子进行阐述
假设存在一个叫A的Deployment,包含3个Pod,每个副本的Request值是1核,当前3个Pod的CPU利用率分别是60%、70%与80%,此时我们设置HPA阈值为50%,最小副本为3,最大副本为10。
接下来我们将上述的数据带入公式中:
  • 总的Pod的利用率是60%+70%+80% = 210%;
  • 当前的Target是3;
  • 算式的结果是70%,大于50%阈值,因此当前的Target 数目过小,需要进行扩容;
  • 重新设置 ,此时算式的结果为42%低于50%,判断还需要扩容两个容器;
  • 此时HPA设置Replicas为5,进行Pod的水平扩容。


03

影响HPA的细节

经过前面的推演,可以协助我们快速理解HPA最核心的原理,不过上面的推演结果和实际情况下是有所出入的,如果我们进一步试验的话,会发现 Replicas最终的结果是6而不是5。这是由于 HPA 中一些细节的处理导致的,主要包含如下三个主要的方面:

3.1 噪声处理

通过前面的公式可以发现,Target的数目很大程度上会影响最终的结果,而在Kubernetes中,无论是变更或者升级,都更倾向于使用Recreate而不是Restart的方式进行处理。
这就导致了在Deployment的生命周期中,可能会出现某一个时间,Target会由于计算了Starting或者 Stopping的Pod而变得很大。这就会给HPA的计算带来非常大的噪声,在HPA Controller的计算中,如果发现当前的对象存在Starting或者Stopping的Pod会直接跳过当前的计算周期,等待状态都变为Running再进行计算。

3.2 冷却周期

HPA控制器观测资源使用率并作出决策是有周期的,执行是需要时间的,在执行自动伸缩过程中metrics不是静止不变的,可能降低或者升高,如果执行太频繁可能导致资源的使用快速抖动,因此控制器每次决策后的一段时间内不再进行新的决策。
在弹性伸缩中,冷却周期是不能逃避的一个话题,很多时候我们期望快速弹出与快速回收,而另一方面,我们又不希望集群震荡,所以一个弹性伸缩活动冷却周期的具体数值是多少,一直被开发者所挑战。在HPA中,默认的扩容冷却周期是3min,缩容冷却周期是5min。可以通过调整kube-controller-manager组件启动参数设置冷却时间:
--horizontal-pod-autoscaler-downscale-delay扩容冷却
--horizontal-pod-autoscaler-upscale-delay缩容冷却
针对不同的k8s版本,可以参考相应k8s版本kube-controller-manager组件关于HPA的启动参数:

3.3 边界值计算

我们回到刚才的计算公式,第一次我们算出需要弹出的容器数目是 5,此时扩容后整体的负载是42%,但是我们似乎忽略了一个问题:
一个全新的 Pod启动会不会自己就占用了部分资源?
此外,8%的缓冲区是否就能够缓解整体的负载情况?
要知道当一次弹性扩容完成后,下一次扩容要最少等待3分钟才可以继续扩容。为了解决这些问题,HPA引入了边界值,目前在计算边界条件时,会自动加入10%的缓冲,这也是为什么在刚才的例子中最终的计算结果为6的原因。 


04

HPA 的API版本

目前HPA已经支持三大版本:autoscaling/v1、autoscaling/v2beta1和autuscaling/v2beta2 三个大版本。
  • API的v1版本,在当前稳定版本(autoscaling/v1)中只支持基于 CPU 指标的扩缩。
  • API的beta版本,autoscaling/v2beta1版和autuscaling/v2beta2版引入了基于内存和自定义指标的扩缩,在autoscaling/v2beta1中增加支持custom metrics,在 autoscaling/v2beta2 中增加支持 external metrics。


05

实现流程图

关键组件介绍:
  • Prometheus:采集Pod的性能指标数据。
  • Custom Metrics server:从Prometheus中采集性能指标数据。它是资源指标数据的聚合器,实现了自定义指标API(Resource Metres API),通过Kubernetes的Custom Metrics server(Prometheus Adapter)层将自定义指标HPA注册Maste API server中,以/apis/custom.metrics.k8s.io路径提供指标数据。
  • HAI Controler:为APA控制器,通过自定义指标API从API Server中获取指标数据,以决策扩缩容操作。


06


安装

组件包括Prometheus,Metrics server,Custom Metrics server(prometheus-adapter),如果集群已经安装了Prometheus,Metrics server,只需安装Custom Metrics server即可。

6.1 安装Custom Metrics server

测试环境当中已经安装了Prometheus,Metrics server,这里只需安装Custom Metrics server即可,下载prometheus-adapter的helm chart,使用helm一键部署。
编辑values.yaml添加平台Prometheus.service地址,使用如下命令一键部署:
helm install  prometheus-adapter --namespace monitoring ../prometheus-adapter/ -f values.yaml

6.2 配置

我们可以将Prometheus中的任何一个指标都用于HPA,但是前提是我们能通过查询语句将它拿到(包括指标名称和其对应的值)。
Prometheus适配器在configmap里配置了如何从prometheus获取数据,并与k8s的资源做对应,以及如何在api接口中展示的规则。


07

验证

列出prometheus提供的自定义指标,发现所有Prometheus里能查看的监控指标在这里都被获取到了。
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq .
获取monitoring命名孔径下所有Pod的FS使用率:
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/monitoring/pods/*/fs_usage_bytes" | jq .
从自定义metrics API中获取每秒请求总数。
例如Prometheus监控的应用,暴露了名为http_requests_total的自定义指标。Prometheus适配器删除_total后缀,并将度量标记为计数器度量(counter metric)。
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-6c994884cf-m6l6m",
"apiVersion": "/v1"
},
"metricName": "http_requests",
"timestamp": "2020-10-09T03:01:01Z",
"value": "1072m"
},
{
"describedObject": {
"kind": "Pod",
"namespace": "default",
"name": "podinfo-6c994884cf-pns2n",
"apiVersion": "/v1"
},
"metricName": "http_requests",
"timestamp": "2020-10-09T03:01:01Z",
"value": "1035m"
}
]
}
自定义API SERVER收到请求后会从Prometheus里面查询http_requests_total的值,然后把这个值换算成一个以时间为单位的请求率。
m代表milli-units,例如1035m代表1035 milli-requests(就是大约1个请求),用十进制表示为 1.035。可能度量指标API将返回没有后缀的整数,否则返回以千分单位的数量。
这意味着我们可能会看到你的度量指标在1和1035m(也就是在十进制记数法中的 1 和 1.035之间波动)。

7.1 创建HPA

基于pod/svc/CPU/memory创建HPA:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: podinfo-hpa-f
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: memory
target:
type: AverageValue
averageValue: 200Mi
- type: Pods
pods:
metric:
name: http_requests
target:
type: AverageValue
averageValue: 50
- type: Object
object:
metric:
name: http_requests
describedObject:
apiVersion: v1
kind: service
name: podinfo
target:
type: Value
value: 50
一个HPA中可以定义多种指标,如果定义多个指标将针对每种类型指标都计算Pod副本数量,取最大的进行扩缩容。
换句话说,系统会根据CPU和pod的自定义指标计算,在每个调度周期(默认为30s)都会计算出一个缩放的推荐值并记录下来,在每次计算缩放值时都会查看历史的推荐值,从最近的一段历史推荐值中挑选最大的,任何一个达到了都进行扩容。
上面HPA相关配置如下:
1)scaleTargetRef:自动扩容缩容的对象,可以是Deployment或者ReplicaSet,这里写具体的Deployment的名称。
2)metrics:这里是指标的目标值。在type中定义类型;通过target来定义指标的阈值,系统将在指标达到阈值的时候出发扩缩容操作。
3)可以指定资源度量指标使用绝对数值或者百分比,需要将 target 类型 AverageUtilization(百分比)替换成AverageValue(绝对数值),同时将target.averageUtilization替换成target.averageValue并设定相应的值。百分比适用于cpu/内存指标。
4)metrics中的type有如下类型:
  • Resource:基于资源的指标,可以是CPU或者是内存,如果基于这个类型的指标来做只需要部署Metric-server即可,不需要部署自定义APISERVER。
  • Pods:基于Pod的指标,系统将对Deployment中的全部Pod副本指标进行平均值计算,如果是Pod则该指标必须来源于Pod本身。
  • Object:基于Ingress或者其他自定义指标,比如ServiceMonitor。它的target类型可以是Value或者AverageValue(根据Pod副本数计算平均值)。

7.2 压测服务并验证HPA

以每秒200个请求的速度为podinfo服务加压,
[root@ysgz-33 home]# ./bin/hey -n 10000 –q 2 -c 100 http://10.3.37.189:9898
一段时间后发现podinfo服务的pod数量增加了,撤掉加压,过一会儿pod数量发生了缩减。
可以通过kubectl describe hpa 命令查看当前影响HPA的各种状态条件信息。
使用 autoscaling/v2beta2 格式的 HorizontalPodAutoscale时,可以看到Kubernetes为 HPA设置的状态条件(Status Conditions)。
这些状态条件可以显示当前HPA是否能够执行扩缩以及是否受到一定的限制。status.conditions字段展示了这些状态条件:
  • AbleToScale表明HPA是否可以获取和更新扩缩信息,以及是否存在阻止扩缩的各种回退条件。
  • ScalingActive表明HPA是否被启用(即目标的副本数量不为零)以及是否能够完成扩缩计算。当这一状态为False时,通常表明获取度量指标存在问题。
  • ScalingLimitted 表明所需扩缩的值被HPA所定义的最大或者最小值所限制。(即已经达到最大或者最小扩缩值)


08

扩展

本次测试使用的压测工具安装。
hey压测工具安装:
yum install golang -y
export GOROOT=/usr/lib/golang
export GOPATH=/home
# 生效配置:
source /etc/profile

cd /home
go get -u github.com/rakyll/hey
go install github.com/rakyll/hey
./bin/hey -n 10000 -q 10 -c 50 http://地址
使用域名时,注意添加本地域名解析:

-n 请求次数

-q 请求速度

-c 请求并发数

09

总结

9.1 在集群中做了这样一个配置后,集群可支持一个HPA中定义多种指标(cpu/内存,访问量及其他Prometheus能获取的指标)实现HPA;
9.2 如果定义了多种指标,系统会根据CPU和pod的自定义指标计算,在每个调度周期(默认为30s)都会计算出一个缩放的推荐值并记录下来,在每次计算缩放值时都会查看历史的推荐值,从最近的一段历史推荐值中挑选最大的,任何一个达到了都进行扩容。 

 

 

END



本文作者:符 海

本文来源:IT那活儿(上海新炬王翦团队)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129487.html

相关文章

  • k8sHPA--通过 Prometheus adaptor 来自定义监控指标

    摘要:与通过来自定义监控指标自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。适配器删除后缀并将度量标记为计数器度量标准。负载测试完成后,会将部署缩到其初始副本您可能已经注意到自动缩放器不会立即对使用峰值做出反应。 k8s与HPA--通过 Prometheus adaptor 来自定义监控指标 自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。 Kubernetes中的自...

    孙吉亮 评论0 收藏0
  • k8sHPA--通过 Prometheus adaptor 来自定义监控指标

    摘要:与通过来自定义监控指标自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。适配器删除后缀并将度量标记为计数器度量标准。负载测试完成后,会将部署缩到其初始副本您可能已经注意到自动缩放器不会立即对使用峰值做出反应。 k8s与HPA--通过 Prometheus adaptor 来自定义监控指标 自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。 Kubernetes中的自...

    HollisChuang 评论0 收藏0
  • k8sHPA--通过 Prometheus adaptor 来自定义监控指标

    摘要:与通过来自定义监控指标自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。适配器删除后缀并将度量标记为计数器度量标准。负载测试完成后,会将部署缩到其初始副本您可能已经注意到自动缩放器不会立即对使用峰值做出反应。 k8s与HPA--通过 Prometheus adaptor 来自定义监控指标 自动扩展是一种根据资源使用情况自动扩展或缩小工作负载的方法。 Kubernetes中的自...

    ityouknow 评论0 收藏0
  • 容器监控实践—Custom Metrics

    摘要:自定义指标由提供,由此可支持任意采集到的指标。文件清单的,收集级别的监控数据监控服务端,从拉数据并存储为时序数据。本文为容器监控实践系列文章,完整内容见 概述 上文metric-server提到,kubernetes的监控指标分为两种: Core metrics(核心指标):从 Kubelet、cAdvisor 等获取度量数据,再由metrics-server提供给 Dashboar...

    laznrbfe 评论0 收藏0
  • 容器监控实践—Custom Metrics

    摘要:自定义指标由提供,由此可支持任意采集到的指标。文件清单的,收集级别的监控数据监控服务端,从拉数据并存储为时序数据。本文为容器监控实践系列文章,完整内容见 概述 上文metric-server提到,kubernetes的监控指标分为两种: Core metrics(核心指标):从 Kubelet、cAdvisor 等获取度量数据,再由metrics-server提供给 Dashboar...

    DangoSky 评论0 收藏0
  • 容器监控实践—Heapster

    摘要:还可以把数据导入到第三方工具展示或使用场景共同组成了一个流行的监控解决方案原生的监控图表信息来自在中也用到了,将作为,向其获取,作为水平扩缩容的监控依据监控指标流程首先从获取集群中所有的信息。 概述 该项目将被废弃(RETIRED) Heapster是Kubernetes旗下的一个项目,Heapster是一个收集者,并不是采集 1.Heapster可以收集Node节点上的cAdvis...

    DDreach 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<