Configura las herramientas de redes de SR-IOV

En este documento, se describe cómo configurar las herramientas de redes de virtualización de entrada y salida de raíz única (SR-IOV) para clústeres de Anthos en equipos físicos. SR-IOV proporciona virtualización de E/S para hacer que una tarjeta de interfaz de red (NIC) esté disponible como dispositivos de red en el kernel de Linux. Esto te permite administrar y asignar conexiones de red a tus Pods. Se mejora el rendimiento a medida que los paquetes se mueven directamente entre la NIC y el Pod.

Usa esta función si necesitas herramientas de redes rápidas para tus cargas de trabajo de Pods. La SR-IOV para clústeres de Anthos alojados en equipos físicos te permite configurar las funciones virtuales (VF) en los dispositivos compatibles de los nodos del clúster. También puedes especificar el módulo de kernel en particular para vincularlo a las VF.

Esta función está disponible para clústeres que ejecutan cargas de trabajo, como clústeres híbridos, independientes y de usuario.

El proceso de configuración consta de los siguientes pasos de alto nivel:

  1. Configura el clúster para habilitar las herramientas de redes de SR-IOV.
  2. Configura el operador de SR-IOV, un recurso SriovOperatorConfig personalizado.
  3. Establece políticas de SR-IOV y configura tus VF.
  4. Crea un recurso personalizado NetworkAttachmentDefinition que haga referencia a tus VF.

Requisitos

La función de herramientas de redes de SR-IOV requiere que los controladores oficiales para los adaptadores de red estén presentes en los nodos del clúster. Instala los controladores antes de usar el operador de SR-IOV. Además, si deseas usar el módulo vfio-pci para las VF, asegúrate de que el módulo esté disponible en los nodos en los que se usará.

Habilita las herramientas de redes de SR-IOV para un clúster

A fin de habilitar las herramientas de redes de SR-IOV para clústeres de Anthos en equipos físicos, agrega los siguientes campos multipleNetworkInterfaces y sriovOperator a la sección clusterNetwork del objeto de clúster y configura ambos campos como true.

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: cluster1
spec:
  clusterNetwork:
    multipleNetworkInterfaces: true
    sriovOperator: true
...

El campo sriovOperator puede mutar y se puede cambiar después de que se crea el clúster.

Configura el operador SR-IOV

El recurso personalizado SriovOperatorConfig proporciona una configuración global para la función de herramientas de redes de SR-IOV. Este recurso personalizado empaquetado tiene el nombre default y está en el espacio de nombres gke-operators. El recurso personalizado SriovOperatorConfig se respeta solo para este nombre y espacio de nombres.

Puedes editar este objeto con el siguiente comando:

kubectl -n gke-operators edit sriovoperatorconfigs.sriovnetwork.k8s.cni.cncf.io default

Este es un ejemplo de una configuración de recurso personalizado SriovOperatorConfig:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovOperatorConfig
metadata:
  name: default
  namespace: gke-operators
spec:
  configDaemonNodeSelector:
    nodePool: "withSriov"
  disableDrain: false
  logLevel: 0

La sección configDaemonNodeSelector te permite limitar qué nodos puede manejar el operador de SR-IOV. En el ejemplo anterior, el operador se limita solo a los nodos que tienen una etiqueta nodePool: withSriov. Si no se especifica el campo configDaemonNodeSelector, se aplican las siguientes etiquetas predeterminadas:

beta.kubernetes.io/os: linux
node-role.kubernetes.io/worker: ""

En el campo disableDrain, se especifica si se debe realizar una operación de desvío de nodos de Kubernetes antes de que se deba reiniciar el nodo o antes de que se cambie una configuración específica de VF.

Crea políticas de SR-IOV

Para configurar VF específicas en el clúster, debes crear un recurso personalizado SriovNetworkNodePolicy en el espacio de nombres gke-operators.

A continuación, se muestra un manifiesto de ejemplo para un recurso personalizado SriovNetworkNodePolicy:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
  namespace: gke-operators
spec:
  deviceType: "netdevice"
  mtu: 1600
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
    deviceID: "1015"
    rootDevices:
    - 0000:01:00.0
    vendor: "15b3"
  numVfs: 4
  priority: 80
  resourceName: "mlnx"

