7.8. 为 SR-IOV 配置额外网络

重要

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

有关红帽技术预览功能支持范围的详情,请参阅 https://access.redhat.com/support/offerings/techpreview/

7.8.1. 关于 OpenShift Container Platform 中的 SR-IOV 硬件

OpenShift Container Platform 包含在节点上使用 SR-IOV 硬件的功能。您可以将 SR-IOV 虚拟功能 (VF) 接口附加到带有 SR-IOV 硬件的节点上的 Pod。

您可以通过部署 SR-IOV Network Operator,使用 OpenShift Container Platform 控制台来安装 SR-IOV。SR-IOV Network Operator 会创建和管理 SR-IOV 堆栈的组件。Operator 提供以下功能:

  • 在集群中发现 SR-IOV 网络设备。
  • 在节点上初始化支持的 SR-IOV NIC 模型。
  • 在节点上置备 SR-IOV 网络设备插件。
  • 在节点上置备 SR-IOV CNI 插件可执行文件。
  • 在集群中置备 Network Resources Injector(网络资源注入器)。
  • 管理 SR-IOV 网络设备插件的配置。
  • 为 SR-IOV CNI 插件生成 NetworkAttachmentDefinition 自定义资源 (CR) 。

以上提到的 SR-IOV 组件的功能。

  • SR-IOV 网络设备插件是一个 Kubernetes 设备插件,用于发现、公告和分配 SR-IOV 网络虚拟功能 (VF) 资源。在 Kubernetes 中使用设备插件能够利用有限的资源,这些资源通常为于物理设备中。设备插件可以使 Kubernetes 调度程序了解资源可用性,因此调度程序可以在具有足够资源的节点上调度 Pod。
  • SR-IOV CNI 插件探测从 SR-IOV 设备插件中直接分配给 Pod 的 VF 接口。
  • Network Resources Injector 是一个 Kubernetes Dynamic Admission Controller Webhook,它提供通过请求和限制为自定义网络资源(如 SR-IOV VF)应用 Kubernetes Pod 规格的功能。
注意

Network Resources Injector 会被默认启用且无法禁用。

7.8.1.1. 支持的设备

OpenShift Container Platform 支持以下网络接口卡 (NIC):

  • Intel XXV710-DA2 25G 卡,厂商 ID 0x8086,设备 ID 0x158b
  • Mellanox MT27710 系列 [ConnectX-4 Lx] 25G 卡,厂商 ID 0x15b3,设备 ID 0x1015
  • Mellanox MT27800 系列 [ConnectX-5] 100G 卡,厂商 ID 0x15b3,设备 ID 0x1017

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

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

每个 worker 节点都会创建了一个 CR,并共享与该节点相同的名称。.spec.interfaces 列表提供有关节点上网络设备的信息。

重要

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

以下是由 SR-IOV Network Operator 创建的 SriovNetworkNodeState CR 示例:

apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodeState
metadata:
  name: node-25 1
  namespace: sriov-network-operator
  ownerReferences:
  - apiVersion: sriovnetwork.openshift.io/v1
    blockOwnerDeletion: true
    controller: true
    kind: SriovNetworkNodePolicy
    name: default
spec:
  dpConfigVersion: d41d8cd98f00b204e9800998ecf8427e
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 设备列表。

7.8.1.3. 在 Pod 中使用虚拟功能 (VF) 的示例

您可以在附加了 SR-IOV VF 的 Pod 中运行远程直接内存访问 (RDMA) 或 Data Plane Development Kit (DPDK) 应用程序。在以下示例中,Pod 在 RDMA 模式中使用 VF:

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:

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

7.8.2. 安装 SR-IOV Network Operator

作为集群管理员,您可以使用 OpenShift Container Platform CLI 或 Web 控制台安装 SR-IOV Network Operator。

7.8.2.1. 使用 CLI 安装 Operator

作为集群管理员,您可以使用 CLI 安装 Operator。

