Alocar recursos de rede usando o DRANET gerenciado pelo GKE

O DRANET do Google Kubernetes Engine (GKE) é um recurso gerenciado do GKE que se baseia no projeto de código aberto DRANET, que implementa a API DRA do Kubernetes para recursos de rede. Com a DRANET, é possível solicitar e alocar recursos de rede de alto desempenho para seus pods, incluindo interfaces de rede que dão suporte ao acesso direto à memória remota (RDMA, na sigla em inglês). Essa abordagem fornece uma API portátil e alinhada ao upstream para o gerenciamento de recursos de rede.

Neste documento, apresentamos uma visão geral conceitual da DRANET do GKE e mostramos como alocar recursos de rede para cargas de trabalho nos clusters do GKE.

Este documento é destinado a arquitetos de nuvem e especialistas em Rede que projetam redes para as organizações. Para uma visão geral de toda a documentação do GKE, consulte Explorar a documentação do GKE. Para saber mais sobre papéis e tarefas comuns mencionados no conteúdo do Google Cloud , consulte Papéis e tarefas comuns de usuário do GKE.

Antes de ler este documento, você precisa conhecer:

Como funciona a DRANET gerenciada pelo GKE

A DRANET gerenciada pelo GKE é implementada por um DaemonSet networking-dra-driver. Esse DaemonSet é executado em nós com GPUs, TPUs ou VMs otimizadas para armazenamento que têm o GKE DRANET ativado.

Ele funciona como um agente no nível do nó para tornar as interfaces de rede detectáveis e alocáveis para pods usando as APIs de alocação dinâmica de recursos (DRA, na sigla em inglês) do Kubernetes.

Nas versões 1.34.1-gke.1829001 e posteriores do GKE, o GKE instala automaticamente recursos DeviceClass para rede. Essas classes definem os tipos de dispositivos de rede que podem ser solicitados. Por exemplo, o GKE cria a classe mrdma.google.com para VMs de GPU, a classe netdev.google.com para TPU e outros dispositivos de rede e a classe irdma.google.com para VMs otimizadas para armazenamento (como Z4M).

Para usar a DRANET do GKE, primeiro ative o driver da DRANET do GKE em um pool de nós com GPUs, TPUs ou VMs otimizadas para armazenamento.

Para solicitar dispositivos de rede para uma carga de trabalho, defina um ResourceClaimTemplate. Esse modelo especifica o DeviceClass e o modo de alocação, como solicitar todos os dispositivos disponíveis em um nó. Na especificação do pod, faça referência a esse modelo em um campo resourceClaims para conceder ao pod acesso às interfaces de rede solicitadas no nó.

Quando usar a DRANET gerenciada pelo GKE

A DRANET do GKE oferece uma maneira padronizada de gerenciar recursos de rede que conhecem a topologia e as dependências. Essa padronização o torna uma solução adequada para IA e ML, grandes sistemas de arquivos paralelos e outras cargas de trabalho de armazenamento com uso intensivo de dados que exigem redes de alto desempenho.

Os casos de uso comuns para solicitar interfaces de rede para um pod incluem:

  • Solicitando todas as interfaces disponíveis com capacidade de RDMA.
  • Solicitar um número específico de interfaces compatíveis com RDMA.
  • Solicitando todas as interfaces não RDMA disponíveis.
  • Solicitar um número específico de interfaces não RDMA.

Principais considerações ao usar a DRANET gerenciada pelo GKE para redes

