惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
I
InfoQ
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
博客园 - Franky
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园_首页
罗磊的独立博客
V
V2EX
李成银的技术随笔
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
True Tiger Recordings
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
F
Fox-IT International blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
M
Microsoft Research Blog - Microsoft Research
Know Your Adversary
Know Your Adversary
爱范儿
爱范儿
The Register - Security
The Register - Security
G
Google Developers Blog
The Hacker News
The Hacker News
Malwarebytes
Malwarebytes
S
Securelist
博客园 - 三生石上(FineUI控件)
Jina AI
Jina AI
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
博客园 - 叶小钗
F
Fortinet All Blogs
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
博客园 - 聂微东
T
Threatpost
博客园 - 【当耐特】
D
Docker
P
Privacy & Cybersecurity Law Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
G
GRAHAM CLULEY
V
Visual Studio Blog
C
Cisco Blogs
IT之家
IT之家
S
Security Archives - TechRepublic
Latest news
Latest news
阮一峰的网络日志
阮一峰的网络日志

陈少文的网站

容器化部署 Hermes Agent 部署 JuiceFS CSI Driver 使用 A2A Gateway 打通多 OpenClaw Loggie 部署与配置 OpenClaw 运维 - 让飞轮转起来 你也可以这样落地 AI Agent - SOPS 篇 AGFS 文件系统性能测试 面向 AI Agent 的文件系统 - AGFS OpenViking 使用与 OpenClaw 集成 如何远程给OpenClaw发送消息 容器化部署 OpenClaw 使用 Skills 和 MCP 扩展 OpenClaw OpenClaw 安装与配置 LVM 日常运维 MinIO 基础设施选型与优化 容器部署 ClickHouse 容器化部署 Redis 容器部署中间件 容器部署多节点 FoundationDB 及运维 使用 HAProxy 代理 MinIO 及性能测试 多机多盘 MinIO 集群在不同纠删码配置下的性能测试 多机多盘 minio 集群不同纠删码配置在 IPoIB 下的性能测试 MinIO 多节点多盘部署与运维 Cursor 之下,何以立足 你也可以这样落地 AI Agent - MCP 篇 阿里云 eRDMA 测试及 PD 分离应用部署 你也可以这样落地 AI Agent - 运维事件篇 常见的几种 LLM Agent 架构 你也可以这样落地 AI Agent - 案例篇 ext4、xfs、zfs、btrfs 在 RAID6 下的性能测试 RAID 下 ZFS 运维操作 RAID 下 XFS 运维操作 RAID 下 Btrfs 运维操作 xfs 在各种 RAID 下的性能测试 RAID 存储技术 使用 LLaMA-Factory 微调 Qwen3 模型 vLLM 部署 PD 分离应用 使用 lmcache 能显著改善模型推理的 TTFT 什么是 Prefix Cache NVIDIA RTX 5090 推理测试 什么是模型量化 Kubernetes 基础环境要求 如何升级 Kubernetes 节点的 cgroup 版本 在服务器上使用 claude-code 常用 NPU 运维及故障处理 NVIDIA DCGM 使用指南 如何清理僵尸进程 使用 VLLM Benchmark 进行模型性能测试 眼看他拔地起,眼看他化作泥 - KubeSphere 在 Kubernetes 集群部署 Dragonfly history 命令使用 AI 相关论文 在服务器上使用 Gemini CLI Ascend DMI 工具使用指南 Kubernetes 下开源的 GPU 虚拟化项目 FoundationDB 数据备份与恢复 认知觉醒 给 Node Exporter 添加抓取凭证 部署 smokeping-prober 探测网络质量 Opscli 支持 MCP 提供 Cline\Cursor 集成 kube-proxy 异常导致节点上的 Pod 无法访问 Service 为什么 NFS Over RDMA 比 NFS 的 FIO 大块读性能好很多 3FS 关键技术和设计 DeepSeek 3FS 运维指南 容器化部署 DeepSeek 3FS 存储系统 3FS 的一些性能测试 在 Kubernetes 中使用 Fluid 挂载 3FS 存储及性能测试 NFS Over RDMA kubectl logs 无法查看 Pod 日志报错 NotFound 使用 Dante 提供 SOCKS5 转发 使用 Calico 限制 Pod 的带宽 分布式计算框架 Ray 以 Qwen 为例,学习大模型的结构 NVIDIA 环境变量配置 Ascend 环境变量配置 Fluid 下的 Juicefs 企业版维护 使用 vLLM 进行模型推理 使用 Nerdctl 构建多架构镜像 使用 vLLM 应用验证推理节点 AI 应用开发技术栈 在 Kubernetes 部署 Jumpserver 跳板机 使用 Ops 项目查看并监控集群事件 使用 Fluid 和 S3FS 对接 S3 存储及性能测试 使用 Fluid 对接 S3 存储及性能测试 使用 TensorBoard 可视化 PyTorch 训练过程 使用 PyTorch 在 MNIST 数据集训练模型 Ubuntu 切换指定版本的内核 MPI 通信原语及 Python 编程使用 Ops 发布 v1.0.0 版本 常见的几种网络拓扑结构 RDMA 技术 InfiniBand 网络及常用命令 使用 Fluid 对接 OBS 存储及性能测试 使用 Iceberg 和 Spark 在 Kubernetes 上处理数据 GPU 主机如何开启 GDS 什么是 Token 什么是 FLOPs 什么是 PD 分离 Kubernetes 下的 DLRover 工作流程分析 NVIDIA GPU 核心与架构演进史
SR-IOV 技术
2024-11-03 · via 陈少文的网站

