Executar cargas de trabalho de computação de alto desempenho (HPC) com o H4D

Este documento explica como executar cargas de trabalho de computação de alta performance (HPC) em clusters do Google Kubernetes Engine (GKE) que usam a série de máquinas H4D e o acesso direto à memória remota (RDMA).

A H4D é uma série de máquinas na família de máquinas com otimização para computação do Compute Engine. A série de máquinas é otimizada para alta performance, baixo custo e escalonabilidade. O H4D funciona bem para aplicativos que escalonam em vários nós. As instâncias H4D configuradas para usar RDMA oferecem suporte a até 200 Gbps de largura de banda de rede entre nós.

Antes de começar

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

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

Configurar o cluster e as redes do GKE

Use o Cluster Toolkit para criar rapidamente um cluster do GKE pronto para produção que usa VMs H4D vinculadas a reservas. As instruções do Cluster Toolkit nesta seção usam o blueprint do GKE H4D.

Como alternativa, use a Google Cloud CLI para ter flexibilidade máxima na configuração do ambiente de cluster com VMs vinculadas a reserva ou de início flexível.

Cluster Toolkit

  1. Configure o Cluster Toolkit. Recomendamos usar o Cloud Shell porque as dependências já estão pré-instaladas para o Cluster Toolkit.

  2. Consiga o endereço IP da máquina host em que você instalou o Cluster Toolkit:

    curl ifconfig.me
    

    Salve esse endereço IP para usar na variável IP_ADDRESS em uma etapa posterior.

  3. Crie um bucket do Cloud Storage para armazenar o estado da implantação do Terraform:

    gcloud storage buckets create gs://BUCKET_NAME \
        --default-storage-class=STANDARD \
        --project=PROJECT_ID \
        --location=COMPUTE_REGION_TERRAFORM_STATE \
        --uniform-bucket-level-access
    gcloud storage buckets update gs://BUCKET_NAME --versioning
    

    Substitua as seguintes variáveis:

    • BUCKET_NAME: o nome do novo bucket do Cloud Storage.
    • PROJECT_ID: o ID do projeto Google Cloud .
    • COMPUTE_REGION_TERRAFORM_STATE: a região de computação em que você quer armazenar o estado da implantação do Terraform.
  4. No blueprint examples/gke-h4d/gke-h4d-deployment.yaml do repositório do GitHub, preencha as seguintes configurações nas seções terraform_backend_defaults e vars para corresponder aos valores específicos da sua implantação:

    • DEPLOYMENT_NAME: um nome exclusivo para o implantação, que precisa ter entre 6 e 30 caracteres. Se o nome da implantação não for exclusivo em um projeto, a criação do cluster vai falhar. O valor padrão é gke-h4d.
    • BUCKET_NAME: o nome do bucket do Cloud Storage criado na etapa anterior.
    • PROJECT_ID: o ID do projeto Google Cloud .
    • COMPUTE_REGION: a região de computação do cluster, que precisa corresponder à região em que as máquinas estão disponíveis para sua reserva.
    • COMPUTE_ZONE: a zona do Compute para o pool de nós de máquinas H4D. Essa zona precisa corresponder à zona em que as máquinas estão disponíveis na sua reserva.
    • NODE_COUNT: o número de nós H4D no seu cluster.
    • IP_ADDRESS/SUFFIX: o intervalo de endereços IP que você quer permitir para se conectar ao cluster. Esse bloco CIDR precisa incluir o endereço IP da máquina que você quer usar para chamar o Terraform. Para mais informações, consulte Como as redes autorizadas funcionam.
    • Para o campo reservation, use uma das seguintes opções, dependendo se você quer segmentar blocos específicos em uma reserva ao provisionar o pool de nós:

      • Para colocar o pool de nós em qualquer lugar da reserva, forneça o nome dela (RESERVATION_NAME).
      • Para segmentar um bloco específico na sua reserva, use os nomes da reserva e do bloco no seguinte formato:

          RESERVATION_NAME/reservationBlocks/BLOCK_NAME
        

        Se você não souber quais blocos estão disponíveis na sua reserva, consulte Ver uma topologia de reserva.

  5. Gere as credenciais padrão do aplicativo (ADC) para dar acesso ao Terraform. Se você estiver usando o Cloud Shell, execute o seguinte comando:

    gcloud auth application-default login
    
  6. Implante o blueprint para provisionar a infraestrutura do GKE usando os tipos de máquina H4D:

    ./gcluster deploy -d examples/gke-h4d/gke-h4d-deployment.yaml examples/gke-h4d/gke-h4d.yaml
    
  7. Quando solicitado, selecione (A)plicar para implantar o blueprint.

  8. Além disso, esse blueprint provisiona uma instância do Filestore e a conecta ao cluster do GKE com um volume permanente (PV). Um exemplo de modelo de job está incluído neste blueprint. Esse modelo executa um job paralelo que lê e grava dados nesse armazenamento compartilhado. Um kubectl create é mostrado nas saídas de implantação e pode ser usado para acionar o job de exemplo.

CLI do Google Cloud

