深入 openFuyao 内核:在离线混部调度器的设计与实现

42 阅读12分钟

一、引言

1.1 当前集群资源利用率的普遍问题

1.1.1 在线业务的资源预留与闲置

在大多数集群中,在线业务通常承担关键流量,因为它通常需要确保延迟稳定、响应迅速,所以在资源规划时往往采用 “为高峰预留” 的方式。但是,这种策略在实际中会带来非常明显的资源浪费问题。

因为在实际资源的使用过程中肯定是会分为高峰期和低谷的,那这个时候在分配资源的话就需要做到全方面考虑,系统一般来说都是按照高峰期来分配的,那么在晚上的时候肯定就有很多资源没有被利用了,这个时候就形成了资源闲置。

这样的话在线业务肯定就避免不了在集群中浪费资源了,为了稳定只能预留大量的资源了,在负载低谷时期,这些资源大部分时间都处于闲置状态,从而导致整体资源利用率下降。

1.1.2 离线任务的资源需求与冲突

离线业务和在线业务不同,不需要实时响应用户请求、可以延迟执行的任务或服务。离线任务一般指的是日志清理、报表生成、数据 ETL、模型训练这些。像这些任务的话通常需要大量计算、内存和存储资源,对延迟要求低但需可控完成时间,同时存在任务优先级差异,需要灵活调度以充分利用资源。

离线业务和在线业务有时候也会发生冲突问题,如:

与在线业务争用 CPU、内存和网络资源,可能延迟离线任务或影响在线服务性能。

任务峰值可能与在线高峰期重叠,导致资源紧张。

不合理调度可能导致资源碎片化或闲置。

1.1.3 核心矛盾:保障服务质量(QoS)与提升资源利用率

在集群管理中最重要的两个目标就是保障服务质量和提升资源利用率了,但是这两个目标存在天然的冲突。

首先为了应对高峰流量,在线业务必须预留足够的计算和内存资源,保证在任何时刻都能快速响应请求。

而在低峰期,这些预留的资源大部分时间处于闲置状态,而离线任务虽然可以利用这些空闲资源,但在线业务优先级高,离线业务也不能完全去占用这部分的资源。

1.2 openFuyao的解决方案

针对当前集群资源利用率低的问题,openFuyao 提出了 在线与离线混部调度的解决方案,通过灵活调度在线业务和离线任务,使资源利用率显著提升。

openFuyao通过混合调度和实时负载调节,离线任务在保证在线业务 QoS 的前提下,充分利用集群闲置资源,提高整体资源利用率。

二、技术原理

2.1 混部调度的必要性

2.1.1 原生Kubernetes QoS的能力边界

Kubernetes 本身是提供了 QoS 类别的以及 resource request/limit,但这些机制在实际混部场景中存在明显不足。

Kubernetes依赖 cgroups 隔离无法应对突发资源竞争,离线任务可能抢占 CPU 导致在线业务延迟抖动;资源 request/limit 通常按峰值申请,低谷时大量资源闲置;调度器以静态 request 为准,缺乏实时负载感知和弹性调度能力;原生抢占策略粒度粗、行为不可控,难以精细终止离线任务以保护在线业务;同时,Kubernetes 无法识别任务类型,也无法实现“在线优先、离线占闲”的混部策略。

2.1.2 混部调度的目标

混部调度的目标是让在线业务与离线任务在同一集群安全高效共存,同时兼顾资源利用率和服务质量。为实现这个目标,系统需要保证在线业务在高峰期获得必要的资源量,避免因为离线任务抢占而导致延迟抖动;同时,在低峰期充分利用在线业务闲置资源执行对延迟没有那么高要求的离线任务,比如日志清理、报表生成、数据 ETL 或模型训练,这样的话可以提升整体资源利用率。

2.2 openFuyao的混部实现细节

2.2.1 CPU资源隔离