La sección nodeSelector te permite limitar aún más los nodos en los que se deben crear las VF. Esta limitación se encuentra sobre los selectores del SriovOperatorConfig descrito en la sección anterior.

El campo deviceType especifica el módulo de kernel que se usará para las VF. Las opciones de deviceType disponibles son las siguientes:

  • netdevice para el módulo de kernel estándar específico de VF
  • vfio-pci para el controlador de VFIO-PCI

resourceName define con qué nombre se representan las VF en el nodo de Kubernetes

Una vez completado el proceso de configuración, los nodos seleccionados del clúster contienen el recurso definido como se presenta en el siguiente ejemplo (observa gke.io/mlnx):

apiVersion: v1
kind: Node
metadata:
  name: worker-01
spec:

status:
  allocatable:
    cpu: 47410m
    ephemeral-storage: "210725550141"
    gke.io/mlnx: "4"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 59884492Ki
    pods: "250"
  capacity:
    cpu: "48"
    ephemeral-storage: 228651856Ki
    gke.io/mlnx: "4"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 65516492Ki
    pods: "250"

El operador siempre agregará el prefijo gke.io/ a cada recurso que definas con SriovNetworkNodePolicy.

Especifica un selector de NIC

Para que SriovNetworkNodePolicy funcione de forma correcta, especifica al menos un selector en la sección nicSelector. En este campo, hay varias opciones sobre cómo identificar funciones físicas (PF) específicas en los nodos del clúster. La mayor parte de la información que requiere este campo se descubre en tu nombre y se guarda en el recurso personalizado SriovNetworkNodeState. Habrá un objeto por cada nodo que este operador pueda controlar.

Usa el siguiente comando para ver todos los nodos disponibles:

kubectl -n gke-operators get sriovnetworknodestates.sriovnetwork.k8s.cni.cncf.io -o yaml

Este un ejemplo de un nodo:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
  name: worker-01
  namespace: gke-operators
spec:
  dpConfigVersion: "6368949"
status:
  interfaces:
  - deviceID: "1015"
    driver: mlx5_core
    eSwitchMode: legacy
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9c
    mtu: 1500
    name: enp1s0f0
    pciAddress: "0000:01:00.0"
    totalvfs: 4
    vendor: 15b3
  - deviceID: "1015"
    driver: mlx5_core
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9d
    mtu: 1500
    name: enp1s0f1
    pciAddress: "0000:01:00.1"
    totalvfs: 2
    vendor: 15b3
  syncStatus: Succeeded

Configura la partición de funciones físicas

Presta especial atención al campo pfNames de la sección nicSelector. Además de definir la PF exacta que se usará, te permite especificar las VF exactas que se usarán para la PF especificada y el recurso definido en la política.

Por ejemplo:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
  namespace: gke-operators
spec:
  deviceType: "netdevice"
  mtu: 1600
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#3-6
    deviceID: "1015"
    rootDevices:
    - 0000:01:00.0
    vendor: "15b3"
  numVfs: 7
  priority: 80
  resourceName: "mlnx"

