2026-01-07 04:00:00

NVIDIA GB200 NVL72 正在将 AI 基础设施推向新的极限,使大规模语言模型训练和低延迟推理工作负载成为可能。随着 Kubernetes 在部署和扩展这些工作负载中的核心作用日益增强,快速演进的 AI 工作负载、基础设施需求和新硬件架构为 Kubernetes 编排和资源管理带来了新的挑战。
在本文中,我们将深入探讨如何通过 Kubernetes DRA (Dynamic Resource Allocation) 和 NVIDIA DRA Driver 在 GB200 平台上启用 Multi-Node NVLink (MNNVL),实现跨节点的 GPU 到 GPU 高带宽通信。
DRA (Dynamic Resource Allocation,动态资源分配) 是 Kubernetes v1.30 引入的革命性功能,用于解决传统 Device Plugin 框架在处理复杂异构硬件时的局限性。
DRA 最初始的版本(KEP-3063),于 1.26 版本引入,因可用性问题,在 1.32 版本被撤回 当前的 DRA 是第二个版本(KEP-4381) 于 1.30 引入。
传统 Device Plugin 将硬件资源抽象为简单整数计数器,无法表达:
设备特定参数(如 GPU 显存、计算能力、拓扑连接)
资源共享需求(设备无法在容器间共享)
硬件拓扑关系(NVLink 连接、PCIe 亲和性)
DRA 遵循 Kubernetes 声明式原则,将硬件资源特性作为一等公民纳入 API:
GB200 NVL72 通过引入 Multi-Node NVLink (MNNVL) 技术,将单机 GPU 性能限制扩展到整个机架层面,为分布式 AI 工作负载带来革命性改进。
传统的单节点 DGX 系统受限于单机物理限制,MNNVL 改变了这一局面:
NVIDIA Internode Memory Exchange Service (IMEX) 是 GPU 驱动层面的软件,允许 GPU 跨节点通信。IMEX 对每个单独的 GPU 内存导出/导入操作进行细粒度访问控制,并在称为 IMEX 域的节点组中运行。
作为 NVIDIA GPUs 的 DRA 驱动程序的一部分提供的 ComputeDomains,将底层 GPU 构造(NVIDIA NVLink 和 NVIDIA IMEX)与现代 Kubernetes 原生调度概念(动态资源分配,简称 DRA)连接起来,为在现代 GPU 硬件上运行分布式多节点工作负载提供所需的基础支持。
如果没有 ComputeDomains,多节点 NVLink 设置将不得不手动定义并固定到位,这限制了 Kubernetes 旨在提供的灵活性,并以牺牲安全隔离、故障隔离和成本效率为代价。
ComputeDomains 通过以下方式工作:
通过 ComputeDomains,运行分布式训练或跨复杂 NVLink 连接 GPU 架构的推理变得像部署标准 Kubernetes 工作负载一样简单。
软件信息:
硬件信息:
GPU 基本信息:
|
|
GPU 拓扑:
|
|
|
|
提示:部署过程可能需要 5-10 分钟,请耐心等待。可以通过
kubectl get pods -n gpu-operator监控部署进度。
如果部署成功,那么节点上可以看到 nvidia.com/gpu 资源
|
|
|
|
重要参数说明:
resources.gpus.enabled=false:禁用默认 GPU 资源管理,由 GPU Operator 处理nvidiaDriverRoot=/run/nvidia/driver:指定 NVIDIA 驱动路径
正常情况下,可以看到节点间的 nvidia.com/gpu.clique label。
|
|
创建 IMEX 负载
|
|
查看日志,正常能看到注入的 imex channel
|
|
至此,说明 nvidia-dra-driver 部署成功。
首先安装 MPI Operator,用于运行多节点 MPI 作业:
|
|
|
|
Apply
|
|
会自动启动 Pod 进行测试
|
|
查看日志
|
|
测试结果如下:
|
|
测试结果显示跨节点 GPU-to-GPU 通信带宽稳定在 820 GB/s 左右,远超传统 InfiniBand 等网络互联方案的性能,为大规模分布式 AI 训练提供了强大的通信基础。
通过本文的实战指南,您已经学会了如何在 GB200 平台上部署和配置 NVIDIA DRA Driver,以启用 Multi-Node NVLink (MNNVL) 功能。主要成就包括:
ComputeDomains 技术将复杂的底层 GPU 硬件抽象为 Kubernetes 原生资源,使得多节点分布式 AI 工作负载的管理变得简单而高效。未来,随着更多 NVIDIA 架构的支持,这项技术将在 AI 基础设施领域发挥越来越重要的作用。
2025-12-17 04:00:00

