AWS EKS 成本优化实战:识别和清理”幽灵”资源的完整指南
引言:那些悄悄吃掉预算的隐形资源
作为云架构师,我经常遇到这样的场景:团队的 AWS 账单月复一月地增长,但没人能说清楚钱花在了哪里。当我们深入分析 EKS 集群时,往往会发现一个令人沮丧的事实——大量资源正在”空转”,却持续产生费用。
最近在 Reddit 上看到一个开源项目 CloudSlash 的更新讨论,作者针对社区反馈优化了 EKS 资源检测引擎,这让我想系统性地聊聊 EKS 环境中那些容易被忽视的成本陷阱。
问题分析:EKS 资源浪费的三大元凶
1. 幽灵 Node Group(Ghost Node Groups)
这是 EKS 环境中最隐蔽的成本杀手。问题的根源在于 Kubernetes 的架构设计:
- DaemonSet 的特性:像
kube-proxy、aws-node(VPC CNI)这类系统组件以 DaemonSet 形式运行,会在每个节点上自动部署一个 Pod - Autoscaler 的保守策略:Cluster Autoscaler 在缩容时会检查节点上是否有 Pod 运行。由于系统 DaemonSet 始终存在,autoscaler 可能认为节点”仍在使用”
- 结果:Node Group 保持活跃状态,EC2 实例持续运行,但实际上没有任何用户工作负载
这种情况在以下场景尤为常见:
- 开发/测试环境在下班后没有工作负载
- 批处理任务完成后,节点未能正确缩容
- 蓝绿部署后,旧的 Node Group 未被清理
2. 僵尸控制平面(Zombie Control Planes)
很多团队不知道的是:EKS 控制平面本身就是收费的,每个集群每小时约 $0.10(每月约 $72)。即使集群中没有任何工作节点,控制平面费用依然产生。
常见的僵尸集群来源:
- 临时创建用于 POC 验证的集群
- CI/CD 流水线创建的测试集群未被销毁
- 项目结束后遗留的开发环境
- 团队成员离职后无人维护的集群
3. 孤立的 Fargate Profile(Orphaned Fargate Profiles)
这是一种典型的配置漂移(Configuration Drift)问题。Fargate Profile 通过 namespace selector 来决定哪些 Pod 应该运行在 Fargate 上。当目标 namespace 被删除后:
- Fargate Profile 本身不会自动删除
- Profile 配置指向一个不存在的 namespace
- 虽然不直接产生费用,但会造成配置混乱和技术债务
- 可能影响后续同名 namespace 的创建和调度行为
解决方案探讨:检测与清理策略对比
方案 A:手动审计 + 脚本检测
最基础的方法是编写自定义脚本进行检测:
# 检测空闲 Node Group 的示例脚本
#!/bin/bash
for cluster in $(aws eks list-clusters --query 'clusters[]' --output text); do
for nodegroup in $(aws eks list-nodegroups --cluster-name $cluster --query 'nodegroups[]' --output text); do
desired=$(aws eks describe-nodegroup --cluster-name $cluster --nodegroup-name $nodegroup \
--query 'nodegroup.scalingConfig.desiredSize' --output text)
if [ "$desired" -eq 0 ]; then
echo "警告: $cluster/$nodegroup 期望节点数为 0"
fi
done
done
优点:成本为零,完全可控
缺点:需要持续维护,难以覆盖所有边缘情况,无法检测”只有系统 Pod”的场景
方案 B:使用 AWS 原生工具
结合 AWS Cost Explorer、Trusted Advisor 和 CloudWatch 进行监控:
- Cost Explorer:按 EKS 集群标签分析成本趋势
- CloudWatch Container Insights:监控 Pod 和节点的资源利用率
- Trusted Advisor:检测闲置的 EC2 实例
优点:官方支持,与 AWS 生态深度集成
缺点:需要额外配置,Container Insights 有额外费用,无法直接识别”幽灵”Node Group
方案 C:专用的云资源治理工具
像 CloudSlash 这类专门的”云垃圾收集器”工具提供了更智能的检测逻辑:
- 幽灵检测:区分系统 Pod 和用户 Pod,识别仅运行 DaemonSet 的节点
- 僵尸识别:检测长期空闲(如 >7 天)的控制平面
- 配置验证:交叉检查 Fargate Profile 与实际 namespace 状态
- 安全标签:支持白名单机制,防止误删正在开发的资源
优点:开箱即用,检测逻辑更智能,减少误报
缺点:引入第三方依赖,高级功能可能需要付费
最佳实践:构建完整的 EKS 成本治理体系
1. 建立资源标签规范
标签是云资源治理的基础。建议至少包含:
Environment: dev/staging/prod
Team: platform/backend/data
Project: project-name
Owner: [email protected]
ExpireDate: 2025-03-01 # 临时资源必填
2. 实施白名单保护机制
对于正在开发或有特殊用途的资源,使用标签进行保护。CloudSlash 的做法值得借鉴:
# 永久忽略
cloudslash:ignore = true
# 设置过期时间
cloudslash:ignore = 2026-01-01
# 基于成本阈值
cloudslash:ignore = cost<15
3. 建立定期审计流程
建议的审计频率:
- 每日:自动扫描并发送报告到 Slack/邮件
- 每周:团队 review 扫描结果,确认可清理资源
- 每月:与财务数据对账,验证优化效果
4. 自动化清理流水线
对于非生产环境,可以考虑自动化清理:
# 示例:GitLab CI 定时清理任务
cleanup-dev-clusters:
stage: maintenance
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
script:
- cloudslash scan --environment dev --auto-remediate
only:
- schedules
5. 配置 Cluster Autoscaler 的缩容策略
优化 Cluster Autoscaler 配置,减少幽灵节点的产生:
--scale-down-unneeded-time=10m
--scale-down-delay-after-add=10m
--skip-nodes-with-system-pods=false # 谨慎使用
--skip-nodes-with-local-storage=false
总结
EKS 成本优化不是一次性工作,而是需要持续关注的运维实践。从这次 CloudSlash 的更新讨论中,我们可以看到社区对于”智能检测”的需求——不仅要找到闲置资源,还要区分”真正的废弃”和”暂时的空闲”。
无论你选择自建脚本、使用 AWS 原生工具,还是采用第三方解决方案,关键是要建立起完整的资源治理体系:标签规范 → 自动检测 → 人工确认 → 安全清理。只有这样,才能在保证业务稳定的前提下,持续优化云成本。
需要优化您的 AWS 架构? 欢迎在评论区分享您的经验。您的团队是如何处理 EKS 资源浪费问题的?有没有遇到过”幽灵”资源导致的成本意外?