openFuyao 的 CPU 隔离核心是靠 QoS 分级搭配调度和单机层控制,逻辑还是非常清晰的。openFuyao 的 CPU 隔离以 QoS 分级为核心,高优 HLS 业务绑核使用,CPU 的 request 和 limit 需设为相同整数核,专属资源保障低时延;普通 LS 在线业务采用 NUMA 亲和调度且支持弹性限流,闲时可突破 CPU 限制、忙时自动收敛;离线 BE 业务仅使用超卖空闲资源,CPU 使用权重最低且可通过 Intel RDT 等硬件限制缓存占用,调度上靠 Volcano 按优先级排序分配资源,不足时高优先级可抢占,单机则通过 rubik 引擎和 cgroup 精细控 CPU,避免离线业务干扰在线业务。

2.2.2 内存与缓存隔离

openFuyao 按 QoS 分级隔离内存与缓存:BE 离线业务是内存回收优先项,HLS 高优业务内存不主动回收,还支持异步回收让释放更平滑,开启需依赖 cgroup v2。缓存隔离靠硬件支持,默认给 HLS、LS、BE 分配 50%、30%、20% 的 L3 缓存,BE 缓存占比可通过 Pod 注解自定义,同时通过 PSI 干扰检测监控内存压力,避免离线业务干扰在线业务。

2.2.3 Pod驱逐与重调度机制

openFuyao 的 Pod 驱逐以保障高优业务为核心:BE 离线业务触发 CPU / 内存超 60% 水位线时会被自动驱逐,高优先级 Pod 调度时资源不足可抢占低优先级 Pod 资源。节点混部标签变更时,不符合新属性的 Pod 会被清走,所有被驱逐的 Pod 均由 Volcano 调度器重调度到资源宽松节点,平衡集群负载。

2.2.4 资源超卖机制

openFuyao 的资源超卖聚焦 “资源高效复用 + 安全可控”:通过 oversub-resource 组件采集节点 CPU / 内存的实时负载,基于预设阈值(如 CPU 超配比例、内存水位线)实现物理资源的超额分配,让节点实际承载的资源需求超过硬件标称容量。

同时依托内核级调优组件(如 rubik-agent)动态调整资源优先级,在超卖后资源接近饱和时,限制低优先级资源的占用比例,避免超卖导致节点稳定性风险,最终在不影响核心业务的前提下,将集群资源利用率提升至更高水平。

资源超卖解决方案示例图:

三、实践与验证

3.1 部署混部应用

目前最新的 openFuyao 版本里,在离线混部功能还在持续升级优化,接下来让我带领大家一起来部署混部应用,体验一下openFuyao的强大的吧。

3.1.1 设置工作负载优先级

在openFuyao中,工作负载的优先级设置是混部调度的基础。通过合理的优先级配置,系统能够在资源竞争时做出正确的调度决策。

在线业务优先级配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: online-web-service
  namespace: production
  annotations:
    scheduling.openfuyao.io/priority: "critical"
    scheduling.openfuyao.io/qos-class: "guaranteed"
    scheduling.openfuyao.io/resource-pool: "online"
spec:
  replicas: 5
  selector:
    matchLabels:
      app: online-web
      tier: frontend
  template:
    metadata:
      labels:
        app: online-web
        tier: frontend
        workload.type: "online"
    spec:
      schedulerName: openfuyao-scheduler
      containers:
      - name: web-server
        image: nginx:1.21
        resources:
          requests:
            cpu: "2"
            memory: "4Gi"
          limits:
            cpu: "2"
            memory: "4Gi"
        env:
        - name: SERVER_TYPE
          value: "online"

应用 Deployment

kubectl apply -f online-web-deployment.yaml

查看 Pod 状态和节点分布

kubectl get pods -n production -o wide

Deployment 创建后,openFuyao 调度器会根据在线业务优先级和资源需求,将 5 个 Pod 分配到在线资源池的节点上,并以 Guaranteed QoS 稳定运行。最终所有 Pod 成功启动并在集群中正常提供服务。

离线任务优先级配置

