1. 为什么需要K8s压力测试当你把业务迁移到Kubernetes集群后最怕遇到什么情况我猜一定是半夜被报警叫醒发现服务因为流量激增而崩溃。去年我们团队就经历过一次促销活动带来的流量是平时的20倍HPAHorizontal Pod Autoscaler没有按预期扩容导致整个服务雪崩。这就是不做压力测试的代价。压力测试不仅仅是模拟高并发请求那么简单它更像是对集群的一次全面体检。通过压测我们可以验证服务极限知道你的服务在崩溃前能承受多少流量就像知道桥梁的最大承重优化资源配置避免给Pod分配过多资源造成浪费我见过一个Node.js服务配置了4核CPU实际只用0.5核检验HPA可靠性动态扩缩容不是配置好就能用的需要实测验证触发条件是否准确2. HPA动态扩缩容实战2.1 HPA工作原理揭秘HPA就像集群的智能空调系统当温度CPU/内存使用率超过设定阈值时会自动增加Pod数量来降温。但很多人不知道的是HPA有这三个关键参数决定它的灵敏度metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 # 这是黄金参数 behavior: # 这是多数人忽略的调速器 scaleDown: stabilizationWindowSeconds: 300 # 缩容冷却时间 policies: - type: Percent value: 10 # 每次最多减少10%的Pod实测发现当averageUtilization设为50%时如果突然遇到流量高峰HPA可能需要3-5分钟才能完成扩容。这时可以配合behavior参数调整扩缩容速度behavior: scaleUp: stabilizationWindowSeconds: 0 policies: - type: Percent value: 100 # 允许一次性翻倍扩容 - type: Pods value: 4 # 或者每次至少增加4个Pod2.2 真实压测场景演示我们用php-apache做测试对象先部署基础服务kubectl apply -f - EOF apiVersion: apps/v1 kind: Deployment metadata: name: php-apache spec: replicas: 1 selector: matchLabels: app: php-apache template: metadata: labels: app: php-apache spec: containers: - name: php-apache image: k8s.gcr.io/hpa-example resources: requests: cpu: 200m limits: cpu: 500m EOF然后用hey工具模拟真实流量kubectl run hey --imagerakyll/hey -- \ -c 200 -n 1000000 -q 50 http://php-apache.default.svc.cluster.local这时候通过Grafana观察会发现一个有趣现象虽然CPU使用率已经超过80%但HPA没有立即扩容。这是因为HPA默认采集的是最近1分钟的平均值瞬时峰值不会触发扩容。这就是为什么生产环境需要结合自定义指标如QPS来做更灵敏的扩容判断。3. 资源优化实战技巧3.1 Requests和Limits的黄金比例经过上百次压测我总结出资源配置的3:5法则Requests设为实际需求的60%如实际需要300m就设200mLimits设为Requests的1.5-2倍这样配置的好处是提高集群资源利用率不会因为requests过高导致碎片给突发流量留出缓冲空间避免OOM Killer误杀Podresources: requests: cpu: 200m memory: 256Mi limits: cpu: 500m memory: 512Mi3.2 垂直扩缩容VPA的隐藏用法虽然HPA负责水平扩缩容但当遇到Java这类内存敏感型应用时还需要配合VPAVertical Pod Autoscaler# 安装VPA组件 helm install vpa recommender \ --repo https://charts.fairwinds.com/stable \ --set recommender.extraArgs.v4配置自动内存调整apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: my-app-vpa spec: targetRef: apiVersion: apps/v1 kind: Deployment name: my-app updatePolicy: updateMode: Auto实测发现VPA可以将内存配置优化到最佳状态减少30%以上的内存浪费。但要注意VPA会导致Pod重建不适合有状态服务。4. 高级压测方案设计4.1 分布式压测架构当需要模拟10万级并发时单机压测工具就不够用了。我们在生产环境使用这样的架构[K6控制中心] - [K6 Worker Pods] - [被测服务]部署命令kubectl apply -f - EOF apiVersion: apps/v1 kind: Deployment metadata: name: k6-worker spec: replicas: 10 # 10个worker节点 template: spec: containers: - name: k6 image: loadimpact/k6 command: [sleep] args: [infinity] EOF然后通过k6的分布式执行模式kubectl exec -it k6-worker-0 -- \ k6 run --vus 1000 --duration 30m \ --out cloud \ script.js4.2 混沌工程结合压测真正的稳定性测试需要引入故障。我们使用chaos-mesh模拟网络延迟apiVersion: chaos-mesh.org/v1alpha1 kind: NetworkChaos metadata: name: network-delay spec: action: delay mode: one selector: namespaces: - default labelSelectors: app: php-apache delay: latency: 500ms correlation: 100 jitter: 100ms在压测过程中随机注入网络延迟、Pod故障等异常可以暴露出更多潜在问题。比如我们就曾发现当Node节点CPU负载超过70%时kube-proxy的转发性能会急剧下降。5. 监控与数据分析压测不是简单的发请求关键是要建立完整的监控链路。我们的监控矩阵包括监控层级工具关键指标基础设施Node ExporterCPU steal、磁盘IO等待容器运行时cAdvisor容器内存泄漏应用性能Prometheus99线响应时间业务指标自定义Exporter订单创建成功率特别是要关注这些黄金指标饱和度CPU throttling次数表示limit设置过低错误率5xx错误增长趋势流量QPS与Pod数量的比值延迟P99响应时间变化配置Prometheus告警规则示例- alert: HighCPUThrottling expr: rate(container_cpu_cfs_throttled_seconds_total{container!}[5m]) 0.1 for: 10m labels: severity: warning annotations: summary: Pod {{ $labels.pod }} CPU throttling过高压测结束后用Grafana的Heatmap面板分析响应时间分布往往能发现隐藏的性能瓶颈。比如我们发现当MySQL连接数超过配置的max_connections时响应时间会从50ms直接飙升到2000ms。经过三年多的K8s压测实践最大的体会是没有经过压测的HPA配置就是耍流氓。每次业务大促前我们都会用历史峰值流量的3倍进行全链路压测这已经成为保障稳定性的最后一道防线。