注:

使用多用户 CNI 为 OKE 上的云池配置 SR-IOV 接口

简介

SR-IOV 是一种规范,允许单个 PCIe 设备显示为多个单独的物理 PCIe 设备。SR-IOV 通过引入物理功能 (physical function,PF) 和虚拟功能 (virtual function,VF) 的理念来发挥作用。PF 由主机使用,通常表示单个 NIC 端口。VF 是 PF 的轻量级版本。在适当的支持下,SR-IOV 为物理硬件(如 SmartNIC)提供了一种将自身作为多个不同的(网络接口)设备呈现的方式。通过容器,我们可以将这些接口 (VF) 之一从主机移到容器或 Pod 的网络名称空间中,以便容器现在可以直接访问接口。这种优势在于,我们不会使用 virt-io 获取任何开销,也不会获得本机设备性能。

:本教程中介绍的插件和流程仅适用于裸金属实例。对于基于虚拟机的实例,需要一组不同的插件和配置。

目标

本教程介绍了如何为在 OKE 群集上运行的 pod 设置基于 SR-IOV 虚拟功能的辅助网络接口。它利用 SRIOV-CNI 插件将 SR-IOV 虚拟功能管理为可以在节点上分配的资源,使用多用户元 CNI 将其他网络接口添加到 pod。

工作原理

该方法具有多个层和组件。Kubernetes 设备插件管理一组虚拟功能并将其发布为节点上的可分配资源。当 pod 请求此类资源时,可以将 pod 分配给资源可用的节点,而 SR-IOV CNI 可以将虚拟功能激活到 pod 的网络名称空间中。CNI 元插件(如 Multus)处理 Pod 的多个网络附件,以便 Pod 可以通过 SR-IOV 和叠加网络进行通信。

我们首先在支持 SR-IOV 的 smartNICs 上设置了一些 VF,然后将自己呈现为单个 NIC。然后,我们将这些 VF 配置为 Oracle Cloud Infrastructure (OCI) 可识别的 MAC 地址。这些 VF 是在多用户外部创建的,可以是手动创建的(如本教程中所述),也可以是在创建节点时调用的脚本。此时,我们有一个 VF 池,每个 VF 由主机标识为单独的 NIC 和 OCI MAC 地址。Kubernetes 网络检测工作组维护了一个专用网络设备插件,该插件将搜索 VF 并发布为可分配的节点资源。SR-IOV CNI(也来自 Kubernetes 网络检测工作组)与设备插件一起工作,并根据云池生命周期管理这些虚拟功能的分配。

现在,我们有一个或多个节点具有 VF 池,这些 VF 由 SR-IOV 设备插件识别和管理,作为可分配的节点资源。这些可由 pod 请求。SR-IOV CNI 在创建云池时将 VF 激活(移动)到云池的网络名称空间,并在删除云池时释放 VF(将其移回根名称空间)。这使 VF 可分配给其他云池。像 Multus 这样的元插件可以为 CNI 提供 VF 信息并管理 Pod 上的多个网络附件。

多用户云池图像

任务 1:设置主机

我们从裸金属主机开始,可在其中为 PCIe 接口设置 VF。对于裸金属主机,我们执行以下步骤。

  1. 创建 VF:通过 SSH 连接到裸金属节点。查找物理设备并向其添加虚拟功能。

    :仅自动化需要用于获取设备名称的脚本。

    此处的示例在设备上创建两个 VF。

    # Gets the physical device. Alterntively, just run `ip addr show` and look at the primary iface to set $PHYSDEV
    URL=http://169.254.169.254/opc/v1/vnics/
    baseAddress=`curl -s ${URL} | jq -r '.[0] | .privateIp'`
    PHYSDEV=`ip -o -4 addr show | grep ${baseAddress} | awk -F: '{gsub(/^[ \t]|[ \t]$/,"",$2);split($2,out,/[ \t]+/);print out[1]}'`
    
    # Add two VFs
    echo "2" > /sys/class/net/${PHYSDEV}/device/sriov_numvfs
    
    # Verify the VFs
    ip link show ${PHYSDEV}
    
  2. 将 OCI MAC 地址分配给 VF。

    这些 VF 现在将具有自动生成的 MAC 地址(或 000)。我们需要为来自这些通信的 OCI MAC 地址设置为允许在 OCI 网络上使用。在主机上创建与创建的 VF 数相同的 VNIC 附件数。记下每个 VNIC 附件的 MAC 地址。现在,我们将 OCI 识别的每个 MAC 地址分配给我们创建的 VFS。

    # For each MAC address from the VNIC attachments
    
    ip link set ${PHYSDEV} vf <n= 0..numVFs> mac <MAC Address from VNIC attachment> spoofchk off
    
    # verify all VFs have Mac addresses from OCI
    ip link show ${PHYSDEV}
    
    

这将完成主机设置(最好是自动执行),因为需要在需要向云池提供 SR-IOV 网络资源的每台主机上执行该设置。

任务 2:安装 SR-IOV CNI

此 CNI 可以作为守护进程集安装在 1.16+ 群集上。没有 SR-IOV 设备的节点由设备插件本身以正常方式进行处理。

git clone https://github.com/k8snetworkplumbingwg/sriov-cni.git && cd sriov-cni
kubectl apply -f images/k8s-v1.16/sriov-cni-daemonset.yaml && cd..