Considere os seguintes pontos ao usar a DRANET do GKE para rede:

  • Interfaces de rede dedicadas

    Quando você usa a DRANET do GKE para reivindicar uma interface de rede para um pod, essa interface é dedicada a esse pod. Outros pods no mesmo nó não podem compartilhá-la. Essa abordagem ajuda a garantir que o pod tenha acesso exclusivo à largura de banda e aos recursos completos dessa interface, o que é um benefício importante para cargas de trabalho sensíveis ao desempenho.

  • Usar o driver DRANET gerenciado pelo GKE de forma independente

    É possível ativar o driver de DRA do GKE para gerenciar recursos de rede sem ativar outros drivers de DRANET do GKE. Para fazer isso, adicione o rótulo cloud.google.com/gke-networking-dra-driver=true a um pool de nós com GPUs, TPUs ou VMs otimizadas para armazenamento.

  • Usar outros drivers de DRA do GKE

    Para alcançar uma maior capacidade de processamento em cargas de trabalho de IA/ML exigentes, combine a API DRA para aceleradores (como GPUs e TPUs) com a rede gerenciada DRANET do GKE. Essa abordagem combinada melhora o alinhamento de recursos e o reconhecimento de topologia. Para saber como usar a DRA com outros recursos, consulte Preparar a infraestrutura do GKE para cargas de trabalho de DRA.

  • Evitar configurações conflitantes

    O driver DRANET do GKE gerencia interfaces RDMA e gVNICs que não têm intervalos de endereços IP secundários configurados. Não use o driver DRANET do GKE e a API de várias redes do GKE com um recurso de rede do tipo Device no mesmo cluster. Não é possível usar o driver e a API juntos porque as duas APIs tentam gerenciar o mesmo conjunto de NICs, o que pode levar a uma configuração incorreta e a um comportamento imprevisível.

  • Ciclo de vida gerenciado do driver DRANET

    No GKE versão 1.34 e posterior, o GKE cria automaticamente o namespace gerenciado gke-managed-networking-dra-driver no cluster. Assim como várias outras cargas de trabalho do sistema do GKE, os pods do driver DRANET só são executados em nós em que são relevantes (como nós com GPUs, TPUs e outro hardware especializado). Em nós em que o driver não é relevante, nenhum pod para esse driver é executado. Não modifique manualmente o DaemonSet networking-dra-driver. Mudanças manuais, como atualizar o campo nodeAffinity, podem interferir no gerenciamento do recurso DRANET pelo GKE e fazer com que os pods do daemon DRANET sejam programados em nós não compatíveis.

Requisitos

Para usar a DRANET gerenciada pelo GKE, seu ambiente precisa atender aos seguintes requisitos:

  • Standard: 1.34.1-gke.1829001 ou mais recente (1.36.3-gke.1767000 ou mais recente para VMs Z4M).
  • Autopilot: 1.35.2-gke.1842000 ou mais recente (1.37.0-gke.4713000 ou mais recente para VMs Z4M).
  • O GKE Dataplane V2 está ativado no cluster.

Você também precisa usar um dos seguintes tipos de máquina otimizados para acelerador ou armazenamento:

Série de máquina Tipo de máquina Modelo de acelerador Tecnologia de rede DeviceClass
A3 Ultra a3-ultragpu-8g GPU NVIDIA H200 RDMA mrdma.google.com
A4 a4-highgpu-8g GPU NVIDIA B200 RDMA mrdma.google.com
A4X a4x-highgpu-4g GPU NVIDIA GB200 RDMA mrdma.google.com
A4X Max a4x-maxgpu-4g-metal GPU NVIDIA B300 RDMA mrdma.google.com
TPU v7 tpu7x-standard-4t TPU v7 NetDevice netdev.google.com
TPU v6e ct6e-standard-8t TPU Trillium NetDevice netdev.google.com
TPU v6e ct6e-standard-4t TPU Trillium NetDevice netdev.google.com
TPU v6e ct6e-standard-1t TPU Trillium NetDevice netdev.google.com
Z4M Qualquer tipo de máquina Z4M que ofereça suporte ao IRDMA Não relevante (otimizado para armazenamento) RDMA irdma.google.com

Limitações

O GKE DRANET tem as seguintes limitações:

  • Não é possível usar a DRANET do GKE para alocar a placa de rede (NIC) padrão ou NICs virtuais (como veth).
  • Alguns tipos de instância, especificamente nós bare metal como a4x-max, são incompatíveis com clusters de escalonamento automático e do Autopilot.

Considerações específicas da máquina

Dependendo da arquitetura de hardware subjacente dos nós, algumas séries de máquinas exigem outras flags de pool de nós, pacotes de imagens de contêiner ou DaemonSets do sistema para configurar interfaces RDMA com o GKE DRANET.

Bare metal do A4X Max

  • Implantar o asapd-lite: ao usar nós de GPU bare metal, como o A4X Max, é necessário implantar o DaemonSet asapd-lite no cluster. O DaemonSet asapd-lite configura as placas de rede (NICs) RDMA. Sem ele, as interfaces filhas não são criadas, e o driver dranet filtra as NICs de RDMA, impedindo a funcionalidade de RDMA nos pods. Para instruções completas de configuração, consulte Configurar as NICs MRDMA com asapd-lite.

