GaiaGPU: Sharing GPUs in Container Clouds
* 精简概括
*.1 What
GaiaGPU,用于在容器之间共享 GPU memory and computing resources
*.2 Why
提高 GPU 利用率
基于容器的 GPU 虚拟化仍处于初始阶段
*.3 How
根据 Kubernetes 的设备插件框架将物理 GPU 划分为多个虚拟 GPU(vGPUs)。每个容器可以按需分配一个或多个 vGPUs。一个 vGPU 由 GPU 内存和计算资源组成。
GaiaGPU 包括四个组件:GPU Manager, GPU Scheduler, vGPU Manager, vGPU Library
在主机级别,GPU Manager 负责创建 vGPU,而 GPU Scheduler 负责将物理 GPU 资源分配给 vGPU。
在容器级别,vGPU Library component 负责管理特定容器的 GPU 资源。
提供了两种在运行时更改容器资源的方法。一种是弹性资源分配,临时改变容器资源,另一种是动态资源分配,永久修改容器资源。
0 Abstract
提出一个方法,GaiaGPU,用于在容器之间共享 GPU memory and computing resources。
GaiaGPU 将物理 GPU 划分为多个虚拟 GPU,将虚拟 GPU 分配给容器。
为提高资源利用率,采用了弹性资源分配(elastic resource allocation)和动态资源分配(dynamic resource allocation)。
1 Introduction
GPU 虚拟化技术用于在隔离的虚拟环境中共享 GPU。
现有的大多数 GPU 虚拟化技术都应用于虚拟机。基于容器的 GPU 虚拟化仍处于初始阶段。
提出 GaiaGPU,用于在多个隔离容器之间透明地共享 GPU 内存和计算资源
根据 Kubernetes 的设备插件框架将物理 GPU 划分为多个虚拟 GPU(vGPUs)。每个容器可以按需分配一个或多个 vGPUs。一个 vGPU 由 GPU 内存和计算资源组成。
提供了两种在运行时更改容器资源的方法。一种是弹性资源分配,临时改变容器资源,另一种是动态资源分配,永久修改容器资源。
2 Related Work
2.1 GPU Virtualization
现有的大多数 GPU 虚拟化技术基于虚拟机(VMs)
有三种基本类型的虚拟化 GPU:API 重定向、部分和完全虚拟化以及硬件支持的虚拟化.
vCUDA 和 rCUDA 使用 API 重定向技术来实现 GPU 虚拟化。它们在虚拟机中构建一个包装的 CUDA 库,以拦截 GPU 调用并将这些调用重定向到主机上进行执行。
GPUvm 在 Xen 虚拟化器中同时实现了部分和完全虚拟化。为了隔离运行在物理 GPU 上的多个虚拟机,GPUvm 将物理 GPU 内存和 MMIO 区域划分为分区,并将每个分区分配给一个单独的虚拟机。
NVIDIA GRID 在硬件级别实现了 GPU 虚拟化。它创建虚拟 GPU 并将其分配给容器。
有一些研究致力于支持容器中的 GPU.
NVIDIA GRID 也可以在容器环境中使用。然而,它需要特定的硬件设备和虚拟 GPU 的相同资源配置。每个容器只能分配一个虚拟 GPU。
NVIDIA Docker 可以使 Docker 镜像利用 GPU。然而,在 NVIDIA Docker 中没有共享,因为它将整个 GPU 分配给一个容器。
ConvGPU 是一种用于与容器共享 GPU 内存的解决方案。它拦截 CUDA 库以管理每个容器的内存分配/释放。然而,ConvGPU 只支持内存资源的共享,并且只虚拟化单个 GPU。
2.2 Device plugin
Kubernetes 为云供应商提供了设备插件框架(device plugin framework),旨在向集群宣传计算资源(例如 GPU、高性能 NIC、FPGA)而无需更改 Kubernetes 核心代码。
设备插件的工作流程分为两个阶段:
- 资源发现:每种扩展资源类型都要实现一个设备插件,设备插件通过 gRPC 服务向 Kubelet (即节点代理)注册自己,之后,设备插件将设备列表发送给 Kubelet,最后,Kubelet 负责向 Kubernetes Master 广告这些扩展资源
- 资源分配:用户请求设备时,主节点上的调度器会根据所需资源选择特定的 Kubernetes 节点来启动容器。所选的 Kubernetes 节点上的 Kubelet 将设备请求发送给设备插件。最后,设备插件将相应的设备分配给容器。
GaiaGPU 采用了设备插件框架来在容器之间共享资源。
3 Design and Implementation
3.1 Design and Implementation
GaiaGPU 包括四个组件:GPU Manager, GPU Scheduler, vGPU Manager, vGPU Library
在主机级别,GPU Manager 负责创建 vGPU,而 GPU Scheduler 负责将物理 GPU 资源分配给 vGPU。
在容器级别,vGPU Library component 负责管理特定容器的 GPU 资源。
3.1.1 GPU Manager
是一个 Device plugin,用于向 Kubelet 广告 GPU.
GPU Manager 在主机上运行,负责创建 vGPU 并通过 gRPC 服务与 Kubelet 通信。通信内容包括注册、列出和监听、分配。
GPU 在两个资源维度上进行虚拟化:内存和计算资源。
- 内存。将 256M 内存划分为一个单位,每个内存单位称为 vmemory 设备
- 计算资源。由于设备插件框架不支持分配 GPU 的一部分,文章将物理 GPU 划分为 100 个 vprocessor 设备,每个 vprocessor 拥有 GPU 利用率的 1%
GPU Manager 向 Kubelet 发送一个由所有 vmemory 和 vprocessor 设备组成的列表
当用户在容器规范中需要 GPU 设备时,Kubelet 从 GPU Manager 发送的设备列表中任意选择相应数量的设备。
需要一些额外的步骤将虚拟设备映射到物理设备。
3.1.2 GPU Scheduler
GPU Scheduler 负责处理 GPU Manager 发送的调度请求。
如果调度成功,GPU Scheduler 会返回一个包含已分配 GPU 信息的响应。
GPU Scheduler 基于拓扑结构来分配 GPU。GPU 拓扑结构是一种树状拓扑结构。
3.1.3 vGPU Manager
运行在主机上的 vGPU Manager 提供容器配置,并监视分配了 vGPU 的容器.
3.1.4 vGPU Library
运行在容器中的 vGPU Library 用于管理其部署容器的 GPU 资源
它通过 LD_LIBRARY_PATH 机制拦截 CUDA 库中与内存和计算相关的 API
3.1.5 资源限制
有两种资源限制类型。一种是硬限制,意味着当容器消耗超出其请求的资源时,将不会分配资源。另一种是弹性限制,指的是当容器使用的资源超过其请求并且系统中有空闲资源时,容器仍然可以获得资源。
对于内存资源,采用硬限制。弹性限制用于计算资源。
3.1.6 工作流
GaiaGPU 的工作流程如下:
Step 1:GPU Manager 向 Kubelet(即节点代理)注册自身并广告 vGPU
Step 2:Kubelet 接收主控节点发送的容器请求,该请求需要 GPU 设备
Step 3:Kubelet 向 GPU Manager 发送一个 allocateRequest
Step 4:GPU Manager 向 GPU Scheduler 发送一个调度请求。然后,GPU Scheduler 根据调度策略分配物理 GPU。如果调度成功,它会返回一个包含已分配 GPU 信息的响应
Step 5:GPU Manager 将容器的配置发送给 vGPU Manager
Step 6:GPU Manager 将容器的环境变量、挂载信息和设备信息返回给 Kubelet
Step 7:Kubelet 根据 allocateResponse 创建和初始化一个容器
Step 8:vGPU Library 向 vGPU Manager 注册自身,并管理其部署容器的 GPU 资源
Step 9:vGPU Manager 监视分配了 GPU 的运行中容器,并在它们停止运行时清理这些容器
3.2 Optimization
在创建容器时,用户无法准确估算所需的资源。
容器的资源不仅影响应用程序的性能,甚至决定了应用程序的状态.
提供了两种在运行时更改容器资源的方法:弹性资源分配临时修改容器的计算资源限制,而动态资源分配永久性地改变容器的资源。
3.2.1 Elastic Resource Allocation 弹性资源分配
目的是充分利用空闲的计算资源
如果物理 GPU 有空闲资源,即使容器消耗的 GPU 资源超过其需求,vGPU 库仍会为容器分配计算资源。如果系统没有剩余资源且容器消耗的资源超过其需求,vGPU 库将回收超额分配的资源。
采用非抢占策略来回收超额分配的资源,这意味着容器会占用资源直到内核执行完成。
$CU_{cores}$ 类似于令牌,当容器执行内核函数时会消耗它,当内核函数执行完成时会产生它。$CU_{cores}$ 的初始值等于容器所需的计算资源。当 $CU_{cores}$ 为零时,vGPU 库不会为容器分配任何计算资源,直到 $CU_{cores}$ 大于 0
3.2.2 Dynamic Resource Allocation 动态资源分配
动态资源分配修改容器的资源,包括内存和计算资源,而不需要停止容器。
动态资源分配旨在解决两个问题。第一个问题是在硬限制下更新容器的内存和计算资源。第二个问题是在弹性限制下向容器添加内存资源。
疑惑:
论文对于内存的限制的描述前后矛盾
4 Experiments
5 Conclusion
提出了一种在容器之间共享 GPU 内存和计算资源的方法.
基于 Kubernetes 的设备插件框架,我们将物理 GPU 划分为多个虚拟 GPU(vGPU)并将 vGPU 分配给容器。
GaiaGPU 采用了两层资源管理,一层用于在主机层管理 vGPU 资源,另一层用于在容器层管理容器消耗的资源。
# 概念学习
#.1 Kubernetes
Kubernetes(通常缩写为 K8s)是一个开源的容器编排和管理平台,用于自动化部署、扩展和管理容器化应用程序。
Kubernetes 的主要目标是简化容器化应用程序的部署和管理,使开发人员和运维团队能够更轻松地构建、交付和运行应用程序。