$ kubectl top pods --sort-by=memory
Kubernetes 是当今最流行的容器编排平台,但如果你在 AWS EKS、GKE 或 Azure AKS 上运行 Kubernetes,你可能会惊讶地发现:平均有 40-60% 的计算资源被浪费了。今天我们就来聊聊如何优化 Kubernetes 的云成本。
Kubernetes 成本浪费的根源
1. Resource Request/Limit 设置不合理
开发者通常为了"保险"而请求过多资源:
resources:
requests:
cpu: "2" # 实际只需要 0.2
memory: "4Gi" # 实际只需要 512Mi
limits:
cpu: "4"
memory: "8Gi"
结果:每个 Pod 占用大量调度空间,但实际利用率极低。
2. 过度配置节点
为了应对突发流量,节点规格通常选得过大:
- m5.24xlarge(96 vCPU, 384GB RAM)太贵
- 实际工作负载可能只需要 8-16 vCPU
- 大量内存处于 idle 状态
3. 缺乏自动伸缩
- HPA 只扩展 Pod,不缩节点
- 非高峰期节点仍然空转
- 没有根据负载动态调整集群规模
优化策略一:正确的 Resource 设置
使用 VPA(Vertical Pod Autoscaler)
VPA 可以自动分析 Pod 历史资源使用,并推荐或自动调整请求值:
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"
基于历史数据设置 Request
用 Prometheus + 监控工具分析真实使用量:
# Prometheus 查询 99 分位数 CPU 使用率
quantile_over_time(0.99,
rate(container_cpu_usage_seconds_total{container!=""}[5m])[14d]
)
优化策略二:多实例类型和 Spot 节点池
EKS 节点组配置
# eksctl 创建 Spot 节点组 eksctl create nodegroup \ --cluster=my-cluster \ --name=spot-ng \ --node-type=m5.large \ --nodes=10 \ --node-spot-enabled \ --spot-fleet-enabled
Karpenter(动态节点管理)
Karpenter 是 AWS 原生的 K8s 节点管理工具:
- 根据实际 Pod 需求动态启动/终止节点
- 自动选择最合适大小的实例
- 可以配置 Spot 和 On-Demand 混合
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: default
spec:
requirements:
- key: node.kubernetes.io/instance-type
operator: In
values: [m5.large, m5.xlarge, c5.large]
- key: topology.kubernetes.io/zone
operator: In
values: [us-east-1a, us-east-1b]
limits:
resources:
cpu: "100"
provider:
instanceProfile: KarpenterNodeRole
spotPool:
strategy: lowest-price
poolSize: 3
优化策略三:Namespace 配额和 LimitRange
设置 ResourceQuota
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota
spec:
hard:
requests.cpu: "40"
requests.memory: 100Gi
limits.cpu: "80"
limits.memory: 200Gi
pods: "50"
设置 LimitRange(默认值)
apiVersion: v1
kind: LimitRange
metadata:
name: limits
spec:
limits:
- default:
cpu: 500m
memory: 256Mi
defaultRequest:
cpu: 100m
memory: 128Mi
type: Container
优化策略四:KEDA 实现事件驱动伸缩
KEDA(Kubernetes Event-driven Autoscaling)可以根据外部指标伸缩:
- Kafka lag
- Prometheus 指标
- AWS SQS 队列深度
- 定时(cron)
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: my-scaler
spec:
scaleTargetRef:
name: my-deployment
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus:9090
metricName: http_requests
threshold: "100"
监控工具:Kubecost
Kubecost 是 Kubernetes 原生的成本监控工具:
- 按 Namespace/Deployment/Pod 分解成本
- 识别资源浪费和优化机会
- 提供 Right-Sizing 建议
- 集成 Prometheus
# Helm 安装 Kubecost helm install kubecost kubecost/cost-analyzer \ --namespace kubecost \ --set kubecostToken="xxxxx" \ --set prometheus.enabled=true
最佳实践总结
- 使用 VPA 分析并调整 Resource Request/Limit
- 创建 Spot 节点池处理非关键工作负载
- 使用 Karpenter 或 Cluster Autoscaler 动态管理节点
- 通过 ResourceQuota 和 LimitRange 控制命名空间配额
- 使用 KEDA 实现事件驱动的 Pod 伸缩
- 部署 Kubecost 持续监控和报告集群成本
- 定期审查 Right-Sizing 建议
Kubernetes 成本优化不是一次性的工作,而是需要持续监控和迭代改进的过程。