VMs Z4M com otimização para armazenamento

  • Requisitos de imagem de contêiner: para usar o RDMA em instâncias Z4M, use uma imagem de contêiner do Rocky Linux 8 configurada com os pacotes de RDMA de espaço do usuário necessários. Outras distribuições, como Ubuntu ou Debian, não são compatíveis. Os pacotes upstream padrão para essas distribuições não têm as extensões de ABI personalizadas que o driver IRDMA exige. Sem essas extensões, os pacotes falham no ambiente de execução com um erro -ENOSPC. Para instruções de configuração, consulte Usar interfaces RDMA em um pool de nós otimizado para armazenamento.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Para usar a Google Cloud CLI nesta tarefa, instale e inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando o comando gcloud components update. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.

Funções exigidas

Para receber as permissões necessárias para criar pools de nós e alocar recursos de rede, peça ao administrador para conceder a você o papel do IAM de administrador do Kubernetes Engine (roles/container.admin) no projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.

Criar um cluster

Crie um cluster do GKE Standard que use o GKE Dataplane V2:

gcloud container clusters create CLUSTER_NAME \
    --enable-dataplane-v2 \
    --region=CONTROL_PLANE_LOCATION \
    --project=PROJECT_ID \
    --cluster-version=CLUSTER_VERSION

Substitua:

  • CLUSTER_NAME: o nome do novo cluster;
  • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster, como us-central1 ou us-central1-a.
  • PROJECT_ID: o ID do projeto Google Cloud .
  • CLUSTER_VERSION: a versão do GKE para o cluster:
    • VMs Z4M: 1.36.3-gke.1767000 ou mais recente
    • Todas as outras VMs ou instâncias bare metal compatíveis: 1.34.1-gke.1829001 ou mais recente

Usar interfaces RDMA de um pool de nós de GPU

As seções a seguir descrevem como configurar um pool de nós de GPU e uma carga de trabalho para usar interfaces de rede RDMA com o GKE DRANET.

Ativar o driver DRANET gerenciado pelo GKE em um pool de nós de GPU

Para ativar o driver DRANET do GKE em um pool de nós de GPU compatível com RDMA, adicione o rótulo cloud.google.com/gke-networking-dra-driver=true ao criar o pool de nós.

gcloud beta container node-pools create NODE_POOL_NAME \
  --region=REGION \
  --cluster=CLUSTER_NAME \
  --node-locations=NODE_LOCATIONS \
  --accelerator type=ACCELERATOR_TYPE,count=ACCELERATOR_COUNT,gpu-driver-version=DRIVER_VERSION \
  --machine-type=MACHINE_TYPE \
  --num-nodes=NUM_NODES \
  --reservation-affinity=specific \
  --reservation=projects/RESERVATION_PROJECT/reservations/RESERVATION_NAME/reservationBlocks/RESERVATION_BLOCK \
  --accelerator-network-profile=auto \
  --node-labels=cloud.google.com/gke-networking-dra-driver=true

Substitua:

  • NODE_POOL_NAME: o nome do novo pool de nós.
  • REGION: a região do Google Cloud para o cluster.
  • CLUSTER_NAME: o nome do cluster.
  • ACCELERATOR_TYPE: o tipo de acelerador de GPU:

    Exemplo:

    • VMs A4: insira nvidia-b200.
    • VMs A3 Ultra: insira nvidia-h200-141gb.
  • ACCELERATOR_COUNT: o número de GPUs que serão anexadas aos nós no pool de nós. Por exemplo, para as VMs a4-highgpu-8g e a3-ultragpu-8g, a quantidade de GPUs é 8.

  • DRIVER_VERSION: a versão do driver de GPU a ser usada. Por exemplo, default ou latest.

  • MACHINE_TYPE: o tipo de máquina do pool de nós, por exemplo, a3-ultragpu-8g.

  • NUM_NODES: o número de nós do pool de nós. Para início flexível, esse valor precisa ser definido como 0.

  • RESERVATION_PROJECT: o ID do projeto da reserva.

  • RESERVATION_NAME: o nome da sua reserva. Para encontrar esse valor, consulte Ver solicitações de reserva adiantada.

  • RESERVATION_BLOCK: o nome de um bloco específico dentro da reserva. Para encontrar esse valor, consulte Ver solicitações de reserva adiantada.