En el ejemplo anterior, el recurso gke.io/mlnx usa solo VF numeradas de 3 a 6 y muestra solo cuatro VF disponibles. Debido a que las VF siempre se crean a partir del índice cero, el número solicitado de VF, numVfs, debe ser al menos tan alto como el valor de cierre del rango (se cuenta desde cero). Esta lógica de numeración es la razón por la que numVfs se configura como 7 en el ejemplo anterior. Si estableces un rango de 3 a 4 (enp65s0f0#3-4), tu numVfs debe ser al menos 5.

Cuando no se especifica la partición, numVfs define el rango de VF que se usa, que siempre comienza desde cero. Por ejemplo, si configuras numVfs=3 sin especificar la partición, se usan las VF 0-2.

Comprende la prioridad de las políticas

Puedes especificar varios objetos SriovNetworkNodePolicy para manejar varios proveedores o diferentes opciones de configuración de VF. Administrar múltiples objetos y proveedores puede resultar problemático cuando varias políticas hacen referencia a la misma PF. Para manejar estas situaciones, el campo priority resuelve los conflictos por nodo.

A continuación, se muestra la lógica de priorización para las políticas de PF superpuestas:

  1. Una política de mayor prioridad reemplaza una con prioridad más baja solo cuando la partición de PF se superpone.

  2. Las mismas políticas de prioridad se combinan:

    1. Las políticas se ordenan por nombre y se procesan en ese orden.
    2. Las políticas se reemplazan con particiones de PF superpuestas.
    3. Las políticas con particiones de PF no superpuestas se combinan y están presentes.

Una política de prioridad alta es una con un valor numérico más bajo en el campo priority. Por ejemplo, la prioridad es más alta para una política con priority: 10 que para una política con priority: 20.

En las siguientes secciones, se proporcionan ejemplos de políticas para diferentes opciones de configuración de partición.

PF particionada

La implementación de los siguientes dos manifiestos SriovNetworkNodePolicy da como resultado dos recursos disponibles: gke.io/dev-kernel y gke.io/dev-vfio. Cada recurso tiene dos VF que no se superponen.

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#0-1
  numVfs: 2
  priority: 70
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

Partición de PF superpuesta

La implementación de los siguientes dos manifiestos SriovNetworkNodePolicy da como resultado que solo el recurso gke.io/dev-vfio esté disponible. El rango de VF de policy-1 es 0-2, que se superpone con policy-2. Debido a la asignación de nombres, policy-2 se procesa después de policy-1. Por lo tanto, solo está disponible el recurso especificado en policy-2, gke.io/dev-vfio.

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
  numVfs: 3
  priority: 70
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

Partición de PF no superpuesta con diferentes prioridades

La implementación de los siguientes dos manifiestos SriovNetworkNodePolicy da como resultado dos recursos disponibles: gke.io/dev-kernel y gke.io/dev-vfio. Cada recurso tiene dos VF que no se superponen. Aunque policy-1 tiene una prioridad mayor que policy-2, como la partición de PF no se superpone, combinamos las dos políticas.

kind: SriovNetworkNodePolicy
metadata:
  name: policy-1
spec:
  deviceType: "netdevice"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0
  numVfs: 2
  priority: 10
  resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
  name: policy-2
spec:
  deviceType: "vfio-pci"
  nodeSelector:
    baremetal.cluster.gke.io/node-pool: node-pool-1
  nicSelector:
    pfNames:
    - enp65s0f0#2-3
  numVfs: 4
  priority: 70
  resourceName: "dev-vfio"

Comprueba el estado de configuración de la política de SR-IOV

Cuando aplicas las políticas de SR-IOV, puedes hacer un seguimiento y ver la configuración final de los nodos en el recurso personalizado SriovNetworkNodeState del nodo específico. En la sección status, el campo syncStatus representa la etapa actual del daemon de configuración. El estado Succeeded indica que la configuración finalizó. En la sección spec del recurso personalizado SriovNetworkNodeState, se define el estado final de la configuración de VF para ese nodo, según la cantidad de políticas y sus prioridades. Todas las VF creadas se mostrarán en la sección status para las PF especificadas.

Este es un ejemplo de recurso personalizado SriovNetworkNodeState:

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
  name: worker-02
  namespace: gke-operators
spec:
  dpConfigVersion: "9022068"
  interfaces:
  - linkType: eth
    name: enp1s0f0
    numVfs: 2
    pciAddress: "0000:01:00.0"
    vfGroups:
    - deviceType: netdevice
      policyName: policy-1
      resourceName: mlnx
      vfRange: 0-1
status:
  interfaces:
  - Vfs:
    - deviceID: "1016"
      driver: mlx5_core
      mac: 96:8b:39:d8:89:d2
      mtu: 1500
      name: enp1s0f0np0v0
      pciAddress: "0000:01:00.2"
      vendor: 15b3
      vfID: 0
    - deviceID: "1016"
      driver: mlx5_core
      mac: 82:8e:65:fe:9b:cb
      mtu: 1500
      name: enp1s0f0np0v1
      pciAddress: "0000:01:00.3"
      vendor: 15b3
      vfID: 1
    deviceID: "1015"
    driver: mlx5_core
    eSwitchMode: legacy
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9c
    mtu: 1500
    name: enp1s0f0
    numVfs: 2
    pciAddress: "0000:01:00.0"
    totalvfs: 2
    vendor: 15b3
  - deviceID: "1015"
    driver: mlx5_core
    linkSpeed: 10000 Mb/s
    linkType: ETH
    mac: 1c:34:da:5c:2b:9d
    mtu: 1500
    name: enp1s0f1
    pciAddress: "0000:01:00.1"
    totalvfs: 2
    vendor: 15b3
  syncStatus: Succeeded

Crea un recurso personalizado NetworkAttachmentDefinition

Después de configurar correctamente las VF en el clúster y de que se puedan ver en el nodo de Kubernetes como un recurso, debes crear una NetworkAttachmentDefinition que haga referencia al recurso. Haz la referencia con una anotación k8s.v1.cni.cncf.io/resourceName. A continuación, se muestra un ejemplo de manifiesto NetworkAttachmentDefinition que hace referencia al recurso gke.io/mlnx:

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-sriov-1
  annotations:
    k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
  config: '{
      "cniVersion": "0.3.0",
      "name": "mynetwork",
      "type": "sriov",
      "ipam": {
        "type": "whereabouts",
        "range": "21.0.108.0/21",
        "range_start": "21.0.111.16",
        "range_end": "21.0.111.18"
      }
    }'

