一、概念
1、工作逻辑
HPA都会周期的根据定义的指标去查询资源利用率。控制器管理器找到scaleTargetRef定义的资源,再根据标签选择pod,再从资源指标API中获取指标。
HPA从聚合API(metrics.k8s.io、custom.metrics.k8s.io、external.metrics.k8s.io)处获取指标,metrics.k8s.io通常由Metrics Server提供,需要单独安装。custom.metrics.k8s.io可以由prometheus提供、external.metrics.k8s.io一般由云厂商提供。
HPA支持对Deployment、StatefulSet类型的控制器进行扩缩容
二、扩缩算法
1、算法
期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]
示例,如果当前指标为200M,期望指标为100M,则副本数加倍,如果当前为50M,则副本数减半。
在决定扩缩之前,还要决定是否缺少任何指标,以及有多少个pod就绪。
所有设置了删除时间戳的pod(带有删除时间戳的对象正在关闭/移除的过程中)都会别忽略,所有失败的pod都会被抛弃。
如果某个pod缺失度量值,将暂时忽略
当使用CPU来计算时,未就绪状态的pod都会被忽略
缺失的度量值或者未就绪的pod,HPA会保守的计算,当缩容时,会认为值为期望目标值,当扩容时,会认为值为期望目标值。这样会减少扩缩的幅度,保证集群的稳定。
如果定义了多个指标,HPA将会按照最大值进行扩缩。
可以通过配置kube-contraller-manager的启动参数 `–horizontal-pod-autoscaler-downscale-stabilization默认为5分钟。 来设置每次扩缩容的等待时间,消除短时间内指标的波动产生的影响。
三、配置扩缩行为
注:需要1.23版本及以上
可以单独配置扩容或者缩容行为,可以设置scaleUp或scaleDown来控制。
还可以指定一个稳定期,防止频繁扩缩容,还可以指定变化率。
1、扩缩策略
如果有多个策略同时存在,则通过计算后,改变最大的策略将会生效。
behavior:
scaleDown:
policies:
- type: Pods
value: 4
periodSeconds: 60
- type: Percent
value: 10
periodSeconds: 60
以上示例:第一个策略为一分钟最多4个副本,第一个策略为一分钟最多10%的副本,当pod数量小于40个的时候,策略1生效,因为策略1的变化幅度大,当40个pod以上,则第二个策略的变化幅度大,第二个策略生效。
2、稳定窗口
配置扩缩容的等待时间,避免因为突发的资源抖动频繁的扩缩容
3、禁用HPA
如果目标的期望副本数为0,而HPA的最小副本数大于0,则HPA会停止调整目标
四、配置HPA
当启用HPA时,建议从清单中清除Deployment或者StateFulSet的replicas值,如果不做,在apply -f时,会将pod变更为yaml中的值。如何修改
kubectl apply edit-last-applied deployment/<Deployment 名称>
在编辑器中,删除 spec.replicas。当你保存并退出编辑器时,kubectl 会应用更新。 在此步骤中不会更改 Pod 计数。
你现在可以从清单中删除 spec.replicas。如果你使用源代码管理, 还应提交你的更改或采取任何其他步骤来修改源代码,以适应你如何跟踪更新。
从这里开始,你可以运行 kubectl apply -f deployment.yaml
注:
1、部署metrics-server
直接部署mertics-server
[root@k8s-master-01 ~]# kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/high-availability-1.21+.yaml
[root@k8s-master-01 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
metrics-server-8568cf894b-7qbq6 1/1 Running 22 216d=
验证metrics-server 是否采集到node数据:
[root@k8s-master-01 ~]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
10.0.0.11 168m 8% 2290Mi 70%
10.0.0.12 139m 13% 1280Mi 102%
10.0.0.13 122m 12% 1220Mi 97%
10.0.0.21 210m 10% 2295Mi 71%
10.0.0.22 126m 6% 2279Mi 71%
10.0.0.23 99m 4% 2610Mi 81%
修改controller-manager参数
#定义pod数量⽔平伸缩的间隔周期,默认15秒
--horizontal-pod-autoscaler-sync-period
#⽤于设置 pod 的初始化时间, 在此时间内的 pod,CPU 资源指标将不会被采纳,默认为5分钟
--horizontal-pod-autoscaler-cpu-initialization-period
#⽤于设置 pod 准备时间, 在此时间内的 pod 统统被认为未就绪及不采集数据,默认为30秒
--horizontal-pod-autoscaler-initial-readiness-delay
2、运行php-apache 服务器并暴露服务
直接部署服务,并通过service暴露
kubectl apply -f https://k8s.io/examples/application/php-apache.yaml
3、配置HPA自动伸缩
通过命令创建HPA,并关联到名字为php-apache的deployment控制器上
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
查看HPA状态
[root@k8s-master-01 ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 16s
给php-apache服务增加负载
# 在单独的终端中运行它
# 以便负载生成继续,你可以继续执行其余步骤
kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
持续观测HPA的状态,在服务压力大的时候扩容到8台,再停止压测服务,会发现副本数会将为最小。
[root@k8s-master-01 ~]# kubectl get hpa php-apache --watch
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 3m16s
php-apache Deployment/php-apache 250%/50% 1 10 1 3m19s
php-apache Deployment/php-apache 250%/50% 1 10 4 3m34s
php-apache Deployment/php-apache 250%/50% 1 10 5 3m50s
php-apache Deployment/php-apache 99%/50% 1 10 5 4m21s
php-apache Deployment/php-apache 99%/50% 1 10 8 4m36s
php-apache Deployment/php-apache 0%/50% 1 10 8 5m22s
php-apache Deployment/php-apache 0%/50% 1 10 8 10m
php-apache Deployment/php-apache 0%/50% 1 10 1 10m
4、基于自定义度量指标自动扩缩
当我们从metrics.k8s.io
API 获取的指标来进行自动扩缩容时,只能以CPU、内存作为资源度量指标。只能使用绝对值或者百分比。
因为cpu或者内存并不能全面的代表机器的压力,所以我们引入通过外部的指标,来进行扩缩容。
custom metrics(自定义度量指标)包括两种度量指标
pod度量指标:比如根据pod的网络io来进行伸缩
object度量指标:比如根据ingress的并发数来进行伸缩