Esse comando usa perfis de rede do acelerador para configurar automaticamente redes VPC e sub-redes para as VMs de acelerador. Como alternativa, é possível especificar explicitamente sua rede VPC e as sub-redes.

Implantar recursos de RDMA de uma carga de trabalho

Para alocar recursos de RDMA para um pod, especifique um ResourceClaimTemplate.

  1. Crie um ResourceClaimTemplate para definir como alocar os dispositivos RDMA. O manifesto a seguir solicita todos os dispositivos mrdma disponíveis no nó. Salve o manifesto como all-mrdma-template.yaml:

    apiVersion: resource.k8s.io/v1
    kind: ResourceClaimTemplate
    metadata:
      name: all-mrdma
    spec:
      spec:
        devices:
          requests:
          - name: req-mrdma
            exactly:
              deviceClassName: mrdma.google.com
              allocationMode: All
    
  2. Aplique o manifesto:

    kubectl apply -f all-mrdma-template.yaml
    
  3. Implante a carga de trabalho e faça referência ao ResourceClaimTemplate. O manifesto a seguir implanta um pod que faz referência ao modelo all-mrdma, que concede ao pod acesso às interfaces RDMA no nó. Salve o manifesto como agnhost-rdma-pod.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: agnhost-rdma
      namespace: default
      labels:
        app: agnhost
    spec:
      containers:
      - name: agnhost
        image: registry.k8s.io/e2e-test-images/agnhost:2.39
        args: ["netexec", "--http-port", "80"]
        ports:
        - name: agnhost-port
          containerPort: 80
        resources:
          claims:
          - name: rdma
          limits:
            nvidia.com/gpu: 1
      resourceClaims:
      - name: rdma
        resourceClaimTemplateName: all-mrdma
    
  4. Aplique o manifesto:

    kubectl apply -f agnhost-rdma-pod.yaml
    
  5. Verifique se as outras interfaces de rede alocadas estão visíveis dentro do pod.

    kubectl exec agnhost-rdma -- ls /sys/class/net
    

    O exemplo de saída a seguir mostra as interfaces padrão eth0 e lo, além das interfaces RDMA alocadas, como gpu0rdma0. O número e os nomes das interfaces de rede (NICs) variam de acordo com o tipo de máquina do nó do GKE.

    eth0
    gpu0rdma0
    gpu1rdma0
    gpu2rdma0
    gpu3rdma0
    lo
    

Usar interfaces de rede não RDMA em um pool de nós de TPU

As seções a seguir descrevem como configurar um pool de nós de TPU e uma carga de trabalho para usar interfaces de rede que não são RDMA com o GKE DRANET.

Verificar DeviceClasses de rede

Verifique se os recursos DeviceClass para rede existem no cluster.

kubectl get deviceclass netdev.google.com

O resultado será o seguinte:

NAME                AGE
netdev.google.com   2d22h

Ativar o driver DRANET gerenciado pelo GKE em um pool de nós de fração de TPU

Para ativar o driver DRANET do GKE ao criar um pool de nós de fração de TPU, adicione o rótulo cloud.google.com/gke-networking-dra-driver=true.

gcloud beta container node-pools create NODE_POOL_NAME \
    --location=LOCATION \
    --cluster=CLUSTER_NAME \
    --node-locations=NODE_LOCATIONS \
    --machine-type=MACHINE_TYPE \
    --tpu-topology=TPU_TOPOLOGY \
    --num-nodes=NUM_NODES \
    --accelerator-network-profile=auto \
    --node-labels=cloud.google.com/gke-networking-dra-driver=true

Substitua:

  • NODE_POOL_NAME: o nome do novo pool de nós.
  • LOCATION: a região ou zona do Google Cloud do cluster.
  • CLUSTER_NAME: o nome do cluster.
  • NODE_LOCATIONS: as zonas do Google Cloud para os nós no pool de nós.
  • MACHINE_TYPE: o tipo de máquina a ser usado para nós. Para mais informações sobre os tipos de máquinas compatíveis com TPU, consulte Escolher a versão da TPU.
  • TPU_TOPOLOGY: a topologia da TPU, por exemplo, 2x4x4. O formato da topologia depende da versão da TPU. Para saber mais sobre as topologias de TPU, consulte Escolher uma topologia.
  • NUM_NODES: o número de nós no pool de nós.

