第 24 章 硬件网络

24.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 驱动程序: 挂载到容器中的字符设备

对于需要高带宽或低延迟的应用程序,您可以在裸机或 Red Hat OpenStack Platform(RHOSP)基础架构上安装 OpenShift Container Platform 集群上的额外网络使用 SR-IOV 网络设备。

您可以为 SR-IOV 网络配置多网络策略。对这个功能的支持是技术预览,SR-IOV 额外网络只支持内核 NIC。它们不支持 Data Plane Development Kit (DPDK) 应用程序。

注意

与 SR-IOV 网络相比,在 SR-IOV 网络中创建多网络策略可能无法为应用程序提供相同的性能。

重要

SR-IOV 网络的多网络策略只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

您可以使用以下命令在节点上启用 SR-IOV:

$ oc label node <node_name> feature.node.kubernetes.io/network-sriov.capable="true"

24.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 Network Operator 启动时部署在 worker 节点上的守护进程集。守护进程负责在集群中发现和初始化 SR-IOV 网络设备。
SR-IOV Network 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 来禁用。禁用 SR-IOV Network Operator Admission Controller Webhook 时要小心。您可以在特定情况下禁用 webhook,如故障排除,或者想要使用不支持的设备。

24.1.1.1. 支持的平台

在以下平台上支持 SR-IOV Network Operator:

  • 裸机
  • Red Hat OpenStack Platform(RHOSP)

24.1.1.2. 支持的设备

OpenShift Container Platform 支持以下网络接口控制器:

表 24.1. 支持的网络接口控制器

制造商model供应商 ID设备 ID

Broadcom

BCM57414

14e4

16d7

Broadcom

BCM57508

14e4

1750

Broadcom

BCM57504

14e4

1751

Intel

X710

8086

1572

Intel

XL710

8086

1583

Intel

X710 基本 T

8086

15ff

Intel

XXV710

8086

158b

Intel

E810-CQDA2

8086

1592

Intel

E810-2CQDA2

8086

1592

Intel

E810-XXVDA2

8086

159b

Intel

E810-XXVDA4

8086

1593

Mellanox

MT27700 系列 [ConnectX-4]

15b3

1013

Mellanox

MT27710 系列 [ConnectX-4 Lx]

15b3

1015

Mellanox

MT27800 系列 [ConnectX-5]

15b3

1017

Mellanox

MT28880 系列 [ConnectX-5 Ex]

15b3

1019

Mellanox

MT28908 系列 [ConnectX-6]

15b3

101b

Mellanox

MT2892 Family [ConnectX‑6 Dx]

15b3

101d

Mellanox

MT2894 Family [ConnectX‑6 Lx]

15b3

101f

Mellanox

ConnectX-6 NIC 模式中的 MT42822 BlueField-2

15b3

a2d6

Pensando [1]

用于 ionic 驱动程序的 DSC-25 双端口 25G 分布式服务卡

0x1dd8

0x1002

Pensando [1]

用于 ionic 驱动程序的 DSC-100 双端口 100G 分布式服务卡

0x1dd8

0x1003

Silicom

STS 系列

8086

1591

  1. 支持 OpenShift SR-IOV,但在使用 SR-IOV 时,您必须使用 SR-IOV CNI 配置文件设置静态的虚拟功能(VF)介质访问控制(MAC)地址。
注意

有关支持的卡和兼容的 OpenShift Container Platform 版本的最新列表,请参阅 Openshift Single Root I/O Virtualization(SR-IOV)和 PTP 硬件网络支持列表

24.1.1.3. 自动发现 SR-IOV 网络设备

SR-IOV Network Operator 将搜索集群以获取 worker 节点上的 SR-IOV 功能网络设备。Operator 会为每个提供兼容 SR-IOV 网络设备的 worker 节点创建并更新一个 SriovNetworkNodeState 自定义资源 (CR) 。

为 CR 分配了与 worker 节点相同的名称。status.interfaces 列表提供有关节点上网络设备的信息。

重要

不要修改 SriovNetworkNodeState 对象。Operator 会自动创建和管理这些资源。

24.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

1
name 字段的值与 worker 节点的名称相同。
2
interfaces 小节包括 Operator 在 worker 节点上发现的所有 SR-IOV 设备列表。

24.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

24.1.1.5. 用于容器应用程序的 DPDK 库

一个可选的库 app-netutil 提供了几个 API 方法,用于从该 pod 中运行的容器内收集 pod 的网络信息。

此库可以将 SR-IOV 虚拟功能(VF)集成到 Data Plane Development Kit(DPDK)模式中。该程序库提供 Golang API 和 C API。

当前,采用三个 API 方法:

GetCPUInfo()
此函数决定了哪些 CPU 可供容器使用并返回相关列表。
GetHugepages()
此函数决定了每个容器在 Pod spec 中请求的巨页内存量并返回相应的值。
GetInterfaces()
此函数决定了容器中的一组接口,并返回相关的列表。返回值包括每个接口的接口类型和特定于类型的数据。

库的存储库包括用于构建容器镜像 dpdk-app-centos 的示例 Dockerfile。根据 pod 规格中的环境变量,容器镜像可以运行以下 DPDK 示例应用程序之一:l2fwd, l3wdtestpmd。容器镜像提供了一个将 app-netutil 库集成到容器镜像本身的示例。库也可以集成到 init 容器中。init 容器可以收集所需的数据,并将数据传递给现有的 DPDK 工作负载。

24.1.1.6. Downward API 的巨页资源注入

当 pod 规格包含巨页的资源请求或限制时,Network Resources Injector 会自动在 pod 规格中添加 Downward API 字段,以便为容器提供巨页信息。

Network Resources Injector 添加一个名为 podnetinfo 的卷,并挂载到 pod 中的每个容器的 /etc/podnetinfo。卷使用 Downward API,并包含一个用于大页面请求和限制的文件。文件命名规则如下:

  • /etc/podnetinfo/hugepages_1G_request_<container-name>
  • /etc/podnetinfo/hugepages_1G_limit_<container-name>
  • /etc/podnetinfo/hugepages_2M_request_<container-name>
  • /etc/podnetinfo/hugepages_2M_limit_<container-name>

上一个列表中指定的路径与 app-netutil 库兼容。默认情况下,库配置为搜索 /etc/podnetinfo 目录中的资源信息。如果您选择自己手动指定 Downward API 路径项目,app-netutil 库除上列表中的路径外还会搜索以下路径。

  • /etc/podnetinfo/hugepages_request
  • /etc/podnetinfo/hugepages_limit
  • /etc/podnetinfo/hugepages_1G_request
  • /etc/podnetinfo/hugepages_1G_limit
  • /etc/podnetinfo/hugepages_2M_request
  • /etc/podnetinfo/hugepages_2M_limit

与 Network Resources Injector 可以创建的路径一样,以上列表中的路径可以选择以一个 _<container-name> 后缀结尾。

24.1.2. 其他资源

24.1.3. 后续步骤