先决条件

  • 在裸机环境中安装的集群,其中的节点带有支持 SR-IOV 的硬件。
  • OpenShift Container Platform 命令行界面 (CLI),通常称为 oc
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 通过完成以下操作,为 SR-IOV Network Operator 创建命名空间:

    1. 创建用来定义 sriov-network-operator 命名空间的以下 Namespace 自定义资源 (CR) ,然后在 sriov-namespace.yaml 文件中保存这些 YAML 数据:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: sriov-network-operator
        labels:
          openshift.io/run-level: "1"
    2. 运行以下命令创建命名空间:

      $ oc create -f sriov-namespace.yaml
  2. 通过创建以下对象,在您上一步创建的命名空间中安装 SR-IOV Network Operator:

    1. 创建以下 OperatorGroup CR,并在 sriov-operatorgroup.yaml 文件中保存 YAML:

      apiVersion: operators.coreos.com/v1
      kind: OperatorGroup
      metadata:
        name: sriov-network-operators
        namespace: sriov-network-operator
      spec:
        targetNamespaces:
        - sriov-network-operator
    2. 通过运行以下命令来创建 OperatorGroup CR:

      $ oc create -f sriov-operatorgroup.yaml
    3. 运行以下命令获取下一步所需的 channel 值。

      $ oc get packagemanifest sriov-network-operator -n openshift-marketplace -o jsonpath='{.status.defaultChannel}'
      
      4.2
    4. 创建以下订阅 CR,并将 YAML 保存到 sriov-sub.yaml 文件中:

      订阅示例

      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: sriov-network-operator-subscription
        namespace: sriov-network-operator
      spec:
        channel: <channel> 1
        name: sriov-network-operator
        source: redhat-operators 2
        sourceNamespace: openshift-marketplace

      1
      使用在前一步中获得的值指定 .status.defaultChannel 参数。
      2
      您必须指定 redhat-operators 值。
    5. 运行以下命令创建订阅对象:

      $ oc create -f sriov-sub.yaml
    6. 进入 sriov-network-operator 项目:

      $ oc project sriov-network-operator
      
      Now using project "sriov-network-operator"

7.8.2.2. 使用 Web 控制台安装 Operator

作为集群管理员,您可以使用 Web 控制台安装 Operator。

注意

如上一节所述,您必须创建命名空间 CR 和 OperatorGroup CR。

流程

  1. 使用 OpenShift Container Platform Web 控制台安装 SR-IOV Network Operator:

    1. 在 OpenShift Container Platform Web 控制台中,点击 OperatorsOperatorHub
    2. 从可用的 Operators 列表中选择 SR-IOV Network Operator,然后点 Install
    3. Create Operator Subscription 页面中,在集群的一个特定的命名空间中 选择sriov-network-operator。然后,点击 Subscribe
  2. 可选:验证 SR-IOV Network Operator 是否已成功安装:

    1. 切换到 OperatorsInstalled Operators 页面。
    2. 确保 SR-IOV Network Operatorsriov-network-operator 项目中列出,状态InstallSucceeded

      注意

      在安装过程中,Operator 可能会显示 Failed 状态。如果安装过程结束后有 InstallSucceeded 信息,您可以忽略这个 Failed 信息。

      如果 Operator 没有被成功安装,请按照以下步骤进行故障排除:

      • 进入 Operators → Installed Operators 页面,检查 Operator SubscriptionsInstall Plans 选项卡中的 Status 项中是否有任何错误。
      • 进入 WorkloadsPods 页面,在 sriov-network-operator 项目中检查 Pod 的日志。

7.8.3. 配置 SR-IOV 网络设备

SR-IOV Network Operator 把 SriovNetworkNodePolicy.sriovnetwork.openshift.io 自定义资源定义 (CRD) 添加到 OpenShift Container Platform。您可以通过创建一个 SriovNetworkNodePolicy 自定义资源 (CR) 来配置 SR-IOV 网络设备。

注意

