Nota:

Configuración de interfaces SR-IOV para pods en OKE mediante Multus CNI

Introducción

SR-IOV es una especificación que permite que un único dispositivo PCIe parezca ser varios dispositivos físicos PCIe independientes. SR-IOV funciona introduciendo la idea de funciones físicas (PF) y funciones virtuales (VF). El host utiliza un PF y, por lo general, representa un único puerto NIC. VF es una versión ligera de ese PF. Con la compatibilidad adecuada, SR-IOV presenta una manera de que el hardware físico (como SmartNIC) se presente como varios dispositivos distintos (interfaz de red). Con los contenedores, podemos mover una de estas interfaces (una VF) desde el host al espacio de nombres de red para un contenedor o un pod, de modo que el contenedor ahora pueda acceder directamente a la interfaz. La ventaja que ofrece es que no obtenemos ninguna sobrecarga con virt-io y obtenemos el rendimiento del dispositivo nativo.

Nota: Los plugins y el proceso descritos en este tutorial se aplican solo a las instancias con hardware dedicado. Para las instancias basadas en máquinas virtuales, se necesita un juego diferente de plugins y configuración.

Objetivo

En este tutorial, se describe cómo configurar interfaces de red secundarias basadas en funciones virtuales SR-IOV para pods que se ejecutan en clusters de OKE. Utiliza el plugin SRIOV-CNI para gestionar las funciones virtuales SR-IOV como recursos que se pueden asignar en un nodo y el Multus meta CNI para agregar interfaces de red adicionales a los pods.

Funcionamiento

El enfoque tiene varias capas y componentes. En su crux, un plugin de dispositivo de Kubernetes gestiona un conjunto de funciones virtuales y lo publica como un recurso asignable en el nodo. Cuando un pod solicita dicho recurso, el pod se puede asignar a un nodo donde el recurso está disponible y un CNI SR-IOV puede asociar la función virtual al espacio de nombres de red del pod. Un metaplugin CNI, como Multus, maneja varias conexiones de red al Pod para que el Pod pueda comunicarse tanto por la SR-IOV como por las redes de superposición.

Primero configuramos una serie de VF en smartNICs con capacidad de SR-IOV, que luego se presentarán como NIC individuales. A continuación, configuramos estas VF con direcciones MAC que reconoce Oracle Cloud Infrastructure (OCI). Estas VF se crean fuera de Multus, ya sea manualmente (como se describe en este tutorial) o mediante una secuencia de comandos que se puede invocar en el momento de la creación del nodo. En este punto, tenemos una agrupación de VF cada una identificada por el host como una NIC independiente y una dirección MAC de OCI. El grupo de trabajo de conexión de red de Kubernetes mantiene un plugin de dispositivo de red de propósito especial que detecta y publica las VF como recursos de nodo asignables. El CNI SR-IOV (también del grupo de trabajo de conexión de red de Kubernetes) funciona junto con el plugin de dispositivo y gestiona la asignación de estas funciones virtuales al pod según el ciclo de vida del pod.

Ahora tenemos uno o más nodos con una agrupación de VF que son reconocidos y gestionados por el plugin de dispositivo SR-IOV como recursos de nodo asignables. Estos pueden ser solicitados por pods. La CNI SR-IOV conecta ( mueve) la VF al espacio de nombres de red del pod en la creación del pod y libera la VF (la mueve de nuevo al espacio de nombres raíz) en la supresión del pod. Esto hace que la VF esté disponible para ser asignada a otro pod. Un meta plugin como Multus puede proporcionar la información de VF al CNI y gestionar varios anexos de red en el pod.

Imagen de varios pod

Tarea 1: configurar los hosts