1. 什么是 SR-IOV 技术

SR-IOV(Single Root I/O Virtualization)是一种虚拟化技术,它允许虚拟机、容器直接访问物理硬件资源,从而提高 I/O 性能,还能减少主机 CPU 消耗。

如上图,SR-IOV 将单个物理设备(例如网络接口卡,NIC)划分成多个虚拟功能 (Virtual Functions, VFs),每个 VF 可以被分配给不同的虚拟机或容器,像独立的设备一样使用。

2. 开启 SR-IOV 软件硬件支持

在开机时按下 Del 或 F2 等键进入 BIOS 设置界面,相关的配置通常在 Advanced \ System Configuration \ Virtualization 中。

  • 开启 VT-d

VT-d 是定向 I/O 虚拟化技术,俗称虚拟化直通技术。允许宿主机将某些硬件资源(比如硬盘、显卡、网卡)的管辖权直接移交给虚拟机。

  • 开启 SR-IOV

SR-IOV(Single Root I/O Virtualization)是一种 PCIe 设备虚拟化技术,它允许将单个物理 PCIe 设备(如网卡)划分为多个虚拟功能(VF)。

  • 开启 IOMMU

开启 IOMMU 后,系统能够为每个虚拟机分配独立的设备地址空间,提供设备的内存隔离和保护,防止虚拟机之间发生内存地址冲突。

  • 系统设置

编辑 Grub 配置

1
vim /etc/default/grub

GRUB_CMDLINE_LINUX 中添加 intel_iommu=on iommu=pt

生成 Grub 配置

1
grub-mkconfig -o /boot/grub/grub.cfg

重启系统

1
reboot

查看是否开启 IOMMU

1
dmesg | grep -e DMAR -e IOMMU

3. 查看本地网络设备

  • 查看 SR-IOV 设备
1
2
3
4
5
6
7
lspci -v | grep -i SR-IOV

        Capabilities: [bcc] Single Root I/O Virtualization (SR-IOV)
        Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
        Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
        Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
        Capabilities: [160] Single Root I/O Virtualization (SR-IOV)

这其中 1 个 [bcc] 是 NVIDIA 显卡的 SR-IOV 设备,剩下的 4 个 [160] 是 Intel 网卡。

3.1 查看网卡

  • 列出网卡
1
2
3
ls /sys/class/net/

eth0          eth1          bond1          lo        calixxx      ...

其中,ethX 是真实的物理网卡,bondX 是网络绑定 (bonding) 接口,lo 是本机的 loopback 网络接口,calixxx 是网络插件 Calico 为容器提供的网络接口.

网络绑定是一种将多个物理网络接口组合为一个逻辑接口的方法。

  • 查看 bond 绑定的网卡
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
cat /proc/net/bonding/bond1

Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
...

Slave Interface: eth5
MII Status: up
Speed: 10000 Mbps
...

Slave Interface: eth4
MII Status: up
Speed: 10000 Mbps
...

这意味着,bond1 绑定了两个 eth5 和 eth4 网卡,聚合成一个虚拟网卡提供 20 Gbps 的带宽。

3.2 创建 SR-IOV VF

SR-IOV 针对的是物理网卡,不能针对 bond 绑定的网卡,而要使用 ethX 网卡。

  • 查看之前是否已经开启 SR-IOV
1
2
3
cat /sys/class/net/eth0/device/sriov_numvfs

0
  • 开启 SR-IOV
1
echo 2 > /sys/class/net/eth0/device/sriov_numvfs
  • 查看 VF
1
2
3
4
lspci | grep Virtual

3d:02.0 Ethernet controller: Intel Corporation Ethernet Virtual Function 700 Series (rev 09)
3d:02.1 Ethernet controller: Intel Corporation Ethernet Virtual Function 700 Series (rev 09)

这样就给网卡创建了 2 个 SR-IOV VF。

  • 查看网卡
1
2
3
4
5
6
7
ip link show eth0

4: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 90:f7:b2:4b:dc:3d brd ff:ff:ff:ff:ff:ff
    vf 0     link/ether 2e:3a:41:bc:02:cc brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off
    vf 1     link/ether 5a:d4:e4:45:83:7b brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off
    altname enp61s0f0

3.3 删除 SR-IOV VF

1
echo 0 > /sys/class/net/eth0/device/sriov_numvfs

4 K8s 下使用 SR-IOV

4.1 Pod 中如何使用 SR-IOV

SR-IOV 设备的 VF 资源在 Pod 中是无法被直接访问的,需要基于 Kubernetes 的资源扩展方式实现对 VF 的管理。