当应用由 SriovNetworkNodePolicy CR 指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。它可能需要几分钟时间来应用配置更改。确保集群中有足够的可用节点,用以预先处理被驱除的工作负载。

在应用了配置更新后,sriov-network-operator 命名空间中的所有 Pod 都将变为 Running 状态。

先决条件

  • 安装 OpenShift 命令行界面 (CLI),通常称为 oc
  • 以具有 cluster-admin 特权的用户身份登录。
  • 您必须已安装了 SR-IOV Operator。

流程

  1. 创建以下 SriovNetworkNodePolicy CR,然后在 <name>-sriov-node-network.yaml 文件中保存 YAML。使用配置的实际名称替换 <name>

    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: <name> 1
      namespace: sriov-network-operator 2
    spec:
      resourceName: <sriov_resource_name> 3
      nodeSelector:
        feature.node.kubernetes.io/network-sriov.capable: "true" 4
      priority: <priority> 5
      mtu: <mtu> 6
      numVfs: <num> 7
      nicSelector: 8
        vendor: "<vendor_code>" 9
        deviceID: "<device_id>" 10
        pfNames: ["<pf_name>", ...] 11
        rootDevices: ["<pci_bus_id>", "..."] 12
      deviceType: <device_type> 13
      isRdma: false 14
    1
    为 CR 指定一个名称。
    2
    指定 SR-IOV Operator 安装到的命名空间。
    3
    指定 SR-IOV 设备插件的资源名称。如果 Pod spec 中引用了,则会添加 openshift.io/ 前缀。您可以为一个资源名称创建多个 SriovNetworkNodePolicy CR。
    4
    指定节点选择器来选择要配置哪些节点。用户可以选择手动标记节点,也可以使用 Kubernetes Node Feature Discovery 等工具进行。只有所选节点上的 SR-IOV 网络设备才会被配置。SR-IOV CNI 插件和设备插件只能部署到所选节点上。
    5
    指定一个 099 之间的整数。大数值的优先级较低,因此优先级 99 低于优先级 10
    6
    为虚拟功能(VF)的最大传输单位 (MTU) 指定一个值。MTU 的值必须是在 19000 之间。如果您不需要指定 MTU,请指定一个 " 值。
    7
    为 SR-IOV 物理网络设备指定要创建的虚拟功能 (VF) 的数量。对于 Intel 网络接口卡 (NIC) ,VF 的数量不能超过该设备支持的 VF 总数。对于 Mellanox NIC,VF 的数量不能超过 128
    8
    nicSelector 映射为 Operator 选择要配置的以太网设备。您不需要为所有参数指定值。建议您以足够的准确度来识别以太网适配器,以便尽量减小意外选择其他以太网设备的可能性。如果指定了rootDevices,则必须同时为 vendordeviceIDpfNames 指定一个值。如果同时指定了 pfNamesrootDevices,请确保它们指向同一个设备。
    9
    指定 SR-IOV 网络设备的厂商十六进制代码。允许的值只能是 808615b3
    10
    指定 SR-IOV 网络设备的设备十六进制代码。允许的值只能是 158b10151017
    11
    参数接受包括以太网设备的一个或多个物理功能 (PF) 的数组。
    12
    参数接受一个包括一个或多个 PCI 总线地址,用于以太网设备的物理功能的数组。使用以下格式提供地址: 0000:02:00.1
    13
    指定虚拟功能的驱动程序类型。您可以指定以下值之一:netdevicevfio-pci。默认值为 netdevice
    14
    指定是否启用 RDMA 模式。默认值为 false。在 Mellanox 以太网适配器中只支持 RDMA over Converged Ethernet (RoCE) 模式。
    注意

    如果将 RDMA 标记设定为 true,您可以继续使用启用了 RDMA 的 VF 作为普通网络设备。设备可在其中的一个模式中使用。

  2. 运行以下命令来创建 CR:

    $ oc create -f <filename> 1
    1
    <filename> 替换为您在上一步中创建的文件的名称。

