Este documento descreve como configurar a rede de virtualização de entrada/saída de raiz única (SR-IOV) para o Google Distributed Cloud. A SR-IOV oferece virtualização de E/S para disponibilizar uma placa de rede (NIC) como dispositivos de rede no kernel do Linux. Isto permite-lhe gerir e atribuir ligações de rede aos seus pods. O desempenho é melhorado à medida que os pacotes se movem diretamente entre a NIC e o pod.
Use esta funcionalidade se precisar de uma rede rápida para as cargas de trabalho do pod. O SR-IOV para o Google Distributed Cloud permite-lhe configurar as funções virtuais (VFs) nos dispositivos suportados dos nós do cluster. Também pode especificar o módulo do kernel específico a associar aos VFs.
Esta funcionalidade está disponível para clusters que executam cargas de trabalho, como clusters híbridos, autónomos e de utilizadores. A funcionalidade de rede SR-IOV requer que o cluster tenha, pelo menos, dois nós.
O processo de configuração consiste nos seguintes passos gerais:
- Configure o cluster para ativar a rede SR-IOV.
- Configure o operador SR-IOV, um
SriovOperatorConfig
recurso personalizado. - Configure políticas de SR-IOV e configure as suas VFs.
- Crie um
NetworkAttachmentDefinition
recurso personalizado que faça referência aos seus VFs.
Requisitos
A funcionalidade de rede SR-IOV requer que os controladores oficiais dos adaptadores de rede estejam presentes nos nós do cluster. Instale os controladores antes de usar o operador SR-IOV. Além disso, para usar o módulo vfio-pci
para os seus VFs, certifique-se de que o módulo está disponível nos nós onde vai ser usado.
Ative a rede SR-IOV para um cluster
Para ativar a rede SR-IOV para o Google Distributed Cloud, adicione o campo
multipleNetworkInterfaces
e o campo
sriovOperator
à secção clusterNetwork
do objeto Cluster e defina ambos os campos
como true
.
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: cluster1
spec:
clusterNetwork:
multipleNetworkInterfaces: true
sriovOperator: true
...
O campo sriovOperator
é mutável e pode ser alterado após a criação do cluster.
Configure o operador SR-IOV
O recurso personalizado SriovOperatorConfig
fornece a configuração global para a funcionalidade de rede SR-IOV. Este recurso personalizado agrupado tem o nome default
e está no espaço de nomes gke-operators
. O recurso personalizado SriovOperatorConfig
é respeitado apenas para este nome e espaço de nomes.
Pode editar este objeto com o seguinte comando:
kubectl -n gke-operators edit sriovoperatorconfigs.sriovnetwork.k8s.cni.cncf.io default
Segue-se um exemplo de uma configuração 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
A secção configDaemonNodeSelector
permite-lhe limitar os nós que o operador SR-IOV pode processar. No exemplo anterior, o operador está limitado apenas aos nós que têm uma etiqueta nodePool: withSriov
. Se o campo configDaemonNodeSelector
não for especificado, são aplicadas as seguintes etiquetas predefinidas:
beta.kubernetes.io/os: linux
node-role.kubernetes.io/worker: ""
O campo disableDrain
especifica se deve ser realizada uma operação de esvaziamento do nó do Kubernetes antes de o nó ter de ser reiniciado ou antes de uma configuração de VF específica ser alterada.
Crie políticas de SR-IOV
Para configurar VFs específicos no cluster, tem de criar um
SriovNetworkNodePolicy
recurso personalizado no espaço de nomes gke-operators
.
Segue-se um exemplo de manifesto para um SriovNetworkNodePolicy
recurso personalizado:
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"
A secção nodeSelector
permite-lhe limitar ainda mais os nós nos quais os VFs têm de ser criados. Esta limitação é adicional aos seletores do elemento SriovOperatorConfig
descritos na secção anterior.
O campo deviceType
especifica o módulo do kernel a usar para os VFs. As opções
disponíveis para deviceType
são:
netdevice
para o módulo de kernel padrão específico do VFvfio-pci
para o controlador VFIO-PCI
O elemento resourceName
define o nome pelo qual os VFs são representados no nó do Kubernetes.
Após a conclusão do processo de configuração, os nós do cluster selecionados contêm o recurso definido, conforme apresentado no exemplo seguinte (repare no 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"
O operador adiciona sempre o prefixo gke.io/
a todos os recursos que definir com SriovNetworkNodePolicy
.
Especifique um seletor de NIC
Para que o elemento SriovNetworkNodePolicy
funcione corretamente, especifique, pelo menos, um seletor na secção nicSelector
. Este campo contém várias opções sobre como identificar funções físicas (PFs) específicas nos nós do cluster. A maioria das informações necessárias para este campo é descoberta automaticamente e guardada no recurso personalizado SriovNetworkNodeState
. Vai existir um objeto para cada nó que este operador pode processar.
Use o seguinte comando para ver todos os nós disponíveis:
kubectl -n gke-operators get sriovnetworknodestates.sriovnetwork.k8s.cni.cncf.io -o yaml
Segue-se um exemplo de um nó:
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
Defina a partição de funções físicas
Preste especial atenção ao campo pfNames
da secção nicSelector
. Além de definir o PF exato a usar, permite-lhe especificar os VFs exatos a usar para o PF especificado e o recurso definido na política.
Segue-se um exemplo:
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"
No exemplo anterior, o recurso gke.io/mlnx
usa apenas VFs numerados de 3 a 6 e mostra apenas quatro VFs disponíveis. Uma vez que os VFs são sempre criados a partir do índice zero, o número de VFs pedido, numVfs
, tem de ser, pelo menos, tão elevado quanto o valor de fecho do intervalo (a contar do zero). Esta lógica de numeração explica por que motivo
numVfs
está definido como 7
no exemplo anterior. Se definir um intervalo de 3 a 4 (enp65s0f0#3-4
), o seu numVfs
tem de ser, pelo menos, 5
.
Quando a partição não é especificada, o numVfs
define o intervalo de VFs que está a ser usado, que começa sempre a partir de zero. Por exemplo, se definir numVfs=3
sem especificar a partição, são usados VFs 0-2
.
Compreenda a prioridade das políticas
Pode especificar vários objetos SriovNetworkNodePolicy
para processar vários fornecedores ou diferentes configurações de VF. A gestão de vários objetos e fornecedores pode tornar-se problemática quando várias políticas fazem referência ao mesmo PF. Para lidar com estas situações, o campo priority
resolve os conflitos por nó.
Segue-se a lógica de priorização para políticas de PF sobrepostas:
Uma política de prioridade mais elevada substitui uma política de prioridade mais baixa apenas quando a partição de PF se sobrepõe.
As políticas com a mesma prioridade são unidas:
- As políticas são ordenadas por nome e processadas nessa ordem
- As políticas com partição de PF sobreposta são substituídas
- As políticas com partição de PF não sobreposta são unidas e todas estão presentes
Uma política de prioridade elevada é aquela com um valor numérico mais baixo no campo priority
. Por exemplo, a prioridade é mais elevada para uma política com priority: 10
do que para uma política com priority: 20
.
As secções seguintes fornecem exemplos de políticas para diferentes configurações de partição.
AP particionada
A implementação dos dois manifestos SriovNetworkNodePolicy
seguintes resulta em dois recursos disponíveis: gke.io/dev-kernel
e gke.io/dev-vfio
. Cada recurso tem dois VFs que não se sobrepõem.
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"
Partição de PF sobreposta
A implementação dos dois manifestos SriovNetworkNodePolicy
seguintes resulta na disponibilidade apenas do recurso gke.io/dev-vfio
. O intervalo de VF de policy-1
é
0-2
, que se sobrepõe a policy-2
. Devido à nomenclatura, policy-2
é processado
depois de policy-1
. Por conseguinte, apenas o recurso especificado em policy-2
,
gke.io/dev-vfio
, está disponível.
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"
Particionamento de PF não sobreposto com diferentes prioridades
A implementação dos dois manifestos SriovNetworkNodePolicy
seguintes resulta em dois recursos disponíveis: gke.io/dev-kernel
e gke.io/dev-vfio
. Cada recurso tem dois VFs que não se sobrepõem. Embora policy-1
tenha uma prioridade mais elevada do que policy-2
, uma vez que a partição de PF não se sobrepõe, vamos unir as duas 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"
Verifique o estado da configuração da política SR-IOV
Quando aplica as políticas de SR-IOV, pode acompanhar e ver a configuração final dos nós no recurso personalizado SriovNetworkNodeState
para o nó específico. Na secção status
, o campo syncStatus
representa
a fase atual do daemon de configuração. O estado Succeeded
indica que a configuração está concluída. A secção spec
do recurso personalizado SriovNetworkNodeState
define o estado final da configuração dos VFs para esse nó, com base no número de políticas e nas respetivas prioridades. Todas as VFs criadas são apresentadas na secção status
para os PFs especificados.
Segue-se um exemplo de um SriovNetworkNodeState
recurso personalizado:
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
Crie um NetworkAttachmentDefinition
recurso personalizado
Depois de configurar com êxito as VFs no cluster e estas ficarem visíveis no nó do Kubernetes como um recurso, tem de criar um NetworkAttachmentDefinition
que faça referência ao recurso. Faça a referência
com uma anotação k8s.v1.cni.cncf.io/resourceName
.
Segue-se um exemplo de um manifesto NetworkAttachmentDefinition
que faz referência ao 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"
}
}'
O NetworkAttachmentDefinition
tem de ter o sriov
como tipo de CNI.
Referencie quaisquer NetworkAttachmentDefinition
recursos personalizados implementados nos seus pods com uma anotação k8s.v1.cni.cncf.io/networks
.
Segue-se um exemplo de como referenciar o recurso personalizado NetworkAttachmentDefinition
anterior num pod:
apiVersion: v1
kind: Pod
metadata:
name: samplepod
annotations:
k8s.v1.cni.cncf.io/networks: gke-sriov-1
spec:
containers:
...
Quando faz referência a um recurso personalizado NetworkAttachmentDefinition
em cargas de trabalho,
não tem de se preocupar com as definições de recursos dos pods nem com o posicionamento em
nós específicos, uma vez que isto é feito automaticamente.
O exemplo seguinte mostra um recurso personalizado NetworkAttachmentDefinition
com uma configuração de VLAN. Neste exemplo, cada VF pertence à 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"
}
}'
Informações adicionais
As secções seguintes contêm informações para ajudar a configurar a rede SR-IOV.
Reinícios do nó
Quando o operador SR-IOV configura os nós, estes podem ter de ser reiniciados. Pode ser necessário reiniciar os nós durante a configuração do VF ou do kernel. A configuração do kernel envolve a ativação do suporte da funcionalidade SR-IOV no sistema operativo.
Adaptadores de rede suportados
A tabela seguinte indica os adaptadores de rede suportados para clusters da versão 1.33.x:
Nome | ID do fornecedor | ID do dispositivo | ID do 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 |