在上一篇 告别 TCP/IP 延迟:Kubernetes 中的 RDMA 高性能网络实战 中,我们介绍了如何在 Kubernetes 中启用 RDMA(InfiniBand)能力,实现了相比 TCP/IP 延迟降低 20-40 倍、带宽提升 40 倍以上的效果。然而在超大规模 AI 训练场景下,即便是 InfiniBand 的带宽也可能成为瓶颈——当 GPU 间需要频繁同步梯度时,跨节点通信效率直接决定了整体训练吞吐。那么,有没有比 InfiniBand 更高效的多节点互联方案?答案是 MNNVL(Multi-Node NVLink)。
GB200 NVL72 是 NVIDIA 推出的超级系统,专为大规模 AI 训练和推理设计。完整一柜 GB200 NVL72 系统包含 72 个 GB200 GPU + 36 个 Grace CPU,通过第五代 NVLink 高速互连。本文测试的是其中的 2 个节点子集(每节点 4 个 GB200 + 2 个 Grace,共 8 个 GPU),主要关注不同互联方案在多节点场景下的带宽差异。
MNNVL(Multi-Node NVLink) 是 GB200 NVL72 的核心创新特性,它通过 NVLink 实现跨节点 GPU 直连,让多节点 GPU 集群的性能接近单节点。与传统的 InfiniBand 网络相比,MNNVL 具有以下优势(支持 MNNVL 的 NCCL 版本通常会优先选择该通道,也可通过 NCCL_MNNVL_ENABLE=1 显式开启或确认使用):
在实际生产环境中,我们需要了解不同网络方案的性能差异,以便在混合集群、容错场景或特定拓扑下做出最优选择。本文通过 2 节点 8 GPU 的 NCCL micro-benchmark 实测数据 对比 MNNVL、InfiniBand 和 TCP 以太网的性能表现,为 AI 训练集群的网络选型提供参考(并非完整业务训练 benchmark)。
核心亮点:2 节点 8 GPU 配置下,MNNVL 实测带宽 811GB/s,InfiniBand 为 85GB/s,性能提升 9.5 倍!实测数据证明 MNNVL 是 GB200 NVL72 多节点通信的最佳选择。
测试结果概览
| 连接方式 | 带宽 | 性能倍数 | 说明 |
|---|---|---|---|
| MNNVL | 811GB/s | 9.5x | 跨节点 GPU 直连,性能最优 ✅ |
| InfiniBand (400G) | 85GB/s | 1x | 传统网络方案,性能中等 ⚠️ |
| TCP 以太网 | 2GB/s | 0.02x | 普通网络,性能最低 ❌ |
说明:上表中的带宽数值均来自 nccl-tests 输出的 Bus bandwidth(busbw) 指标,是 NCCL 对整体通信效率的“等效总线带宽”度量,并不等同于单条物理链路的单向线速。
关键发现:
GPU 基本信息:
|
|
GPU 拓扑:
|
|
⚠️ 重要提示:需要在所有待测试节点安装环境,同时安装目录要保持一致。
nccl-tests 包含一系列测试项目,主要用于测试和验证 NCCL 的性能以及操作正确性。
These tests check both the performance and the correctness of NCCL operations.
|
|
参数说明:
--prefix=/usr/local/openmpi:指定 MPI 安装位置为 /usr/local/openmpi
|
|
参数说明:
CUDA_HOME:CUDA 安装位置注意:需要记录下这里的 nccl 文件夹路径,make 之后会在 nccl 目录下生成 build 目录,后续编译 nccl-tests 的时候会用到该目录。
|
|
参数说明:
MPI=1:开启 MPI
NAME_SUFFIX=_mpi:编译产物带上 _mpi 后缀,便于区分
CUDA_HOME:CUDA 安装位置
MPI_HOME:上一步编译 OpenMPI 的位置
NCCL_HOME:上一步 nccl build 的目录,就是 nccl 源码目录增加 /build
构建完成后,会在 build 目录下生成可执行文件:
|
|
|
|
注意:以下是一个示例命令,实际测试中根据场景调整参数(如
-g参数)。
|
|
ENV 相关参数:
-x NCCL_DEBUG=INFO:把环境变量 NCCL_DEBUG=INFO 随进程一起下发,使 NCCL 打印初始化、网络选择、通道等调试信息。
-x PATH:将当前 shell 的 PATH 原样传递到远端进程,保证可执行文件能被找到。
-x LD_LIBRARY_PATH:同样传递动态库搜索路径,避免远端节点找不到 CUDA/OpenMPI/NCCL 的 .so 文件。
-x CUDA_HOME -x MPI_HOME -x NCCL_HOME:同上,传递 CUDA、MPI、NCCL home 目录
-np 2:进程数为 2
-H 10.0.6.41:1,10.0.6.42:1:指定节点列表,这里控制哪台机器跑几个进程。
测试相关参数:
-b 16G:最小消息 16GB(示例命令中使用)
-e 16G:最大消息 16GB(示例命令中使用)
-f 2:每次测试数据量按照 2 倍递增
-g 4:每个 MPI 进程使用的 GPU 数量,当前是 4 GPU
-c 1:使用 1 个通信通道
-i 100:warm-up 后跑 100 次取平均
通过显式启用 NCCL_MNNVL_ENABLE=1 和 NCCL_IMEX_ENABLE=1,指定 NCCL 使用 MNNVL 进行跨节点通信。
测试命令:
|
|
测试结果:
|
|
性能表现:
-x NCCL_MNNVL_ENABLE=0 以及 -x NCCL_IMEX_ENABLE=0 配置,关闭 MNNVL,强制走 IB。-x NCCL_IB_HCA="mlx5_0" 指定 IB 卡测试命令:
|
|
测试结果:
|
|
性能表现:
增加以下参数:
-x NCCL_MNNVL_ENABLE=0 -x NCCL_IMEX_ENABLE=0:关闭 MNNVL
-x NCCL_IB_DISABLE=1:禁用 IB 网络
看看纯 TCP 网络下的性能。
|
|
ps:因为纯 TCP 太慢,为了缩短测试时间,这里将消息大小从 16GB 降到 1GB,迭代次数从 100 次降到 10 次,因此只能粗略对比数量级差距,而不是与 MNNVL/IB 完全同条件对比。
测试结果:
|
|
性能表现:
通过本次 2 节点 8 GPU 的 nccl-tests,对 GB200 NVL72 系统中的不同互联方案有了更直观的量化认识:
但是,这么好的性能也是有代价的——GB200 NVL72 售价高达数百万美元 😱
看完测试数据,我只想说: 🤑 贫穷限制了我的想象力,原来"带宽不够"也能用钱解决。
2025-12-03 06:00:00

