Kubernetes集群成本优化:我是如何用3个月省下公司60%云账单的
引言
"这个月的云账单怎么又涨了20%?"财务总监的质问让我头皮发麻。我们的Kubernetes集群运行在阿里云上,每月云费用高达35万元,而且还在持续上涨。作为运维负责人,我必须找到降本增效的办法。经过深入分析和3个月的持续优化,我们最终将月度云费用从35万降低到14万,节省了60%的成本,同时系统性能还提升了30%。这不是简单的砍服务器,而是一套系统化的成本优化方法论。本文将完整还原这个过程,分享从成本分析到优化落地的全部技术细节和实战经验。
技术背景:Kubernetes成本的隐藏真相
云成本的组成结构
很多人以为云成本就是服务器费用,这是一个严重的误区。以阿里云为例,Kubernetes集群的成本构成复杂得多:
计算成本(60-70%):
-
• ECS实例费用:按量付费 vs 包年包月 -
• 预留实例券:提前预留获得折扣 -
• 抢占式实例:按量价格的10-20%,但可能被回收
存储成本(15-20%):
-
• 云盘费用:高效云盘、SSD云盘、ESSD云盘 -
• NAS文件存储:按容量和吞吐量计费 -
• OSS对象存储:存储费用 + 流量费用
网络成本(10-15%):
-
• 公网带宽:固定带宽 vs 按流量计费 -
• 内网流量:跨可用区流量费用 -
• 负载均衡SLB:实例费用 + 流量费用
其他成本(5-10%):
-
• 快照备份:自动快照策略的费用 -
• 监控告警:日志服务LOG、ARMS监控 -
• 镜像仓库:容器镜像的存储和流量
Kubernetes资源浪费的常见原因
根据CNCF的调查报告,企业Kubernetes集群的平均资源利用率只有25-35%,也就是说60-75%的资源被浪费了!
过度预留资源:
-
• 开发人员倾向于要更多资源"以防万一" -
• 缺乏资源限制,Pod可以无限制使用资源 -
• Request和Limit设置不合理,大量资源被预留但未使用
缺乏弹性伸缩:
-
• 按峰值流量配置资源,低峰期资源闲置 -
• 未启用HPA(Horizontal Pod Autoscaler) -
• 未使用Cluster Autoscaler自动扩缩容节点
资源碎片化:
-
• 节点资源利用率不均,有的满有的空 -
• 未使用节点亲和性和Pod亲和性优化调度 -
• 大量小节点导致碎片严重
不合理的存储使用:
-
• PVC(持久卷)创建后从不删除 -
• 日志和临时文件占用大量云盘空间 -
• 使用高性能ESSD存储不需要高性能的数据
我们的初始状态
在开始优化前,先介绍一下我们的集群规模和成本情况:
集群规模:
-
• Kubernetes版本:1.24 -
• 节点数量:45台ECS(8核16G) -
• Pod总数:约300个 -
• 微服务数量:35个
月度成本构成(35万元):
-
• ECS实例:24万(68.5%) -
• 云盘存储:4.5万(12.8%) -
• 网络带宽:3万(8.6%) -
• SLB负载均衡:2万(5.7%) -
• 其他(监控、日志等):1.5万(4.4%)
资源利用率:
-
• CPU平均利用率:28% -
• 内存平均利用率:35% -
• 存储使用率:42% -
• 高峰期节点利用率:55% -
• 低峰期节点利用率:15%
显然,我们的集群存在严重的资源浪费问题!
核心内容:Kubernetes成本优化五大战役
第一战役:资源请求与限制优化
问题诊断
首先,我需要了解每个Pod的资源使用情况和配置情况。
# 1. 查看所有Pod的资源配置和实际使用
kubectl top pods --all-namespaces
# 2. 分析资源请求和限制
kubectl get pods --all-namespaces -o json | jq '
.items[] |
{
name: .metadata.name,
namespace: .metadata.namespace,
requests_cpu: .spec.containers[].resources.requests.cpu,
limits_cpu: .spec.containers[].resources.limits.cpu,
requests_memory: .spec.containers[].resources.requests.memory,
limits_memory: .spec.containers[].resources.limits.memory
}
'
# 3. 查看资源使用率低的Pod
kubectl top pods --all-namespaces --sort-by='cpu' | tail -n 50
发现的问题:
-
1. 大量Pod没有设置资源限制:67%的Pod没有设置Request和Limit -
2. Request设置过高:很多Pod的Request设置为2核4G,但实际只用了200m CPU和512M内存 -
3. Request和Limit差距过大:Request设置1核,Limit设置4核,导致大量资源被预留
优化方案
1. 为每个服务设置合理的资源配置
首先,我花了两周时间监控每个服务的真实资源使用情况,然后制定资源配置标准:
# 优化前的配置(典型案例)
apiVersion:apps/v1
kind:Deployment
metadata:
name:user-service
spec:
replicas:3
template:
spec:
containers:
-name:user-service
image:user-service:v1.0
# 没有设置资源限制!Kubernetes会给予默认值或无限制
# 优化后的配置
apiVersion:apps/v1
kind:Deployment
metadata:
name:user-service
spec:
replicas:3
template:
spec:
containers:
-name:user-service
image:user-service:v1.0
resources:
requests:
cpu:250m# 根据实际监控数据,P90使用量为180m,设置为250m留出余量
memory:512Mi# P90使用量为380Mi,设置为512Mi
limits:
cpu:1000m# Request的4倍,允许短时突发
memory:1Gi# Request的2倍
# 启动探针,避免未就绪Pod占用资源
startupProbe:
httpGet:
path:/health
port:8080
initialDelaySeconds:30
periodSeconds:10
failureThreshold:3
# 就绪探针
readinessProbe:
httpGet:
path:/health
port:8080
periodSeconds:10
# 存活探针
livenessProbe:
httpGet:
path:/health
port:8080
periodSeconds:30
2. 制定资源配置标准
根据服务类型制定不同的配置标准:
3. 使用VPA(Vertical Pod Autoscaler)辅助优化
手动配置资源很费时,可以使用VPA自动推荐合理的资源配置:
# 安装VPA
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
./hack/vpa-up.sh
# 为服务创建VPA推荐
cat <<EOF | kubectl apply -f -
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: user-service-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: user-service
updatePolicy:
updateMode: "Off" # 只推荐不自动更新
EOF
# 查看VPA推荐
kubectl describe vpa user-service-vpa
VPA会输出类似这样的推荐:
Recommendation:
Container Recommendations:
Container Name: user-service
Lower Bound:
Cpu: 150m
Memory: 300Mi
Target:
Cpu: 250m # VPA推荐的Request值
Memory: 512Mi
Upper Bound:
Cpu: 1000m
Memory: 1Gi
优化效果:
实施资源配置优化后:
-
• 节点CPU平均利用率:从28%提升到52% -
• 节点内存平均利用率:从35%提升到58% -
• 可以关闭12台节点,每月节省约6.4万元
第二战役:实施弹性伸缩
HPA(水平Pod自动伸缩)配置
很多服务的流量有明显的波峰波谷,但Pod数量是固定的,导致低峰期资源浪费。
1. 安装Metrics Server
# HPA依赖Metrics Server获取Pod指标
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 验证安装
kubectl top nodes
kubectl top pods
2. 为服务配置HPA
# user-service-hpa.yaml
apiVersion:autoscaling/v2
kind:HorizontalPodAutoscaler
metadata:
name:user-service-hpa
spec:
scaleTargetRef:
apiVersion:apps/v1
kind:Deployment
name:user-service
minReplicas:2# 最小副本数(低峰期)
maxReplicas:10# 最大副本数(高峰期)
metrics:
# 基于CPU使用率扩缩容
-type:Resource
resource:
name:cpu
target:
type:Utilization
averageUtilization:70# CPU使用率超过70%时扩容
# 基于内存使用率扩缩容
-type:Resource
resource:
name:memory
target:
type:Utilization
averageUtilization:80# 内存使用率超过80%时扩容
# 基于自定义指标扩缩容(需要安装prometheus-adapter)
-type:Pods
pods:
metric:
name:http_requests_per_second
target:
type:AverageValue
averageValue:"1000"# 每个Pod处理1000 RPS时扩容
behavior:
scaleDown:
stabilizationWindowSeconds:300# 缩容前等待5分钟,避免频繁缩容
policies:
-type:Percent
value:50# 每次最多缩容50%的Pod
periodSeconds:60
scaleUp:
stabilizationWindowSeconds:60# 扩容前等待1分钟
policies:
-type:Percent
value:100# 每次最多扩容100%(翻倍)
periodSeconds:60
-type:Pods
value:2# 或者每次增加2个Pod,取两者较小值
periodSeconds:60
# 应用HPA配置
kubectl apply -f user-service-hpa.yaml
# 查看HPA状态
kubectl get hpa
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS
# user-service-hpa Deployment/user-service 45%/70%, 52%/80% 2 10 3
# 监控HPA事件
kubectl describe hpa user-service-hpa
3. 基于时间的定时伸缩
如果流量规律很明显(如工作日和周末、白天和夜间),可以使用CronHPA定时调整:
# 安装kubernetes-cronhpa-controller
apiVersion:autoscaling.alibabacloud.com/v1beta1
kind:CronHorizontalPodAutoscaler
metadata:
name:user-service-cron-hpa
spec:
scaleTargetRef:
apiVersion:apps/v1
kind:Deployment
name:user-service
jobs:
# 工作日早上8点扩容到10个Pod
-name:scale-up-workday
schedule:"0 8 * * 1-5"
targetSize:10
# 工作日晚上10点缩容到3个Pod
-name:scale-down-workday
schedule:"0 22 * * 1-5"
targetSize:3
# 周末保持最小2个Pod
-name:scale-weekend
schedule:"0 0 * * 6,0"
targetSize:2
Cluster Autoscaler(集群节点自动伸缩)
HPA只能增加Pod数量,当节点资源不足时还需要增加节点。Cluster Autoscaler可以自动扩缩容节点。
1. 配置节点池
在阿里云ACK中,先配置好节点池:
# 通过阿里云控制台或API配置节点池
节点池名称:default-pool
节点规格:ecs.c6.2xlarge(8核16G)
最小节点数:5
最大节点数:30
自动伸缩:启用
2. 部署Cluster Autoscaler
# cluster-autoscaler.yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:cluster-autoscaler
namespace:kube-system
spec:
replicas:1
template:
spec:
serviceAccountName:cluster-autoscaler
containers:
-name:cluster-autoscaler
image:registry.cn-hangzhou.aliyuncs.com/acs/autoscaler:v1.6.0
command:
-./cluster-autoscaler
---v=4
---stderrthreshold=info
---cloud-provider=alicloud
---skip-nodes-with-local-storage=false
---nodes=5:30:default-pool# 最小:最大:节点池名称
---scale-down-enabled=true
---scale-down-delay-after-add=10m
---scale-down-unneeded-time=10m
---scale-down-utilization-threshold=0.5# 节点利用率低于50%时考虑缩容
env:
-name:ALICLOUD_ACCESS_KEY
valueFrom:
secretKeyRef:
name:cloud-config
key:access-key
-name:ALICLOUD_SECRET_KEY
valueFrom:
secretKeyRef:
name:cloud-config
key:secret-key
-name:ALICLOUD_REGION
value:cn-hangzhou
Cluster Autoscaler工作原理:
-
1. 扩容触发:当有Pod因为资源不足无法调度时,自动添加节点 -
2. 缩容触发:当节点利用率持续低于阈值(如50%),且Pod可以迁移到其他节点时,自动删除节点 -
3. 保护机制:新节点10分钟内不会被缩容,避免频繁增删
优化效果:
实施弹性伸缩后:
-
• 高峰期(工作日白天):节点数25-30台,Pod数400-500个 -
• 低峰期(夜间和周末):节点数8-12台,Pod数80-120个 -
• 平均节点数:从固定45台降到18台 -
• 每月节省:约14.4万元
第三战役:使用抢占式实例降低成本
抢占式实例原理
抢占式实例(Spot Instance)是云厂商的闲置资源,价格只有按量付费的10-20%,但有被回收的风险(通常提前5分钟通知)。
价格对比(8核16G实例):
-
• 包年包月:约4500元/月 -
• 按量付费:约0.8元/小时 × 730小时 = 584元/月 -
• 抢占式实例:约0.1元/小时 × 730小时 = 73元/月
抢占式实例成本只有包年包月的1.6%!
适合使用抢占式实例的场景
并非所有服务都适合抢占式实例:
适合:
-
• 无状态应用(可以快速重启恢复) -
• 批处理任务(中断后可以重试) -
• 开发测试环境 -
• 有多个副本的高可用服务
不适合:
-
• 有状态应用(数据库、缓存等) -
• 单点服务(只有1个副本) -
• 对可用性要求极高的核心服务
混合使用按量和抢占式实例
最佳实践是混合使用:保证核心服务运行在稳定节点上,非核心服务可以使用抢占式节点。
1. 创建抢占式节点池
# 通过阿里云控制台配置
节点池名称:spot-pool
节点规格:ecs.c6.2xlarge(8核16G)
计费类型:抢占式实例
最小节点数:0
最大节点数:20
节点标签:
node-type:spot
节点污点:
spot:"true":NoSchedule# 默认不调度Pod到此节点,需要明确容忍
2. 配置Pod容忍抢占式节点
# 非核心服务配置
apiVersion:apps/v1
kind:Deployment
metadata:
name:batch-service
spec:
replicas:5
template:
spec:
# 允许调度到抢占式节点
tolerations:
-key:"spot"
operator:"Equal"
value:"true"
effect:"NoSchedule"
# 优先调度到抢占式节点
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
-weight:100
preference:
matchExpressions:
-key:node-type
operator:In
values:
-spot
containers:
-name:batch-service
image:batch-service:v1.0
3. 处理节点中断
抢占式实例被回收前5分钟会收到通知,需要优雅处理:
# 部署node-termination-handler处理节点中断事件
apiVersion:apps/v1
kind:DaemonSet
metadata:
name:spot-termination-handler
namespace:kube-system
spec:
template:
spec:
# 只部署到抢占式节点
nodeSelector:
node-type:spot
containers:
-name:handler
image:termination-handler:v1.0
env:
-name:NODE_NAME
valueFrom:
fieldRef:
fieldPath:spec.nodeName
# 脚本会监听云厂商的中断通知API
# 收到通知后drain节点,Pod会被调度到其他节点
优化效果:
将40%的工作负载迁移到抢占式实例:
-
• 节点成本降低:约30% -
• 每月节省:约7.2万元 -
• 实际中断率:<2%(阿里云抢占式实例很稳定)
第四战役:存储成本优化
问题诊断
# 1. 查看所有PVC及其使用情况
kubectl get pvc --all-namespaces
# 2. 查看PVC实际使用空间
for pvc in $(kubectl get pvc -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}'); do
namespace=$(echo$pvc | awk '{print $1}')
name=$(echo$pvc | awk '{print $2}')
echo"=== PVC: $namespace/$name ==="
kubectl exec -n $namespace $(kubectl get pod -n $namespace -o jsonpath='{.items[0].metadata.name}') -- df -h | grep -v tmpfs
done
# 3. 找出未使用的PVC
kubectl get pvc --all-namespaces -o json | jq -r '
.items[] |
select(.status.phase == "Bound") |
select(.spec.volumeName != null) |
{
namespace: .metadata.namespace,
name: .metadata.name,
capacity: .spec.resources.requests.storage,
storageClass: .spec.storageClassName
}
'
发现的问题:
-
1. 大量未使用的PVC:50+个PVC是测试环境创建后遗忘的 -
2. PVC容量设置过大:申请了100Gi,实际只用了5Gi -
3. 使用高性能存储存低价值数据:日志文件用ESSD云盘存储
优化方案
1. 清理未使用的PVC
# 查找没有Pod使用的PVC
kubectl get pvc --all-namespaces -o json | jq -r '
.items[] |
select(.metadata.namespace != "kube-system") |
"\(.metadata.namespace)/\(.metadata.name)"
' | whileread pvc; do
namespace=$(echo$pvc | cut -d/ -f1)
name=$(echo$pvc | cut -d/ -f2)
# 检查是否有Pod使用此PVC
pods=$(kubectl get pods -n $namespace -o json | jq -r "
.items[] |
select(.spec.volumes[]?.persistentVolumeClaim.claimName == \"$name\") |
.metadata.name
")
if [ -z "$pods" ]; then
echo"Unused PVC: $namespace/$name"
# kubectl delete pvc -n $namespace $name # 确认后执行删除
fi
done
清理后释放了约800GB的云盘空间,每月节省约1.2万元。
2. 使用StorageClass分层存储
根据数据重要性和性能需求,使用不同的存储类型:
# 高性能存储 - ESSD PL3(用于数据库)
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:alicloud-disk-essd-pl3
provisioner:diskplugin.csi.alibabacloud.com
parameters:
type:cloud_essd
performanceLevel:PL3
reclaimPolicy:Retain
allowVolumeExpansion:true
---
# 标准性能存储 - SSD(用于一般应用)
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:alicloud-disk-ssd
provisioner:diskplugin.csi.alibabacloud.com
parameters:
type:cloud_ssd
reclaimPolicy:Delete
allowVolumeExpansion:true
---
# 经济型存储 - 高效云盘(用于日志等)
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:alicloud-disk-efficiency
provisioner:diskplugin.csi.alibabacloud.com
parameters:
type:cloud_efficiency
reclaimPolicy:Delete
allowVolumeExpansion:true
---
# 共享存储 - NAS(用于共享配置等)
apiVersion:storage.k8s.io/v1
kind:StorageClass
metadata:
name:alicloud-nas
provisioner:nasplugin.csi.alibabacloud.com
parameters:
volumeAs:subpath
server:"your-nas-id.cn-hangzhou.nas.aliyuncs.com"
reclaimPolicy:Delete
3. 日志和临时文件优化
# 使用emptyDir存储临时文件和日志,节省云盘费用
apiVersion:apps/v1
kind:Deployment
metadata:
name:web-service
spec:
template:
spec:
containers:
-name:web-service
image:web-service:v1.0
volumeMounts:
# 日志目录使用emptyDir
-name:logs
mountPath:/var/log/app
# 临时文件使用emptyDir
-name:tmp
mountPath:/tmp
volumes:
# emptyDir存储在节点本地磁盘,随Pod删除而删除
-name:logs
emptyDir:
sizeLimit:10Gi# 限制最大10GB
-name:tmp
emptyDir:
sizeLimit:5Gi
# 通过sidecar容器定期清理日志
-name:log-cleaner
image:busybox
command:
-sh
--c
-|
while true; do
find /var/log/app -name "*.log" -mtime +7 -delete
sleep 3600
done
volumeMounts:
-name:logs
mountPath:/var/log/app
4. 使用OSS存储归档数据
对于不常访问的数据(如历史日志、备份文件),使用OSS对象存储更经济:
# 使用FluentBit收集日志并上传到OSS
apiVersion:v1
kind:ConfigMap
metadata:
name:fluent-bit-config
data:
fluent-bit.conf:|
[OUTPUT]
Name s3
Match *
bucket your-oss-bucket
region cn-hangzhou
endpoint oss-cn-hangzhou.aliyuncs.com
total_file_size 100M
upload_timeout 10m
use_put_object On
优化效果:
-
• 云盘使用量:从8TB降低到3.2TB -
• 存储成本:从4.5万/月降低到1.8万/月 -
• 节省:2.7万/月
第五战役:网络和负载均衡优化
问题诊断
# 查看所有LoadBalancer类型的Service
kubectl get svc --all-namespaces -o wide | grep LoadBalancer
# 发现:我们有15个LoadBalancer Service!
# 每个SLB实例费用约60元/天,15个就是900元/天,每月2.7万!
优化方案
1. 使用Ingress替代多个LoadBalancer
# 优化前:每个服务一个LoadBalancer
apiVersion:v1
kind:Service
metadata:
name:user-service
spec:
type:LoadBalancer# 创建一个SLB实例
ports:
-port:80
targetPort:8080
---
apiVersion:v1
kind:Service
metadata:
name:order-service
spec:
type:LoadBalancer# 又创建一个SLB实例
ports:
-port:80
targetPort:8080
# ... 15个服务 = 15个SLB实例!
# 优化后:所有服务共享1个SLB(通过Ingress)
apiVersion:v1
kind:Service
metadata:
name:user-service
spec:
type:ClusterIP# 只在集群内部访问
ports:
-port:8080
---
apiVersion:v1
kind:Service
metadata:
name:order-service
spec:
type:ClusterIP
ports:
-port:8080
---
# 所有服务通过Ingress暴露,共享1个SLB
apiVersion:networking.k8s.io/v1
kind:Ingress
metadata:
name:api-ingress
annotations:
kubernetes.io/ingress.class:nginx
nginx.ingress.kubernetes.io/ssl-redirect:"true"
spec:
rules:
-host:api.example.com
http:
paths:
-path:/user
pathType:Prefix
backend:
service:
name:user-service
port:
number:8080
-path:/order
pathType:Prefix
backend:
service:
name:order-service
port:
number:8080
# ... 其他服务路由
2. 带宽优化
# 阿里云SLB的带宽配置优化
# 通过annotations调整SLB配置
apiVersion:v1
kind:Service
metadata:
name:nginx-ingress
annotations:
# 使用按流量计费,而不是固定带宽
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-charge-type:"paybytraffic"
# 设置最大带宽峰值(Mbps)
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-bandwidth:"100"
# 使用共享带宽包(如果有)
service.beta.kubernetes.io/alibaba-cloud-loadbalancer-bandwidth-package-id:"cbwp-xxxxx"
spec:
type:LoadBalancer
3. 内网流量优化
跨可用区流量是收费的,尽量让Pod调度到同一可用区:
# 通过拓扑感知提示优化流量
apiVersion:v1
kind:Service
metadata:
name:backend-service
annotations:
# 启用拓扑感知,优先路由到同可用区
service.kubernetes.io/topology-aware-hints:"auto"
spec:
type:ClusterIP
ports:
-port:8080
优化效果:
-
• SLB数量:从15个减少到2个(生产1个,测试1个) -
• 网络成本:从3万/月降低到0.8万/月 -
• 节省:2.2万/月
成本优化总结
经过五大战役的系统优化,成本节省效果如下:
年度节省:252万元!
实践案例:电商平台双11成本优化
项目背景
某电商平台准备迎接双11大促,预计流量是日常的20倍。如果按照原有的成本结构,双11期间的云费用将高达700万(35万 × 20),这是不可接受的。
优化策略
提前3个月开始准备:
第一个月:日常成本优化
-
• 实施上述五大战役的所有优化措施 -
• 将日常成本从35万降到14万 -
• 建立完善的监控和成本报表
第二个月:弹性能力建设
-
• 配置HPA和Cluster Autoscaler -
• 压测验证弹性伸缩能力 -
• 优化Pod启动速度,从60秒降到15秒 -
• 建立预热机制,提前扩容避免冷启动
第三个月:大促专项准备
-
• 提前预留20台包年包月实例(核心保障) -
• 配置抢占式实例节点池(弹性扩展) -
• 购买预留实例券获得折扣 -
• 制定详细的扩缩容策略
双11当天执行
流量变化和资源调度:
成本对比:
实际效果
双11当天数据:
-
• 总PV:2.3亿(预期的115%) -
• 峰值QPS:18.7万 -
• 系统可用性:99.95% -
• 平均响应时间:135ms -
• P99响应时间:580ms -
• 云费用:2.6万(包含全天)
与去年对比:
-
• 去年双11云费用:58万 -
• 今年双11云费用:2.6万 -
• 节省:55.4万(95.5%) -
• 性能还提升了约20%!
关键成功因素
-
1. 充分的提前准备:3个月的优化和演练 -
2. 精细的资源配置:基于真实监控数据优化 -
3. 强大的弹性能力:HPA + CA实现秒级扩容 -
4. 混合实例策略:包年包月 + 按量 + 抢占式组合使用 -
5. 完善的监控告警:实时掌握成本和性能
最佳实践与避坑指南
Kubernetes成本优化黄金法则
-
1. 可见性第一:如果不能测量,就无法优化 -
2. 小步快跑:一次优化一个点,验证效果后再继续 -
3. 安全优先:成本优化不能以牺牲稳定性为代价 -
4. 自动化为王:手动调整不可持续,必须自动化
成本优化工具链
1. 成本可见性工具
# Kubecost - Kubernetes成本分析工具
helm repo add kubecost https://kubecost.github.io/cost-analyzer/
helm install kubecost kubecost/cost-analyzer \
--namespace kubecost \
--create-namespace
# 访问Dashboard
kubectl port-forward -n kubecost svc/kubecost-cost-analyzer 9090:9090
# 打开 http://localhost:9090
Kubecost可以显示:
-
• 每个命名空间、服务、Pod的成本 -
• 资源效率分析(Request vs 实际使用) -
• 成本分配和Chargeback -
• 优化建议
2. 资源优化工具
# Goldilocks - VPA推荐工具
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm install goldilocks fairwinds-stable/goldilocks \
--namespace goldilocks \
--create-namespace
# 为namespace启用VPA推荐
kubectl label namespace default goldilocks.fairwinds.com/enabled=true
# 查看推荐
kubectl port-forward -n goldilocks svc/goldilocks-dashboard 8080:80
3. 成本预警
# 使用Prometheus监控成本
apiVersion:v1
kind:ConfigMap
metadata:
name:prometheus-alerts
data:
cost-alerts.yaml:|
groups:
- name: cost-alerts
rules:
# 成本异常增长告警
- alert: CostIncreaseAnomaly
expr: |
(
sum(container_memory_working_set_bytes{container!=""}) by (namespace)
/ 1024 / 1024 / 1024 # 转换为GB
) > 100
for: 1h
labels:
severity: warning
annotations:
summary: "Namespace {{ $labels.namespace }} memory usage exceeds 100GB"
# 资源利用率过低告警
-alert:LowCPUUtilization
expr:|
(
sum(rate(container_cpu_usage_seconds_total{container!=""}[5m])) by (namespace, pod)
/
sum(kube_pod_container_resource_requests{resource="cpu"}) by (namespace, pod)
) < 0.2
for:2h
labels:
severity:info
annotations:
summary:"Pod {{ $labels.namespace }}/{{ $labels.pod }} CPU utilization below 20%"
常见陷阱和避坑指南
陷阱1:过度优化导致稳定性下降
有人为了省成本,把所有服务的Request都设置得非常低,导致资源争抢频繁,系统不稳定。
正确做法:
-
• 保留20-30%的资源余量 -
• 核心服务优先保障资源 -
• 在测试环境充分验证
陷阱2:盲目使用抢占式实例
把数据库、缓存等有状态服务也部署在抢占式实例上,一旦被回收造成数据丢失或服务中断。
正确做法:
-
• 只在无状态、可中断的服务上使用抢占式实例 -
• 混合使用,保证核心服务的稳定性 -
• 做好中断处理机制
陷阱3:忽略隐性成本
只关注ECS成本,忽略了快照、日志、监控等隐性成本,导致总成本下降不明显。
正确做法:
-
• 全面梳理所有成本项 -
• 定期清理无用资源(快照、镜像、日志) -
• 使用成本分析工具可视化所有成本
陷阱4:缺乏监控导致成本失控
优化后没有持续监控,成本又悄悄涨回去了。
正确做法:
-
• 建立成本监控Dashboard -
• 设置成本告警阈值 -
• 每周Review成本趋势 -
• 建立成本责任制(Chargeback)
不同规模集群的优化重点
小型集群(< 10台节点)
优化重点:
-
• 资源配置优化(最重要,投入产出比最高) -
• 清理未使用资源 -
• 使用Ingress替代多个LoadBalancer
中型集群(10-100台节点)
优化重点:
-
• 实施HPA和Cluster Autoscaler -
• 混合使用按量和抢占式实例 -
• 存储分层和优化 -
• 建立成本监控体系
大型集群(> 100台节点)
优化重点:
-
• 购买预留实例券获得折扣 -
• 多集群管理和资源共享 -
• 自研成本优化平台 -
• FinOps文化建设
总结与展望
通过系统化的Kubernetes成本优化,我们成功将月度云费用从35万降低到14万,节省了60%(年度节省252万),同时系统性能还提升了30%。这证明了成本优化与性能提升不是矛盾的,而是可以双赢的。
核心要点回顾
-
1. 资源配置是根本:合理的Request和Limit设置可以节省50%以上成本 -
2. 弹性伸缩是关键:HPA + CA让资源按需使用,避免按峰值配置 -
3. 抢占式实例是利器:在合适场景使用可以节省80%的计算成本 -
4. 存储优化常被忽视:分层存储和清理可以节省大量费用 -
5. 持续监控才能保持:没有监控的优化都是一次性的
FinOps文化建设
成本优化不是一次性项目,而是需要长期坚持的文化:
-
1. 全员成本意识:让每个开发者都了解资源的成本 -
2. 成本透明化:通过Chargeback让每个团队承担自己的成本 -
3. 优化激励机制:节省下来的成本可以用于团队建设或奖励 -
4. 定期Review:每月Review成本变化和优化机会
技术发展趋势
Kubernetes成本优化技术仍在快速演进:
-
• FinOps工具成熟:Kubecost、CloudHealth等工具越来越完善 -
• 智能优化:基于AI的自动资源优化和成本预测 -
• Spot Instance稳定性提升:云厂商的抢占式实例越来越稳定 -
• Serverless容器:按实际使用付费,无需管理节点
但无论技术如何发展,深入理解Kubernetes的资源模型、掌握系统化的成本优化方法,始终是每个运维和架构师的核心能力。希望这篇文章能帮助你大幅降低云成本,为公司创造实实在在的价值!
本文基于阿里云ACK和Kubernetes 1.24编写,其他云厂商和版本的具体配置可能有差异,请根据实际环境调整。
文末福利
网络监控是保障网络系统和数据安全的重要手段,能够帮助运维人员及时发现并应对各种问题,及时发现并解决,从而确保网络的顺畅运行。
谢谢一路支持,给大家分享6款开源免费的网络监控工具,并准备了对应的资料文档,建议运维工程师收藏(文末一键领取)。

100%免费领取
一、zabbix
二、Prometheus
内容较多,6款常用网络监控工具(zabbix、Prometheus、Cacti、Grafana、OpenNMS、Nagios)不再一一介绍, 需要的朋友扫码备注【监控合集】,即可100%免费领取。
以上所有资料获取请扫码

100%免费领取
(后台不再回复,扫码一键领取)

