k8s学习笔记-HPA控制器
Horizontal Pod Autoscaling,简称HPA,是Kubernetes中实现POD水平自动伸缩的功能。为什么要水平而不叫垂直, 那是因为自动扩展主要分为两种:
水平扩展(scale out),针对于实例数目的增减
垂直扩展(scal up),即单个实例可以使用的资源的增减, 比如增加cpu和增大内存
而HPA属于前者。它可以根据CPU使用率或应用自定义metrics自动扩展Pod数量(支持 replication controller、deployment 和 replica set)
对于Kubernetes中的POD集群来说,HPA就是实现这种水平伸缩的控制器, 它能在当POD中业务负载上升的时候,创建新的POD来保证业务系统稳定运行,当POD中业务负载下降的时候,可以销毁POD来提高资源利用率。
自动伸缩是一种根据资源使用情况自动伸缩工作负载的方法。
自动伸缩在Kubernetes中有两个维度:cluster Autoscaler处理节点扩容操作和Horizontal Pod Autoscaler自动缩放rs或rc中的pod。
cluster Autoscaler和Horizontal Pod Autoscaler一起可用于动态调整的计算能力以及并行性的水平,你的系统需要满足sla。
虽然cluster Autoscaler高度依赖于托管集群的云提供商的底层功能,但是HPA可以独立于您的IaaS/PaaS提供商进行操作。
在Kubernetes v1.1中首次引入了hpa特性,自那时起已经有了很大的发展。
hpa第一个版本基于观察到的CPU利用率,后续版本支持基于内存使用。
在Kubernetes 1.6中引入了一个新的API自定义指标API,它允许HPA访问任意指标。
Kubernetes 1.7引入了聚合层,允许第三方应用程序通过注册为API附加组件来扩展Kubernetes API。
自定义指标API以及聚合层使得像Prometheus这样的监控系统可以向HPA控制器公开特定于应用程序的指标。
如下图:
HPA 实现了一个控制环,可以周期性的从资源指标API查询特定应用的CPU/MEM信息。
HPA自身是一个控制循环,周期由 controller-manager的 --horizontal-pod-autoscaler-sync-period选项定义,默认为30s

获取metrics的两种方式:

Heapster: heapster提供metrics服务, 但是在v1(autoscaling/v1)版本中仅支持以CPU作为扩展度量指标, 而其他比如:内存, 网络流量, qps等目前处于beta阶段(autoscaling/v2beta1)
Cousom: 同样处于beta阶段(autoscaling/v2beta1), 但是涉及到自定义的REST API的开发, 复杂度会大一些, 并且当需要从自定义的监控中获取数据时,只能设置绝对值,无法设置使用率
工作流程:
1.创建HPA资源,设定目标CPU使用率限额,以及最大、最小实例数, 一定要设置Pod的资源限制参数: request, 否则HPA不会工作。
2.控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况
3.然后与创建时设定的值和指标做对比(平均值之和/限额),求出目标调整的实例个数
4.目标调整的实例数不能超过1中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数
然后就是重复2-4步
自动伸缩算法:
HPA Controller会通过调整副本数量使得CPU使用率尽量向期望值靠近,而且不是完全相等.另外,官方考虑到自动扩展的决策可能需要一段时间才会生效:例如当pod所需要的CPU负荷过大,从而在创建一个新pod的过程中,系统的CPU使用量可能会同样在有一个攀升的过程。所以,在每一次作出决策后的一段时间内,将不再进行扩展决策。对于扩容而言,这个时间段为3分钟,缩容为5分钟(可以通过--horizontal-pod-autoscaler-downscale-delay, --horizontal-pod-autoscaler-upscale-delay进行调整)。
HPA Controller中有一个tolerance(容忍力)的概念,它允许一定范围内的使用量的不稳定,现在默认为0.1,这也是出于维护系统稳定性的考虑。例如,设定HPA调度策略为cpu使用率高于50%触发扩容,那么只有当使用率大于55%或者小于45%才会触发伸缩活动,HPA会尽力把Pod的使用率控制在这个范围之间。
具体的每次扩容或者缩容的多少Pod的算法为:
Ceil(前采集到的使用率 / 用户自定义的使用率) * Pod数量)
每次最大扩容pod数量不会超过当前副本数量的2倍
Kubernetes Metrics Server是一个集群范围的资源使用数据聚合器,是Heapster的继承者。
metrics服务器通过从kubernet.summary_api收集数据收集节点和pod的CPU和内存使用情况。
summary API是一个内存有效的API,用于将数据从Kubelet/cAdvisor传递到metrics server。

