HAMi vGPU调度揭秘:hami-scheduler核心流程全解析

作者:很菜不狗2026.07.04 11:11浏览量:13

简介:本文深度解析HAMi vGPU解决方案中hami-scheduler的工作原理,从Webhook触发到高级调度策略实现的全流程,帮助开发者掌握vGPU资源调度机制,理解如何通过扩展调度器实现GPU资源的高效分配与管理。

一、教程目标

本教程将系统解析HAMi vGPU解决方案中hami-scheduler的核心工作流程,重点说明:

  1. 如何通过Webhook机制将vGPU Pod调度权移交至hami-scheduler
  2. 调度器扩展(Extender Scheduler)如何与原生kube-scheduler协同工作
  3. 节点资源评估与高级调度策略的触发机制
  4. 异步资源上报与调度内存模型的构建过程

二、适用场景

  1. 需要为AI训练任务分配专属GPU资源的集群环境
  2. 存在多租户GPU资源隔离需求的平台
  3. 需要实现GPU资源碎片整理、负载均衡等高级调度策略的场景
  4. 混合使用普通Pod与vGPU Pod的异构计算集群

三、前置准备

  1. 基础环境:已部署Kubernetes集群(v1.18+),建议3节点以上
  2. 组件依赖:
    • 已安装Device Plugin实现GPU资源发现
    • 配置了MutatingAdmissionWebhook准入控制器
  3. 权限要求:
    • 集群管理员权限(用于创建Webhook配置)
    • Scheduler组件的RBAC扩展权限
  4. 知识储备:
    • 理解Kubernetes调度器扩展机制
    • 熟悉Admission Webhook工作原理
    • 掌握GPU资源管理基础概念

四、核心工作流程解析

1. Webhook触发阶段(准入控制)

当用户提交包含vGPU资源请求的Pod时,kube-apiserver会触发MutatingWebhook流程:

  1. # MutatingWebhookConfiguration配置示例
  2. apiVersion: admissionregistration.k8s.io/v1
  3. kind: MutatingWebhookConfiguration
  4. metadata:
  5. name: hami-webhook
  6. webhooks:
  7. - name: hami.scheduler.mutating.webhook
  8. rules:
  9. - operations: ["CREATE"]
  10. resources: ["pods"]
  11. clientConfig:
  12. url: https://hami-webhook-service:443/mutate

处理逻辑:

  1. 检测Pod中的resources.limits是否包含hami.io/vgpu资源
  2. 对特权模式Pod(securityContext.privileged=true)跳过处理
  3. 对已指定nodeName的Pod直接拒绝(防止强制绑定破坏调度逻辑)
  4. 修改Pod的spec.schedulerName字段为hami-scheduler

2. 调度器扩展架构

hami-scheduler采用”主调度器+扩展插件”的混合架构:

  1. hami-scheduler Pod内部结构:
  2. └── kube-scheduler (主调度器)
  3. └── extender-scheduler (扩展容器)
  4. └── 提供Webhook API
  5. └── 提供Scheduler Extender API

关键配置:

  1. # KubeSchedulerConfiguration扩展配置
  2. apiVersion: kubescheduler.config.k8s.io/v1beta2
  3. kind: KubeSchedulerConfiguration
  4. extenders:
  5. - urlPrefix: "http://127.0.0.1:8888/scheduler"
  6. filterVerb: "filter"
  7. prioritizeVerb: "prioritize"
  8. weight: 1
  9. enableHTTPSSecure: false

3. 调度流程详解

阶段一:原生调度流程

  1. 预选阶段(Filter):kube-scheduler执行默认的节点过滤逻辑
  2. 优选阶段(Score):
    • 调用Extender的/scheduler/prioritize接口
    • 传递候选节点列表和待调度Pod信息

阶段二:扩展调度流程

  1. // Extender Scheduler伪代码实现
  2. func (e *Extender) Prioritize(pod *v1.Pod, nodes []*v1.Node) ([]SchedulerExtenderNodeScore, error) {
  3. // 1. 从Node Annotations解析GPU资源总量
  4. // 2. 从已运行Pod的Annotations解析GPU使用量
  5. // 3. 计算剩余可用资源
  6. // 4. 应用调度策略打分
  7. scores := make([]SchedulerExtenderNodeScore, 0, len(nodes))
  8. for _, node := range nodes {
  9. available := e.calculateAvailableResources(node)
  10. score := e.applySchedulingPolicy(pod, node, available)
  11. scores = append(scores, SchedulerExtenderNodeScore{
  12. Node: node.Name,
  13. Score: int64(score),
  14. })
  15. }
  16. return scores, nil
  17. }

