第 8 章 硬件网络
8.1. 关于单根 I/O 虚拟化(SR-IOV)硬件网络
Single Root I/O 虚拟化 (SR-IOV) 规范是针对一类 PCI 设备分配的标准,可与多个 pod 共享单个设备。
通过 SR-IOV,您可以将主机节点上识别为物理功能 (PF) 的兼容网络设备分段为多个虚拟功能 (VF)。VF 和其它网络设备一样使用。该设备的 SR-IOV 设备驱动程序决定了如何公开容器中的 VF:
-
netdevice
驱动程序: 容器netns
中的常规内核网络设备 -
vfio-pci
驱动程序: 挂载到容器中的字符设备
您可以将 SR-IOV 网络设备与 OpenShift Container Platform 集群中的其他网络搭配,用于需要高带宽或低延迟的应用程序。
8.1.1. 负责管理 SR-IOV 网络设备的组件
SR-IOV Network Operator 会创建和管理 SR-IOV 堆栈的组件。它执行以下功能:
- 编配 SR-IOV 网络设备的发现和管理
- 为 SR-IOV Container Network Interface (CNI) 生成 NetworkAttachmentDefinition 自定义资源
- 创建和更新 SR-IOV 网络设备插件的配置
- 创建节点特定 SriovNetworkNodeState 自定义资源
-
更新每个 SriovNetworkNodeState 自定义资源的
spec.interfaces
字段
Operator 置备以下组件:
- SR-IOV 网络配置守护进程
- SR-IOV Operator 启动时在 worker 节点上部署的 DaemonSet。守护进程负责在集群中发现和初始化 SR-IOV 网络设备。
- SR-IOV Operator Webhook
- 这是动态准入控制器 Webhook,用于验证 Operator 自定义资源,并为未设置的字段设置适当的默认值。
- SR-IOV Network Resources Injector(网络资源注入器)。
- 这是一个动态准入控制器 Webhook,它提供通过请求和限制为自定义网络资源(如 SR-IOV VF)应用 Kubernetes Pod 规格的功能。
- SR-IOV 网络设备插件
- 这个设备插件用于发现、公告并分配 SR-IOV 网络虚拟功能 (VF) 资源。在 Kubernetes 中使用设备插件能够利用有限的资源,这些资源通常为于物理设备中。设备插件可以使 Kubernetes 调度程序了解资源可用性,因此调度程序可以在具有足够资源的节点上调度 Pod。
- SR-IOV CNI 插件
- SR-IOV CNI 插件会附加从 SR-IOV 设备插件中直接分配给 Pod 的 VF 接口。
SR-IOV Network resources injector 和 SR-IOV Operator Webhook 会被默认启用,可通过编辑 default
SriovOperatorConfig CR 来禁用。
8.1.1.1. 支持的设备
OpenShift Container Platform 支持以下网络接口卡 (NIC) 模式:
-
Intel XXV710-DA2 25G 卡,厂商 ID
0x8086
,设备 ID0x158b
-
Mellanox MT27710 系列 [ConnectX-4 Lx] 25G 卡,厂商 ID
0x15b3
,设备 ID0x1015
-
Mellanox MT27800 系列 [ConnectX-5] 100G 卡,厂商 ID
0x15b3
,设备 ID0x1017
8.1.1.2. 在 Pod 中使用虚拟功能的示例
您可以在附加了 SR-IOV VF 的 Pod 中运行远程直接内存访问 (RDMA) 或 Data Plane Development Kit (DPDK) 应用程序。
本示例演示了在 RDMA 模式中使用虚拟功能 (VF) 的 Pod:
使用 RDMA 模式的 Pod 规格
apiVersion: v1 kind: Pod metadata: name: rdma-app annotations: k8s.v1.cni.cncf.io/networks: sriov-rdma-mlnx spec: containers: - name: testpmd image: <RDMA_image> imagePullPolicy: IfNotPresent securityContext: capabilities: add: ["IPC_LOCK"] command: ["sleep", "infinity"]
以下示例演示了在 DPDK 模式中使用 VF 的 Pod:
使用 DPDK 模式的 Pod 规格
apiVersion: v1 kind: Pod metadata: name: dpdk-app annotations: k8s.v1.cni.cncf.io/networks: sriov-dpdk-net spec: containers: - name: testpmd image: <DPDK_image> securityContext: capabilities: add: ["IPC_LOCK"] volumeMounts: - mountPath: /dev/hugepages name: hugepage resources: limits: memory: "1Gi" cpu: "2" hugepages-1Gi: "4Gi" requests: memory: "1Gi" cpu: "2" hugepages-1Gi: "4Gi" command: ["sleep", "infinity"] volumes: - name: hugepage emptyDir: medium: HugePages
可以使用一个可选的库来协助容器中运行的应用程序收集与 pod 关联的网络信息。这个程序库名为 'app-netutil'。这个库的源代码包括在 app-netutil
GitHub repo 中。
这个库的目的是简化将 SR-IOV VF 整合到 DPDK 模式中的操作。该程序库提供 GO API 和 C API,并包括了使用这两种语言的示例。
还有一个 Docker 镜像示例 'dpdk-app-centos',它可以根据 pod-spec: l2fwd 、l3wd 或 testpmd 中的环境变量运行以下 DPDK 示例应用程序之一。这个 Docker 镜像提供了将 'app-netutil' 整合到容器镜像本身的示例。这个库也可以整合到初始容器(init-container)中,该容器收集所需数据并将数据传递给现有的 DPDK 工作负载。