Kubernetes 调度策略深度拆解:我如何帮团队省下 90% 的资源成本

举报
Echo_Wish 发表于 2025/11/28 21:23:55 2025/11/28
【摘要】 Kubernetes 调度策略深度拆解:我如何帮团队省下 90% 的资源成本

Kubernetes 调度策略深度拆解:我如何帮团队省下 90% 的资源成本

作者|Echo_Wish(爱算账的 K8s 打工人)

兄弟姐妹们,实话实说:很多公司的 Kubernetes 集群资源使用率真实情况只有 10%~30%。你没看错,就是这点儿。
大家不是技术不行,而是默认调度 + 一堆“看起来合理”的配置把钱烧没了。

我见过太多集群:节点 CPU 一直空着,Pod 却在横着扩;大部分 Deployment 的 request 都是拍脑袋写的;HPA 靠天吃饭;调度策略完全走默认;晚上没人访问服务,集群却和白天一样热火朝天地烧钱。

所以我想写一篇真正落地、接地气、能帮你 省真金白银 的调度策略指南。下面的招数都是我自己在生产环境试过的,省下来不仅是成本,更是 KPI 吧(你懂的)。


一、为什么默认调度会浪费资源?

Kubernetes 默认调度器(kube-scheduler)遵循一种“大家都能跑就行”的哲学,优先保证可靠性,但绝不帮你省钱。

默认的问题:

  • Request 填大了 → 导致 资源虚空占用(实际不需要那么多)。
  • Pod 分散调度 → 节点之间负载不均,出现大量 碎片化
  • 低峰期没有自动缩容 → 白白浪费节点成本
  • 没用 NodeAffinity / Taints → Pod 跑得乱七八糟 → 影响 bin-packing。

简单说:
默认调度不是为省钱设计的,而是为“不出事”设计的。


二、想省 90% 成本?先搞清楚资源是怎么烧掉的

来看一张典型“企业集群 CPU 使用情况”的 ASCII 图:

节点1: [##########------------------------] 35%
节点2: [######----------------------------] 20%
节点3: [########--------------------------] 25%
节点4: [#---------------------------------] 5%
节点5: [#---------------------------------] 3%
节点6: [#################################] 90%(重点服务)

真实情况:三个节点能干这六个节点的活。

这就是 bin-packing 不好 + pod 分布不均 的结果。

下面我给你一个从“浪费”走向“极致省钱”的完整路径。


三、四大调度策略 + 实战配置(真正能省钱)


策略一:优化 Request / Limit(最有效的降本手段,没有之一)

很多团队 CPU request 全靠猜,写得特别大,比如:

resources:
  requests:
    cpu: 500m
    memory: 1Gi

实际上服务平均 CPU 可能就只有 30m。

Result:节点被虚假占满,真正的资源利用率低得可怜。

怎么解决?

步骤 1:用 metrics-server 或 Prometheus 查看真实资源使用

kubectl top pod

步骤 2:按照平均值 + 波动给 request,而不是盲目加大

例如你的服务平时使用 20–50m CPU,那么 request 给 50–80m 都很安全。


策略二:使用 Pod 优先级(PriorityClass)让重要服务先占坑

遇到资源紧张时,谁先被挤掉?
默认:大家地位一样 → 调度器乱来。

用 PriorityClass 能保证关键服务永远有资源:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: critical-app
value: 1000000
globalDefault: false
description: "关键服务,不可驱逐"

然后在 Pod 里使用:

priorityClassName: critical-app

这样 bin-packing 时关键服务先放,高优先级抢占低优先级 → 节点资源利用更紧凑。


策略三:Pod 亲和性/反亲和性,让调度真正“聪明”起来

让 Pod 尽量挤在一起(bin packing 强化版)

affinity:
  podAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: myservice
        topologyKey: kubernetes.io/hostname

效果:
Pod 越多,就越被安排在同一个节点,空出更多节点可供缩容。

反亲和性:防止相同 Pod 全堆一台(必要时启用)

例如高可用服务:

podAntiAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
  - labelSelector:
      matchLabels:
        app: gateway
    topologyKey: kubernetes.io/hostname

策略四:使用 Descheduler + Cluster Autoscaler(成本杀手锏)

光靠 scheduler 不够,因为 Pod 会随着时间推移变得不均衡,这就需要 Descheduler 来重新平衡

示意图:

初始:
节点180%
节点210%
节点315%

Descheduler 运行后:
节点160%
节点260%
节点325%

→ Cluster Autoscaler 自动把节点3缩掉 → 节省钱。

Descheduler 配置示例

profiles:
- name: Default
  pluginConfig:
  - name: "RemoveDuplicates"
  - name: "LowNodeUtilization"
    args:
      thresholds:
        cpu: 20
        memory: 20
      targetThresholds:
        cpu: 80
        memory: 80

Descheduler 会把“不满载”的节点 Pod 全挪走 → Autoscaler 自动缩容 → 真正省钱。


四、最容易忽视的关键:按时间动态调度(夜间成本减半)

不少服务晚上根本没多少访问量,但 Pod 仍然占着资源不松口。

👇 推荐用 HPA + CronJob 做“时间维度调度”:

例:夜间自动缩容,只保留 1 个 Pod

apiVersion: batch/v1
kind: CronJob
metadata:
  name: night-scale
spec:
  schedule: "0 1 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: kubectl
            image: bitnami/kubectl
            command: ["kubectl", "scale", "deploy/myapp", "--replicas=1"]
          restartPolicy: OnFailure

白天流量恢复:

schedule: "0 7 * * *"
command: ["kubectl", "scale", "deploy/myapp", "--replicas=10"]

一个简单策略 → 节省 30–40% 的节点成本


五、我踩过的坑和真实感受

这些年从 50 台节点省到 15 台节点,不夸张说省了好几百万——但这个过程不轻松。

我见过这些坑:

  • 开发随便填 request,导致整集群被“虚空占用”
  • 调度策略写得很复杂,却没人维护
  • Autoscaler 配置错误 → 峰值瞬间崩
  • SRE 只看 CPU,不看内存,结果内存 OOM 把 Pod 全踢下线

也见过好的情况:

  • 用好 bin-packing → 节点减少 50%
  • 夜间缩容策略 → 再省 30%
  • 优先级 + 节点池分层 → 再省 10%

真正让我省下 90% 成本的不是某个神技,而是这四件事:

  1. 请求值填准确
  2. Pod 调度更聪明
  3. 持续重平衡
  4. 自动缩容策略完善

没有玄学,就是扎实的工程方法。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。