En este documento, se describe cómo configurar las herramientas de redes de virtualización de entrada/salida de raíz única (SR-IOV) para Google Distributed Cloud. 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 Google Distributed Cloud 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. La función de herramientas de redes de SR-IOV requiere que el clúster tenga al menos dos nodos.
El proceso de configuración consta de los siguientes pasos de alto nivel:
- Configura el clúster para habilitar las herramientas de redes de SR-IOV.
- Configura el operador de SR-IOV, un recurso
SriovOperatorConfig
personalizado. - Establece políticas de SR-IOV y configura tus VF.
- 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
Para habilitar las herramientas de redes de SR-IOV para Google Distributed Cloud, agrega el campo multipleNetworkInterfaces
y el campo sriovOperator
a la sección clusterNetwork
del objeto Clúster y establece ambos campos en 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 VFvfio-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:
Una política de mayor prioridad reemplaza una con prioridad más baja solo cuando la partición de PF se superpone.
Las mismas políticas de prioridad se combinan:
- Las políticas se ordenan por nombre y se procesan en ese orden.
- Las políticas se reemplazan con particiones de PF superpuestas.
- 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.29.x:
Nombre | ID del 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 |