Para mais informações, consulte Criar um pool de nós de fração de TPU de host único.

Implantar uma carga de trabalho que reivindica todos os dispositivos de rede

Para alocar dispositivos de rede que não sejam RDMA para um pod, especifique um ResourceClaimTemplate.

  1. Crie um ResourceClaimTemplate que faça referência ao DeviceClass netdev.google.com. O manifesto a seguir solicita todos os dispositivos de rede não RDMA disponíveis no nó.

    Salve o manifesto como all-netdev-template.yaml:

    apiVersion: resource.k8s.io/v1
    kind: ResourceClaimTemplate
    metadata:
      name: all-netdev
    spec:
      spec:
        devices:
          requests:
          - name: req-netdev
            exactly:
              deviceClassName: netdev.google.com
              allocationMode: All
    
  2. Aplique o manifesto:

    kubectl apply -f all-netdev-template.yaml
    
  3. Implante a carga de trabalho e faça referência ao ResourceClaimTemplate. O manifesto a seguir implanta um pod que usa o modelo all-netdev para conceder ao pod acesso a todos os dispositivos de rede que não são RDMA no nó. Salve o manifesto como netdev-pod.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: agnhost-netdev
      namespace: default
      labels:
        app: agnhost
    spec:
      containers:
      - name: agnhost
        image: registry.k8s.io/e2e-test-images/agnhost:2.39
        args: ["netexec", "--http-port", "80"]
        ports:
        - name: agnhost-port
          containerPort: 80
        resources:
          claims:
          - name: netdev
          limits:
            google.com/tpu: 4
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: TPU_ACCELERATOR
        cloud.google.com/gke-tpu-topology: TPU_TOPOLOGY
      resourceClaims:
      - name: netdev
        resourceClaimTemplateName: all-netdev
    

    Substitua:

    • TPU_ACCELERATOR: o tipo de acelerador de TPU, por exemplo, tpu-v5p-slice.
    • TPU_TOPOLOGY: a topologia da TPU, por exemplo, 2x4x4.
  4. Aplique o manifesto:

    kubectl apply -f netdev-pod.yaml
    
  5. Verifique se as outras interfaces de rede alocadas estão visíveis dentro do pod.

    kubectl exec agnhost-netdev -- ls /sys/class/net
    

    O exemplo de saída a seguir mostra as interfaces padrão eth0 e lo, além dos dispositivos de rede alocados, que têm nomes como eth1 e eth2. O número de NICs e os nomes delas variam de acordo com o tipo de máquina do nó do GKE.

    eth0
    eth1
    eth2
    lo
    

Usar interfaces RDMA em um pool de nós otimizado para armazenamento

As seções a seguir descrevem como configurar um pool de nós otimizado para armazenamento e uma carga de trabalho para usar interfaces de rede RDMA com o GKE DRANET, usando uma VM Z4M (z4m-highmem-192) como exemplo.

Criar um pool de nós com armazenamento otimizado

Crie um pool de nós otimizado para armazenamento com a flag --accelerator-network-profile=auto para que o GKE provisione e anexe automaticamente as redes VPC, sub-redes e interfaces de rede secundárias do Falcon. Nos pools de nós Z4M, o GKE ativa a DRANET por padrão. Portanto, não é necessário especificar o rótulo de nó cloud.google.com/gke-networking-dra-driver=true ao criar o pool de nós. Este exemplo usa o tipo de máquina z4m-highmem-192, que tem NICs físicas duplas do Titanium e fornece duas interfaces RDMA. Para ver a lista de tipos de máquina compatíveis, consulte Requisitos.

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --project=PROJECT_ID \
    --zone=ZONE \
    --machine-type=z4m-highmem-192 \
    --num-nodes=NUM_NODES \
    --accelerator-network-profile=auto

Substitua:

  • NODE_POOL_NAME: o nome do novo pool de nós.
  • CLUSTER_NAME: o nome do cluster.
  • PROJECT_ID: o ID do projeto Google Cloud .
  • ZONE: a zona do Google Cloud para o pool de nós.
  • NUM_NODES: o número de nós no pool de nós. Para testar o tráfego RDMA entre nós com os pods de exemplo rdma-server e rdma-client, especifique pelo menos 2.

Preparar a imagem do contêiner de carga de trabalho otimizada para armazenamento