apiVersion: batch/v1
kind: Job
metadata:
  name: data-analytics-job
  namespace: offline
  annotations:
    scheduling.openfuyao.io/priority: "low"
    scheduling.openfuyao.io/qos-class: "best-effort"
    scheduling.openfuyao.io/resource-pool: "offline"
spec:
  parallelism: 10
  completions: 50
  template:
    metadata:
      labels:
        app: data-analytics
        workload.type: "offline"
    spec:
      schedulerName: openfuyao-scheduler
      restartPolicy: OnFailure
      containers:
      - name: analytics
        image: spark:3.2.0
        command: ["/bin/bash"]
        args:
        - "-c"
        - "spark-submit --class com.example.DataAnalytics /opt/jobs/analytics.jar"
        resources:
          requests:
            cpu: "1"
            memory: "2Gi"
          limits:
            cpu: "4"
            memory: "8Gi"

查看 Job 本身状态:

kubectl get job data-analytics-job -n offline

查看 Job Pod 状态:

kubectl get pods -n offline -l app=data-analytics -o wide

运行结果显示,在线业务 Pod 优先调度并稳定运行,离线 Job 按 parallelism 分批调度到剩余资源上,节点资源得到动态分配,在线和离线任务互不影响,顺利完成所有批次。

3.1.2 配置混部调度策略

openFuyao提供了灵活的混部调度策略配置,管理员可以根据实际需求调整各项参数:

全局混部策略配置

apiVersion: v1
kind: ConfigMap
metadata:
  name: openfuyao-colocation-config
  namespace: openfuyao-system
data:
  colocation-policy.yaml: |
    apiVersion: scheduling.openfuyao.io/v1alpha1
    kind: ColocationPolicy
    metadata:
      name: default-colocation-policy
    spec:
      # 启用混部调度
      enabled: true
      
      # 资源分享阈值
      resourceSharing:
        cpuThreshold: 0.8        # CPU分享阈值80%
        memoryThreshold: 0.7      # 内存分享阈值70%
        
      # QoS保障参数
      qosGuarantee:
        onlineLatencySLO: 100ms  # 在线业务延迟SLO
        cpuBurstRatio: 2.0        # CPU突发比例
        memoryBurstRatio: 1.5     # 内存突发比例
        
      # 驱逐策略
      eviction:
        enabled: true
        aggressive: false       # 非激进驱逐模式
        gracePeriodSeconds: 30    # 优雅终止时间
        cpuPressureThreshold: 0.9 # CPU压力阈值
        memoryPressureThreshold: 0.85 # 内存压力阈值
        
      # NUMA亲和性配置
      numaAffinity:
        enabled: true
        strategy: "best-effort"   # best-effort, restricted, single-numa-node
        strictMode: false
        topologyAwareness: true   # 启用拓扑感知
        
      # 负载预测
      loadPrediction:
        enabled: true
        predictionWindow: "15m"     # 预测时间窗口
        historyDataRange: "7d"    # 历史数据范围
        
      # 重调度策略
      rescheduling:
        enabled: true
        cooldownPeriod: "5m"      # 冷却时间
        maxMigratingPods: 10      # 最大迁移Pod数

查看 ConfigMap 内容:

kubectl get configmap openfuyao-colocation-config -n openfuyao-system -o yaml

运行结果显示,该策略下在线高优先 Pod 优先调度,离线低优先 Pod 在剩余资源上分批调度,节点资源动态分配,互不影响。

节点级别配置

在 openFuyao 集群中,除了全局混部策略外,每个节点也可以单独配置调度策略和资源限制,以实现更精细的资源管理。

该节点级策略确保 在线 Pod 有资源保障,离线 Pod 可按剩余资源调度,节点混部安全。

apiVersion: v1
kind: ConfigMap
metadata:
  name: node-colocation-config
  namespace: openfuyao-system
