GPUDirect RDMA 和 GPUDirect Storage#
关于 GPUDirect RDMA 和 GPUDirect Storage#
GPUDirect RDMA 是 NVIDIA GPU 中的一项技术,它允许 GPU 和第三方对等设备之间使用 PCI Express 进行直接数据交换。第三方设备可以是网络接口,例如 NVIDIA ConnectX SmartNIC 或 BlueField DPU,或视频采集适配器。
GPUDirect Storage (GDS) 实现了本地或远程存储(例如 NFS 服务器或 NVMe/NVMe over Fabric (NVMe-oF))与 GPU 内存之间的直接数据路径。GDS 在 GPU 内存和存储之间执行直接内存访问 (DMA) 传输。DMA 避免了通过 CPU 的反弹缓冲区。此直接路径提高了系统带宽,并降低了 CPU 的延迟和利用率负载。
为了支持 GPUDirect RDMA,需要用户空间 CUDA API。内核模式支持由以下两种方法之一提供:来自 Linux 内核的 DMA-BUF 或旧版 nvidia-peermem
内核模块。NVIDIA 建议使用 DMA-BUF,而不是使用 GPU 驱动程序中的 nvidia-peermem
内核模块。
从 Operator 的 v23.9.1 版本开始,Operator 使用 GDS 驱动程序版本 2.17.5 或更高版本。此版本及更高版本仅在使用 NVIDIA Open GPU 内核模块驱动程序时才受支持。用于安装 Operator 的示例命令包括 Helm 的 --set useOpenKernelModules=true
命令行参数。
与 Network Operator 结合使用,GPU Operator 可用于设置网络相关组件,例如网络设备内核驱动程序和 Kubernetes 设备插件,以使工作负载能够利用 GPUDirect RDMA 和 GPUDirect Storage。有关安装信息,请参阅 Network Operator 文档。
常用先决条件#
配置 GPUDirect RDMA 或 GPUDirect Storage 的先决条件取决于您是使用来自 Linux 内核的 DMA-BUF 还是旧版 nvidia-peermem
内核模块。
技术 |
DMA-BUF |
旧版 NVIDIA-peermem |
---|---|---|
GPU 驱动程序 |
需要 Open Kernel 模块驱动程序。 |
任何受支持的驱动程序。 |
CUDA |
CUDA 11.7 或更高版本。CUDA 运行时由驱动程序提供。 |
无最低版本。CUDA 运行时由驱动程序提供。 |
GPU |
图灵架构数据中心、Quadro RTX 和 RTX GPU 或更高版本。 |
所有数据中心、Quadro RTX 和 RTX GPU 或更高版本。 |
网络设备驱动程序 |
MLNX_OFED 或 DOCA-OFED 是可选的。您可以使用来自软件包管理器的 Linux 驱动程序软件包。 |
需要 MLNX_OFED 或 DOCA-OFED。 |
Linux 内核 |
5.12 或更高版本。 |
无最低版本。 |
确保安装了网络设备驱动程序。
您可以使用 Network Operator 来管理 MLNX_OFED 和 DOCA-OFED 驱动程序的驱动程序生命周期。
您可以在每台主机上安装驱动程序。有关 MLNX_OFED、DOCA-OFED 和 Linux 内置驱动程序的信息,请参阅网络文档中的 Adapter Software。
对于 VMware vSphere 上的安装,请参阅以下其他先决条件
确保网络接口控制器和 NVIDIA GPU 位于同一 PCIe IO 根复合体中。
启用以下 PCI 选项
pciPassthru.allowP2P = true
pciPassthru.RelaxACSforP2P = true
pciPassthru.use64bitMMIO = true
pciPassthru.64bitMMIOSizeGB = 128
有关配置设置的信息,请参阅 VMWare 的 在 vSphere 7 上部署 AI 就绪的企业平台 文档。
配置 GPUDirect RDMA#
平台支持#
以下平台支持使用 RDMA 的 GPUDirect
裸机和 vSphere VM 上使用 GPU 直通和 vGPU 的 Kubernetes。
VMware vSphere with Tanzu。
对于裸机和 vSphere VM 上使用 GPU 直通和 vGPU 配置的 Red Hat OpenShift Container Platform,请参阅 NVIDIA AI Enterprise with OpenShift。
有关受支持版本的信息,请参阅平台支持页面上的 GPUDirect RDMA 支持。
安装 GPU Operator 并启用 GPUDirect RDMA#
要使用由 Network Operator 安装的 DMA-BUF 和网络设备驱动程序
$ helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
--set driver.useOpenKernelModules=true
要使用主机上安装的 DMA-BUF 和网络设备驱动程序
$ helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
--set driver.useOpenKernelModules=true \
--set driver.rdma.useHostMofed=true
要使用旧版 nvidia-peermem
内核模块而不是 DMA-BUF,请将 --set driver.rdma.enabled=true
添加到上述任一命令。对于使用旧版内核驱动程序,driver.useOpenKernelModules=true
参数是可选的。
验证 GPUDirect with RDMA 的安装#
在安装过程中,NVIDIA 驱动程序守护程序集运行一个 init 容器,以等待网络设备内核驱动程序准备就绪。此 init 容器检查节点上的 Mellanox NIC,并确保必要的内核符号由内核驱动程序导出。
如果您在安装 Operator 时需要使用 driver.rdma.enabled=true
参数,则在验证后,nvidia-peermem-ctr 容器将在每个驱动程序 pod 内启动。
确认驱动程序守护程序集的 pod 模板包含 mofed-validation init 容器和 nvidia-driver-ctr 容器
$ kubectl describe ds -n gpu-operator nvidia-driver-daemonset
示例输出
以下部分输出省略了所有安装通用的 init 容器和容器。
... Init Containers: mofed-validation: Container ID: containerd://5a36c66b43f676df616e25ba7ae0c81aeaa517308f28ec44e474b2f699218de3 Image: nvcr.io/nvidia/cloud-native/gpu-operator-validator:v1.8.1 Image ID: nvcr.io/nvidia/cloud-native/gpu-operator-validator@sha256:7a70e95fd19c3425cd4394f4b47bbf2119a70bd22d67d72e485b4d730853262c ... Containers: nvidia-driver-ctr: Container ID: containerd://199a760946c55c3d7254fa0ebe6a6557dd231179057d4909e26c0e6aec49ab0f Image: nvcr.io/nvaie/vgpu-guest-driver:470.63.01-ubuntu20.04 Image ID: nvcr.io/nvaie/vgpu-guest-driver@sha256:a1b7d2c8e1bad9bb72d257ddfc5cec341e790901e7574ba2c32acaddaaa94625 ... nvidia-peermem-ctr: Container ID: containerd://0742d86f6017bf0c304b549ebd8caad58084a4185a1225b2c9a7f5c4a171054d Image: nvcr.io/nvaie/vgpu-guest-driver:470.63.01-ubuntu20.04 Image ID: nvcr.io/nvaie/vgpu-guest-driver@sha256:a1b7d2c8e1bad9bb72d257ddfc5cec341e790901e7574ba2c32acaddaaa94625 ...
仅当您在安装 Operator 时需要指定
driver.rdma.enabled=true
参数时,nvidia-peermem-ctr 容器才存在。仅限旧版:确认 nvidia-peermem-ctr 容器已成功加载 nvidia-peermem 内核模块
$ kubectl logs -n gpu-operator ds/nvidia-driver-daemonset -c nvidia-peermem-ctr
或者,对于守护程序集中的每个 pod,运行
kubectl logs -n gpu-operator nvidia-driver-daemonset-xxxxx -c nvidia-peermem-ctr
。示例输出
waiting for mellanox ofed and nvidia drivers to be installed waiting for mellanox ofed and nvidia drivers to be installed successfully loaded nvidia-peermem module
通过执行数据传输来验证安装#
您可以执行以下步骤来验证 GPUDirect with RDMA 是否已正确配置,以及 pod 是否可以执行 RDMA 数据传输。
获取主机上 InfiniBand 设备的网络接口名称
$ kubectl exec -it -n network-operator mofed-ubuntu22.04-ds-xxxxx -- ibdev2netdev
示例输出
mlx5_0 port 1 ==> ens64np1 (Up)
使用 macvlan 网络附件在设备上配置辅助网络
创建一个文件,例如
demo-macvlannetwork.yaml
,其内容如下例所示apiVersion: mellanox.com/v1alpha1 kind: MacvlanNetwork metadata: name: demo-macvlannetwork spec: networkNamespace: "default" master: "ens64np1" mode: "bridge" mtu: 1500 ipam: | { "type": "whereabouts", "range": "192.168.2.225/28", "exclude": [ "192.168.2.229/30", "192.168.2.236/32" ] }
将
ens64np1
替换为上一步中ibdev2netdev
命令报告的网络接口名称。应用清单
$ kubectl apply -f demo-macvlannetwork.yaml
确认附加网络已准备就绪
$ kubectl get macvlannetworks demo-macvlannetwork
示例输出
NAME STATUS AGE demo-macvlannetwork ready 2023-03-10T18:22:28Z
在集群中两个不同的节点上启动两个运行
mellanox/cuda-perftest
容器的 pod。创建一个文件,例如
demo-pod-1.yaml
,用于第一个 pod,其内容如下所示apiVersion: v1 kind: Pod metadata: name: demo-pod-1 annotations: k8s.v1.cni.cncf.io/networks: demo-macvlannetwork # If a network with static IPAM is used replace network annotation with the below. # k8s.v1.cni.cncf.io/networks: '[ # { "name": "rdma-net", # "ips": ["192.168.111.101/24"], # "gateway": ["192.168.111.1"] # } # ]' spec: nodeSelector: # Note: Replace hostname or remove selector altogether kubernetes.io/hostname: nvnode1 restartPolicy: OnFailure containers: - image: mellanox/cuda-perftest name: rdma-gpu-test-ctr securityContext: capabilities: add: [ "IPC_LOCK" ] resources: limits: nvidia.com/gpu: 1 rdma/rdma_shared_device_a: 1 requests: nvidia.com/gpu: 1 rdma/rdma_shared_device_a: 1
应用清单
$ kubectl apply -f demo-pod-1.yaml
创建一个文件,例如
demo-pod-2.yaml
,用于第二个 pod,其内容如下所示apiVersion: v1 kind: Pod metadata: name: demo-pod-2 annotations: k8s.v1.cni.cncf.io/networks: demo-macvlannetwork # If a network with static IPAM is used replace network annotation with the below. # k8s.v1.cni.cncf.io/networks: '[ # { "name": "rdma-net", # "ips": ["192.168.111.101/24"], # "gateway": ["192.168.111.1"] # } # ]' spec: nodeSelector: # Note: Replace hostname or remove selector altogether kubernetes.io/hostname: nvnode2 restartPolicy: OnFailure containers: - image: mellanox/cuda-perftest name: rdma-gpu-test-ctr securityContext: capabilities: add: [ "IPC_LOCK" ] resources: limits: nvidia.com/gpu: 1 rdma/rdma_shared_device_a: 1 requests: nvidia.com/gpu: 1 rdma/rdma_shared_device_a: 1
应用清单
$ kubectl apply -f demo-pod-2.yaml
获取 pod 的 IP 地址
$ kubectl get pods -o wide
示例输出
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo-pod-1 1/1 Running 0 3d4h 192.168.38.90 nvnode1 <none> <none> demo-pod-2 1/1 Running 0 3d4h 192.168.47.89 nvnode2 <none> <none>
从一个终端,在第一个 pod 上的容器中打开一个 shell 并启动性能测试服务器
$ kubectl exec -it demo-pod-1 -- ib_write_bw --use_cuda=0 --use_cuda_dmabuf \ -d mlx5_0 -a -F --report_gbits -q 1
示例输出
************************************ * Waiting for client to connect... * ************************************
从另一个终端,在第二个 pod 上的容器中打开一个 shell 并运行性能客户端
$ kubectl exec -it demo-pod-2 -- ib_write_bw -n 5000 --use_cuda=0 --use_cuda_dmabuf \ -d mlx5_0 -a -F --report_gbits -q 1 192.168.38.90
示例输出
--------------------------------------------------------------------------------------- RDMA_Write BW Test Dual-port : OFF Device : mlx5_0 Number of qps : 1 Transport type : IB Connection type : RC Using SRQ : OFF PCIe relax order: ON ibv_wr* API : ON TX depth : 128 CQ Moderation : 100 Mtu : 1024[B] Link type : Ethernet GID index : 5 Max inline data : 0[B] rdma_cm QPs : OFF Data ex. method : Ethernet --------------------------------------------------------------------------------------- local address: LID 0000 QPN 0x01ac PSN 0xc76db1 RKey 0x23beb2 VAddr 0x007f26a2c8b000 GID: 00:00:00:00:00:00:00:00:00:00:255:255:192:168:02:226 remote address: LID 0000 QPN 0x01a9 PSN 0x2f722 RKey 0x23beaf VAddr 0x007f820b24f000 GID: 00:00:00:00:00:00:00:00:00:00:255:255:192:168:02:225 --------------------------------------------------------------------------------------- #bytes #iterations BW peak[Gb/sec] BW average[Gb/sec] MsgRate[Mpps] 2 5000 0.11 0.11 6.897101 4 5000 0.22 0.22 6.995646 8 5000 0.45 0.45 7.014752 16 5000 0.90 0.90 7.017509 32 5000 1.80 1.80 7.020162 64 5000 3.59 3.59 7.007110 128 5000 7.19 7.18 7.009540 256 5000 15.06 14.98 7.313517 512 5000 30.04 29.73 7.259329 1024 5000 59.65 58.81 7.178529 2048 5000 91.53 91.47 5.582931 4096 5000 92.13 92.06 2.809574 8192 5000 92.35 92.31 1.408535 16384 5000 92.46 92.46 0.705381 32768 5000 92.36 92.35 0.352302 65536 5000 92.39 92.38 0.176196 131072 5000 92.42 92.41 0.088131 262144 5000 92.45 92.44 0.044080 524288 5000 92.42 92.42 0.022034 1048576 5000 92.40 92.40 0.011015 2097152 5000 92.40 92.39 0.005507 4194304 5000 92.40 92.39 0.002753 8388608 5000 92.39 92.39 0.001377 ---------------------------------------------------------------------------------------
命令输出表明数据传输速率约为 92 Gbps。
删除 pod
$ kubectl delete -f demo-pod-1.yaml -f demo-pod-2.yaml
删除辅助网络
$ kubectl delete -f demo-macvlannetworks.yaml
使用 GPUDirect Storage#
平台支持#
请参阅平台支持页面上的 GPUDirect Storage 支持。
安装 GPU Operator 并启用 GPUDirect Storage#
以下部分适用于以下配置,并描述如何使用 Helm Chart 部署 GPU Operator
裸机和 vSphere VM 上使用 GPU 直通和 vGPU 的 Kubernetes。
从 v22.9.1 开始,GPU Operator 提供了一个选项,可以在 NVIDIA 驱动程序守护程序集的引导期间加载 nvidia-fs
内核模块。从 v23.9.1 开始,GPU Operator 部署了一个 GDS 版本,该版本需要使用 NVIDIA Open Kernel 模块驱动程序。
以下示例命令适用于使用 Network Operator 安装网络设备内核驱动程序的集群。
$ helm install --wait --generate-name \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v24.9.2 \
--set driver.useOpenKernelModules=true \
--set gds.enabled=true
将 --set driver.rdma.enabled=true
添加到命令以使用旧版 nvidia-peermem
内核模块。
验证#
在安装过程中,init 容器与驱动程序守护程序集一起使用,以等待网络设备内核驱动程序准备就绪。此 init 容器检查节点上的 Mellanox NIC,并确保必要的内核符号由内核驱动程序导出。验证完成后,nvidia-fs-ctr 容器在驱动程序 pod 内启动。
如果您在安装 Operator 时需要使用 driver.rdma.enabled=true
参数,则在验证后,nvidia-peermem-ctr 容器将在每个驱动程序 pod 内启动。
$ kubectl get pod -n gpu-operator
示例输出
gpu-operator gpu-feature-discovery-pktzg 1/1 Running 0 11m
gpu-operator gpu-operator-1672257888-node-feature-discovery-master-7ccb7txmc 1/1 Running 0 12m
gpu-operator gpu-operator-1672257888-node-feature-discovery-worker-bqhrl 1/1 Running 0 11m
gpu-operator gpu-operator-6f64c86bc-zjqdh 1/1 Running 0 12m
gpu-operator nvidia-container-toolkit-daemonset-rgwqg 1/1 Running 0 11m
gpu-operator nvidia-cuda-validator-8whvt 0/1 Completed 0 8m50s
gpu-operator nvidia-dcgm-exporter-pt9q9 1/1 Running 0 11m
gpu-operator nvidia-device-plugin-daemonset-472fc 1/1 Running 0 11m
gpu-operator nvidia-device-plugin-validator-29nhc 0/1 Completed 0 8m34s
gpu-operator nvidia-driver-daemonset-j9vw6 3/3 Running 0 12m
gpu-operator nvidia-mig-manager-mtjcw 1/1 Running 0 7m35s
gpu-operator nvidia-operator-validator-b8nz2 1/1 Running 0 11m
$ kubectl describe pod -n gpu-operator nvidia-driver-daemonset-xxxx
<snip>
Init Containers:
mofed-validation:
Container ID: containerd://a31a8c16ce7596073fef7cb106da94c452fdff111879e7fc3ec58b9cef83856a
Image: nvcr.io/nvidia/cloud-native/gpu-operator-validator:v22.9.1
Image ID: nvcr.io/nvidia/cloud-native/gpu-operator-validator@sha256:18c9ea88ae06d479e6657b8a4126a8ee3f4300a40c16ddc29fb7ab3763d46005
<snip>
Containers:
nvidia-driver-ctr:
Container ID: containerd://7cf162e4ee4af865c0be2023d61fbbf68c828d396207e7eab2506f9c2a5238a4
Image: nvcr.io/nvidia/driver:525.60.13-ubuntu20.04
Image ID: nvcr.io/nvidia/driver@sha256:0ee0c585fa720f177734b3295a073f402d75986c1fe018ae68bd73fe9c21b8d8
<snip>
nvidia-peermem-ctr:
Container ID: containerd://5c71c9f8ccb719728a0503500abecfb5423e8088f474d686ee34b5fe3746c28e
Image: nvcr.io/nvidia/driver:525.60.13-ubuntu20.04
Image ID: nvcr.io/nvidia/driver@sha256:0ee0c585fa720f177734b3295a073f402d75986c1fe018ae68bd73fe9c21b8d8
<snip>
nvidia-fs-ctr:
Container ID: containerd://f5c597d59e1cf8747aa20b8c229a6f6edd3ed588b9d24860209ba0cc009c0850
Image: nvcr.io/nvidia/cloud-native/nvidia-fs:2.14.13-ubuntu20.04
Image ID: nvcr.io/nvidia/cloud-native/nvidia-fs@sha256:109485365f68caeaee1edee0f3f4d722fe5b5d7071811fc81c630c8a840b847b
<snip>
最后,验证 NVIDIA 内核模块是否已加载到工作节点上
$ lsmod | grep nvidia
nvidia_fs 245760 0
nvidia_peermem 16384 0
nvidia_modeset 1159168 0
nvidia_uvm 1048576 0
nvidia 39059456 115 nvidia_uvm,nvidia_modeset
ib_core 319488 9 rdma_cm,ib_ipoib,iw_cm,ib_umad,rdma_ucm,ib_uverbs,mlx5_ib,ib_cm
drm 491520 6 drm_kms_helper,drm_vram_helper,nvidia,mgag200,ttm