As cargas de trabalho que usam o Cloud RDMA em nós otimizados para armazenamento exigem uma imagem de contêiner do Rocky Linux 8 com as bibliotecas RDMA de espaço do usuário personalizadas (rdma-core) para o Cloud RDMA instaladas. Não use pacotes upstream padrão. Eles não têm as extensões de ABI personalizadas exigidas pelo driver IRDMA do host e falham no ambiente de execução com erros -ENOSPC. Para verificar as atribuições de endereço IP e testar a conectividade RDMA, instale também iproute, libibverbs-utils, librdmacm-utils, infiniband-diags e perftest.

Para ver um exemplo de Dockerfile que configura o Package Repository necessário, consulte Preparar a imagem Docker. No comando dnf install, inclua iproute para inspecionar as atribuições de IP com o comando ip. Para mais informações sobre os pacotes necessários, consulte RPMs do Cloud RDMA.

Implantar uma carga de trabalho com recursos de RDMA

Para alocar interfaces RDMA a um pod em um nó otimizado para armazenamento, crie um ResourceClaimTemplate que solicite o irdma.google.com DeviceClass:

  1. Crie um manifesto ResourceClaimTemplate e salve-o como irdma-template.yaml:

    apiVersion: resource.k8s.io/v1
    kind: ResourceClaimTemplate
    metadata:
      name: irdma-template
    spec:
      spec:
        devices:
          requests:
          - name: irdma
            exactly:
              deviceClassName: irdma.google.com
              allocationMode: ExactCount
              count: 2
    

    Nesse manifesto:

    • deviceClassName: irdma.google.com: solicita interfaces de rede IRDMA gerenciadas pelo DRANET do GKE em nós otimizados para armazenamento.
    • allocationMode: ExactCount e count: 2: solicita as duas interfaces IRDMA disponíveis em um nó z4m-highmem-192. Se a carga de trabalho precisar apenas de uma interface RDMA ou se você usar um tipo de máquina Z4M que forneça uma interface IRDMA, especifique 1.
  2. Aplique o manifesto:

    kubectl apply -f irdma-template.yaml
    
  3. Crie um manifesto que defina dois pods, rdma-server e rdma-client, para que você possa testar o tráfego RDMA entre nós. Cada pod adiciona a capacidade IPC_LOCK e faz referência ao ResourceClaimTemplate irdma-template. Salve o manifesto como irdma-pods.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: rdma-server
      labels:
        app: perftest
        role: server
    spec:
      restartPolicy: Never
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values: ["perftest"]
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: perftest
        image: IMAGE_URI
        command: ["sleep", "infinity"]
        securityContext:
          capabilities:
            add: ["IPC_LOCK"]
        resources:
          claims:
          - name: irdma
      resourceClaims:
      - name: irdma
        resourceClaimTemplateName: irdma-template
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: rdma-client
      labels:
        app: perftest
        role: client
    spec:
      restartPolicy: Never
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values: ["perftest"]
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: perftest
        image: IMAGE_URI
        command: ["sleep", "infinity"]
        securityContext:
          capabilities:
            add: ["IPC_LOCK"]
        resources:
          claims:
          - name: irdma
      resourceClaims:
      - name: irdma
        resourceClaimTemplateName: irdma-template
    

    Substitua as duas instâncias de IMAGE_URI pelo URI da imagem de contêiner do RDMA do Rocky Linux 8.

    Nesse manifesto:

    • metadata.labels: rotula cada pod com app: perftest e um rótulo role. Os dois pods compartilham o rótulo app: perftest para que a regra de antiafinidade se aplique a eles. O rótulo role distingue o pod rdma-server (role: server) do pod rdma-client (role: client) para que você possa testar a conectividade RDMA entre pods em nós.
    • affinity.podAntiAffinity: impede que o Kubernetes programe pods que compartilham o rótulo app: perftest no mesmo nó. Como os dois pods têm esse rótulo, eles são executados em hosts físicos separados para testes de RDMA entre nós, mesmo quando o ResourceClaimTemplate solicita apenas uma interface (count: 1). O pool de nós precisa ter pelo menos dois nós para programar os dois pods.
    • securityContext.capabilities.add: ["IPC_LOCK"]: permite que o contêiner bloqueie páginas de memória, o que é necessário para que as bibliotecas de espaço do usuário do RDMA registrem regiões de memória para acesso direto à memória.
    • spec.resourceClaims: gera um ResourceClaim específico do pod (chamado irdma) do ResourceClaimTemplate irdma-template.
    • containers.resources.claims: concede ao contêiner perftest acesso às interfaces alocadas pela declaração irdma.
  4. Aplique o manifesto:

    kubectl apply -f irdma-pods.yaml
    
  5. Verifique se as interfaces RDMA alocadas (rdma0 e rdma1) estão visíveis no pod do servidor:

    kubectl exec rdma-server -- ip -br addr show
    

    O resultado será o seguinte:

    lo               UNKNOWN        127.0.0.1/8
    rdma1            UP             10.5.0.3/32
    rdma0            UP             10.31.0.3/32
    eth0@if18        UP             10.120.2.6/32
    

