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 fornece 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 
SriovOperatorConfigrecurso personalizado. - Configure políticas de SR-IOV e configure as suas VFs.
 - Crie um 
NetworkAttachmentDefinitionrecurso 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 defaultSegue-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:
netdevicepara o módulo de kernel padrão específico do VFvfio-pcipara 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 yamlSegue-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 PF não se sobrepõe, unimos 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 SriovNetworkNodeStaterecurso 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 NetworkAttachmentDefinitionrecursos 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 |