En este documento se describe cómo configurar la red 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 que una tarjeta de interfaz de red (NIC) esté disponible como dispositivo de red en el kernel de Linux. Esto te permite gestionar y asignar conexiones de red a tus pods. El rendimiento mejora, ya que los paquetes se mueven directamente entre la NIC y el pod.
Usa esta función si necesitas una red rápida para tus cargas de trabajo de pods. SR-IOV para Google Distributed Cloud te permite configurar las funciones virtuales (VFs) en los dispositivos compatibles de los nodos de tu clúster. También puedes especificar el módulo del kernel concreto que se va a vincular a las VFs.
Esta función está disponible para clústeres que ejecutan cargas de trabajo, como los clústeres híbridos, independientes y de usuario. La función de redes SR-IOV requiere que el clúster tenga al menos dos nodos.
El proceso de configuración consta de los siguientes pasos generales:
- Configura el clúster para habilitar la red SR-IOV.
- Configura el operador SR-IOV, un
SriovOperatorConfig
recurso personalizado. - Configura las políticas de SR-IOV y tus VFs.
- Crea un
NetworkAttachmentDefinition
recurso personalizado que haga referencia a tus VFs.
Requisitos
La función de red SR-IOV requiere que los controladores oficiales de los adaptadores de red estén presentes en los nodos del clúster. Instala los controladores antes de usar el operador SR-IOV. Además, para usar el módulo vfio-pci
en tus VFs, asegúrate de que esté disponible en los nodos en los que se va a usar.
Habilitar la red SR-IOV en un clúster
Para habilitar la red SR-IOV en Google Distributed Cloud, añade el campo multipleNetworkInterfaces
y el campo sriovOperator
a la sección clusterNetwork
del objeto Cluster y asigna el valor true
a ambos campos.
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: cluster1
spec:
clusterNetwork:
multipleNetworkInterfaces: true
sriovOperator: true
...
El campo sriovOperator
es mutable y se puede cambiar después de crear el clúster.
Configurar el operador SR-IOV
El recurso personalizado SriovOperatorConfig
proporciona la configuración global de la función de red SR-IOV. Este recurso personalizado agrupado tiene el nombre default
y está en el espacio de nombres gke-operators
. El SriovOperatorConfig
custom
resource solo se tiene en cuenta 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
A continuación, se muestra un ejemplo de configuración de un 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 los nodos que puede gestionar el operador SR-IOV. En el ejemplo anterior, el operador se limita a los nodos que tienen la 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: ""
El campo disableDrain
especifica si se debe realizar una operación de drenaje de nodos de Kubernetes antes de reiniciar el nodo o antes de cambiar una configuración de VF específica.
Crear políticas de SR-IOV
Para configurar VFs específicos en tu clúster, debes crear un recurso personalizado en el espacio de nombres gke-operators
.SriovNetworkNodePolicy
A continuación, se muestra un ejemplo de manifiesto de 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
le permite limitar aún más los nodos en los que se deben crear los VFs. Esta limitación se suma a los selectores de SriovOperatorConfig
descritos en la sección anterior.
El campo deviceType
especifica el módulo del kernel que se va a usar en las VFs. Las opciones disponibles para deviceType
son las siguientes:
netdevice
para el módulo de kernel estándar específico de VFvfio-pci
para el controlador VFIO-PCI
El resourceName
define el nombre con el que se representan los VFs en el nodo de Kubernetes.
Una vez completado el proceso de configuración, los nodos de clúster seleccionados contendrán el recurso definido, tal como se muestra en el siguiente ejemplo (fíjate en 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 añadirá el prefijo gke.io/
a todos los recursos que definas con SriovNetworkNodePolicy
.
Especificar un selector de NIC
Para que SriovNetworkNodePolicy
funcione correctamente, especifica al menos un selector en la sección nicSelector
. Este campo contiene varias opciones sobre cómo identificar funciones físicas (PFs) específicas en los nodos del clúster. La mayor parte de la información que requiere este campo se detecta automáticamente y se guarda en el SriovNetworkNodeState
recurso personalizado. Habrá un objeto por cada nodo que pueda gestionar este operador.
Usa el siguiente comando para ver todos los nodos disponibles:
kubectl -n gke-operators get sriovnetworknodestates.sriovnetwork.k8s.cni.cncf.io -o yaml
Este es un ejemplo de 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
Definir la partición de funciones físicas
Presta especial atención al campo pfNames
de la sección nicSelector
. Además de definir el PF exacto que se va a usar, te permite especificar los VFs exactos que se van a usar para el PF especificado y el recurso definido en la política.
Veamos un 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
solo usa VFs numerados del 3 al 6 y muestra solo cuatro VFs disponibles. Como los VFs siempre se crean a partir del índice cero, el número de VFs que solicites, numVfs
, debe ser al menos tan alto como el valor de cierre del intervalo (contando desde cero). Por este motivo, en el ejemplo anterior, numVfs
se ha definido como 7
. Si defines un intervalo de 3 a 4 (enp65s0f0#3-4
), tu numVfs
debe ser al menos 5
.
Si no se especifica la partición, numVfs
define el intervalo de VFs que se está usando, que siempre empieza por cero. Por ejemplo, si defines numVfs=3
sin especificar particiones, se usan las VFs 0-2
.
Acerca de la prioridad de las políticas
Puedes especificar varios objetos SriovNetworkNodePolicy
para gestionar diferentes proveedores o configuraciones de VF. Gestionar varios objetos y proveedores puede resultar problemático cuando varias políticas hacen referencia al mismo PF. Para gestionar estas situaciones, el campo priority
resuelve los conflictos por nodo.
Esta es la lógica de priorización de las políticas de PF superpuestas:
Una política de mayor prioridad sobrescribe una de menor prioridad solo cuando la partición de PF se solapa.
Las políticas con la misma prioridad se combinan:
- Las políticas se ordenan por nombre y se procesan en ese orden
- Las políticas con particiones de PF superpuestas se sobrescriben
- Las políticas con partición de PF no superpuesta se combinan y se presentan todas
Una política de alta prioridad es aquella que tiene un valor numérico más bajo en el campo priority
. Por ejemplo, la prioridad es mayor para una política con priority: 10
que para una política con priority: 20
.
En las siguientes secciones se ofrecen ejemplos de políticas para diferentes configuraciones de partición.
PF particionada
Si se implementan los dos manifiestos SriovNetworkNodePolicy
siguientes, habrá dos recursos disponibles: gke.io/dev-kernel
y gke.io/dev-vfio
. Cada recurso tiene dos VFs que no se solapan.
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 solapada
Si se implementan los dos manifiestos SriovNetworkNodePolicy
siguientes, solo estará disponible el recurso gke.io/dev-vfio
. El intervalo de VF de policy-1
es 0-2
, que se solapa con policy-2
. Debido a la nomenclatura, 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
Si se implementan los dos manifiestos SriovNetworkNodePolicy
siguientes, habrá dos recursos disponibles: gke.io/dev-kernel
y gke.io/dev-vfio
. Cada recurso tiene dos VFs que no se solapan. Aunque policy-1
tiene una prioridad mayor que policy-2
, como las particiones de PF no se solapan, 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"
Comprobar el estado de configuración de la política de SR-IOV
Cuando apliques las políticas de SR-IOV, podrás monitorizar 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 fase actual del daemon de configuración. El estado Succeeded
indica que la configuración ha finalizado. La sección spec
del recurso personalizado SriovNetworkNodeState
define el estado final de la configuración de las VFs de ese nodo en función del número de políticas y sus prioridades. Todos los VFs creados se mostrarán en la sección status
de los PFs especificados.
Aquí tienes 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
Crear un recurso personalizado NetworkAttachmentDefinition
Una vez que hayas configurado correctamente las VFs en el clúster y sean visibles en el nodo de Kubernetes como un recurso, tendrás que crear un NetworkAttachmentDefinition
que haga referencia al recurso. Haz la referencia
con una anotación k8s.v1.cni.cncf.io/resourceName
.
Aquí tienes un ejemplo de manifiesto de 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"
}
}'
El NetworkAttachmentDefinition
debe tener el sriov
como tipo de CNI.
Haz referencia a cualquier recurso personalizado NetworkAttachmentDefinition
desplegado en tus pods con una anotación k8s.v1.cni.cncf.io/networks
.
A continuación, se muestra 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 de NetworkAttachmentDefinition
en cargas de trabajo, no tienes que preocuparte por las definiciones de recursos de los pods ni por la colocación en nodos específicos, ya que se hace automáticamente.
En el ejemplo siguiente se muestra un recurso personalizado NetworkAttachmentDefinition
con una configuración de VLAN. En este ejemplo, todos los VF pertenecen 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
En las siguientes secciones se incluye información para ayudarte a configurar la red SR-IOV.
Reinicios de nodos
Cuando el operador de SR-IOV configura los nodos, es posible que sea necesario reiniciar los nodos. Es posible que tengas que reiniciar los nodos durante la configuración de VF o del kernel. La configuración del kernel implica habilitar la compatibilidad con la función SR-IOV en el sistema operativo.
Adaptadores de red compatibles
En la siguiente tabla se indican los adaptadores de red compatibles con los clústeres de la versión 1.33.x:
Nombre | ID de proveedor | ID del dispositivo | ID de dispositivo 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 | 1592 | 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 |