NetworkAttachmentDefinition debe tener sriov como el tipo de CNI. Haz referencia a cualquier recurso personalizado NetworkAttachmentDefinition implementado en tus Pods con una anotación k8s.v1.cni.cncf.io/networks.

Este es un ejemplo de cómo hacer referencia al recurso personalizado NetworkAttachmentDefinition anterior en un Pod:

apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: gke-sriov-1
spec:
  containers:
  ...

Cuando haces referencia a un recurso personalizado NetworkAttachmentDefinition en cargas de trabajo, no tienes que preocuparte por las definiciones de los recursos de los Pods o la ubicación en nodos específicos; esto se hace de forma automática.

En el siguiente ejemplo, se muestra un recurso personalizado NetworkAttachmentDefinition con una configuración de VLAN. En este ejemplo, cada VF pertenece a la VLAN 100:

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-sriov-vlan-100
  annotations:
    k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
  config: '{
      "cniVersion": "0.3.0",
      "name": "mynetwork",
      "type": "sriov",
      "vlan": 100,
      "ipam": {
        "type": "whereabouts",
        "range": "21.0.100.0/21"
      }
    }'

Información adicional

Las siguientes secciones contienen información para ayudarte a configurar las herramientas de redes de SR-IOV.

Reinicios de nodo

Cuando el operador SR-IOV configura los nodos, es posible que estos se deban reiniciar. Puede que sea necesario reiniciar los nodos durante la configuración de VF o del kernel. La configuración del kernel incluye habilitar la compatibilidad con la funcionalidad de SR-IOV en el sistema operativo.

Adaptadores de red compatibles

En la siguiente tabla, se enumeran los adaptadores de red compatibles con los clústeres de la versión 1.12.x:

Nombre ID de proveedor ID de dispositivo ID de dispositivo de VF
Intel i40e XXV710 8086 158a 154c
Intel i40e 25G SFP28 8086 158b 154c
Intel i40e 10G X710 SFP 8086 1572 154c
Intel i40e XXV710 N3000 8086 0d58 154c
Intel i40e 40G XL710 QSFP 8086 1583 154c
Intel ice Columbiaville E810-CQDA2 2CQDA2 8086 1,592 1889
Intel ice Columbiaville E810-XXVDA4 8086 1593 1889
Intel ice Columbiaville E810-XXVDA2 8086 159b 1889
Nvidia mlx5 ConnectX-4 15b3 1013 1014
Nvidia mlx5 ConnectX-4LX 15b3 1015 1016
Nvidia mlx5 ConnectX-5 15b3 1017 1018
Nvidia mlx5 ConnectX-5 Ex 15b3 1019 101a
Nvidia mlx5 ConnectX-6 15b3 101b 101c
Nvidia mlx5 ConnectX-6_Dx 15b3 101d 101e
Nvidia mlx5 MT42822 BlueField-2 integrated ConnectX-6 Dx 15b3 a2d6 101e
Broadcom bnxt BCM57414 2x25G 14e4 16d7 16dc
Broadcom bnxt BCM75508 2x100G 14e4 1750 1806