资源调度优化实战:地理调度、亲和/反亲和与定制调度器,别再把集群当“老虎机”

举报
Echo_Wish 发表于 2026/01/15 20:55:33 2026/01/15
【摘要】 资源调度优化实战:地理调度、亲和/反亲和与定制调度器,别再把集群当“老虎机”

资源调度优化实战:

地理调度、亲和/反亲和与定制调度器,别再把集群当“老虎机”

我是 Echo_Wish,一个在运维这条路上,被调度坑过、救过火、背过锅的老运维。

我先说一句可能有点扎心的话:

90% 的集群“资源不够”,不是机器不够,而是调度太随缘。

很多团队的真实状态是这样的👇

  • 机器买了一堆

  • 集群也上了

  • Kubernetes 也部署了

  • 结果:

    • 有的节点快被压死
    • 有的节点在“养老”
    • 跨地域访问延迟飙升
    • 一出故障就是“玄学”

为什么?
因为调度策略从来没认真想过

今天这篇文章,咱不讲调度器源码(那玩意看完只会更焦虑),我只围绕三个真正能救命的实战点聊清楚:

  1. 地理调度:让流量少走弯路
  2. 亲和 / 反亲和:让 Pod 知道该跟谁混、该躲谁
  3. 定制调度器:当默认调度真的不懂你业务时

咱用运维人能听懂的方式讲。


一、地理调度:别再让“北京用户请求广州机器”

1️⃣ 这是个真实到离谱的问题

我遇到过一个系统:

  • 用户主要在 华东
  • 机器分布在 北京 + 上海
  • 服务部署随缘

结果就是:

  • 用户在上海
  • 请求被调度到北京
  • RTT 高、超时多、投诉多

开发第一反应:

“是不是 JVM GC 有问题?”

运维一看:

“哥们,你这请求在全国旅游。”


2️⃣ 地理调度的核心思想很简单

一句话总结:

请求在哪,服务尽量在哪

在 Kubernetes 里,地理信息本质上就是 Node Label

kubectl label node node-shanghai region=shanghai
kubectl label node node-beijing region=beijing

3️⃣ Pod 侧约束:我只想待在“本地”

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      nodeSelector:
        region: shanghai

这是最简单粗暴的地理调度

适合场景:

  • 单地域服务
  • 边缘计算
  • CDN 辅助服务

4️⃣ 更现实的玩法:优先就近,而不是“非此即彼”

affinity:
  nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      preference:
        matchExpressions:
        - key: region
          operator: In
          values:
          - shanghai

意思是:

优先上海,不行再说

这才是生产该有的态度。


📌 Echo_Wish 的感受

地理调度不是“优化”,而是“止血”
你不做,用户体验迟早替你付出代价。


二、亲和 / 反亲和:Pod 也是“社交动物”

1️⃣ 为什么 Pod 需要“亲疏远近”?

现实中有三类需求非常常见:

  1. 强依赖组件

    • Web ↔ Cache
    • API ↔ Sidecar
  2. 高可用隔离

    • 同一服务的副本不能在同一台机器
  3. 资源竞争隔离

    • CPU 怪兽和 IO 怪兽别住一起

如果你全靠默认调度:
👉 等着事故找你吧


2️⃣ Pod 亲和:兄弟,咱住近点

affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: redis
      topologyKey: kubernetes.io/hostname

含义是:

这个 Pod 必须和 redis 在同一节点

适合场景:

  • 本地缓存
  • 高频 RPC
  • Sidecar 模式

3️⃣ Pod 反亲和:兄弟,对不起,咱得分开住

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: order-service
      topologyKey: kubernetes.io/hostname

这个配置,救过无数系统的命

它能保证:

  • 同一个服务的副本
  • 不会被调度到同一节点

节点挂一个,服务还活着。


4️⃣ 强约束 vs 软约束,别一刀切

preferredDuringSchedulingIgnoredDuringExecution:

这是我个人最推荐的写法。

理由很简单:

可用性 > 完美性

很多事故,都是“约束太严格,结果调度不出来 Pod”。


📌 Echo_Wish 的一句话总结

亲和是为了性能,反亲和是为了命
能不用反亲和的系统,说明你还没被打过。


三、定制调度器:当默认调度器真的不懂你业务

1️⃣ 什么时候你才需要它?

我先劝退一波人:

80% 的集群,不需要自定义调度器

但如果你有以下情况之一👇

  • GPU / FPGA / 专用卡
  • 特殊网络拓扑
  • 强 SLA / 强优先级
  • 成本感知调度(抢占 + 计费)

那默认调度器真的不懂你。


2️⃣ 最低成本方式:Scheduler Extender

--scheduler-extender-url=http://extender:8080

Extender 负责两件事:

  • Filter:哪些节点不能用
  • Score:哪些节点更合适

示例逻辑(伪代码):

def score(nodes, pod):
    for node in nodes:
        if node.has_gpu and pod.need_gpu:
            score[node] += 100
        if node.cpu_usage > 80:
            score[node] -= 50

3️⃣ 真·定制调度器(慎重)

spec:
  schedulerName: my-scheduler

然后你自己实现:

  • 队列
  • 过滤
  • 打分
  • 绑定

我说句大实话:

这一步不是技术难,是责任重

一旦出问题:

  • 全集群 Pod 卡住
  • 恢复成本极高

📌 我的真实建议

能靠 Label + Affinity 解决的,
千万别上定制调度器。


四、把调度当“系统设计”,而不是 YAML 技巧

很多人学调度,学的是:

  • 字段
  • 参数
  • 示例

但真正该学的是:

  • 你的业务怕什么?
  • 是延迟?
  • 是单点?
  • 是成本?
  • 是资源争抢?

然后反推:

  • 地理调度解决“远”
  • 反亲和解决“死”
  • 定制调度解决“特殊”

五、写在最后:调度,是运维真正的“内功”

我常跟新人说一句话:

不会调度的运维,
迟早会被“资源不够”这四个字压垮。

而真正成熟的运维,会越来越少喊:

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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