GPU 算力拉满了,网络却成了瓶颈?在大模型训练和推理场景中,传统 TCP/IP 网络的延迟和 CPU 开销正在严重制约集群性能。RDMA 技术通过绕过内核直接访问内存,降低网络延迟。本文将手把手教你在 Kubernetes 中启用 RDMA 能力,从 Device Plugin 部署到性能验证,让你的 AI 集群真正发挥出硬件的全部潜力。
RDMA (Remote Direct Memory Access) 是一种高性能网络通信技术,允许网络中的计算机直接从另一台计算机的内存中读取或写入数据,而无需涉及两台计算机的操作系统内核或 CPU。
RDMA 支持多种网络传输协议,常见的包括:
在 Kubernetes 环境中,我们通常关注如何将这些高性能网络能力暴露给 Pod 使用。
随着大模型(LLM)训练和推理需求的爆发式增长,分布式计算集群对网络带宽和延迟提出了极高的要求。在传统的 TCP/IP 网络架构中,数据传输需要经过操作系统内核的多次上下文切换和内存拷贝,这在高带宽(如 100Gbps+)场景下会消耗大量的 CPU 资源,并引入不可忽视的延迟,成为制约 GPU 集群性能的瓶颈。
为了解决这一问题,RDMA (Remote Direct Memory Access) 技术被广泛应用。它允许应用程序直接访问远程节点的内存,绕过内核网络栈,从而实现高吞吐、低延迟和低 CPU 占用。
然而,Kubernetes 原生并不直接支持 RDMA 设备的管理和调度。为了在 Kubernetes 集群中充分利用 RDMA 硬件能力,我们需要解决以下关键问题:
本文将基于 Mellanox 提供的 k8s-rdma-shared-dev-plugin,详细介绍在 Kubernetes 中启用原生 RDMA 的完整流程与最佳实践。
推荐使用由 Mellanox 官方维护的 DevicePlugin:k8s-rdma-shared-device-plugin
确保节点已安装对应版本的 MOFED/OFED 驱动及用户态库(libibverbs、rdmacm 等)。驱动安装方式本文不赘述。
先 clone 项目:
|
|
|
|
部署成功后 kube-system 中会出现 rdma-shared-dp-ds DaemonSet,它会在每个节点挂载 RDMA 设备并注册可调度资源。
|
|
Device Plugin 的核心是 ConfigMap。默认配置可参考:configmap.yaml
|
|
关键字段:
resourceName:Pod 申请资源写的名字,建议自定义如 rdma/ib
rdmaHcaMax:单卡允许共享的 Pod 数量,默认 1000selectors:定义哪些物理网卡由 device plugin 接管,是配置的关键
接下来介绍如何收集所需信息。
|
|
|
|
这里可以看到 IB 卡对应的接口名称,例如 mlx5_0 的接口名称为 ibp3s0。
这里可以获取到配置中需要的 ifNames 参数。
mst status -v 可以列出所有 UP 状态网卡及其 PCI ID:
|
|
示例中 mlx5_0 的 PCI ID 为 0000:03:00.0。
根据上一步获取到的 PCI ID 查询:
|
|
15b3:Mellanox/NVIDIA 厂商 ID1021:具体设备 ID这里可以获取到配置中需要的 vendors、deviceIDs 参数。
汇总以上信息即可写出 selectors,示例如下(可配置多块网卡):
|
|
更新 ConfigMap 后重启 Device Plugin:
|
|
|
|
已经能在 Node 上看到 rdma/hca_shared_devices_a 资源了。
基于 Ubuntu 安装 ibv_devices、ibv_devinfo、ibstat、ibstatus 等工具构建一个用于测试的镜像。
|
|
构建镜像:
|
|
已经推送到 dockerhub:lixd96/rdma-test:latest
启动一个 Pod 申请 RDMA 资源:
|
|
进入 Pod,使用 ibv_devices 和 ibv_devinfo 查看 IB 卡信息:
|
|
可以看到 Pod 内已经识别到 mlx5_0 等 RDMA 设备。
例如:
|
|
为了全面验证 RDMA 的性能,我们需要启动两个 Pod 进行带宽和延迟测试。
Pod 1 (Server):
|
|
Pod 2 (Client):
|
|
部署后查看 Pod 状态:
|
|
进入 Pod,使用 ibv_devices 和 ibv_devinfo 查看 IB 卡信息:
|
|
可以看到 Pod 内已经识别到 mlx5_0 等 RDMA 设备。
例如:
|
|
使用 ib_write_bw 工具测试 RDMA 带宽性能。
进入 rdma-server 启动 server:
|
|
进入 rdma-client 启动 Client:
|
|
结果如下:
|
|
测试结果为 46 GB/s 带宽,IB 卡为 400Gb/s,理论带宽为 50GB/s,该结果已经接近 IB 带宽上限,说明 RDMA 已能正常使用。
|
|
除了带宽,延迟也是 RDMA 的重要性能指标。使用 ib_write_lat 测试延迟:
在 rdma-server 中启动:
|
|
在 rdma-client 中连接:
|
|
测试结果示例:
|
|
测试结果显示,RDMA 的单向延迟约为 2.73 微秒,相比传统 TCP/IP 网络(通常 50-100 微秒),延迟降低了 20-40 倍。同时标准差仅为 0.04 微秒,说明延迟非常稳定,充分体现了 RDMA 的低延迟优势。
在 Kubernetes RDMA 方案中,是否引入 Multus CNI 取决于具体的应用场景和网络需求。
如果你的需求满足以下条件,通常不需要 Multus CNI:
k8s-rdma-shared-dev-plugin 可以在不改变 Pod 网络命名空间结构的情况下,将 RDMA 设备文件(/dev/infiniband/*)暴露给 Pod。在这种模式下,Pod 依然使用默认 CNI(如 Calico、Flannel)分配的 IP 进行常规通信,同时拥有了访问 RDMA 硬件的能力。这是最简单、维护成本最低的方案。
如果存在以下需求,则建议引入 Multus CNI:
sriov-cni 将物理网卡虚拟化为 VF 直接透传给 Pod,通常需要 Multus 来管理这个额外的网络接口。对于大多数基于 k8s-rdma-shared-dev-plugin 的分布式推理和训练任务,不需要 额外部署 Multus CNI。直接通过 Device Plugin 暴露设备,配合应用层的 RDMA 库即可实现高性能通信。引入 Multus 会显著增加网络配置的复杂度,应仅在确有必要(如强隔离、SR-IOV)时使用。
本文系统性地梳理了在 Kubernetes 集群中落地 RDMA 技术的完整路径。从基础概念的认知,到硬件环境的准备,再到 Device Plugin 的部署与配置,最后通过实际的性能压测验证了 RDMA 性能的优越性。
核心要点回顾:
k8s-rdma-shared-dev-plugin 配合 Shared 模式是最轻量级的方案。它无需复杂的网络改造,即可让 Pod 获得原生 RDMA 能力。随着云原生 AI 的持续演进,底层网络设施的性能优化将变得愈发重要。掌握 RDMA 在 Kubernetes 中的配置与管理,将成为构建高性能 AI 平台的必备技能。未来,我们还可以进一步探索 GPUDirect RDMA、SR-IOV 等进阶技术,以应对更大规模、更低延迟的计算挑战。
2025-11-05 06:00:00

在云原生时代,存储的高可用性是生产环境的生命线。一个设计良好的存储系统,不仅要能在节点故障时保证数据不丢失,还要做到业务无感知、自动恢复。
本文将深入剖析 Longhorn 的高可用机制:从两层架构设计到 iSCSI 协议的巧妙运用,从多副本写入到 Raft 共识算法,再到自动故障恢复流程。通过理论分析和实战演示,带你彻底理解 Longhorn 如何在分布式环境中实现数据的高可用性。
📚 系列文章:本文是 Longhorn 系列的第二篇,重点剖析高可用原理。如果你还不了解 Longhorn 的基本概念和部署方法,建议先阅读上一篇:云原生分布式存储系统:Longhorn 初体验
要理解 Longhorn 的高可用机制,首先需要了解其架构设计。好的架构是高可用的基础。
Longhorn 采用了清晰的分层架构设计:
Longhorn 设计为两层结构:
数据平面(Data Plane)
控制平面(Control Plane)
这种设计的优势在于:
在 Kubernetes 中,Longhorn 的核心组件包括:
Longhorn Engine
Longhorn Replica
/var/lib/longhorn)Longhorn Manager
了解了 Longhorn 的架构设计后,让我们通过一个完整的实例,从 PVC 创建到 Pod 使用,详细了解 Longhorn 的工作流程。
Longhorn 部署完成后,会自动创建两个 StorageClass:
|
|
输出示例:
|
|
让我们通过一个实际例子来演示 Longhorn 的完整工作流程。创建一个使用 Longhorn PVC 的 MariaDB Pod:
|
|
当创建 PVC 时,会触发以下流程:
Step 1:PVC 创建
longhorn StorageClassStep 2:CSI Driver 响应
Step 3:Volume CRD 创建
Volume CRD 对象
|
|
输出示例:
|
|
Step 4:Engine 和 Replica 调度
块设备的挂载分为两个阶段:
阶段 1:Attach(附加到节点)
当 Pod 被调度到某个节点时:
查看模拟的块设备:
|
|
输出示例:
|
|
注意文件类型为 b(block),表示这是一个块设备。
阶段 2:Mount(挂载到 Pod)
Kubelet 将该块设备格式化为文件系统(如 ext4、xfs),并挂载到 Pod 的指定路径。
小结: 通过 Attach 和 Mount 两个阶段,Longhorn 成功将卷挂载到 Pod 中。其中,iSCSI 协议模拟的块设备是实现高可用的关键,它使得 Longhorn 能够拦截所有 I/O 操作,从而实现多副本同步。接下来我们将深入剖析这个高可用机制。
这是 Longhorn 高可用的核心机制。当应用写入数据时,经历以下流程:
核心思想: 通过 iSCSI 协议模拟块设备,将所有 I/O 操作拦截并转发给 Engine,由 Engine 使用 Raft 算法同步到多个 Replica,实现数据高可用。

详细步骤:
Step 1:应用写入
/bitnami/mariadb/data.db
Step 2:文件系统层
Step 3:块设备层
/dev/longhorn/xxx
Step 4:iSCSI 协议转发
Step 5:Engine 多副本复制
Step 6:Replica 持久化
/var/lib/longhorn/replicas/<volume-name>-<id>/
关键要点:
从上面的数据写入流程图可以看出,Longhorn 的高可用实现依赖以下关键技术:
1) iSCSI 协议的巧妙运用
与传统存储(如 Ceph)不同,Longhorn 通过 iSCSI 协议模拟了一个块设备,从而能够:
2) Raft 共识算法
Longhorn 使用 Raft 算法确保数据一致性:
3) 数据副本分布
|
|
Longhorn Manager 会智能调度,确保:
通过多副本和 Raft 共识算法,Longhorn 实现了数据的高可用性。但真正考验存储系统可靠性的,是当节点故障时的自动恢复能力。本章将详细介绍 Longhorn 如何检测故障、降级运行,并自动重建副本。
健康监控
系统降级
Degraded(降级)举例:3 副本的卷
重建流程
Step 1:检测故障
|
|
Step 2:调度新副本
Step 3:数据同步
Step 4:恢复健康
Degraded 恢复为 Healthy
查看恢复进度:
|
|
模拟节点故障:
|
|
恢复时间线:
通过前面的分析,我们深入了解了 Longhorn 的高可用实现机制。那么,与其他存储方案相比,Longhorn 的优势在哪里?它适合什么样的场景?本章将进行详细对比分析。
| 特性 | NFS | Ceph | Longhorn |
|---|---|---|---|
| 高可用性 | ❌ 单点故障 | ✅ 高可用 | ✅ 高可用 |
| 自动故障恢复 | ❌ 需手动处理 | ✅ 自动恢复 | ✅ 自动恢复 |
| 部署复杂度 | ✅ 简单 | ❌ 复杂 | ✅ 简单 |
| 资源占用 | ✅ 低 | ❌ 高 | ✅ 中等 |
| 数据一致性 | ⚠️ 弱一致性 | ✅ 强一致性 | ✅ 强一致性(Raft) |
| 故障容忍度 | 0 | N/2 | N/2 |
1. 微服务架构
2. 强一致性保证
3. 自动故障恢复
4. 云原生设计
本文从架构、原理到实战,全面剖析了 Longhorn 如何实现云原生存储的高可用性。通过数据写入流程图和故障恢复示例,我们深入理解了其背后的核心技术机制:
架构层面
技术实现
高可用保证
适用场景
总结
Longhorn 通过精心的架构设计和成熟的分布式算法,在简单性、可靠性和性能之间取得了完美平衡。它的高可用机制不仅理论上完善(Raft 共识、多副本复制),更在实践中证明了可靠性(自动故障恢复、降级运行)。
对于追求"简单可靠"的中小规模 Kubernetes 集群来说,Longhorn 无疑是一个"刚刚好"的云原生存储解决方案——既不会像 NFS 那样让你担心数据安全,也不会像 Ceph 那样让你头疼运维复杂度。
2025-10-15 06:00:00

本文将介绍云原生分布式存储系统 Longhorn,包括其核心概念、架构原理,以及如何在 Kubernetes 集群中部署和使用。
Longhorn 是一个开源的、云原生的分布式块存储系统,专为 Kubernetes 环境设计。它最初由 Rancher Labs 开发,现已成为云原生计算基金会(CNCF)的孵化项目。
主要特点:
Longhorn 适用于以下场景:
Longhorn 的核心设计理念是为每个 Volume 创建独立的 Engine 进行管理,Engine 负责将 Volume 复制到多个节点,以实现高可用存储。
为什么为每个 Volume 创建一个独立的 Engine?
这样可以保证当某个 Engine 出现问题时,其他 Volume 不受影响,实现了故障隔离。
Longhorn 主要包含以下核心组件:
控制平面组件:
数据平面组件:
CSI 组件(Kubernetes 官方):
数据存放位置:Longhorn 使用集群节点的本地磁盘(默认 /var/lib/longhorn)组成分布式存储池,数据副本分布在这些节点的磁盘上。
|
|
高可用原理:
安装 Longhorn 前需要确保环境满足以下要求:
完整要求参考:https://longhorn.io/docs/1.7.3/deploy/install/#installation-requirements
open-iscsi
bash、curl、findmnt、grep、awk、blkid、lsblk 等命令Longhorn 需要以下依赖:
1) open-iscsi
apt-get install open-iscsi(Ubuntu/Debian)2) NFS 客户端
apt-get install nfs-common(Ubuntu/Debian)3) Mount Propagation
注意:第4章会介绍使用 DaemonSet 自动安装这些依赖的方式(推荐),这里仅作说明。如需手动安装,参考 官方文档
使用 DaemonSet 自动安装依赖(推荐)
官方提供了 DaemonSet 方式自动在所有节点安装依赖,无需手动登录每个节点操作:
|
|
检查安装状态
使用以下脚本检查初始化是否成功:
|
|
日志中输出 iscsi install successfully 或 nfs install successfully 表示安装成功。
推荐使用 Helm 进行安装:
|
|
注意:1.8.2 和 1.9.1 版本需要 Kubernetes 1.25+,1.7.3 只需要 1.21+
1) 检查 Pod 状态
|
|
正常情况下,所有 Pod 应处于 Running 状态:
|
|
部署完成后,默认会创建两个 StorageClass:
|
|
输出示例:
|
|
1) 创建 PVC
使用 Longhorn 存储类创建 PVC:
|
|
2) 创建 Pod 使用 PVC
创建一个 Pod 挂载使用该 PVC:
|
|
部署后可以进入 Pod 验证挂载:
|
|
Longhorn 提供了 Web UI 用于管理和监控。
修改 Service 为 NodePort 类型
默认情况下,longhorn-frontend Service 是 ClusterIP 类型,需要修改为 NodePort:
|
|
查看分配的端口:
|
|
输出示例:
|
|
通过任意节点 IP + NodePort 访问 Web UI:http://<node-ip>:30123
Web UI 界面

在 Web UI 中可以:
本文全面介绍了 Longhorn 这款云原生分布式存储系统,从架构原理到实际部署使用,涵盖了以下内容:
在 Kubernetes 环境中,不同场景适合不同的存储方案:
测试/开发环境 → NFS
大型生产环境 → Ceph
中小规模生产环境 → Longhorn
总结:如果你的生产环境规模不大(几十个节点以内),又希望在存储可靠性和运维复杂度之间取得平衡,Longhorn 是最佳选择。它既保证了生产级的可靠性,又避免了 Ceph 的复杂度,是"刚刚好"的分布式存储方案。
2025-08-20 06:00:00

在上一篇《Volcano初探:批处理调度引擎的云原生实践》中,我们通过Helm快速部署了Volcano集群,并成功运行了首个测试任务,验证了其基础调度能力。本文将进一步探索Volcano的GPU虚拟化功能,聚焦如何通过HAMi vGPU 技术实现GPU资源的细粒度共享与硬隔离。
批处理调度引擎 Volcano 支持 GPU 虚拟化功能,该功能主要由 HAMi 提供。
HAMi vGPU 提供的 GPU 虚拟化包括 HAMi-Core 和 Dynamic MIG 两种模式:
| Mode | Isolation | MIG GPU Required | Annotation | Core/Memory Control | Recommended For |
|---|---|---|---|---|---|
| HAMI-core | Software (VCUDA) | No | No | Yes | General workloads |
| Dynamic MIG | Hardware | Yes | Yes | MIG-controlled | Performance-sensitive jobs |
如果硬件支持 MIG 同时运行的是性能敏感型任务,那么推荐使用 Dynamic MIG 模型,不支持 MIG 依旧可以使用更加通用,对硬件无要求的 HAMi-Core 模式。
本文主要以 HAMi-Core 进行演示,HAMi vGPU 如何集成到 Volcano。
使用流程:
1)创建集群
2)安装 GPU-Operator,但是不安装 DevicePlugin
3)安装 Volcano,并配置开启 vGPU 插件
4)安装 volcano-vgpu-device-plugin
5)验证
使用 KubeClipper 部署一个集群进行验证。
Kubernetes教程(十一)—使用 KubeClipper 通过一条命令快速创建 k8s 集群
参考之前的文章 GPU 环境搭建指南:使用 GPU Operator 加速 Kubernetes GPU 环境搭建,使用 GPU Operator 部署环境。
安装 Volcano,部署时需要注意 volcano 和 k8s 的版本兼容性问题,参考官方 README:Kubernetes compatibility
这里部署的 v1.12.0 版本
|
|
部署完成后 Pod 列表如下:
|
|
Volcano 部署完成之后,我们需要编辑调度器配置,开启 deviceshare 插件。
|
|
完整内容如下:
|
|
核心如下:
|
|
开启 vgpu 同时调度策略我们选择 binpack。
HAMi 调度策略可以阅读这篇文章:HAMi vGPU 原理分析 Part4:Spread&Binpack 高级调度策略实现
修改后,不需要重启,Volcano 会自动检测,当文件变化后自动 reload。
|
|
不过 k8s 将 Configmap 同步到 Pod 中也是有延迟的,不想等的话也可以手动重启下。
|
|
接下来我们部署和 Volcano 集成用到的 DevicePlugin:volcano-vgpu-device-plugin。
DevicePlugin 原理可以阅读这篇文章:HAMi vGPU 原理分析 Part1:hami-device-plugin-nvidia 实现,大致逻辑都是一样的。
从项目 volcano-vgpu-device-plugin 根目录获取文件: volcano-vgpu-device-plugin.yml
|
|
部署
|
|
查看 Pod 列表:
|
|
查看 Node 上的 Resource 信息:
|
|
Volcano 新增了下面三个:
|
|
volcano.sh/vgpu-cores: 800:每张 GPU 100 core,8 卡正好 800 core。
volcano.sh/vgpu-memory: 39312 :由于设置了 factor=10,因此实际代表总显存 39312 * 10 = 393120 MB。
volcano.sh/vgpu-number: 80:默认 --device-split-count=10,将 GPU 数量扩大了 10 倍。
说明插件部署成功。
首先启动一个简单 Pod
|
|
查看效果,vgpu-memory 申请的 1024,如下:
但是因为 factor=10,所以实际是 10240 MB。
|
|
启动一个简单的 Volcano Job 试试:
|
|
一切正常:
|
|
查看 Pod 中的 GPU 信息
|
|
日志
|
|
|
|
包括 GPU core & memory 的分配信息,以及对应 Pod 信息,例如:
|
|
直接访问 DevicePlugin Pod 的 9394 端口获取监控信息:
|
|
可以查看到该节点上的 GPU 使用情况,metrics 如下:
|
|
DevicePlugin 都只会注册一个资源,而 Volcano DevicePlugin 却注册了三个资源,如何做到的?
|
|
实际上,Volcano DevicePlugin 内部启动了三个 DevicePlugin 分别使用了三个 ResourceName:
volcano.sh/vgpu-number
volcano.sh/vgpu-memory
volcano.sh/vgpu-cores
|
|
对应 sock 文件如下:
|
|
在获取 Device 时也根据不同的 ResourceName 做了不同实现:
|
|
具体分配 Device 逻辑:
|
|
核心部分:
包括指定环境变量,以及挂载 libvgpu.so 等逻辑。
|
|
同时由于启动了三个 DevicePlugin,为了避免重复调用,Allocate 方法中根据 ResourceName 进行了判断,只有 volcano.sh/vgpu-number 时才真正执行分配逻辑。
|
|
https://github.com/volcano-sh/volcano/blob/master/pkg/scheduler/plugins/deviceshare/deviceshare.go
简单分析一下 Volcano 中的 deviceshare 插件。
这块和 HAMi 实现基本一致,可以参考以下两篇文章:
每个插件都要实现 Volcano 定义的 Plugin 接口:
|
|
核心代码在 OnSessionOpen 实现中,包含了调度的两个方法:
Predicate
NodeOrder
|
|
主要实现调度过程中的节点过滤以及打分两部分逻辑。
过滤不满足设备需求的节点
|
|
核心逻辑在 FilterNode 方法中:
|
|
过滤不满足条件的节点,并为剩余节点打分。
从 core、memory 几方面判断 Node 是否有足够资源,不满足则过滤。
|
|
根据配置的调度策略进行打分。
|
|
逻辑比较简单:
Binpack :device 内存使用率越高,得分越高
Spread: device 有被共享使用得 100 分,否则 0 分。
上一步已经为节点打好分了,这里只需要根据得分排序即可。
|
|
核心部分:
|
|
节点得分 * 权重得到最终得分。
现象:device-plugin 部署后 gpu-memory 显示为 0 就像这样:
|
|
具体原因:https://github.com/volcano-sh/devices/issues/19
相关描述:
the size of device list exceeds the bound, and ListAndWatch failed as a result。
简而言之就是超过阈值的显存就会报错,导致 DevicePlugin 无法正常上报,因此显示为 0。
解决方案:需要在启动时设置参数 --gpu-memory-factor=10,将最小的显存块从默认 1MB 改成 10MB,就像这样:
|
|
这样最大能显示的数值就扩大了 10 倍,就可以避免该问题。
效果如下:
|
|
volcano.sh/vgpu-memory: 39312 :由于设置了 factor=10,因此实际代表总显存 39312 * 10 = 393120 MB。
当前环境是 L40S*8,单卡显存 49140,49140 * 8 = 393120,正好符合,说明一切正常。
本文主要验证了 Volcano 如何通过集成HAMi vGPU技术实现 Kubernetes 环境下的 GPU 虚拟化,重点验证了HAMi-Core 模式的完整工作流程。
解答前面的问题:Volcano DevicePlugin 如何实现同时注册三个资源的?
通过启动三个 DevicePlugin 以实现注册 volcano.sh/vgpu-number、volcano.sh/vgpu-memory、volcano.sh/vgpu-cores 三种资源。
推荐阅读: