vf需经sr-iov插件注册为扩展资源(如intel.com/sriov_net_0),pod须声明该资源、挂载/dev/vfio、启用特权或特定capabilities,并绕过cni直接通过hostnetwork/loadbalancer接入流量。

VF 设备怎么被 Pod 正确识别并挂载
DPDK 应用在容器里跑不起来,八成卡在 VF 没进到 Pod 里。Kubernetes 默认不把 SR-IOV 设备当“可调度资源”处理,vfio-pci 驱动加载后,VF 只是 Linux 设备树里的一个节点,K8s 完全看不见。
必须靠 SR-IOV Network Device Plugin(官方维护的 k8s-sriov-network-device-plugin)把 VF 注册成扩展资源,比如 intel.com/sriov_net_0。它会扫描 /sys/class/net/ 下绑定 vfio-pci 的 VF 接口,生成节点标签和资源名。
- 确保 VF 已用
echo "vfio-pci" > /sys/bus/pci/devices/0000:xx:yy.z/driver_override并bind到vfio-pci,否则插件直接跳过 - 插件 DaemonSet 必须用
hostNetwork: true,否则无法访问宿主机 PCI 设备路径 - Pod 的
resources.limits["intel.com/sriov_net_0"]值必须为1(不能是"1"字符串),否则调度失败且无明确报错
DPDK 应用启动时找不到 VF PCI 地址
即使 VF 进了 Pod,dpdk-devbind.py -s 看不到设备,或 rte_eal_init() 报 EAL: Couldn't get fd on hugepage file 或 No probed devices,本质是容器没拿到 VF 的 PCI 设备节点和 IOMMU 组权限。
VF 不是普通网卡——它需要完整的 PCI 设备文件(/dev/vfio/xxx)+ hugepage + udev 规则 + cgroup device 白名单,缺一不可。
- Pod spec 中必须显式挂载
/dev/vfio目录:volumeMounts: [{name: vfio, mountPath: /dev/vfio}],对应volumes: [{name: vfio, hostPath: {path: /dev/vfio}}] - 启用
securityContext.privileged: true(DPDK 早期版本绕不开);若用较新 DPDK(22.11+)且内核支持,可改用capabilities: {add: ["SYS_ADMIN", "IPC_LOCK"]}+ 显式device_cgroup_rules - 确保宿主机已开启 IOMMU(
intel_iommu=on或amd_iommu=on),且vfio-pci在 initramfs 里加载(否则重启后 VF 绑定丢失)
Kubernetes Service 和 CNI 怎么绕过 VF 流量
VF 被 Pod 独占后,传统 CNI(如 Calico、Cilium)的 veth pair、iptables、eBPF 转发全部失效。Service ClusterIP 流量不会自动进入 VF,更不会被 DPDK 应用收到。
这不是配置问题,是架构冲突:DPDK 绕过内核协议栈,而 K8s Service 依赖内核 netfilter。想让外部流量进 VF,只能走外部负载均衡或 HostPort + 物理网络直通。
- 不要给 DPDK Pod 配
service: ClusterIP,它根本收不到请求;可用type: LoadBalancer并配合 MetalLB 或硬件 LB 将流量导向宿主机物理端口 - 若需同节点其他 Pod 访问该 DPDK 服务,必须走 HostNetwork + NodePort,并在宿主机上用
iptables DNAT把目标端口映射到 VF 绑定的物理 IP(注意:不是容器 IP) - CNI 插件如
multus可为 Pod 添加第二接口(例如 macvlan 到 VF 所在物理网卡),但该接口仍需 DPDK 应用自己调用rte_eth_dev_start()启用,CNI 不参与数据面
VF 数量变化时 Pod 调度失败却没提示
宿主机上增删 VF(echo 4 > /sys/class/net/enp1s0f0/device/sriov_numvfs)后,kubectl describe node 里 intel.com/sriov_net_0 的 Allocatable 数没更新,旧 Pod 可能卡在 Pending,新 Pod 调度失败但事件里只显示 “0/1 nodes are available”,完全不提 SR-IOV 资源不足。
因为 Device Plugin 不监听 sysfs 变化,只在启动时扫描一次。手动触发重发现必须删掉插件的 DaemonSet 再重装,或者用它的 rescan 接口(如果启用了 HTTP endpoint)。
- 上线前务必固定 VF 数量,避免运行时调整;生产环境建议用
modprobe.conf设置options ixgbe max_vfs=4等参数固化 - 检查 Device Plugin 日志:
kubectl logs -n kube-system ds/sriov-network-device-plugin -c sriov-network-device-plugin | grep -i "found.*vf",确认实际发现数量 - 别依赖
kubectl top node查 SR-IOV 资源,它只显示 CPU/Mem;要用kubectl describe node看Capacity和Allocatable下的自定义资源行
VF 生命周期和内核驱动状态强耦合,任何一步绑定失败都不会抛出清晰错误,而是静默降级到普通网卡模式——这时候 DPDK 应用可能还在跑,但早已不在预期的数据路径上。