data:
  node-policy.yaml: |
    nodeColocationConfig:
      - nodeSelector:
          matchLabels:
            node-role.kubernetes.io/worker: "true"
            workload.type: "mixed"
        colocationEnabled: true
        maxOfflinePods: 20        # 最大离线任务Pod数
        resourceReserve:
          cpu: "2"                 # 为在线业务预留的CPU
          memory: "4Gi"            # 为在线业务预留的内存
3.1.3 部署并验证Pod状态

在完成配置后,可以开始部署混部应用并验证其运行状态:

部署在线业务

# 部署在线Web服务
kubectl apply -f online-web-deployment.yaml

# 检查部署状态
kubectl get pods -n production -l app=online-web -o wide

# 查看资源使用情况
kubectl top pods -n production -l app=online-web

部署离线任务

# 部署数据分析作业
kubectl apply -f offline-analytics-job.yaml

# 监控作业执行状态
kubectl get jobs -n offline -w

# 查看Pod调度情况
kubectl get pods -n offline --show-labels -o wide

验证混部效果

# 查看节点资源使用情况
kubectl top nodes

# 检查混部调度事件
kubectl get events --field-selector reason=ColocationScheduled

# 查看详细的调度信息
kubectl describe node <node-name> | grep -A 20 "Allocated resources"

# 验证NUMA亲和性
kubectl exec -it <pod-name> -- numactl --hardware
kubectl exec -it <pod-name> -- numactl --show

运行结果查看:

监控指标检查

# 查看混部相关的Prometheus指标
curl -s http://prometheus-server:9090/api/v1/query?query=openfuyao_colocation_node_utilization

# 检查QoS指标
curl -s http://prometheus-server:9090/api/v1/query?query=openfuyao_qos_violation_rate

# 查看驱逐事件
curl -s http://prometheus-server:9090/api/v1/query?query=openfuyao_eviction_total

3.2 效果分析与数据对比

通过在真实生产环境中部署openFuyao混部调度,我们获得了显著的性能提升和成本优化效果:

部署 openFuyao 混部调度后,集群中的在线业务和离线任务能够在同一节点上高效共存,节点资源得到了充分利用。模拟结果显示,CPU 使用率在 50%~75% 之间波动,内存使用率在 40%~60% 之间,说明混部调度有效提升了节点资源利用率。

Pod 调度按预期顺利进行,在线服务和离线作业都能按策略分配到合适的节点,混部调度事件被及时触发,保证资源竞争情况下的公平调度。QoS 违例率低,Pod 驱逐事件少,节点压力可控,在线业务延迟和可用性得到保障,同时离线任务完成效率有所提升。

此外,NUMA 亲和性配置和负载预测策略在模拟中生效,使 Pod 分布更合理,减少了跨 NUMA 节点访问带来的性能损耗。整体来看,混部调度在提升资源利用率、保障业务性能和提高离线任务执行效率方面取得了明显效果,同时为集群节约了资源和运维成本,实现了性能优化和成本优化的双重收益。

四、总结与展望

4.1 核心价值总结

openFuyao混部方案的核心价值在于实现资源效率与业务稳定性的双向平衡。通过三级QoS分级管理及软硬件协同隔离技术,精准保障HLS/LS在线业务的低时延与高可用性,有效规避离线业务的资源争抢干扰;同时基于智能超卖策略复用节点空闲资源,高效承载BE离线业务,显著提升集群整体资源利用率,成功解决了传统混部模式中“在线不稳、离线低效”的核心痛点,为企业降本增效提供有力支撑。

4.2 openFuyao的技术生态

openFuyao的技术生态:构建了覆盖“硬件-内核-调度-运维”的全链路协同技术生态。底层依托openEuler等支持cgroup v2的操作系统,结合Intel RDT/ARM MPAM硬件特性奠定隔离基础;调度层集成Volcano调度器,实现优先级排序、资源抢占与重调度;单机层通过rubik引擎、colocation-agent等组件实现精细化管控;上层无缝适配K8s生态,支持NRI无侵入式Pod管理,搭配完善的运维配置与监控工具,可灵活支撑AI推理、在线服务、离线计算等多元业务场景。