【Kubernetes知识点】HPA如何控制不同的资源实现自动扩缩容?
目录
- 1 概念
- 1.1 什么是HPA
- 1.2 Deployment 与 HPA 的关系
- 1.2.1 工作原理
- 1.3 StatefulSet 与 HPA 的关系
- 1.3.1 工作原理
- 2 实验案例:HPA 控制 StatefulSet 进行扩缩容
- 2.1 部署一个有状态应用
- 2.2 创建 HPA
- 2.3 验证HPA扩缩容
- 3 总结
- 3.1 注意事项:
❤️ 摘要:Kubernetes 作为当前最流行的容器编排平台,提供了 Horizontal Pod Autoscaler (HPA) 以便根据资源利用情况自动调整 Pod 副本数。本文将深入探讨 HPA 如何自动扩缩容
Deployment
和StatefulSet
,并通过实验演示其工作原理。
❤️ 本文内容关联文章:
- 《一文读懂Deployment以及实践攻略》
- 《一文读懂StatefulSet以及实践攻略》
- 《一文读懂HPA弹性扩展以及实践攻略》
1 概念
1.1 什么是HPA
❔ 说明:如果想更好理解下面的描述, 建议先看《一文读懂HPA弹性扩展以及实践攻略》,了解HPA弹性扩展的基本原理。
Horizontal Pod Autoscaler (HPA) 是 Kubernetes 中的一个控制器,它通过监控 Pod 的资源使用情况(如 CPU 或内存使用率),根据设定的指标自动调整 Pod 副本的数量。HPA 常用于解决云原生应用中负载波动的问题,确保在高负载时增加 Pod 副本以提升服务能力,在负载下降时减少 Pod 副本以节约资源。
HPA 可以结合 Deployment
和 StatefulSet
这两种常见的 Kubernetes 资源类型,分别应对无状态和有状态应用的弹性扩缩容需求。
1.2 Deployment 与 HPA 的关系
❔ 说明:如果想更好理解下面的描述, 建议先看《一文读懂Deployment以及实践攻略》,了解Deployment与Replicas,以及Deployment的滚动更新。
当为 Deployment 配置了自动扩缩容,HPA 接管 Deployment ,通过调节replicas
字段来实现 Pod 副本数量的控制。当 HPA 检测到负载变化时,它会自动调整 Deployment 的副本数。
在滚动更新期间,Deployment 控制器会负责通知底层的 ReplicaSets,再由ReplicaSet 管理 Pod 副本。当发生滚动更新时,Deployment 控制器通过调整新旧版本的 ReplicaSets 副本数,确保在更新期间的总副本数满足 HPA 的要求。例如,如果 HPA 设定 Deployment 需要 10 个副本,Deployment 控制器会动态调整新旧版本的 Pod 数量,使它们的总数一直为 10。
1.2.1 工作原理
HPA 在控制 Deployment
时,主要通过如下步骤工作:
- 指标采集:HPA 从 Metrics Server 或者 Prometheus 等监控系统中获取 Pod 的资源使用情况,如 CPU 或内存利用率。
- 扩缩容计算:HPA 根据设定的目标值(例如目标 CPU 使用率)与实际的资源使用情况进行对比,计算需要增加或减少的 Pod 副本数量。
- 副本调整:HPA 调用
Deployment
的 API 更新其replicas
,从而增加或减少实际运行的 Pod 数量。 - 监控和调整:HPA 持续监控资源使用情况,周期性地进行扩缩容操作,以保持系统的平稳运行。
1.3 StatefulSet 与 HPA 的关系
❔ 说明:如果想更好理解下面的描述, 建议先看《一文读懂StatefulSet以及实践攻略》,了解StatefulSet的滚动更新。
如果为 StatefulSet 配置了 HPA,HPA 直接管理 StatefulSet 的 Pod 数量(replicas
字段)。但StatefulSet 不同于 Deployment,StatefulSet 是直接管理一组有状态的 Pod,而不像 Deployment 通过ReplicaSet 作为中间资源管理一组无状态的应用。所以在滚动更新过程中,StatefulSet 需要同时参与处理 Pod 的更新和副本数的动态调整,保证每个 Pod 在 StatefulSet 中有固定的身份和顺序。
1.3.1 工作原理
HPA 在控制 StatefulSet
时,主要通过如下步骤工作:
- 指标采集:HPA 从 Metrics Server 或者 Prometheus 等监控系统中获取 Pod 的资源使用情况,如 CPU 或内存利用率。
- 扩缩容计算:HPA 根据设定的目标值(例如目标 CPU 使用率)与实际的资源使用情况进行对比,计算需要增加或减少的 Pod 副本数量。
- 副本调整: 不同于无状态的
Deployment
,StatefulSet
的 Pod 是有序创建和删除的,每个 Pod 都有一个固定的身份和独立的数据卷。例如,扩容时,新 Pod 会按顺序从pod-0
增加到pod-1
、pod-2
依次类推。缩容时则是相反,StatefulSet
会从最后一个 Pod 开始有序删除。 - 状态保持: 由于
StatefulSet
通常管理有状态应用(如数据库),这些应用需要保留数据持久化。即使 Pod 被删除,存储卷也不会被删除,而是在重新启动或扩容时重新附加到相应的 Pod。因此,在扩缩容时,HPA 不会影响StatefulSet
中 Pod 的状态或数据。
2 实验案例:HPA 控制 StatefulSet 进行扩缩容
❔ 环境说明:
- Kubernetes 集群已安装
- Metrics Server已安装
❔ 说明:《一文读懂HPA弹性扩展以及实践攻略》文章实践案例是“HPA自动扩缩Deployment应用的案例”,所以下面演示HPA 自动扩缩 StatefulSet。
2.1 部署一个有状态应用
创建一个简单的 StatefulSet
,例如 Redis。
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
clusterIP: None
selector:
app: redis
ports:
- port: 6379
name: redis
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
spec:
serviceName: "redis"
replicas: 1
minReadySeconds: 20
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: harbor.zx/hcie/redis:7.2.4
resources:
requests:
cpu: "100m"
limits:
cpu: "300m"
ports:
- containerPort: 6379
volumeMounts:
- name: redis-storage
mountPath: /data
volumeClaimTemplates:
- metadata:
name: redis-storage
spec:
storageClassName: "nfs-class"
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
创建Redis应用
kubectl apply -f redis-hpa.yaml
创建成功输入如下:
service/redis created
statefulset.apps/redis created
查看redis-service信息
kubectl describe svc redis-service
输出如下:
Name: redis-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=redis
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: None
IPs: None
Port: redis 6379/TCP
TargetPort: 6379/TCP
Endpoints: 172.16.135.254:6379
Session Affinity: None
Events: <none>
❔ 说明: redis-0已经成功关联redis-service
2.2 创建 HPA
为该 StatefulSet
配置 HPA,编制hpa部署文件:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: redis-hpa
spec:
# 关联StatefulSet资源
scaleTargetRef:
apiVersion: apps/v1
kind: StatefulSet
name: redis
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 50
创建HPA资源:
kubectl apply -f autoscaling.yaml
创建成功输入如下:
horizontalpodautoscaler.autoscaling/redis-hpa created
查看hpa信息
kubectl describe hpa redis-hpa
输出如下:
Name: redis-hpa
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Fri, 20 Sep 2024 17:00:39 +0800
Reference: StatefulSet/redis
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): 2% (2m) / 50%
Min replicas: 1
Max replicas: 5
StatefulSet pods: 1 current / 1 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale recommended size matches current size
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request)
ScalingLimited False DesiredWithinRange the desired count is within the acceptable range
❔ 说明:目前hpa已经正常获取redis的pod负载数据,但现在负载比较低。
2.3 验证HPA扩缩容
模拟对 Redis 的高负载请求,redis镜像自带的 Redis Benchmark 工具进行测试。
kubectl run -it --rm --restart=Never --image=harbor.zx/hcie/redis:7.2.4 redis-test -- redis-benchmark -h redis-service -p 6379 -c 50 -n 100000
使用 kubectl get hpa
监控扩缩容效果:
kubectl get hpa
观察到负载从2%到296%, 副本数扩展到最大5个
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
redis-hpa StatefulSet/redis 2%/50% 1 5 1 44m
redis-hpa StatefulSet/redis 125%/50% 1 5 1 44m
redis-hpa StatefulSet/redis 296%/50% 1 5 3 44m
redis-hpa StatefulSet/redis 277%/50% 1 5 5 44m
redis-hpa StatefulSet/redis 256%/50% 1 5 5 45m
redis-hpa StatefulSet/redis 239%/50% 1 5 5 45m
暂停redis-benchmark测试,再等待一会(默认缩容间隔5分钟):
redis-hpa StatefulSet/redis 2%/50% 1 5 5 47m
redis-hpa StatefulSet/redis 2%/50% 1 5 5 52m
redis-hpa StatefulSet/redis 2%/50% 1 5 2 52m
redis-hpa StatefulSet/redis 2%/50% 1 5 1 52m
❔说明: 可以观察到StatefulSet缩减到1个了。在负载上升时,HPA 会逐步增加
StatefulSet
的 Pod 数量,并以有序的方式启动新 Pod;当负载减小时,Pod 数量会逐步减少。
3 总结
通过本文的介绍和实验,我们了解了 HPA 如何通过监控 CPU 或内存等资源利用率,动态调整 Deployment
和 StatefulSet
的原理,实践了 StatefulSet
的自动扩缩容。
3.1 注意事项:
- 指标收集准确性:确保 Metrics Server 或 Prometheus 能够准确采集 Pod 的资源使用情况,否则可能导致 HPA 失效。
- 资源配置:为容器设置合理的
requests
和limits
,以确保 HPA 能够正常工作。 - StatefulSet 扩容速度:由于需要保持有序性,
StatefulSet
的扩缩容速度可能较Deployment
慢,应根据应用需求进行调整。
通过这些实验,我们可以更好地理解 Kubernetes 中 HPA 的强大功能,并根据实际业务场景选择合适的扩缩容策略。