Comenzamos con hosts con hardware dedicado, donde podemos configurar VF para las interfaces PCIe. Con los hosts con hardware dedicado, realizamos los siguientes pasos.

  1. Crear VF: SSH en el nodo con hardware dedicado. Busque el dispositivo físico y agréguele funciones virtuales.

    Nota: La secuencia de comandos para obtener el nombre de dispositivo solo es necesaria para la automatización.

    En el ejemplo, se crean dos VF en el dispositivo.

    # 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. Asigne direcciones MAC de OCI a las VF.

    Estas VF tendrán direcciones MAC generadas automáticamente ahora (o 000). Necesitamos configurar direcciones MAC de OCI para que el tráfico de éstas sea permitido en la red de OCI. Cree el mismo número de asociaciones de VNIC en el host que el número de VF creadas. Tenga en cuenta las direcciones MAC de cada conexión de VNIC. Ahora asignamos cada una de estas direcciones MAC que OCI reconoce al VFS que creamos.

    # 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}
    
    

De esta forma, se completa la configuración del host, que idealmente se debe automatizar, ya que se debe realizar en cada host que necesite proporcionar recursos de red SR-IOV a los pods.

Tarea 2: Instalación de SR-IOV CNI

Este CNI se puede instalar en un cluster 1.16+ como un conjunto de daemon. Los nodos sin dispositivos SR-IOV son manejados correctamente por el propio plugin del dispositivo.

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

Tarea 3: Instalación del plugin del dispositivo de red SR-IOV

Nota: El plugin del dispositivo no crea las VF sobre la marcha, se deben crear por separado.

El plugin del dispositivo detecta y anuncia los dispositivos de red compatibles con SR-IOV en el nodo. Para ello, el plugin de dispositivo requiere una configuración que le permita crear los puntos finales de plugin de dispositivo. La configuración identifica los dispositivos y los controladores utilizados.

  1. Cree un ConfigMap para la agrupación de recursos SR-IOV. Para configurar ConfigMap, necesitamos conocer el ID de proveedor, el ID de dispositivo y el controlador que utiliza el dispositivo.

    1. Para buscar el ID de proveedor y el ID de dispositivo:

      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. En el ejemplo anterior, tenemos dos VF, y el último bit de información nos proporciona el ID de proveedor (14e4) y el ID de dispositivo (16dc). Podemos realizar una comprobación cruzada con los hwdata que utiliza lspci.

      cat /usr/share/hwdata/pci.ids|grep 16dc
      
    3. Para buscar los controladores utilizados:

      # filtering based on the PCIe slots.
      find /sys | grep drivers.*31:02.0|awk -F/ '{print $6}'
      
      bnxt_en
      
      
  2. Configure ConfigMap. ConfigMap debe tener el nombre sriovdp-config y una clave 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. Configure el plugin del dispositivo. Con el mapa de configuración creado, el plugin de dispositivo se puede instalar como un conjunto de daemon.

    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. Una vez que se desplieguen los conjuntos de datos, puede comprobar los logs del contenedor para solucionar problemas. Después de un despliegue correcto, el nodo debe mostrar las funciones virtuales como recursos asignables.

    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"
    }
    

Tarea 4: Instalación de un CNI de metadispositivo (Multus)

Multus es un metacomplemento que puede proporcionar la información de VF a un CNI descendente como el complemento SR-IOV CNI para que maneje la conexión de recursos de red al tiempo que activa pods o pods "de hosts múltiples" con varias interfaces de red.

  1. Instalar Multus:

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

    Nota:

    • La imagen por defecto utilizada por el daemonset con la etiqueta stable necesita que el kubelet sea v1.20.x. Si realiza la instalación en un cluster más antiguo, edite el deamonset en el manifiesto y utilice la etiqueta de imagen de varios v3.7.1.

    • Este manifiesto crea una nueva CRD para kind:NetworkAttachmentDefinition y proporciona un multius binario en todos los nodos mediante un daemonset.

  2. Para conectar interfaces adicionales a los pods, necesitamos una configuración para que la interfaz se conecte. Se encapsula en el tipo de recurso personalizado NetworkAttachmentDefinition. Esta configuración es esencialmente una configuración de CNI empaquetada como un recurso personalizado.

    Vamos a configurar un ejemplo 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
    
    

Tarea 5: Despliegue y pruebe pods con varias interfaces

Acuses de recibo

Más recursos de aprendizaje

Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en un explorador de Oracle Learning.

Para obtener documentación sobre los productos, visite Oracle Help Center.