Para verificar o tráfego de RDMA entre os dois pods, execute rping entre rdma-server e rdma-client:

  1. Inicie o servidor rping no pod do servidor:

    kubectl exec -it rdma-server -- rping -s -a RDMA_IP -v -d
    

    Substitua RDMA_IP pelo endereço IP rdma0 ou rdma1 do pod do servidor, como 10.31.0.3.

  2. Em um segundo terminal, execute o cliente rping no pod cliente:

    kubectl exec -it rdma-client -- rping -c -a RDMA_IP -C 5 -v -d
    

    Na saída do cliente, verifique os seguintes indicadores de uma conexão RDMA bem-sucedida:

    • RDMA_CM_EVENT_ADDR_RESOLVED e RDMA_CM_EVENT_ROUTE_RESOLVED: confirma que o gerenciador de comunicação RDMA resolveu o endereço IP e a rota RDMA de destino.
    • ESTABLISHED e rdma_connect successful: confirma que o cliente criou o par de filas (qp), a fila de conclusão (cq) e o domínio de proteção (pd) e estabeleceu a conexão RDMA.
    • Cinco entradas send completion, recv completion e ping data: rdma-ping-: confirma que cinco iterações de ida e volta de leitura e gravação de RDMA foram concluídas na interface RDMA antes de fechar a conexão (destroy cm_id).

Ativar a DRANET com uma ComputeClass personalizada

Para usar a DRANET gerenciada pelo GKE em clusters do Autopilot ou com o provisionamento automático de nós em clusters do Standard, use um recurso ComputeClass personalizado para ativar o recurso.

  1. Crie um manifesto ComputeClass que ative o driver DRANET e defina o perfil de rede do acelerador como auto:

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: dranet-compute-class
    spec:
      nodePoolAutoCreation:
        enabled: true
      nodePoolConfig:
        dra:
          networking:
            enabled: true
      priorities:
      - machineType: MACHINE_TYPE
        # Omit the gpu section for storage-optimized VMs (such as Z4M).
        gpu:
          count: GPU_COUNT
          type: GPU_TYPE
        acceleratorNetworkProfile: auto
    

    Substitua:

    • MACHINE_TYPE: o tipo de máquina do pool de nós, como a3-ultragpu-8g ou z4m-highmem-192.
    • GPU_COUNT: o número de GPUs para o tipo de máquina.
    • GPU_TYPE: o tipo de GPU, como nvidia-h200.
  2. Aplique o manifesto:

    kubectl apply -f COMPUTE_CLASS_FILENAME.yaml
    
  3. Na especificação do pod, faça referência à ComputeClass usando o seletor de nós cloud.google.com/compute-class:

    apiVersion: v1
    kind: Pod
    metadata:
      name: dranet-pod
    spec:
      nodeSelector:
        cloud.google.com/compute-class: "dranet-compute-class"
      ...
    

Solicitar um número específico de dispositivos de rede

Os exemplos anteriores de GPU e TPU mostram como solicitar todos os dispositivos de rede disponíveis de um determinado tipo definindo allocationMode como All. Para solicitar um número específico de dispositivos, defina allocationMode como ExactCount no ResourceClaimTemplate, conforme mostrado em Implantar uma carga de trabalho com recursos de RDMA.

O exemplo a seguir solicita dois dispositivos de rede RDMA:

apiVersion: resource.k8s.io/v1
kind: ResourceClaimTemplate
metadata:
  name: two-mrdma
spec:
  spec:
    devices:
      requests:
      - name: req-mrdma
        exactly:
          deviceClassName: mrdma.google.com
          allocationMode: ExactCount
          count: 2

A seguir