第 13 章 硬件网络
13.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 集群上安装在裸机或 Red Hat OpenStack Platform(RHOSP)基础架构上安装的额外网络一起使用,用于需要高带宽或低延迟的应用程序。
您可以使用以下命令在节点上启用 SR-IOV:
$ oc label node <node_name> feature.node.kubernetes.io/network-sriov.capable="true"
13.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 网络资源注入程序仅将
resource
字段添加到 pod 中的第一个容器。 - SR-IOV 网络设备插件
- 这个设备插件用于发现、公告并分配 SR-IOV 网络虚拟功能 (VF) 资源。在 Kubernetes 中使用设备插件能够利用有限的资源,这些资源通常为于物理设备中。设备插件可以使 Kubernetes 调度程序了解资源可用性,因此调度程序可以在具有足够资源的节点上调度 pod。
- SR-IOV CNI 插件
- SR-IOV CNI 插件会附加从 SR-IOV 设备插件中直接分配给 pod 的 VF 接口。
- SR-IOV InfiniBand CNI 插件
- 附加从 SR-IOV 设备插件中直接分配给 pod 的 InfiniBand(IB)VF 接口的 CNI 插件。
SR-IOV Network resources injector 和 SR-IOV Operator Webhook 会被默认启用,可通过编辑 default
SriovOperatorConfig
CR 来禁用。
13.1.1.1. 支持的平台
SR-IOV Network Operator 在以下平台上受支持:
- 裸机
- Red Hat OpenStack Platform (RHOSP)
13.1.1.2. 支持的设备
OpenShift Container Platform 支持以下网络接口控制器:
制造商 | Model | 供应商 ID | 设备 ID |
---|---|---|---|
Intel | X710 | 8086 | 1572 |
Intel | XXV710 | 8086 | 158b |
Mellanox | MT27700 系列 [ConnectX-4] | 15b3 | 1013 |
Mellanox | MT27710 系列 [ConnectX-4 Lx] | 15b3 | 1015 |
Mellanox | MT27800 系列 [ConnectX-5] | 15b3 | 1017 |
Mellanox | MT28908 系列 [ConnectX-6] | 15b3 | 101b |
13.1.1.3. 自动发现 SR-IOV 网络设备
SR-IOV Network Operator 将搜索集群以获取 worker 节点上的 SR-IOV 功能网络设备。Operator 会为每个提供兼容 SR-IOV 网络设备的 worker 节点创建并更新一个 SriovNetworkNodeState 自定义资源 (CR) 。
为 CR 分配了与 worker 节点相同的名称。status.interfaces
列表提供有关节点上网络设备的信息。
不要修改 SriovNetworkNodeState
对象。Operator 会自动创建和管理这些资源。
13.1.1.3.1. SriovNetworkNodeState 对象示例
以下 YAML 是由 SR-IOV Network Operator 创建的 SriovNetworkNodeState
对象的示例:
一 个 SriovNetworkNodeState 对象
apiVersion: sriovnetwork.openshift.io/v1 kind: SriovNetworkNodeState metadata: name: node-25 1 namespace: openshift-sriov-network-operator ownerReferences: - apiVersion: sriovnetwork.openshift.io/v1 blockOwnerDeletion: true controller: true kind: SriovNetworkNodePolicy name: default spec: dpConfigVersion: "39824" status: interfaces: 2 - deviceID: "1017" driver: mlx5_core mtu: 1500 name: ens785f0 pciAddress: "0000:18:00.0" totalvfs: 8 vendor: 15b3 - deviceID: "1017" driver: mlx5_core mtu: 1500 name: ens785f1 pciAddress: "0000:18:00.1" totalvfs: 8 vendor: 15b3 - deviceID: 158b driver: i40e mtu: 1500 name: ens817f0 pciAddress: 0000:81:00.0 totalvfs: 64 vendor: "8086" - deviceID: 158b driver: i40e mtu: 1500 name: ens817f1 pciAddress: 0000:81:00.1 totalvfs: 64 vendor: "8086" - deviceID: 158b driver: i40e mtu: 1500 name: ens803f0 pciAddress: 0000:86:00.0 totalvfs: 64 vendor: "8086" syncStatus: Succeeded
13.1.1.4. 在 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: runAsUser: 0 capabilities: add: ["IPC_LOCK","SYS_RESOURCE","NET_RAW"] 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: runAsUser: 0 capabilities: add: ["IPC_LOCK","SYS_RESOURCE","NET_RAW"] 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
13.1.1.5. 用于容器应用程序的 DPDK 库
一个可选的库 app-netutil
提供了几个 API 方法,用于从该 pod 中运行的容器内收集 pod 的网络信息。
此库旨在帮助将 SR-IOV 虚拟功能(VF)集成到 Data Plane Development Kit(DPDK)模式中。该程序库提供 Golang API 和 C API。
当前,采用 3 个 API 方法:
GetCPUInfo()
- 此函数决定了哪些 CPU 可供容器使用,并将列表返回给调用者。
GetHugepages()
此函数决定了每个容器在
Pod
spec 中请求的巨页内存量,并将值返回给调用者。注意通过 Kubernetes Downward API 公开巨页是 Kubernetes 1.20 中的一个 alpha 功能,在 OpenShift Container Platform 中不启用。您可以通过在 Kubernetes 1.20 或更高版本中启用功能门
FEATURE_GATES="DownwardAPIHugePages=true"
来测试 API。GetInterfaces()
- 此函数决定了容器中的一组接口,并返回列表,以及接口类型和类型特定数据。
还有一个 Docker 镜像示例 dpdk-app-centos
,它可以根据 pod-spec: l2fwd
、l3wd
或 testpmd
中的环境变量运行以下 DPDK 示例应用程序之一。这个 Docker 镜像提供了一个将 app-netutil
整合到容器镜像本身的示例。该程序库也可以整合到 init-container
中,该容器收集所需数据并将数据传递给现有的 DPDK 工作负载。
13.1.2. 后续步骤
- 配置 SR-IOV Network Operator
- 可选: 配置 SR-IOV Network Operator
- 配置 SR-IOV 网络设备
- 如果使用 OpenShift Virtualization: 为虚拟机配置 SR-IOV 网络设备
- 配置 SR-IOV 网络附加
- 将 pod 添加到额外网络