K8s实战_HPA功能实验
title: K8s实战_HPA功能实验 date: 2026-03-11 categories: - K8s tags: - 实验 cover:
摘要:这份实战模拟了运维工程师在真实生产中遇到的场景:业务高峰流量导致 CPU 激增,系统自动横向扩容。
实战目标
-
部署一个 CPU 密集型的 Web 服务。
-
配置基于 CPU 利用率的 HPA 策略。
-
使用压测工具模拟高并发流量。
-
观察 Pod 副本数的动态增减及流量分发。
①编写实战 YAML (hpa-practice.yaml)
将所有的资源合在一个文件中
# 1. 定义业务 Deployment apiVersion: apps/v1 kind: Deployment metadata: name: hpa-worker spec: replicas: 1 selector: matchLabels: app: hpa-worker template: metadata: labels: app: hpa-worker spec: containers: - name: php-apache # 这里请替换为你从渡渡鸟拉取的镜像地址 image: hpa-example:latest ports: - containerPort: 80 resources: requests: cpu: 200m # 必须配置!这是HPA计算的基准 limits: cpu: 500m --- # 2. 定义对外服务的 Service apiVersion: v1 kind: Service metadata: name: hpa-worker-service spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: hpa-worker --- # 3. 定义 HPA 策略 apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: worker-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: hpa-worker minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 # 当CPU达到request的50%(即100m)时触发扩容
执行部署
kubectl apply -f hpa-practice.yaml
②状态检查
检查pod运行状态
kubectl get pod #确保是running
检查HPA状态
kubectl get hpa worker-hpa
-
关键点:如果
TARGETS列显示<unknown>/50%,说明 Metrics-Server 没调通或 Pod 还没产生数据,请等待 1 分钟。 -
正常值:应显示
0%/50%。
③压力测试(模拟负载)
打开两个新的终端窗口,以便实时观察变化。
窗口1:监控HPA动态
# 持续监控副本数和CPU变化 kubectl get hpa worker-hpa -w
窗口2:启动压测容器
使用 busybox 启动一个无限循环的负载生成器。
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://hpa-worker-service; done"
④观察验证
扩容阶段(Scaling Up)
随着压测进行,你会观察到窗口 A 的输出:
-
TARGETS里的百分比迅速上升(如150%/50%)。 -
REPLICAS从 1 变成 3,再变成 6,最终可能达到 10。 -
运维验证:执行
kubectl get pods,你会看到大量新的 Pod 正在Creating或Running。
负载平滑阶段
当副本数增加到足够多时,平均 CPU 利用率会回落到 50% 左右,副本数停止增长。
缩容阶段(Scaling Down)
在窗口 B 按下 Ctrl+C 停止压测。
-
注意:副本数并不会立刻减少。
-
运维知识点:K8s 为了防止“扩缩容震荡”(刚缩容流量又来了),默认有 5 分钟 的缩容冷却期(
stabilizationWindowSeconds)。 -
约 5 分钟后,你会看到
REPLICAS回到 1。
⑤实战总结
-
为什么需要 Request? 实验证明,不写 Request,HPA 无法计算百分比,状态永远是
Unknown。 -
Metrics-Server 的重要性:它是 HPA 的“眼睛”。
-
计算公式验证:如果 1 个 Pod 消耗 300m,目标是 100m (50% of 200m),那么
ceil(1 * (300/100)) = 3,所以副本数会变成 3。 -
1.35 版本观察:观察在 CentOS 10 上,Pod 的创建速度和资源调度是否均衡地分布在 Node1 和 Node2 上。
拓展实验-内存维度拓展
很多 Java 应用或缓存服务对 CPU 消耗不高,但会因为内存溢出(OOM)导致崩溃。
修改YAML
将指标改为memory
metrics: - type: Resource resource: name: memory target: type: Utilization averageUtilization: 70
-
模拟测试方法: 你不能通过简单的
wget模拟内存增长。你需要进入 Pod,使用stress-ng工具或编写简单的脚本申请内存。 -
运维排障点: 内存是不可压缩资源。如果 CPU 达到 100%,进程只是变慢;如果内存达到 Limit,进程会被内核 OOM Kill。在实战中观察:HPA 还没来得及扩容,Pod 是否就已经重启了?这就是为什么要合理设置
requests和limits的差值
拓展实验-扩缩灵敏度测试
场景: 生产环境最怕“扩容太慢”和“缩容太快”。
在 K8s 1.35 中,你可以通过 behavior 字段精细控制动作。
-
实验设计:
-
配置一个 快速扩容 策略:一旦超标,立即增加 4 倍副本。
-
配置一个 缓慢缩容 策略:为了应对波动,每次缩容只允许掉 1 个 Pod,且等待 10 分钟。
-
-
测试点:观察
kubectl get hpa -w的时间戳,记录从压力消失到副本数真正开始下降的时间间隔。
拓展实验-多指标综合监控
场景: 一个 Web 接口,CPU 高了要扩容,内存高了也要扩容。
-
实验配置: 在
metrics数组中同时定义 CPU 和 Memory。 -
判定逻辑(重要考点): HPA 会取所有指标中计算出的“最大副本数”作为最终目标。
公式推演:如果根据 CPU 计算需要 5 个副本,根据内存计算需要 8 个副本,HPA 最终会扩容到 8 个。
拓展实验-外部维度监控(Custom Metrics)
这是区分“初级运维”和“资深架构”的分水岭。Metrics-Server 只能看到系统层指标,但运维更关心业务指标。
-
扩展方向:
-
基于 QPS 扩容:配合 Prometheus 和适配器(Prometheus Adapter),根据 Nginx 每秒请求数扩容。
-
基于消息队列积压量:如果 RabbitMQ 里的消息堆积了 10000 条,立刻启动更多的消费者 Pod。
-
拓展实验-结合VPA‘联合演练’
尝试在同一个 Deployment 上同时应用 HPA 和 VPA,观察它们是否会打架。
-
测试建议:
-
给 Pod 开启 VPA 的
Off模式(仅推荐模式)。 -
在 HPA 扩容的过程中,查看 VPA 给出的
Target建议值是否也随之发生了变化。 -
记录下当两者冲突时,系统产生的
Warning事件。
-
更多推荐


所有评论(0)