Este documento descreve como configurar o gateway de inferência de vários clusters do Google Kubernetes Engine (GKE) para balancear a carga de maneira inteligente das cargas de trabalho de inferência de IA/ML em vários clusters do GKE, que podem abranger diferentes regiões. Essa configuração usa a API Gateway, Entrada em vários clusters e recursos personalizados, como InferencePool e InferenceObjective, para melhorar a escalonabilidade, ajudar a garantir a alta disponibilidade e otimizar a utilização de recursos para as implantações de serviço de modelo.
Para entender este documento, familiarize-se com o seguinte:
- Orquestração de IA/ML no GKE.
- Terminologia da IA generativa.
- Conceitos de rede do GKE, incluindo:
- Balanceamento de carga em Google Cloud, principalmente como os balanceadores de carga interagem com o GKE.
Este documento é destinado aos seguintes perfis:
- Engenheiros de machine learning (ML), administradores e operadores de plataforma ou especialistas em dados e IA que querem usar os recursos de orquestração de contêineres do GKE para veicular cargas de trabalho de IA/ML.
- Arquitetos de nuvem ou especialistas em redes que interagem com a rede do GKE.
Para saber mais sobre papéis comuns e tarefas de exemplo referenciados no conteúdo doGoogle Cloud , consulte Funções e tarefas de usuário comuns do GKE Enterprise.
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.
Ative as API Compute Engine, Google Kubernetes Engine, Model Armor e Network Services.
Acesse Ativar acesso a APIs e siga as instruções.
Ative a API Autoscaling.
Acesse a API Autoscaling e siga as instruções.
Pré-requisitos do Hugging Face:
- Crie uma conta do Hugging Face caso ainda não tenha uma.
- Solicite e receba aprovação para acessar o modelo Llama 3.1 no Hugging Face.
- Assine o contrato de consentimento de licença na página do modelo no Hugging Face.
- Gere um token de acesso do Hugging Face com pelo menos permissões de
Read.
Requisitos
- Verifique se o projeto tem cota suficiente para GPUs H100. Para mais informações, consulte Planejar cota de GPU e Cotas de alocação.
- Use o GKE versão 1.34.1-gke.1127000 ou posterior.
- Use CLI gcloud versão 480.0.0 ou mais recente.
- As contas de serviço do nó precisam ter permissões para gravar métricas na API Autoscaling.
- Você precisa ter os seguintes papéis do IAM no projeto:
roles/container.admineroles/iam.serviceAccountAdmin.
Configurar o gateway de inferência de vários clusters
Para configurar o Inference Gateway multicluster do GKE, siga estas etapas:
Criar clusters e pools de nós
Para hospedar suas cargas de trabalho de inferência de IA/ML e ativar o balanceamento de carga entre regiões, crie dois clusters do GKE em regiões diferentes, cada um com um pool de nós de GPU H100.
Crie o primeiro cluster:
gcloud container clusters create CLUSTER_1_NAME \ --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediatelySubstitua:
CLUSTER_1_NAME: o nome do primeiro cluster, por exemplo,gke-west.LOCATION: a região do primeiro cluster, por exemplo,europe-west3.PROJECT_ID: o ID do projeto.GKE_VERSION: a versão do GKE a ser usada, por exemplo,1.34.1-gke.1127000.MACHINE_TYPE: o tipo de máquina dos nós do cluster, por exemplo,c2-standard-16.DISK_TYPE: o tipo de disco para os nós do cluster, por exemplo,pd-standard.
Crie um pool de nós H100 para o primeiro cluster:
gcloud container node-pools create NODE_POOL_NAME \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_1_ZONE \ --node-locations=CLUSTER_1_ZONE \ --cluster=CLUSTER_1_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediatelySubstitua:
NODE_POOL_NAME: o nome do pool de nós, por exemplo,h100.PROJECT_ID: o ID do projeto.CLUSTER_1_ZONE: a zona do primeiro cluster, por exemplo,europe-west3-c.CLUSTER_1_NAME: o nome do primeiro cluster, por exemplo,gke-west.NODE_POOL_MACHINE_TYPE: o tipo de máquina para o pool de nós, por exemplo,a3-highgpu-2g.NUM_NODES: o número de nós no pool de nós, por exemplo,3.
Receba as credenciais:
gcloud container clusters get-credentials CLUSTER_1_NAME \ --location CLUSTER_1_ZONE \ --project=PROJECT_IDSubstitua:
PROJECT_ID: o ID do projeto.CLUSTER_1_NAME: o nome do primeiro cluster, por exemplo,gke-west.CLUSTER_1_ZONE: a zona do primeiro cluster, por exemplo,europe-west3-c.
No primeiro cluster, crie um secret para o token do Hugging Face:
kubectl create secret generic hf-token \ --from-literal=token=HF_TOKENSubstitua
HF_TOKENpelo seu token de acesso do Hugging Face.Crie o segundo cluster em uma região diferente do primeiro:
gcloud container clusters create gke-east --region LOCATION \ --project=PROJECT_ID \ --gateway-api=standard \ --release-channel "rapid" \ --cluster-version=GKE_VERSION \ --machine-type="MACHINE_TYPE" \ --disk-type="DISK_TYPE" \ --enable-managed-prometheus \ --monitoring=SYSTEM,DCGM \ --hpa-profile=performance \ --async # Allows the command to return immediately while the cluster is created in the background.Substitua:
LOCATION: a região do segundo cluster. Essa região precisa ser diferente da do primeiro cluster. Por exemplo,us-east4.PROJECT_ID: o ID do projeto.GKE_VERSION: a versão do GKE a ser usada, por exemplo,1.34.1-gke.1127000.MACHINE_TYPE: o tipo de máquina dos nós do cluster, por exemplo,c2-standard-16.DISK_TYPE: o tipo de disco para os nós do cluster, por exemplo,pd-standard.
Crie um pool de nós H100 para o segundo cluster:
gcloud container node-pools create h100 \ --accelerator "type=nvidia-h100-80gb,count=2,gpu-driver-version=latest" \ --project=PROJECT_ID \ --location=CLUSTER_2_ZONE \ --node-locations=CLUSTER_2_ZONE \ --cluster=CLUSTER_2_NAME \ --machine-type=NODE_POOL_MACHINE_TYPE \ --num-nodes=NUM_NODES \ --spot \ --async # Allows the command to return immediatelySubstitua:
PROJECT_ID: o ID do projeto.CLUSTER_2_ZONE: a zona do segundo cluster, por exemplo,us-east4-a.CLUSTER_2_NAME: o nome do segundo cluster. Por exemplo,gke-east.NODE_POOL_MACHINE_TYPE: o tipo de máquina para o pool de nós, por exemplo,a3-highgpu-2g.NUM_NODES: o número de nós no pool de nós, por exemplo,3.
Para o segundo cluster, receba as credenciais e crie um secret para o token do Hugging Face:
gcloud container clusters get-credentials CLUSTER_2_NAME \ --location CLUSTER_2_ZONE \ --project=PROJECT_ID kubectl create secret generic hf-token --from-literal=token=HF_TOKENSubstitua:
CLUSTER_2_NAME: o nome do segundo cluster. Por exemplo,gke-east.CLUSTER_2_ZONE: a zona do segundo cluster, por exemplo,us-east4-a.PROJECT_ID: o ID do projeto.HF_TOKEN: seu token de acesso do Hugging Face.
Registrar clusters em uma frota
Para ativar recursos de vários clusters, como o gateway de inferência do GKE Multi-cluster, registre seus clusters em uma frota.
Registre os dois clusters na frota do projeto:
gcloud container fleet memberships register CLUSTER_1_NAME \ --gke-cluster CLUSTER_1_ZONE/CLUSTER_1_NAME \ --location=global \ --project=PROJECT_ID gcloud container fleet memberships register CLUSTER_2_NAME \ --gke-cluster CLUSTER_2_ZONE/CLUSTER_2_NAME \ --location=global \ --project=PROJECT_IDSubstitua:
CLUSTER_1_NAME: o nome do primeiro cluster, por exemplo,gke-west.CLUSTER_1_ZONE: a zona do primeiro cluster, por exemplo,europe-west3-c.PROJECT_ID: o ID do projeto.CLUSTER_2_NAME: o nome do segundo cluster. Por exemplo,gke-east.CLUSTER_2_ZONE: a zona do segundo cluster, por exemplo,us-east4-a.
Para permitir que um único gateway gerencie o tráfego em vários clusters, ative o recurso de Entrada de vários clusters e designe um cluster de configuração:
gcloud container fleet ingress enable \ --config-membership=projects/PROJECT_ID/locations/global/memberships/CLUSTER_1_NAMESubstitua:
PROJECT_ID: o ID do projeto.CLUSTER_1_NAME: o nome do primeiro cluster, por exemplo,gke-west.
Criar sub-redes somente proxy
Para um gateway interno, crie uma sub-rede somente proxy em cada região. Os proxies Envoy do gateway interno usam essas sub-redes dedicadas para processar o tráfego na rede VPC.
Crie uma sub-rede na região do primeiro cluster:
gcloud compute networks subnets create CLUSTER_1_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_1_REGION \ --network=default \ --range=10.0.0.0/23 \ --project=PROJECT_IDCrie uma sub-rede na região do segundo cluster:
gcloud compute networks subnets create CLUSTER_2_REGION-subnet \ --purpose=GLOBAL_MANAGED_PROXY \ --role=ACTIVE \ --region=CLUSTER_2_REGION \ --network=default \ --range=10.5.0.0/23 \ --project=PROJECT_IDSubstitua:
PROJECT_ID: o ID do projeto.CLUSTER_1_REGION: a região do primeiro cluster, por exemplo,europe-west3.CLUSTER_2_REGION: a região do segundo cluster, por exemplo,us-east4.
Instalar os CRDs necessários
O gateway de inferência de vários clusters do GKE usa recursos personalizados, como InferencePool e InferenceObjective. O
controlador da API GKE Gateway gerencia a definição de recurso
personalizado (CRD) InferencePool. No entanto, é necessário instalar manualmente o CRD InferenceObjective, que está em versão Alfa, nos clusters.
Defina variáveis de contexto para os clusters:
CLUSTER1_CONTEXT="gke_PROJECT_ID_CLUSTER_1_ZONE_CLUSTER_1_NAME" CLUSTER2_CONTEXT="gke_PROJECT_ID_CLUSTER_2_ZONE_CLUSTER_2_NAME"Substitua:
PROJECT_ID: o ID do projeto.CLUSTER_1_ZONE: a zona do primeiro cluster, por exemplo,europe-west3-c.CLUSTER_1_NAME: o nome do primeiro cluster, por exemplo,gke-west.CLUSTER_2_ZONE: a zona do segundo cluster, por exemplo,us-east4-a.CLUSTER_2_NAME: o nome do segundo cluster, por exemplo,gke-east.
Instale o CRD
InferenceObjectivenos dois clusters:kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=CLUSTER2_CONTEXTSubstitua:
CLUSTER1_CONTEXT: o contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.CLUSTER2_CONTEXT: o contexto do segundo cluster, por exemplo,gke_my-project_us-east4-a_gke-east.
Implantar recursos nos clusters de destino
Para disponibilizar suas cargas de trabalho de inferência de IA/ML em cada cluster, implante os
recursos necessários, como os servidores de modelo e os recursos personalizados InferenceObjective.
Implante os servidores de modelo nos dois clusters:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/manifests/vllm/gpu-deployment.yaml --context=CLUSTER1_CONTEXT kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.1.0/config/manifests/vllm/gpu-deployment.yaml --context=CLUSTER2_CONTEXTSubstitua:
CLUSTER1_CONTEXT: o contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.CLUSTER2_CONTEXT: o contexto do segundo cluster, por exemplo,gke_my-project_us-east4-a_gke-east.
Implante os recursos
InferenceObjectivenos dois clusters. Salve o exemplo de manifesto a seguir em um arquivo chamadoinference-objective.yaml:apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceObjective metadata: name: food-review spec: priority: 10 poolRef: name: llama3-8b-instruct group: "inference.networking.k8s.io"Aplique o manifesto aos dois clusters:
kubectl apply -f inference-objective.yaml --context=CLUSTER1_CONTEXT kubectl apply -f inference-objective.yaml --context=CLUSTER2_CONTEXTSubstitua:
CLUSTER1_CONTEXT: o contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.CLUSTER2_CONTEXT: o contexto do segundo cluster, por exemplo,gke_my-project_us-east4-a_gke-east.
Implante os recursos
InferencePoolnos dois clusters usando o Helm:helm install vllm-llama3-8b-instruct \ --kube-context CLUSTER1_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \ --set provider.name=gke \ --version v1.1.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepoolhelm install vllm-llama3-8b-instruct \ --kube-context CLUSTER2_CONTEXT \ --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \ --set provider.name=gke \ --set inferenceExtension.monitoring.gke.enabled=true \ --version v1.1.0 \ oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepoolSubstitua:
CLUSTER1_CONTEXT: o contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.CLUSTER2_CONTEXT: o contexto do segundo cluster, por exemplo,gke_my-project_us-east4-a_gke-east.
Marque os recursos
InferencePoolcomo exportados nos dois clusters. Essa anotação disponibiliza oInferencePoolpara importação pelo cluster de configuração, que é uma etapa obrigatória para o roteamento de vários clusters.kubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \ --context=CLUSTER1_CONTEXTkubectl annotate inferencepool vllm-llama3-8b-instruct networking.gke.io/export="True" \ --context=CLUSTER2_CONTEXTSubstitua:
CLUSTER1_CONTEXT: o contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.CLUSTER2_CONTEXT: o contexto do segundo cluster, por exemplo,gke_my-project_us-east4-a_gke-east.
Implantar recursos no cluster de configuração
Para definir como o tráfego é roteado e balanceado por carga nos recursos InferencePool
em todos os clusters registrados, implante os recursos Gateway,
HTTPRoute e HealthCheckPolicy. Você implanta esses recursos apenas no cluster de configuração designado, que é gke-west neste documento.
Crie um arquivo chamado
mcig.yamlcom o conteúdo a seguir:--- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: cross-region-gateway namespace: default spec: gatewayClassName: gke-l7-cross-regional-internal-managed-mc addresses: - type: networking.gke.io/ephemeral-ipv4-address/europe-west3 value: "europe-west3" - type: networking.gke.io/ephemeral-ipv4-address/us-east4 value: "us-east4" listeners: - name: http protocol: HTTP port: 80 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: vllm-llama3-8b-instruct-default spec: parentRefs: - name: cross-region-gateway kind: Gateway rules: - backendRefs: - group: networking.gke.io kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct --- apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: health-check-policy namespace: default spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: config: type: HTTP httpHealthCheck: requestPath: /health port: 8000Aplique o manifesto:
kubectl apply -f mcig.yaml --context=CLUSTER1_CONTEXTSubstitua
CLUSTER1_CONTEXTpelo contexto do primeiro cluster (o cluster de configuração), por exemplo,gke_my-project_europe-west3-c_gke-west.
Ativar relatórios de métricas personalizadas
Para ativar a geração de relatórios de métricas personalizadas e melhorar o balanceamento de carga entre regiões, exporte as métricas de uso do cache KV de todos os clusters. O balanceador de carga usa esses dados de uso do cache de KV exportados como um indicador de carga personalizado. Usar esse indicador de carga personalizado permite decisões de balanceamento de carga mais inteligentes com base na carga de trabalho real de cada cluster.
Crie um arquivo chamado
metrics.yamlcom o conteúdo a seguir:apiVersion: autoscaling.gke.io/v1beta1 kind: AutoscalingMetric metadata: name: gpu-cache namespace: default spec: selector: matchLabels: app: vllm-llama3-8b-instruct endpoints: - port: 8000 path: /metrics metrics: - name: vllm:kv_cache_usage_perc # For vLLM versions v0.10.2 and newer exportName: kv-cache - name: vllm:gpu_cache_usage_perc # For vLLM versions v0.6.2 and newer exportName: kv-cache-oldAplique a configuração de métricas aos dois clusters:
kubectl apply -f metrics.yaml --context=CLUSTER1_CONTEXT kubectl apply -f metrics.yaml --context=CLUSTER2_CONTEXTSubstitua:
CLUSTER1_CONTEXT: o contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.CLUSTER2_CONTEXT: o contexto do segundo cluster, por exemplo,gke_my-project_us-east4-a_gke-east.
Configurar a política de balanceamento de carga
Para otimizar a distribuição das solicitações de inferência de IA/ML nos clusters do GKE, configure uma política de balanceamento de carga. Escolher o modo de balanceamento certo ajuda a garantir o uso eficiente dos recursos, evita a sobrecarga de clusters individuais e melhora o desempenho geral e a capacidade de resposta dos serviços de inferência.
Configurar tempos limite
Se as solicitações tiverem durações longas, configure um tempo limite maior para o balanceador de carga. No GCPBackendPolicy, defina o campo timeoutSec como pelo menos o dobro da latência de solicitação P99 estimada.
Por exemplo, o manifesto a seguir define o tempo limite do balanceador de carga como 100 segundos.
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
name: my-backend-policy
spec:
targetRef:
group: "networking.gke.io"
kind: GCPInferencePoolImport
name: vllm-llama3-8b-instruct
default:
timeoutSec: 100
balancingMode: CUSTOM_METRICS
trafficDuration: LONG
customMetrics:
- name: gke.named_metrics.kv-cache
dryRun: false
Para mais informações, consulte Limitações do gateway de vários clusters.
Como os modos de balanceamento de carga Métricas personalizadas e Solicitações em andamento são mutuamente exclusivos, configure apenas um deles no seu GCPBackendPolicy.
Escolha um modo de balanceamento de carga para sua implantação.
Métricas personalizadas
Para um balanceamento de carga ideal, comece com uma utilização de meta de 60%. Para
atingir essa meta, defina maxUtilization: 60 na configuração customMetrics do
GCPBackendPolicy.
Crie um arquivo chamado
backend-policy.yamlcom o seguinte conteúdo para ativar o balanceamento de carga com base na métrica personalizadakv-cache:apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: balancingMode: CUSTOM_METRICS trafficDuration: LONG customMetrics: - name: gke.named_metrics.kv-cache dryRun: false maxUtilization: 60Aplique a nova política:
kubectl apply -f backend-policy.yaml --context=CLUSTER1_CONTEXTSubstitua
CLUSTER1_CONTEXTpelo contexto do primeiro cluster, por exemplo,gke_my-project-europe-west3-c-gke-west.
Solicitações em trânsito
Para usar o modo de balanceamento em andamento, estime o número de solicitações em andamento que cada back-end pode processar e configure explicitamente um valor de capacidade.
Crie um arquivo chamado
backend-policy.yamlcom o seguinte conteúdo para ativar o balanceamento de carga com base no número de solicitações em andamento:kind: GCPBackendPolicy apiVersion: networking.gke.io/v1 metadata: name: my-backend-policy spec: targetRef: group: "networking.gke.io" kind: GCPInferencePoolImport name: vllm-llama3-8b-instruct default: balancingMode: IN_FLIGHT trafficDuration: LONG maxInFlightRequestsPerEndpoint: 1000 dryRun: falseAplique a nova política:
kubectl apply -f backend-policy.yaml --context=CLUSTER1_CONTEXTSubstitua
CLUSTER1_CONTEXTpelo contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.
Verificar a implantação
Para verificar o balanceador de carga interno, envie solicitações da sua rede VPC, já que os balanceadores de carga internos usam endereços IP privados. Execute um pod temporário em um dos clusters para enviar solicitações da rede VPC e verificar o balanceador de carga interno:
Inicie uma sessão de shell interativa em um pod temporário:
kubectl run -it --rm --image=curlimages/curl curly --context=CLUSTER1_CONTEXT -- /bin/shSubstitua
CLUSTER1_CONTEXTpelo contexto do primeiro cluster, por exemplo,gke_my-project_europe-west3-c_gke-west.No novo shell, pegue o endereço IP do gateway e envie uma solicitação de teste:
GW_IP=$(kubectl get gateway/cross-region-gateway -n default -o jsonpath='{.status.addresses[0].value}') curl -i -X POST ${GW_IP}:80/v1/completions -H 'Content-Type: application/json' -d '{ "model": "food-review-1", "prompt": "What is the best pizza in the world?", "max_tokens": 100, "temperature": 0 }'Confira a seguir um exemplo de resposta bem-sucedida:
{ "id": "cmpl-...", "object": "text_completion", "created": 1704067200, "model": "food-review-1", "choices": [ { "text": "The best pizza in the world is subjective, but many argue for Neapolitan pizza...", "index": 0, "logprobs": null, "finish_reason": "length" } ], "usage": { "prompt_tokens": 10, "completion_tokens": 100, "total_tokens": 110 } }
A seguir
- Saiba mais sobre a API GKE Gateway.
- Saiba mais sobre o gateway de inferência multicluster do GKE.
- Saiba mais sobre o Ingress de vários clusters.