K8s 弹性伸缩踩坑实录:周末 2 天烧掉 10 万元!?

01|令人措手不及的告警

那是一个周日的早晨,我正刷着牙,手机却突然开始疯狂震动:

Slack 告警(来自 AWS ):

"您本月的支出已超过预算的 80%。"
财务团队紧急消息

"今天早上 AWS 为什么一下子扣了我们 $5,000?"

原来,原本应该"智能"的 Kubernetes 弹性伸缩彻底失控了。

本以为只是周五下午随手改了个小配置,结果这个通常只需 3 个 Pod 的服务,竟然疯狂扩容了 87 个副本------烧钱速度比拉斯维加斯的赌场还快。

02|问题是怎么发生的?

我们一直在稳定运行一个处理后台任务的 Java 服务,几个月来相安无事...直到我们试图对它进行"优化"。

失误一:过度自信的HPA配置

乍看之下,我们的 HorizontalPodAutoscaler 配置似乎很合理:

yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
  maxReplicas: 100  
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        averageUtilization: 50  

我们期望的效果:「根据 CPU 使用率,在 2-20 个 Pod 之间优雅弹性伸缩」

实际发生的情况:「给我往死里扩!」

失误二:缺乏必要的保护机制

我们在配置伸缩策略时,完全没有设置任何保护措施,留下了多个隐患:

  • 没有设置 PodDisruptionBudget

缩容时 Kubernetes 会直接无差别地删除 Pod,场面堪比《权力的游戏》的大清洗。

  • 缺失 AWS 费用告警

最先发现问题的居然是财务部,而不是监控系统

  • 错误指标

CPU 使用率根本不适合作为该工作负载的伸缩依据

03|我们是如何排查问题的?

第一步:发现异常

在执行 kubectl top pods 后,我们看到:

scss 复制代码
NAME                          CPU(cores)  
worker-service-abc123         5m          # Basically idle  
worker-service-def456         7m  
... (87 more lines of this nonsense)

第二步:确认根本原因

经过排查,我们发现:

  • 我们的 Java 服务在运行过程中偶尔会有 GC 带来短暂的 CPU 峰值
  • HPA 误将这些瞬时波动识别为"资源告急",随即触发扩容
  • 每新增一个 Pod,又会引入更多 GC 活动,进而造成更频繁的峰值
  • 形成一个"波动---扩容---更多波动"的反馈循环。

结果就是在短时间内,大量资源被毫无必要地调度出来,成本极速上升。

04|如何解决问题?

✅ 1. 停止使用 CPU 作为依据指标

针对这个队列处理服务,改用 Kafka 消息积压数作为核心指标:

yaml 复制代码
metrics:
- type: External  # Now scales based on actual work
  external:
    metric:
      name: kafka_messages_behind  
    target:
      averageValue: 1000

✅ 2. 设定合理的伸缩上下限

yaml 复制代码
maxReplicas: 10  # Hard ceiling  
minReplicas: 1   # Let it breathe

✅ 3. 引入成本控制与弹性策略

  • AWS 预算警报: 消费每增加 $500 即触发邮件 + Slack 双重告警
  • 优化 Cluster Autoscaler 参数
ini 复制代码
--scale-down-unneeded-time=15m            # 避免太快回收节点  
--skip-nodes-with-local-storage=true      # 避免误删有状态节点

05|我们的经验教训

这次代价昂贵的事故,让我们团队总结出了几条核心教训:

  1. 自动伸缩并非"配置一次就万事大吉", 它需要持续关注和调整,更像是一只宠物而不是牛群;
  2. 不要在周五下班前部署敏感改动,伸缩类改动建议放在工作日早上;
  3. 财务团队是很灵敏的告警系统,虽然他们收到账单时不会给你好脸色

💡 实用小贴士: 在部署 HPA 配置更改前,强烈建议先运行以下命令,实时观察变化:

arduino 复制代码
kubectl get hpa -w

比起事后看到账单崩溃,实时观察指标的跳动会更有安全感。

相关推荐
颯沓如流星1 小时前
ZKube:优雅易用的 ZooKeeper 可视化管理工具
分布式·zookeeper·云原生
汪汪大队u1 小时前
从 Docker Compose 到 Kubernetes:物联网管理系统迁移实战(3)—— 两个运维坑
运维·docker·kubernetes
团象科技2 小时前
跨境业务运维压力攀升,云原生运维补齐 AI 出海底层支撑短板
运维·人工智能·云原生
小夏子_riotous2 小时前
Kubernetes学习路径——5. Kubernetes 实战入门:Namespace、Pod、Label、Deployment 与 Service 全解析
学习·贪心算法·kubernetes
炸裂狸花猫4 小时前
开源身份认证与访问管理平台 - Keycloak(三)公有云Console集成实践(AWS / 阿里云 / OCI)
阿里云·云原生·keycloak·aws·oci·sso
ん贤4 小时前
Kubernetes(k8s) 详细笔记
笔记·容器·kubernetes
星河耀银海4 小时前
AI基础设施革命:云原生+云边端+算力的协同价值
人工智能·云原生
9命怪猫18 小时前
[K8S小白问题集] - Calico好在哪里?
网络·云原生·容器·kubernetes
齐潇宇18 小时前
k8s-Helm管理器
linux·运维·云原生·容器·kubernetes
容器魔方18 小时前
让Skill从执行中生长:Cloud Agent Harness的三段式Skill自进化机制
云原生·开源·资讯