7.8.4. 配置 SR-IOV 额外网络

您可以通过创建一个 SriovNetwork 自定义资源 (CR) 来配置使用 SR-IOV 硬件的额外网络。当创建 SriovNetwork CR 时,SR-IOV Operator 会自动创建一个 NetworkAttachmentDefinition CR。

注意

如果一个 SriovNetwork 自定义资源 (CR) 已被附件到状态为 running 的 Pod 后,则不能修改或删除它。

先决条件

  • 安装 OpenShift 命令行界面 (CLI),通常称为 oc
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 创建以下 SriovNetwork CR,然后在 <name>-sriov-network.yaml 文件中保存 YAML。用这个额外网络的名称替换 <name>

    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: <name> 1
      namespace: sriov-network-operator 2
    spec:
      networkNamespace: <target_namespace> 3
      ipam: |- 4
        ...
      vlan: <vlan> 5
      resourceName: <sriov_resource_name> 6
    1
    <name> 替换为 CR 的名称。Operator 将创建一个具有相同名称的 NetworkAttachmentDefinition CR。
    2
    指定 SR-IOV Operator 安装到的命名空间。
    3
    <target_namespace> 替换为创建 NetworkAttachmentDefinition CR 的命名空间。
    4
    为 ipam CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理网络附加定义的 IP 地址分配。
    5
    使用额外网络的虚拟 LAN (VLAN) ID 替换 <vlan>。它需要是一个从 04095 范围内的一个整数值。默认值为 0
    6
    <sriov_resource_name> 替换为来自用于为这个额外网络定义 SR-IOV 硬件的 SriovNetworkNodePolicy CR 的 .spec.resourceName 参数的值。
  2. 运行以下命令来创建 CR:

    $ oc create -f <filename> 1
    1
    <filename> 替换为您在上一步中创建的文件的名称。
  3. 可选:通过运行以下命令,确认与在上一步中创建的 SriovNetwork CR 关联的 NetworkAttachmentDefinition CR 是否存在。将 <namespace> 替换为您在 SriovNetwork CR 中指定的命名空间。

    oc get net-attach-def -n <namespace>

7.8.4.1. 配置 ipam CNI 插件

IP 地址管理 (IPAM) CNI 插件为其他 CNI 插件管理 IP 地址分配。您可以配置 ipam 以进行静态 IP 地址分配或使用 DHCP 进行动态 IP 地址分配。您指定的 DHCP 服务器必须可从额外网络访问。

重要

在 OpenShift Container Platform 4.2.0 中,如果您将 Pod 附加到使用 DHCP 进行 IP 地址管理的额外网络中,则 Pod 将无法启动。OpenShift Container Platform 4.2.1 已修复了这个问题。如需更多信息,请参阅 BZ#1754686

以下 JSON 配置对象描述了您可以设置的参数。

重要

如果您将 type 参数设置为 DHCP 值,则无法设置任何其他参数。

ipam CNI 插件 JSON 配置对象

{
  "ipam": {
    "type": "<type>", 1
    "addresses": [ 2
      {
        "address": "<address>", 3
        "gateway": "<gateway>" 4
      }
    ],
    "routes": [ 5
      {
        "dst": "<dst>" 6
        "gw": "<gw>" 7
      }
    ],
    "dns": { 8
      "nameservers": ["<nameserver>"], 9
      "domain": "<domain>", 10
      "search": ["<search_domain>"] 11
    }
  }
}

