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. 制定资源配置标准
根据服务类型制定不同的配置标准:
服务类型 | CPU Request | CPU Limit | Memory Request | Memory Limit | 说明 |
---|---|---|---|---|---|
Web API | 250m-500m | 1000m-2000m | 512Mi-1Gi | 1Gi-2Gi | 高并发低计算 |
后台任务 | 500m-1000m | 2000m-4000m | 1Gi-2Gi | 2Gi-4Gi | 计算密集型 |
数据处理 | 1000m-2000m | 4000m-8000m | 2Gi-4Gi | 4Gi-8Gi | 高计算高内存 |
前端静态 | 100m | 500m | 128Mi | 256Mi | 极低资源 |
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万/月
成本优化总结
经过五大战役的系统优化,成本节省效果如下:
优化项目 | 优化前成本 | 优化后成本 | 节省金额 | 节省比例 |
---|---|---|---|---|
ECS实例 | 24.0万/月 | 9.6万/月 | 14.4万 | 60% |
云盘存储 | 4.5万/月 | 1.8万/月 | 2.7万 | 60% |
网络带宽 | 3.0万/月 | 0.8万/月 | 2.2万 | 73% |
SLB负载均衡 | 2.0万/月 | 0.5万/月 | 1.5万 | 75% |
其他 | 1.5万/月 | 1.3万/月 | 0.2万 | 13% |
合计 | 35.0万/月 | 14.0万/月 | 21.0万 | 60% |
年度节省:252万元!
实践案例:电商平台双11成本优化
项目背景
某电商平台准备迎接双11大促,预计流量是日常的20倍。如果按照原有的成本结构,双11期间的云费用将高达700万(35万 × 20),这是不可接受的。
优化策略
提前3个月开始准备:
第一个月:日常成本优化
- • 实施上述五大战役的所有优化措施
- • 将日常成本从35万降到14万
- • 建立完善的监控和成本报表
第二个月:弹性能力建设
- • 配置HPA和Cluster Autoscaler
- • 压测验证弹性伸缩能力
- • 优化Pod启动速度,从60秒降到15秒
- • 建立预热机制,提前扩容避免冷启动
第三个月:大促专项准备
- • 提前预留20台包年包月实例(核心保障)
- • 配置抢占式实例节点池(弹性扩展)
- • 购买预留实例券获得折扣
- • 制定详细的扩缩容策略
双11当天执行
流量变化和资源调度:
时间段 | 流量倍数 | 节点数 | Pod数 | 成本(元/小时) |
---|---|---|---|---|
00:00-08:00 | 1x | 18 | 120 | 300 |
08:00-18:00 | 5x | 45 | 400 | 750 |
18:00-20:00 | 10x | 80 | 650 | 1350 |
20:00-22:00 | 20x | 120 | 900 | 2100 |
22:00-00:00 | 15x | 95 | 750 | 1650 |
00:00-08:00 | 2x | 25 | 180 | 420 |
成本对比:
方案 | 峰值节点 | 日总成本 | 月度等效成本 |
---|---|---|---|
原方案(固定配置20倍) | 900台固定 | 64.8万 | 700万 |
优化方案(弹性伸缩) | 120台峰值 | 2.4万 | 28万 |
节省 | – | 62.4万/天 | 672万/月 |
实际效果
双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%免费领取
(后台不再回复,扫码一键领取)
本文链接:https://www.yunweipai.com/47440.html
网友评论comments