4. 资源评估机制

异步资源上报流程:

  1. Device Plugin定时上报:

    • 每30秒通过Node Status Update上报GPU总量
    • 写入Node对象的hami.io/gpu-total Annotation
  2. 调度器后台任务:

    1. // 资源同步协程示例
    2. func (e *Extender) startResourceSync() {
    3. ticker := time.NewTicker(10 * time.Second)
    4. for {
    5. select {
    6. case <-ticker.C:
    7. nodes, err := e.k8sClient.CoreV1().Nodes().List(metav1.ListOptions{})
    8. for _, node := range nodes.Items {
    9. e.updateNodeResourceCache(node)
    10. }
    11. }
    12. }
    13. }
  3. 内存数据模型:

    1. type NodeResource struct {
    2. Total map[string]int64 // 资源类型->总量
    3. Allocated map[string]int64 // 已分配量
    4. Available map[string]int64 // 剩余量
    5. LastUpdate time.Time // 最后更新时间
    6. }

五、高级调度策略实现

1. Spread策略(资源分散)

实现原理:

  1. 统计每个节点上已运行的同类Pod数量
  2. 对Pod数量多的节点降低评分
  3. 计算公式:score = 100 - (podCount * 10)

适用场景:

  • 避免多个AI训练任务集中在少数节点
  • 提高集群容错能力

2. Binpack策略(资源紧凑)

实现原理:

  1. 优先选择资源利用率高的节点
  2. 计算公式:score = (available / total) * 100
  3. 设置阈值过滤资源碎片过多的节点

适用场景:

  • 提高GPU资源利用率
  • 减少资源碎片

六、结果验证方法

  1. Webhook验证:

    1. kubectl get pod <vgpu-pod> -o yaml | grep schedulerName
    2. # 应输出:schedulerName: hami-scheduler
  2. 调度日志检查:

    1. kubectl logs <hami-scheduler-pod> extender-scheduler | grep "Prioritize called"
    2. # 应看到调度请求处理日志
  3. 资源状态验证:

    1. kubectl describe node <node-name> | grep hami.io/gpu
    2. # 应显示正确的GPU资源总量和分配情况

七、常见问题排查

问题1:vGPU Pod卡在Pending状态

  • 检查Webhook配置是否正确:
    1. kubectl get mutatingwebhookconfigurations
  • 查看kube-apiserver日志中的Webhook调用记录

问题2:调度器扩展未生效

  • 验证KubeSchedulerConfiguration中的extender配置
  • 检查extender-scheduler容器的日志:
    1. kubectl logs <hami-scheduler-pod> extender-scheduler

问题3:资源数据不更新

  • 检查Device Plugin的Pod状态
  • 验证Node Annotations是否更新:
    1. kubectl get node <node-name> -o yaml | grep hami.io/gpu

八、优化建议

  1. 性能优化:

    • 调整资源上报频率(建议10-30秒)
    • 对大规模集群采用分批同步策略
  2. 高可用设计:

    • 部署多副本hami-scheduler
    • 使用Leader Election机制保证单一调度
  3. 监控增强:

    • 暴露调度延迟指标
    • 跟踪资源评估准确率
  4. 策略扩展:

    • 实现基于Pod优先级的调度
    • 添加节点亲和性/反亲和性支持

九、总结

本教程深入解析了HAMi vGPU解决方案中hami-scheduler的核心工作流程,从Webhook准入控制到扩展调度器的实现机制,详细说明了资源评估模型和高级调度策略的运作原理。通过掌握这些核心机制,开发者可以:

  1. 自主实现类似的GPU资源调度方案
  2. 根据业务需求定制调度策略
  3. 高效排查调度相关问题

后续可进一步探索的方向包括:多维度调度策略组合、动态资源配额管理、以及与监控系统的集成实现自动扩缩容等高级功能。