1
指定 static,以配置插件来管理 IP 地址分配。指定 DHCP,以允许 DHCP 服务器管理 IP 地址分配。如果指定了 DHCP 值,则无法指定任何其他参数。
2
定义分配给虚拟接口的 IP 地址的数组。支持 IPv4 和 IPv6 IP 地址。
3
您以 CIDR 格式指定的分配给 worker 节点上 Pod 的 IP 地址块,如 10.1.1.0/24
4
出口网络流量要路由到的默认网关。
5
描述要在 Pod 中配置的路由的数组。
6
CIDR 格式的 IP 地址范围。
7
用于将网络流量路由到的网关。
8
DNS 配置。可选。
9
用来发送 DNS 查询的一个或多个 IP 地址的数组。
10
附加到主机名的默认域。例如,如果将域设置为 example.com,对 example-host 的 DNS 查找查询将被改写为 example-host.example.com
11
在 DNS 查找查询过程中,附加到非限定主机名(如 example-host)的域名的数组。
7.8.4.1.1. 静态 IP 地址分配配置示例

您可以配置 ipam 以进行静态 IP 地址分配:

{
  "ipam": {
    "type": "static",
      "addresses": [
        {
          "address": "191.168.1.1/24"
        }
      ]
  }
}
7.8.4.1.2. 动态 IP 地址分配配置示例

您可以配置 ipam 以使用 DHCP:

{
  "ipam": {
    "type": "DHCP"
  }
}

7.8.5. 将 Pod 添加到额外网络

您可以将 Pod 添加到额外网络。Pod 继续通过默认网络发送与集群相关的普通网络流量。

注意

如果指定了与 SR-IOV CNI 插件关联的 NetworkAttachmentDefinition CR,则 Network Resources Injector 会自动将 resource 参数注入 Pod CR。

先决条件

  • Pod 必须与额外网络处于相同的命名空间。
  • 安装 OpenShift 命令行界面 (CLI),通常称为 oc
  • 您必须登录集群。
  • 您必须安装了 SR-IOV Operator ,并定义了 SriovNetwork CR。

流程

要添加带有额外网络的 Pod,请完成以下步骤:

  1. 在 Pod 资源定义中,将 k8s.v1.cni.cncf.io/networks 参数添加到 Pod metadata 映射中。k8s.v1.cni.cncf.io/networks 接受由一个或多个 NetworkAttachmentDefinition 自定义资源 (CR) 名称组成并用逗号分隔的字符串:

    metadata:
      annotations:
        k8s.v1.cni.cncf.io/networks: <network>[,<network>,...] 1
    1
    <network> 替换为要与 Pod 关联的额外网络的名称。要指定多个额外网络,请使用逗号分隔各个网络。逗号之间不可包括空格。如果您多次指定同一额外网络,则 Pod 会将多个网络接口附加到该网络。

    在以下示例中,两个额外网络附加到 Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: example-pod
      annotations:
        k8s.v1.cni.cncf.io/networks: net1,net2
    spec:
      containers:
      - name: example-pod
        command: ["/bin/bash", "-c", "sleep 2000000000000"]
        image: centos/tools
  2. 运行以下命令来创建 Pod:

    $ oc create -f pod.yaml
  3. 可选:通过运行以下命令,确认 Pod CR 中是否存在注解。将 <name> 替换为 Pod 的名称。

    $ oc get pod <name> -o yaml

    在以下示例中,example-pod Pod 附加到 net1 额外网络:

    $ oc get pod example-pod -o yaml
    apiVersion: v1
    kind: Pod
    metadata:
      annotations:
        k8s.v1.cni.cncf.io/networks: macvlan-bridge
        k8s.v1.cni.cncf.io/networks-status: |- 1
          [{
              "name": "openshift-sdn",
              "interface": "eth0",
              "ips": [
                  "10.128.2.14"
              ],
              "default": true,
              "dns": {}
          },{
              "name": "macvlan-bridge",
              "interface": "net1",
              "ips": [
                  "20.2.2.100"
              ],
              "mac": "22:2f:60:a5:f8:00",
              "dns": {}
          }]
      name: example-pod
      namespace: default
    spec:
      ...
    status:
      ...
    1
    k8s.v1.cni.cncf.io/networks-status 参数是对象的 JSON 数组。每个对象描述附加到 Pod 的额外网络的状态。注解值保存为纯文本值。