ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

高网和GPU搭配

高网和GPU搭配 表格角色对应什么干什么老板K8S 调度器决定哪个任务分到哪台机器工人GPU 卡干计算活传送带RDMA 高网网卡工人之间传数据--跳过CPU直接通讯工位服务器节点工人和传送带都在上面任务单Pod一个训练任务需要几个工人、几条传送带下面按两种模式分别整理整卡搭配和SR-IOV 切分搭配。整体原理K8S 本身不直接认识 GPU 和高网网卡所以要先通过插件把硬件变成 K8S 可调度的资源text物理硬件 │ ├─ GPU 卡 │ └─ NVIDIA Device Plugin 上报nvidia.com/gpu │ ├─ 高网网卡整卡模式 │ └─ RDMA Device Plugin 上报rdma/hca │ └─ 高网网卡切分模式 └─ SR-IOV 把一张物理网卡切成多个 VF └─ SR-IOV Device Plugin 上报sriov_netPod 里只需要声明text我要几张 GPU 我要几张高网网卡 / 几个虚拟网卡K8S 调度器会自动找到同时满足条件的节点把 Pod 调度过去。一、整卡搭配GPU 高网整张网卡1.1 适用场景每个训练任务需要完整的一张高网网卡不需要把一张物理网卡切给多个 Pod配置最简单1.2 整体流程text节点安装 GPU 驱动 ↓ 节点安装 RDMA / 高网驱动 ↓ 集群部署 NVIDIA Device Plugin ↓ 集群部署 RDMA Device Plugin ↓ Pod 里同时申请 nvidia.com/gpu 和 rdma/hca ↓ K8S 调度到同时有 GPU 和高网网卡的节点 ↓ Pod 内通过 NCCL 环境变量走 RDMA 高网通信1.3 节点前置条件每台 GPU 节点需要完成text1. 安装 GPU 驱动 2. 安装 NVIDIA Container Toolkit 3. 安装高网网卡驱动例如 Mellanox OFED 4. 确认 RDMA 设备可用 5. kubelet 可以开启拓扑感知调度让 GPU、CPU、网卡尽量在同一 NUMA 节点1.4 NVIDIA Device Plugin 配置这个插件的作用是让 K8S 知道每台节点有几张 GPU。yaml# nvidia-device-plugin.yaml # 作用把节点上的 GPU 暴露成 K8S 可调度资源 nvidia.com/gpu apiVersion: apps/v1 kind: DaemonSet metadata: name: nvidia-device-plugin-daemonset namespace: kube-system spec: selector: matchLabels: name: nvidia-device-plugin-ds template: metadata: labels: name: nvidia-device-plugin-ds spec: # 容忍 master/taint 节点保证所有节点都能运行 tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule # 使用宿主机网络方便和节点设备通信 hostNetwork: true containers: - name: nvidia-device-plugin image: nvcr.io/nvidia/k8s-device-plugin:v0.15.0 # 把节点上的设备目录挂载进容器让插件能看到 GPU 设备 volumeMounts: - name: device-plugin mountPath: /var/lib/kubelet/device-plugins volumes: - name: device-plugin hostPath: path: /var/lib/kubelet/device-plugins执行bashkubectl apply -f nvidia-device-plugin.yaml执行后K8S 会自动发现节点上的 GPU并上报为textnvidia.com/gpu1.5 RDMA Device Plugin 配置这个插件的作用是让 K8S 知道每台节点有几张高网 RDMA 网卡。yaml# rdma-device-plugin-config.yaml # 作用定义 RDMA 网卡资源名称和匹配规则 apiVersion: v1 kind: ConfigMap metadata: name: rdma-devices namespace: kube-system data: config.json: | { periodicUpdateInterval: 300, configList: [ { # K8S 中申请高网网卡时使用的资源名 resourceName: rdma_hca, # 每张物理网卡最多可分配的次数 rdmaHcaMax: 1, selectors: { # 网卡厂商 IDMellanox/NVIDIA 网卡通常是 15b3 vendors: [15b3], # 如果网卡名固定可以指定网卡名 # ifNames: [ib0, ib1] } } ] }执行bashkubectl apply -f rdma-device-plugin-config.yamlRDMA Device Plugin 会读取这个配置把匹配到的 RDMA 网卡注册为textrdma/hca如果配置里写的是jsonresourceName: rdma_hca那么 Pod 里申请时通常写成textrdma/rdma_hca具体前缀取决于你部署的 RDMA Device Plugin 版本和资源命名方式。1.6 整卡训练 Pod 配置yaml# training-pod-whole-card.yaml # 作用申请 GPU 和整张高网网卡用于训练任务 apiVersion: v1 kind: Pod metadata: name: training-pod spec: containers: - name: training image: nvcr.io/nvidia/pytorch:24.04-py3 resources: limits: # 申请 8 张 GPU nvidia.com/gpu: 8 # 申请 1 张高网 RDMA 网卡 # 如果 RDMA Device Plugin 注册的资源名是 rdma/rdma_hca就写这个 rdma/rdma_hca: 1 securityContext: capabilities: add: # RDMA 需要锁定内存所以加 IPC_LOCK - IPC_LOCK # 部分高网/RDMA 场景可能需要更多系统资源 - SYS_RESOURCE env: # 不禁用 InfiniBand允许 NCCL 使用高网 RDMA - name: NCCL_IB_DISABLE value: 0 # 开启 GPUDirect RDMA让 GPU 直接和网卡通信减少 CPU 中转 - name: NCCL_NET_GDR_LEVEL value: 5 # 指定使用 Mellanox 网卡驱动 - name: NCCL_IB_HCA value: mlx5 # 普通管理通信走 eth0 - name: NCCL_SOCKET_IFNAME value: eth0 volumeMounts: - name: dshm mountPath: /dev/shm volumes: - name: dshm emptyDir: # 共享内存多进程训练通信常用 medium: Memory sizeLimit: 8Gi执行bashkubectl apply -f training-pod-whole-card.yaml1.7 整卡模式调度原理textPod 申请 nvidia.com/gpu: 8 rdma/rdma_hca: 1 K8S 调度器检查每个节点 节点 AGPU 8 张RDMA 网卡 2 张 → 满足 节点 BGPU 4 张RDMA 网卡 2 张 → 不满足 节点 CGPU 8 张RDMA 网卡 0 张 → 不满足 结果 Pod 被调度到节点 A整卡模式下Pod 拿到的是完整的一张物理网卡。二、切分搭配GPU SR-IOV 高网虚拟网卡2.1 适用场景一张高网网卡带宽很大不想只给一个 Pod 用希望把一张物理网卡切成多个 VF多个 Pod 各自使用一个或多个 VF提高网卡利用率2.2 整体流程text节点 BIOS 开启 SR-IOV 和 IOMMU/VT-d ↓ 节点安装高网网卡驱动 ↓ 集群部署 SR-IOV Network Operator ↓ 集群部署 Multus CNI ↓ 写 SriovNetworkNodePolicy定义怎么切 VF ↓ config-daemon 在节点上创建 VF ↓ SR-IOV Device Plugin 把 VF 注册成 K8S 资源 ↓ 写 SriovNetwork定义虚拟网络名和 IP 分配 ↓ Pod 里申请 GPU 和 SR-IOV 资源并挂载虚拟网络2.3 节点前置条件每台节点需要完成text1. BIOS 开启 SR-IOV 2. BIOS 开启 IOMMU - Intel 平台通常是 VT-d - AMD 平台通常是 AMD-Vi 3. 安装高网网卡驱动 4. 确认物理网卡支持 SR-IOV 5. 确认节点可以创建 VF2.4 SR-IOV Network OperatorSR-IOV Network Operator 是总控组件负责把配置下发到各个节点。它通常包含这些能力text1. 接收 SriovNetworkNodePolicy 2. 把切分策略下发到对应节点 3. 节点上的 config-daemon 执行 VF 创建 4. SR-IOV Device Plugin 把 VF 注册为 K8S 资源 5. SriovNetwork 定义 Pod 怎么挂载虚拟网卡Operator 本身的安装方式取决于你的集群版本例如原生 K8S、OpenShift、ACK 等会有不同安装方式。这里重点是配置对象不是具体安装包。2.5 SriovNetworkNodePolicy 配置这个配置的作用是告诉系统哪张物理网卡切成几个 VF是否开启 RDMA资源名叫什么。yaml# sriov-network-node-policy.yaml # 作用定义物理高网网卡如何切分成多个 VF apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodePolicy metadata: name: highnet-sriov-policy namespace: sriov-network-operator spec: # K8S 中申请 SR-IOV 虚拟网卡时使用的资源名 # Pod 里会用这个名字申请虚拟网卡 resourceName: sriov_highnet # 选择哪些节点生效 # 这里表示只在标签为 highnet-nodetrue 的节点上生效 nodeSelector: highnet-node: true # 选择哪张物理网卡 nicSelector: # 网卡厂商 IDMellanox/NVIDIA 通常是 15b3 vendor: 15b3 # 物理网卡名称根据实际节点网卡名填写 pfNames: - ens1f0 # 把这张物理网卡切成多少个 VF # 例如 8 表示切出 8 个虚拟网卡 numVfs: 8 # 驱动类型 # netdevice普通内核网卡模式 # vfio-pci用户态直通模式适合 DPDK 等场景 deviceType: netdevice # 是否开启 RDMA # true 表示 VF 支持 RDMA 高网通信 isRdma: true # 网卡 MTU # 高网/RDMA 场景有时会调大 MTU mtu: 1500 # 策略优先级 # 数值越小优先级越高 priority: 90执行bashkubectl apply -f sriov-network-node-policy.yaml执行后SR-IOV Network Operator 会把策略下发到符合条件的节点。2.6 Policy 执行后自动完成的事情你执行完kubectl apply后不需要手动切网卡。自动流程如下textSriovNetworkNodePolicy 被提交到 K8S ↓ SR-IOV Network Operator 发现策略 ↓ config-daemon 在目标节点执行 - 找到物理网卡 ens1f0 - 创建 8 个 VF - 绑定对应驱动 - 开启 RDMA ↓ SR-IOV Device Plugin 扫描到 VF ↓ 把 VF 注册为 K8S 资源 sriov_highnet 8验证思路bash# 查看节点资源 kubectl describe node 节点名如果配置成功节点资源里会出现类似textsriov_highnet: 82.7 SriovNetwork 配置这个配置的作用是定义一个虚拟网络名Pod 通过这个网络名挂载 SR-IOV 虚拟网卡。yaml# sriov-network.yaml # 作用定义 SR-IOV 虚拟网络供 Pod 挂载使用 apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetwork metadata: name: highnet-rdma-network namespace: sriov-network-operator spec: # 关联前面 Policy 定义的资源名 resourceName: sriov_highnet # 这个虚拟网络在哪个命名空间可用 networkNamespace: default # IP 地址分配配置 ipam: | { type: host-local, subnet: 192.168.100.0/24 }执行bashkubectl apply -f sriov-network.yaml执行后Pod 里就可以通过texthighnet-rdma-network这个网络名挂载 SR-IOV 虚拟网卡。2.8 切分模式训练 Pod 配置yaml# training-pod-sriov.yaml # 作用申请 GPU 和 SR-IOV 高网虚拟网卡 apiVersion: v1 kind: Pod metadata: name: training-pod-sriov annotations: # 告诉 Multus 给 Pod 挂载 SR-IOV 虚拟网络 k8s.v1.cni.cncf.io/networks: highnet-rdma-network spec: containers: - name: training image: nvcr.io/nvidia/pytorch:24.04-py3 resources: limits: # 申请 8 张 GPU nvidia.com/gpu: 8 # 申请 1 个 SR-IOV 虚拟网卡 sriov_highnet: 1 securityContext: capabilities: add: # RDMA 需要锁定内存 - IPC_LOCK - SYS_RESOURCE env: # 允许 NCCL 使用 InfiniBand/RDMA 高网 - name: NCCL_IB_DISABLE value: 0 # 开启 GPUDirect RDMA - name: NCCL_NET_GDR_LEVEL value: 5 # 指定 Mellanox 网卡驱动 - name: NCCL_IB_HCA value: mlx5 # 管理网通信走 eth0 - name: NCCL_SOCKET_IFNAME value: eth0 volumeMounts: - name: dshm mountPath: /dev/shm volumes: - name: dshm emptyDir: medium: Memory sizeLimit: 8Gi执行bashkubectl apply -f training-pod-sriov.yaml2.9 切分模式调度原理text物理网卡 ens1f0 切成 8 个 VF VF0 VF1 VF2 VF3 VF4 VF5 VF6 VF7 SR-IOV Device Plugin 上报 节点 Asriov_highnet 8 Pod A 申请 nvidia.com/gpu: 8 sriov_highnet: 1 K8S 调度器找到节点 A GPU 满足 sriov_highnet 满足 结果 Pod A 拿到 8 张 GPU Pod A 拿到 1 个 VF例如 VF0切分模式下Pod 拿到的是一个虚拟网卡 VF不是整张物理网卡。三、两种模式对比表格对比项整卡搭配SR-IOV 切分搭配网卡使用方式Pod 使用整张物理网卡Pod 使用物理网卡切出的 VF配置复杂度较低较高网卡利用率一个 Pod 占整张网卡一张网卡可分给多个 Pod隔离性物理级隔离VF 级隔离适合场景任务少、需要完整网卡任务多、希望提高网卡利用率主要资源名nvidia.com/gpu、rdma/hcanvidia.com/gpu、sriov_highnet四、执行顺序总结整卡模式执行顺序bash# 1. 节点装驱动 GPU 驱动 NVIDIA Container Toolkit 高网/RDMA 驱动 # 2. 集群部署插件 kubectl apply -f nvidia-device-plugin.yaml kubectl apply -f rdma-device-plugin-config.yaml # 3. 提交训练任务 kubectl apply -f training-pod-whole-card.yamlSR-IOV 切分模式执行顺序bash# 1. 节点 BIOS 开启 SR-IOV 和 IOMMU # 2. 节点安装高网驱动 # 3. 集群安装 SR-IOV Network Operator # 4. 集群安装 Multus CNI # 5. 配置切分策略 kubectl apply -f sriov-network-node-policy.yaml # 6. 配置虚拟网络 kubectl apply -f sriov-network.yaml # 7. 提交训练任务 kubectl apply -f training-pod-sriov.yaml一句话理解整卡模式是“一个 Pod 用一张完整高网网卡”SR-IOV 切分模式是“一张高网网卡切成多个 VF多个 Pod 分别用”。GPU 始终通过nvidia.com/gpu申请高网通过 RDMA 插件或 SR-IOV 插件暴露给 K8SPod 里同时申请 GPU 和高网资源K8S 调度器负责把它们分配到同一台节点上。
返回列表