kubernetes(k8s)-扩缩容(工作负载HPA、节点)
~人美心善,点个赞赞,谢谢~
扩缩容是 K8s 的核心特性之一,是实现应用弹性与高可用的关键。
一、扩缩容的概念与作用
核心概念
Kubernetes 提供了不同层次的扩缩容机制,主要分为两种:
手动扩缩容:管理员通过命令或修改 YAML 文件直接调整 Pod 副本数。
自动扩缩容:系统根据设定的规则(如 CPU/内存使用率)自动调整 Pod 副本数。
从资源维度看,可以分为:
工作负载扩缩容:调整 Pod 的副本数量。
节点扩缩容:调整集群中 Node 的数量。
为什么需要扩缩容?
1、应对流量波动:
作用:在业务高峰时段(如双十一、促销活动)自动增加 Pod 数量以处理更多请求;在低谷时段自动减少 Pod 以节省资源。
价值:保证应用可用性,同时优化成本。
2、提高资源利用率:
作用:避免在低负载时资源闲置,在高负载时资源不足。
价值:实现"按需使用",降低基础设施成本。
3、实现高可用:
作用:通过运行多个 Pod 副本来避免单点故障。
价值:当某个 Pod 或节点故障时,其他副本可以继续提供服务。
4、支持灰度发布与滚动更新:
作用:在应用发布时,可以逐步增加新版本 Pod 数量,同时减少旧版本 Pod 数量。
价值:实现平滑升级,最小化发布风险。
二、手动扩缩容
这是最基础的扩缩容方式,适用于已知的、固定的负载模式。
实现方式
1、通过 kubectl scale 命令:
# 将名为 my-app 的 Deployment 扩展到 5 个副本
kubectl scale deployment my-app --replicas=5# 将名为 my-statefulset 的 StatefulSet 扩展到 3 个副本
kubectl scale statefulset my-statefulset --replicas=32、通过修改 YAML 文件:
# 编辑 Deployment 配置
kubectl edit deployment my-app
# 然后修改 `spec.replicas` 字段的值3、修改源码文件后重新应用:
apiVersion: apps/v1
kind: Deployment
metadata:name: my-app
spec:replicas: 5 # 直接修改这个值selector:matchLabels:app: my-apptemplate:# ... Pod 模板 ...然后执行:
kubectl apply -f deployment.yaml经典案例:为预期的高流量做准备
假设你运营一个电商网站,预计在"黑色星期五"流量会激增。
操作步骤:
1、正常时期,你的商品服务 Deployment 配置为 3 个副本。
2、在促销活动开始前,通过命令将副本数扩展到 10 个:
kubectl scale deployment product-service --replicas=10 -n production3、活动结束后,再将其缩容回 3 个:
kubectl scale deployment product-service --replicas=3 -n production优点:简单、直接、可预测。
缺点:需要人工干预,无法应对突发流量。
三、自动扩缩容
这是 Kubernetes 最强大的特性之一,主要通过 HPA(Horizontal Pod Autoscaler) 实现。
HPA(水平 Pod 自动扩缩容)
概念:HPA 自动调整 Deployment、ReplicaSet 或 StatefulSet 等控制器的 Pod 副本数,以匹配观察到的 CPU 使用率、内存使用率或其他自定义指标。
工作原理(控制循环)
1、Metrics Server(或其他指标提供商,如 Prometheus)持续收集所有 Pod 的指标数据。
2、HPA 控制器每 15 秒(默认)查询一次 Metrics Server,获取目标资源的指标数据。
3、HPA 将当前指标值与在 HPA 资源中设定的目标值进行比较。
4、根据计算结果,HPA 调整目标资源(如 Deployment)的 .spec.replicas 字段。
5、Deployment Controller 检测到期望的副本数变化,开始创建或删除 Pod。
基于 CPU/Memory 的 HPA 案例
场景:一个 Web API 服务,需要根据 CPU 使用率自动扩缩容。
步骤 1:部署应用并配置资源请求
hpa-demo-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: hpa-demo-app
spec:replicas: 3 # 初始副本数selector:matchLabels:app: hpa-demo-apptemplate:metadata:labels:app: hpa-demo-appspec:containers:- name: appimage: nginx:alpineports:- containerPort: 80resources:requests:cpu: 200m # 重要:HPA 需要这个值来计算使用率memory: 128Milimits:cpu: 500mmemory: 256Mi
---
apiVersion: v1
kind: Service
metadata:name: hpa-demo-service
spec:selector:app: hpa-demo-appports:- port: 80targetPort: 80步骤 2:创建 HPA 资源
hpa-cpu.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: hpa-demo-cpu
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: hpa-demo-app # 目标 DeploymentminReplicas: 2 # 最小副本数maxReplicas: 10 # 最大副本数metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 50 # 目标:所有 Pod 的平均 CPU 使用率维持在 50%behavior: # 伸缩行为配置 (K8s v1.18+)scaleDown:stabilizationWindowSeconds: 300 # 缩容冷却窗口 5 分钟policies:- type: Percentvalue: 50 # 一次最多缩容 50% 的 PodperiodSeconds: 60scaleUp:stabilizationWindowSeconds: 60 # 扩容冷却窗口 1 分钟policies:- type: Percentvalue: 100 # 一次最多扩容 100% 的 PodperiodSeconds: 60应用配置:
kubectl apply -f hpa-demo-deployment.yaml
kubectl apply -f hpa-cpu.yaml步骤 3:测试与验证
1、查看 HPA 状态:
kubectl get hpa hpa-demo-cpu
# 输出示例:
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
# hpa-demo-cpu Deployment/hpa-demo-app 0%/50% 2 10 3 5m2、生成负载进行测试:
使用 kubectl run 创建一个临时 Pod 来模拟流量:
kubectl run -it --rm load-generator --image=busybox -- /bin/sh
# 在 Pod 内执行:
while true; do wget -q -O- http://hpa-demo-service; done3、观察扩缩容过程:
# 在一个新终端窗口 watch HPA 和 Pod 的变化
kubectl get hpa hpa-demo-cpu -w
kubectl get pods -w你会看到当 CPU 使用率超过 50% 时,Pod 数量开始增加;当负载降低后,Pod 数量会逐渐减少(受 scaleDown 行为配置约束)。
基于自定义指标的 HPA
除了 CPU/内存,HPA 还支持基于自定义指标(如 QPS - 每秒请求数)进行扩缩容。这通常需要 Prometheus 和 Prometheus Adapter。
示例 HPA 配置(基于 QPS):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: hpa-demo-custom
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: hpa-demo-appminReplicas: 2maxReplicas: 10metrics:- type: Pods # 基于 Pod 的指标pods:metric:name: http_requests_per_second # 自定义指标名称target:type: AverageValueaverageValue: 100 # 目标:每个 Pod 平均处理 100 QPS四、集群节点扩缩容
当 Pod 需要扩容但没有足够的节点资源时,就需要对节点进行扩缩容。
1. 手动节点扩缩容
在云平台上手动添加或移除 VM。
在物理环境中手动上架或下架服务器。
2. 自动节点扩缩容 - Cluster Autoscaler
概念:Cluster Autoscaler 自动调整 Kubernetes 集群的节点数量。当 Pod 因资源不足而无法调度时,它会增加节点;当节点利用率过低时,它会删除节点。
触发条件:
扩容:Pod 因资源不足而处于
Pending状态。缩容:节点利用率低于阈值(通常为 50%),且其上的 Pod 可以被安全地重新调度到其他节点。
经典案例:应对突发批量任务
场景:一个数据分析平台,平时负载平稳。某用户提交了一个需要大量计算资源的批量任务。
过程:
用户创建了一个需要 20 个 Pod 的 Job,每个 Pod 请求 2 个 CPU。
集群当前没有足够的空闲资源,这些 Pod 处于
Pending状态。Cluster Autoscaler 检测到无法调度的 Pod,通知云提供商创建新的节点。
新节点加入集群后,调度器将 Pod 分配到新节点上运行。
任务完成后,Pod 终止。
Cluster Autoscaler 发现节点利用率很低,且没有不可迁移的 Pod,开始安全地排空并删除这些节点。
五、最佳实践与注意事项
1、合理设置资源请求:HPA 依赖于 resources.requests 进行计算,必须正确设置。
2、配置合理的边界:
minReplicas不能太小,要保证基本的高可用。maxReplicas不能太大,避免"疯狂扩容"导致资源耗尽或成本爆炸。
3、使用 behavior 控制伸缩灵敏度:
扩容可以相对激进(快速响应流量增长)。
缩容应该相对保守(避免在短暂流量下降时频繁缩容)。
4、结合就绪探针和存活探针:确保只有健康的 Pod 被计入指标和接收流量。
5、监控与告警:对 HPA 事件和扩缩容行为设置监控和告警。
总结
| 扩缩容类型 | 控制对象 | 主要依据 | 适用场景 |
|---|---|---|---|
| 手动扩缩容 | Pod 副本数 | 人工判断 | 已知的、计划内的流量变化 |
| HPA | Pod 副本数 | CPU/内存/自定义指标 | 应对不可预测的流量波动 |
| Cluster Autoscaler | 集群节点数 | Pod 调度压力/节点利用率 | 集群资源整体不足或闲置 |
Kubernetes 的扩缩容机制共同构建了一个高度自动化的弹性系统,让应用能够智能地应对各种负载情况,在保证服务质量的同时,最大化资源利用效率。