HPA,Horizontal Pod Autoscaler,两个版本,HPA仅支持CPU指标;HPAv2支持资源指标API和自定义指标API
CA,Cluster Autoscaler,集群规模自动弹性伸缩,能自动增减节点数量,用于云环境
VPA,Vertical Pod Autoscaler,Pod应用垂直伸缩工具,调整Pod对象的CPU和内存资源需求量完成扩展或收缩
AR,Addon Resizer,简化版本的Pod应用垂直伸缩工具,基于集群中节点数量调整附加组件的资源需求量
对于未定义资源需求量的Pod对象,HPA控制器无法定义容器CPU利用率,且不会为该指标采取任何操作
对于每个Pod的自定义指标,HPA仅能处理原始值而非利用率
默认缩容延迟时长为5min,扩容延迟时长为3min,目的是防止出现抖动
HPA获取指标的方式:Heapster和REST客户端
Heapster要事先部署于集群上并在kube-system名称空间运行
事先部署好资源指标API及其API Server,必要时,还要部署好自定义指标API及其相关的API Server
参考的文章:
https://www.codercto.com/a/29478.html
下面演示HPA 的两个版本
autoscaling/v1 HPA
HPA(v1)控制器:
1.创建 deployment及service
kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=2 --requests='cpu=50m,memory=256Mi' --limits='cpu=50m,memory=256Mi' --labels='app=myapp' --expose --port=80
2.创建hpa控制器
kubectl autoscale -h
kubectl autoscale deployment myapp --min=2 --max=8 --cpu-percent=60
[root@k8s-master k8s]# kubectl get hpa|egep myapp
myapp Deployment/myapp 0%/60% 2 8 2 35s
3.开放服务端口
kubectl patch svc myapp -p '{"spec":{"type":"NodePort"}}'
4.客户端压力测试
Mac@~ $ab -c 100 -n 500000 http://10.211.55.11:30127/
5.看到扩容了3个POD
[root@k8s-master ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
myapp Deployment/myapp 102%/60% 2 8 4 4m54s
6.查看Pod
[root@k8s-master ~]# kubectl get pods |egrep myapp
myapp-64bf6764c5-b2kmr 1/1 Running 0 7m51s
myapp-64bf6764c5-b59nw 1/1 Running 0 19s
myapp-64bf6764c5-cbjfw 1/1 Running 0 19s
myapp-64bf6764c5-mhc9d 1/1 Running 0 79s
7.查看详细的信息
[root@k8s-master ~]# kubectl describe hpa
........
resource cpu on pods (as a percentage of request): 13% (6m) / 60%
Min replicas: 1
Max replicas: 8
Deployment pods: 4 current / 4 desired
.........
8.可以查看时时的yaml 文件
kubectl get hpa -o yaml --export

autoscaling/v2beta1 HPAv2
HPA(v2)控制器
HPA(v2)支持从metrics-server中请求核心指标;从k8s-prometheus-adapter一类自定义API中获取自定义指标数据
多个指标计算时,结果中数值较大的胜出

1.删除之前的hpa
kubectl delete hpa myapp
2.配置核心API 的HPA
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa-v1
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 55
- type: Resource
resource:
name: memory
targetAverageValue: 100Mi
scaleTargetRef: 要缩放的目标资源
metrics:计算所需Pod副本数量的指标列表,每个指标单独计算,取所有计算结果的最大值作为最终副本数量
- external,引用非附属于任何对象的全局指标,可以是集群之外的组件的指标数据,如消息队列长度
- object,引用描述集群中某单一对象的特定指标,如Ingress对象上的hits-per-second等
- pods,引用当前被弹性伸缩的Pod对象的特定指标
- resource,引用资源指标,即当前被弹性伸缩的Pod对象中容器的requests和limits中定义的指标
- type,指标源的类型,可为Objects、Pods、Resource
3.压力测试
Mac@~ $ab -c 100 -n 500000 http://10.211.55.11:30127/
4.查看HPA的信息
[root@k8s-master k8s]# kubectl get hpa
[root@k8s-master ~]# kubectl describe hpa
[root@k8s-master ~]#kubectl get hpa -o yaml --export
5.配置自定义api需要的环境
apiVersion: apps/v1
1.ikubernetes/metrics-app 运行时会通过 /metrics路径输出 http_requests_total 和 http_requests_per_second 两个指标
2.注释 prometheus.io/scrape:"true" 使Pod对象能够被 Promethues采集相关指标
3.Prometheus通过服务发现机制发现新创建的Pod对象,根据注释提供的配置信息识别指标并纳入采集对象,而后由k8s-prometheus-adapter将这些指标注册到自定义API中,提供给HPA(v2)控制器和调度器等作为调度评估参数使用
[root@k8s-master ~]# kubectl get pods |egrep metrics
metrics-app-6695bdf47b-gvtzf 1/1 Running 0 4h22m
metrics-app-6695bdf47b-rlng4 1/1 Running 0 4h22m
6.测试自定义的这个API 信息
[root@k8s-master ~]# kubectl get svc |egrep metrics
metrics-app NodePort 10.104.193.140 <none> 80:32556/TCP 4h25m


7.配置自定义api的HPA(添加自定义指标 http_requests_per_second)
apiVersion: autoscaling/v2beta1
8.添加规则:
将prometheus指标升级为k8s自定义指标,需要定义规则
vim k8s-prometheus-adapter/deploy/manifests/custom-metrics-config-map.yaml
- seriesQuery: 'http_requests_total{kubernetes_namespace!="",kubernetes_pod_name!=""}'
1.https://github.com/DirectXMan12/k8s-prometheus-adapter/blob/master/docs/config-walkthrough.md
2.https://github.com/DirectXMan12/k8s-prometheus-adapter/blob/master/docs/walkthrough.md
#while true; do curl http://metrics-app; let i++; sleep 0.$RANDOM; done # 模拟压力
kubectl get hpa


还可以参考下面文章做相应的测试
https://www.jianshu.com/p/9abb697cd833
总结
不是所有的系统都可以依靠CPU/内存使用指标单独满足SLA,大多数Web和移动后端需要以每秒请求处理任何突发流量进行自动缩放。
对于ETL应用程序,可能会由于作业队列长度超过某个阈值而触发自动缩放,等等。
通过prometheus检测你应用程序的正确指标,并为自动伸缩提供正确指标,您可以微调您的应用程序更好地处理突发和确保高可用性。

浙公网安备 33010602011771号