任务 3:安装 SR-IOV 网络设备插件

:设备插件不会实时创建 VF,必须单独创建它们。

设备插件在节点上搜索并通告支持 SR-IOV 的网络设备。要实现此目的,设备插件需要一种配置,使它能够创建设备插件端点。配置标识所使用的设备和驱动程序。

  1. 为 SR-IOV 资源池创建 ConfigMap。要设置 ConfigMap,我们需要知道设备使用的供应商 ID、设备 ID 和驱动程序。

    1. 要查找供应商 ID 和设备 ID,请执行以下操作:

      lspci -nn|grep Virtual
      
      31:02.0 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme-E Ethernet Virtual Function [14e4:16dc]
      31:02.1 Ethernet controller [0200]: Broadcom Inc. and subsidiaries NetXtreme-E Ethernet Virtual Function [14e4:16dc]
      
      
    2. 在上例中,我们有两个 VF,最后的信息位为我们提供了供应商 ID (14e4) 和设备 ID (16dc)。我们可以使用 lspci 使用的 hwdata 进行交叉检查。

      cat /usr/share/hwdata/pci.ids|grep 16dc
      
    3. 要查找使用的驱动程序,请执行以下操作:

      # filtering based on the PCIe slots.
      find /sys | grep drivers.*31:02.0|awk -F/ '{print $6}'
      
      bnxt_en
      
      
  2. 设置 ConfigMap。ConfigMap 应命名为 sriovdp-config,并且应具有键 config.json

    cat << EOF > sriovdp-config.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: sriovdp-config
      namespace: kube-system
    data:
      config.json: |
        {
          "resourceList": [{
                  "resourceName": "mlnx_sriov_rdma",
                  "resourcePrefix": "mellanox.com",
                  "selectors": {
                    "vendors": ["15b3"],
                    "devices": ["101e"],
                    "drivers": ["mlx5_core"],
                    "isRdma": false
                  }
              },
              {
                  "resourceName": "netxtreme_sriov_rdma",
                  "resourcePrefix": "broadcom.com",
                  "selectors": {
                    "vendors": ["14e4"],
                    "devices": ["16dc"],
                    "drivers": ["bnxt_en"],
                    "isRdma": false
                  }
              }
          ]
        }
    EOF
    
    kubectl create -f sriovdp-config.yaml
    
    
  3. 设置设备插件。创建配置映射后,可以将设备插件安装为守护进程集。

    git clone https://github.com/k8snetworkplumbingwg/sriov-network-device-plugin.git && cd sriov-network-device-plugin
    kubectl create -f deployments/k8s-v1.16/sriovdp-daemonset.yaml && cd ..
    
  4. 部署守护进程后,您可以查看容器日志以进行故障排除。成功部署后,节点应列出虚拟功能作为可分配资源。

    kubectl get node <node_name> -o json | jq '.status.allocatable'
    
    {
      "broadcom.com/netxtreme_sriov_rdma": "2",
      "cpu": "128",
      "ephemeral-storage": "37070025462",
      "hugepages-1Gi": "0",
      "hugepages-2Mi": "0",
      "memory": "527632840Ki",
      "pods": "110"
    }
    

任务 4:安装元插件 CNI(多用户)

Multus 是一个元插件,它可以向下游 CNI 提供 VF 信息,例如 SR-IOV CNI 插件,用于在启用具有多个网络接口的“多宿主”云池或云池时处理网络资源检测。

  1. 安装多用户:

    git clone https://github.com/k8snetworkplumbingwg/multus-cni.git && cd multus-cni
    kubectl apply -f images/multus-daemonset.yml && cd ..
    

    • 标记为 stable 的守护进程集使用的默认映像需要 kubelet 为 v1.20.x。如果在较旧的群集上进行安装,请编辑清单中的 deamonset 并使用多用户映像标记 v3.7.1

    • 此清单为 kind:NetworkAttachmentDefinition 创建新的 CRD 并通过守护进程集在所有节点上提供多用户二进制文件。

  2. 要将其他接口附加到 pod,我们需要配置要连接的接口。这封装在 NetworkAttachmentDefinition 类型的定制资源中。此配置本质上是打包为定制资源的 CNI 配置。

    我们来设置一个示例 NetworkAttachmentDefinition

    cat << EOF > sriov-net1.yaml
    apiVersion: k8s.cni.cncf.io/v1
    kind: NetworkAttachmentDefinition
    metadata:
      name: sriov-net1
      annotations:
        k8s.v1.cni.cncf.io/resourceName: broadcom.com/netxtreme_sriov_rdma
    spec:
      config: '{
      "type": "sriov",
      "cniVersion": "0.3.1",
      "name": "sriov-network",
      "ipam": {
        "type": "host-local",
        "subnet": "10.20.30.0/25",
        "routes": [{
          "dst": "0.0.0.0/0"
        }],
        "gateway": "10.20.10.1"
      }
    }'
    EOF
    
    kubectl apply -f sriov-net1.yaml
    
    

任务 5:使用多个接口部署和测试云池

确认

更多学习资源

探索 docs.oracle.com/learn 上的其他实验室,或者访问 Oracle Learning YouTube 频道上的更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 成为 Oracle Learning Explorer。

有关产品文档,请访问 Oracle 帮助中心