Substitua os seguintes valores nos comandos desta seção:

  • PROJECT_ID: o ID do projeto do Google Cloud .
  • CLUSTER_NAME: o nome do cluster.
  • CONTROL_PLANE_LOCATION: o local do Compute Engine do plano de controle do cluster. Forneça uma região para clusters regionais ou uma zona para clusters zonais. Os clusters regionais são recomendados para cargas de trabalho de produção. Para clusters regionais, a região precisa incluir uma zona em que o H4D esteja disponível. Para clusters zonais, a zona precisa ter disponibilidade do H4D. Se você estiver usando uma reserva, a região e a zona precisam corresponder à região e à zona da reserva.
  • COMPUTE_ZONE: a zona do pool de nós. Precisa ser uma zona em que o H4D esteja disponível. Se você estiver usando uma reserva, a região e a zona precisam corresponder às da reserva. Não é possível criar um pool de nós de várias zonas se você quiser que os nós H4D funcionem com o Cloud RDMA.
  • RDMA_NETWORK_PREFIX: o prefixo da rede RDMA (por exemplo, h4d-rdma).
  • RDMA_SUBNET_CIDR: o intervalo CIDR da sub-rede RDMA. Verifique se esse intervalo não se sobrepõe às redes padrão do cluster.
  • NODE_POOL_NAME: o nome do pool de nós H4D.
  • NODE_COUNT: o número de nós H4D a serem criados no pool de nós.
  • H4D_MACHINE_TYPE: o tipo de máquina H4D a ser usado (por exemplo, h4d-highmem-192-lssd).

Crie um cluster com a CLI gcloud seguindo estas etapas:

  1. Crie VPCs e sub-redes: configure a nuvem privada virtual (VPC) e uma sub-rede padrão para o cluster. Para a placa de rede (NIC) IRDMA, crie uma VPC e uma sub-rede dedicadas. A VPC criada com as instruções a seguir usa, conforme necessário, um perfil de rede VPC do Falcon.

    1. Crie uma VPC para a interface de rede IRDMA que usa o protocolo de transporte RDMA sobre Falcon:

      gcloud compute --project=PROJECT_ID \
        networks create RDMA_NETWORK_PREFIX-net \
        --network-profile=COMPUTE_ZONE-vpc-falcon \
        --subnet-mode=custom
      
    2. Crie uma sub-rede para a rede VPC do Falcon:

      gcloud compute --project=PROJECT_ID \
        networks subnets create \
        RDMA_NETWORK_PREFIX-sub-0 \
        --network=RDMA_NETWORK_PREFIX-net \
        --region=CONTROL_PLANE_LOCATION \
        --range=RDMA_SUBNET_CIDR
      
  2. Criar um cluster do GKE com várias redes: crie o cluster. De maneira opcional, com esse comando, é possível fornecer explicitamente os intervalos de CIDR secundários para serviços e pods.

    Execute este comando:

    gcloud container clusters create CLUSTER_NAME --project PROJECT_ID \
      --enable-dataplane-v2 --enable-ip-alias --location=CONTROL_PLANE_LOCATION \
      --enable-multi-networking \
      [--services-ipv4-cidr=SERVICE_CIDR \
      --cluster-ipv4-cidr=POD_CIDR]
    

    Se você usar essas flags opcionais, substitua os seguintes valores adicionais:

    • SERVICE_CIDR: o intervalo CIDR secundário para serviços.
    • POD_CIDR: o intervalo CIDR secundário para pods.

    Ao usar essas flags, verifique se os intervalos CIDR não se sobrepõem aos intervalos de sub-rede para redes de nós adicionais. Por exemplo, SERVICE_CIDR=10.65.0.0/19 e POD_CIDR=10.64.0.0/19.

  3. Criar objetos de rede do GKE: configure a rede VPC usando conjuntos de parâmetros de rede do GKE. Aplique os objetos GKENetworkParamSet e Network:

    kubectl apply -f - <<EOF
    apiVersion: networking.gke.io/v1
    kind: GKENetworkParamSet
    metadata:
      name: rdma-0
    spec:
      vpc: RDMA_NETWORK_PREFIX-net
      vpcSubnet: RDMA_NETWORK_PREFIX-sub-0
      deviceMode: RDMA
    ---
    apiVersion: networking.gke.io/v1
    kind: Network
    metadata:
      name: rdma-0
    spec:
      type: "Device"
      parametersRef:
        group: networking.gke.io
        kind: GKENetworkParamSet
        name: rdma-0
    EOF
    
  4. Crie um pool de nós H4D: crie um pool de nós que use H4D e se conecte à rede VPC do Falcon. É possível usar nós H4D vinculados a reservas e posicionamento compacto. Ou use nós H4D provisionados com início flexível. Selecione a guia que corresponde à sua opção de consumo:

    Vinculada à reserva

    1. Crie uma política de recursos para posicionamento compacto. O posicionamento compacto otimiza o desempenho de cargas de trabalho de HPC com acoplamento rígido, que são executadas em vários nós, garantindo que os nós estejam localizados fisicamente uns em relação aos outros em uma zona.

      Execute este comando:

      gcloud compute resource-policies create group-placement POLICY_NAME \
          --region REGION --collocation collocated
      

      Substitua os seguintes valores:

      • POLICY_NAME: o nome da política de recursos (por exemplo, h4d-compact).
      • REGION: a região do cluster.
    2. Crie um pool de nós que use H4D e se conecte à rede RDMA:

      gcloud container node-pools create NODE_POOL_NAME --project PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION --cluster CLUSTER_NAME --num-nodes=NODE_COUNT \
        --node-locations=COMPUTE_ZONE \
        --machine-type H4D_MACHINE_TYPE \
        --additional-node-network network=RDMA_NETWORK_PREFIX-net,subnetwork=RDMA_NETWORK_PREFIX-sub-0 \
        --placement-policy POLICY_NAME \
        --max-surge-upgrade 0  \
        --max-unavailable-upgrade MAX_UNAVAILABLE
      

      Substitua MAX_UNAVAILABLE pelo número máximo de nós que podem estar indisponíveis ao mesmo tempo durante um upgrade do pool de nós. Para posicionamento compacto, recomendamos upgrades rápidos sem sobrecarga para otimizar a probabilidade de encontrar nós colocados durante os upgrades.

    Início flexível

    Crie um pool de nós que use nós H4D provisionados com flex-start e se conecte à rede VPC do Falcon:

    gcloud container node-pools create NODE_POOL_NAME --project PROJECT_ID \
        --location=CONTROL_PLANE_LOCATION --cluster CLUSTER_NAME \
        --node-locations=COMPUTE_ZONE \
        --machine-type H4D_MACHINE_TYPE \
        --additional-node-network network=RDMA_NETWORK_PREFIX-net,subnetwork=RDMA_NETWORK_PREFIX-sub-0 \
        --flex-start --enable-autoscaling --reservation-affinity=none \
        --min-nodes=0 --max-nodes=MAX_NODES --num-nodes=0
    

    Substitua MAX_NODES pelo número máximo de nós para escalonar automaticamente o pool de nós especificado por zona.