如果需要卸载,请同时删除节点下的 /etc/cni/net.d/*multus* 文件,否则会导致 Pod 无法创建。

4.2 创建 multus

安装 kube-multus 之后,一个 Pod 可以使用多个网卡。

1
kubectl apply -f https://raw.githubusercontent.com/shaowenchen/ops-hub/refs/heads/master/network/kube-multus.yml

4.3 安装 SR-IOV CNI

安装 kube-sriov-cni 之后,创建 Pod 网络时,可以调用 SR-IOV CNI 挂载 VF 资源。

1
kubectl apply -f https://raw.githubusercontent.com/shaowenchen/ops-hub/master/network/kube-sriov-cni.yaml

4.4 安装 SR-IOV 设备插件

安装 sriov-network-device-plugin 之后,创建 Pod 时,Kublet 会通过 GRPC 与 sriov-network-device-plugin 交互来给 Pod 分配 SR-IOV VF。

1
kubectl apply -f https://raw.githubusercontent.com/shaowenchen/ops-hub/refs/heads/master/network/kube-sriov-device-plugin.yaml

4.5 配置可用的 SR-IOV VF

  • 查看网卡
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
ethtool -i eth0

driver: i40e # 驱动
version: 2.25.7
firmware-version: 4.10 0x80001a63 1.2585.0
expansion-rom-version:
bus-info: 0000:3d:00.0 # PCI 地址
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes
  • 确认支持 SR-IOV
1
2
3
lspci -s 0000:3d:00.0 -v | grep SR-IOV

        Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
  • 查看厂商、设备 ID
1
2
3
lspci -s 0000:3d:00.0 -n

3d:00.0 0200: 8086:37d1 (rev 09)

这里的 8086 就是厂商 ID,37d1 就是设备 ID。

1
kubectl -n kube-system edit cm sriovdp-config
1
2
3
4
5
6
7
8
        {
            "resourceName": "eth0",
            "selectors": {
                "drivers": ["i40e"],
                "vendor": ["8086"],
                "device": ["37d1"]
            }
        },
  • 查看发现的 SR-IOV 设备
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
kubectl get node bj6-a-kas-t41-01  -o json | jq '.status.allocatable'

{
  "cpu": "38",
  "ephemeral-storage": "527342541975",
  "hugepages-1Gi": "0",
  "hugepages-2Mi": "0",
  "intel.com/eth0": "2",
  "memory": "127356472Ki",
  "pods": "110",
  "tencent.com/vcuda-core": "100",
  "tencent.com/vcuda-memory": "60"
}

这里的 intel.com/eth0 就是 sirov-device-plugin 识别的 SR-IOV 设备。

4.6 配置 NetworkAttachmentDefinition

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
kubectl apply -f - <<EOF
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/resourceName: intel.com/eth0
  name: sriov-eth0
  namespace: default
spec:
  config: |
    {
        "type": "sriov",
        "cniVersion": "0.3.1",
        "name": "sriov-network",
        "ipam": {
            "type": "host-local"
        }
    }
EOF

如果 Pod 一直处于 ContainerCreating 状态,很有可能是 NetworkAttachmentDefinition 配置错误。

4.7 创建普通 Pod

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: demo-ubuntu
spec:
  containers:
  - name: demo-ubuntu
    image: shaowenchen/demo:ubuntu
    imagePullPolicy: Always
EOF

查看网卡

1
2
3
4
5
6
kubectl exec -it demo-ubuntu ip link show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: eth0@if1659: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP mode DEFAULT group default
    link/ether 52:22:5d:0c:0d:d3 brd ff:ff:ff:ff:ff:ff link-netnsid 0

4.8 创建 SR-IOV Pod

通过注解的方式,可以给 Pod 申请 SR-IOV VF。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: demo-ubuntu-sriov
  annotations:
    k8s.v1.cni.cncf.io/networks: sriov-eth0
spec:
  containers:
  - name: demo-ubuntu
    image: shaowenchen/demo:ubuntu
    imagePullPolicy: Always
    resources:
      requests:
        intel.com/eth0: '1'
      limits:
        intel.com/eth0: '1'
EOF

查看网卡

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
kubectl exec -it demo-ubuntu-sriov ip link show

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3: eth0@if1663: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP mode DEFAULT group default
    link/ether f2:32:06:2f:85:13 brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: net1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
    link/ether 90:f7:b2:4b:dc:40 brd ff:ff:ff:ff:ff:ff
    alias eth0
    altname enp61s0f0

主机上的 eth0 也是 DOWN 状态,这里出现了 net1 网卡就说明已经配置了 SR-IOV VF。

4.9 将 sriov 设置为默认网卡

需要在 kube-system 下创建 NetworkAttachmentDefinition 。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: demo-ubuntu-sriov-default
  annotations:
    v1.multus-cni.io/default-network: sriov-eth0
spec:
  containers:
  - name: demo-ubuntu
    image: shaowenchen/demo:ubuntu
    imagePullPolicy: Always
    resources:
      requests:
        intel.com/eth0: '1'
      limits:
        intel.com/eth0: '1'
EOF

5. 总结

本篇文章,介绍了 SR-IOV 技术以及在 Kubernetes 中的使用。

常用的部署方式还有 https://github.com/k8snetworkplumbingwg/sriov-network-operator ,借助 Operator 可以更快地实现 SR-IOV 与 Kubernetes 的集成。

SR-IOV 实现了对物理网卡的虚拟化、多租户使用。除了借助 sriov-network-device-plugin 实现对 VF 资源的注册,还有一种方式是 k8s-rdma-shared-dev-plugin,在我们生产的环境中,也是使用的这种方式对接 IB 网卡。