GPU资源共享/抢占
GPU共享的整体架构
这个项目是一个Kubernetes GPU共享调度系统,通过两种类型的pod实现GPU资源共享:
1. Shadow Pod(影子Pod)
- 作用:占用物理GPU资源,作为GPU的实际持有者
- 特征:运行一个简单的sleep容器,不执行实际计算任务
- 创建时机:当quota资源不足时自动创建
- 生命周期:由shadow controller管理,根据使用情况自动创建和删除
2. Share Pod(共享Pod)
- 作用:实际执行计算任务的pod,通过device plugin共享shadow pod的GPU资源
- 特征:使用虚拟GPU设备,通过时间片或空间分割方式共享物理GPU
- 资源请求:请求共享GPU资源(如mizar.share.gpu.2表示2路共享)
核心逻辑链路
1. 配额管理(Quota Controller)
- 监控quota资源状态,计算shadow resource需求
- 维护shadow pod与物理GPU的映射关系
- 处理shadow pod的创建和删除逻辑
2. Shadow Pod管理(Shadow Controller)
- 创建逻辑:当quota的ready + pipelining数量为负值时,计算需要创建的shadow pod数量
- 删除逻辑:根据shadow pod的空闲时间决定是否删除
- 条件检查:通过PodInUsing条件跟踪GPU使用状态
3. 设备插件(Device Plugin)
- Share Device Plugin:为share pod提供虚拟GPU设备
- 设备ID格式:
{namespace}/{shadowpod-name}-{index}
- 动态更新设备列表,反映当前可用的shadow pod资源
4. 调度器(Solver)
- ShareGPU Solver:处理share pod事件,管理share pod与shadow pod的绑定关系
- SpotGPU Solver:处理spot pod事件,支持低功耗模式和抢占机制
5. 缓存系统(Mapping Cache)
- 维护三层映射关系:
- Shadow pod → 物理GPU设备
- Share pod → Shadow pod
- 设备状态跟踪(健康、使用中、空闲)
工作流程
- 资源申请:用户创建请求共享GPU的pod(share pod)
- 配额检查:quota controller检查当前资源是否充足
- Shadow Pod创建:如果资源不足,shadow controller创建shadow pod占用物理GPU
- 设备注册:device plugin将shadow pod的GPU注册为虚拟设备
- Pod调度:share pod被调度到有可用shadow pod的节点
- 资源绑定:shareGPU solver将share pod绑定到具体的shadow pod设备
- 使用监控:通过条件系统和metrics监控GPU使用情况
- 资源回收:当share pod结束或shadow pod空闲超时,自动回收资源
关键技术点
- 时间片共享:通过CUDA MPS或时间分片实现GPU计算资源共享
- 动态调整:根据负载动态创建和删除shadow pod
- 优先级管理:支持低功耗模式和抢占机制
- 状态同步:通过Kubernetes条件和annotation保持状态一致性
这种架构实现了GPU资源的超卖和弹性伸缩,显著提高了GPU利用率,同时保持了与传统Kubernetes调度的兼容性。
Spot资源抢占机制
1. 抢占触发条件
spot资源的抢占主要通过以下几种情况触发:
a) 所有者Pod恢复活跃(主要抢占场景)
1 | // owner pod alive, evict spot |
触发条件:当GPU的原始所有者pod(非低功耗模式)重新变得活跃时,spot pod会被立即驱逐。
b) 低功耗模式抢占
1 | func (s *spotGPUSolver) solveBusy(e detectors.Event) error { |
触发条件:当低功耗pod从空闲状态变为繁忙状态时,会驱逐所有使用其GPU资源的spot pod。
2. 抢占执行方式
a) 容器级别抢占(温和抢占)
1 | func (s *spotGPUSolver) evictProcessFor(e detectors.Event) error { |
特点:通过containerd API直接杀死容器进程,实现快速资源回收。
b) Pod级别抢占(强制抢占)
1 | func (s *spotGPUSolver) evictFor(target string) error { |
特点:通过Kubernetes API删除整个pod,确保资源完全释放。
3. 抢占优先级策略
a) 低功耗模式优先
- 低功耗pod享有最高优先级,不会被spot pod抢占
- 只有低功耗pod才能共享GPU给spot pod使用
- 当低功耗pod需要资源时,spot pod会被立即驱逐
b) 资源预留机制
1 | func (s *spotGPUSolver) evictByDevice(e detectors.Event) error { |
4. 抢占后的状态管理
a) 缓存清理
1 | // 更新缓存 |
b) 条件更新
1 | // 更新活跃条件 |
c) 指标记录
1 | // 更新驱逐计数器 |
5. 抢占策略特点
- 实时性:通过事件驱动机制,实时响应资源状态变化
- 分级处理:先尝试容器级温和抢占,必要时进行pod级强制抢占
- 状态一致性:确保缓存、设备插件、Kubernetes状态的一致性
- 可观测性:记录详细的抢占日志和指标,便于监控和调试
- 资源保障:优先保障高优先级任务(低功耗pod)的资源需求
这种抢占机制确保了GPU资源的高效利用,同时在需要时能够快速回收资源给高优先级任务使用。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Roger-Lv's space!
评论