Preparar a imagem do Docker

Prepare sua imagem usando o exemplo de Dockerfile a seguir:

FROM docker.io/rockylinux/rockylinux:8.10

RUN dnf -y install https://depot.ciq.com/public/download/ciq-sigcloud-next-8/ciq-sigcloud-next-8.x86_64/Packages/c/ciq-sigcloud-next-release-6-1.el8_10.cld_next.noarch.rpm
    && dnf -y update ciq-sigcloud-next-release
    && dnf clean all

RUN dnf install rdma-core libibverbs-utils librdmacm-utils infiniband-diags perftest -y

Para mais informações sobre quais imagens são compatíveis com IRDMA, consulte as guias Interfaces nas tabelas em Detalhes do sistema operacional.

Configurar seus manifestos para RDMA

Para ativar o Cloud RDMA, adicione as seguintes anotações aos metadados do pod:

metadata:
  annotations:
    networking.gke.io/default-interface: 'eth0'
    networking.gke.io/interfaces: |
      [
        {"interfaceName":"eth0","network":"default"},
        {"interfaceName":"eth1","network":"rdma-0"},
      ]

Testar RDMA com rping

Para verificar a funcionalidade do Cloud RDMA, execute rping entre um servidor e um pod de cliente:

  1. No pod do servidor, execute o comando rping:

    rping -s
    
  2. No pod do cliente, execute o comando rping:

    rping -c -C 2 -d -a SERVER_IP
    

    Substitua SERVER_IP pelo endereço IP do pod do servidor.

    Se a operação for bem-sucedida, a saída será semelhante a esta:

    created cm_id 0x5b597bf94800
    cma_event type RDMA_CM_EVENT_ADDR_RESOLVED cma_id 0x5b597bf94800 (parent)
    cma_event type RDMA_CM_EVENT_ROUTE_RESOLVED cma_id 0x5b597bf94800 (parent)
    rdma_resolve_addr - rdma_resolve_route successful
    created pd 0x5b597bf94fa0
    created channel 0x5b597bf96830
    created cq 0x5b597bf94ff0
    created qp 0x5b597bf96c00
    rping_setup_buffers called on cb 0x5b597bf8c820
    allocated & registered buffers...
    cq_thread started.
    cma_event type RDMA_CM_EVENT_ESTABLISHED cma_id 0x5b597bf94800 (parent)
    ESTABLISHED
    rdma_connect successful
    RDMA addr 5b597bf8cd80 rkey dadac8c4 len 64
    send completion
    recv completion
    RDMA addr 5b597bf8cff0 rkey 86ef015f len 64
    send completion
    recv completion
    RDMA addr 5b597bf8cd80 rkey dadac8c4 len 64
    send completion
    recv completion
    RDMA addr 5b597bf8cff0 rkey 86ef015f len 64
    send completion
    recv completion
    rping_free_buffers called on cb 0x5b597bf8c820
    destroy cm_id 0x5b597bf94800
    

A seguir