멀티 클러스터 GKE Inference Gateway 설정

이 문서에서는 여러 GKE 클러스터(서로 다른 리전에 걸쳐 있을 수 있음)에서 AI/ML 추론 워크로드를 지능적으로 부하 분산하도록 멀티 클러스터 Google Kubernetes Engine(GKE) 추론 게이트웨이를 설정하는 방법을 설명합니다. 이 설정은 게이트웨이 API, 멀티 클러스터 인그레스, InferencePool 및 InferenceObjective와 같은 커스텀 리소스를 사용하여 확장성을 개선하고, 고가용성을 보장하며, 모델 제공 배포의 리소스 사용률을 최적화합니다.

이 문서를 이해하려면 다음 사항을 숙지해야 합니다.

이 문서는 다음 사용자를 대상으로 합니다.

  • AI/ML 워크로드를 서빙하기 위해 GKE의 컨테이너 조정 기능을 사용하려는 머신러닝 (ML) 엔지니어, 플랫폼 관리자 및 운영자, 데이터 및 AI 전문가
  • GKE 네트워킹과 상호작용하는 클라우드 설계자 또는 네트워킹 전문가

Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대해 자세히 알아보려면 일반 GKE Enterprise 사용자 역할 및 태스크를 참고하세요.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면 gcloud components update 명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
  • Compute Engine API, Kubernetes Engine API, Model Armor, Network Services API를 사용 설정합니다.

    API 액세스 사용 설정으로 이동하여 안내를 따릅니다.

  • Autoscaling API를 사용 설정합니다.

    자동 확장 API로 이동하여 안내를 따릅니다.

  • GKE Hub API를 사용 설정합니다.

    GKE Hub API로 이동하여 안내를 따릅니다.

    또는 Google Cloud CLI를 사용합니다.

    gcloud services enable gkehub.googleapis.com --project=PROJECT_ID
    
  • Hugging Face 기본 요건:

    • Hugging Face 계정이 아직 없으면 이 계정을 만듭니다.
    • Hugging Face에서 Qwen3-32B 모델에 대한 액세스를 요청하고 승인을 받습니다.
    • Hugging Face의 모델 페이지에서 라이선스 동의 계약에 서명합니다.
    • Read 이상의 권한이 있는 Hugging Face 액세스 토큰을 생성합니다.

요구사항

  • 프로젝트에 H100 GPU 할당량이 충분한지 확인합니다. 자세한 내용은 GPU 할당량 계획배정 할당량을 참고하세요.
  • GKE 버전 1.34.1-gke.1127000 이상을 사용합니다.
  • gcloud CLI 버전 480.0.0 이상을 사용합니다.
  • 노드 서비스 계정에는 Autoscaling API에 측정항목을 쓸 수 있는 권한이 있어야 합니다.
  • 프로젝트에 roles/container.adminroles/iam.serviceAccountAdmin IAM 역할이 있어야 합니다.
  • 구성 클러스터를 비롯하여 Fleet에 등록하는 모든 클러스터가 동일한 VPC 네트워크에 있어야 합니다. 멀티 클러스터 게이트웨이는 서로 다른 VPC 네트워크의 클러스터 간 부하 분산을 지원하지 않습니다.

멀티 포트 및 NEG 한도

멀티 클러스터 설정에서 멀티 포트 InferencePool 리소스를 배포할 때는 Google Cloud 백엔드 서비스 NEG 한도를 고려하세요. 각 영역의 각 포트는 전용 NEG를 만듭니다. 예를 들어 영역이 3개이고 포트가 8개로 구성된 InferencePool이 있는 리전 클러스터는 NEG 24개를 사용합니다. 백엔드 서비스는 NEG 50개로 제한되므로 제한에 도달하기 전에 최대 2개의 클러스터에서 이 특정 InferencePool만 집계할 수 있습니다.

멀티 클러스터 추론 게이트웨이 설정

멀티 클러스터 GKE 추론 게이트웨이를 설정하려면 다음 단계를 따르세요.

클러스터 및 노드 풀 만들기

AI/ML 추론 워크로드를 호스팅하고 리전 간 부하 분산을 사용 설정하려면 서로 다른 리전에 각각 H100 GPU 노드 풀이 있는 두 개의 GKE 클러스터를 만드세요.

  1. 첫 번째 클러스터를 만듭니다.

    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 immediately
    

    다음을 바꿉니다.

    • CLUSTER_1_NAME: 첫 번째 클러스터의 이름입니다(예: gke-west).
    • LOCATION: 첫 번째 클러스터의 리전(예: europe-west3)
    • PROJECT_ID: 프로젝트 ID입니다.
    • GKE_VERSION: 사용할 GKE 버전입니다(예: 1.34.1-gke.1127000).
    • MACHINE_TYPE: 클러스터 노드의 머신 유형(예: c2-standard-16)
    • DISK_TYPE: 클러스터 노드의 디스크 유형입니다(예: pd-standard).
  2. 첫 번째 클러스터의 H100 노드 풀을 만듭니다.

    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 immediately
    

    다음을 바꿉니다.

    • NODE_POOL_NAME: 노드 풀의 이름입니다(예: h100).
    • PROJECT_ID: 프로젝트 ID입니다.
    • CLUSTER_1_ZONE: 첫 번째 클러스터의 영역입니다(예: europe-west3-c).
    • CLUSTER_1_NAME: 첫 번째 클러스터의 이름입니다(예: gke-west).
    • NODE_POOL_MACHINE_TYPE: 노드 풀의 머신 유형(예: a3-highgpu-2g)
    • NUM_NODES: 노드 풀의 노드 수입니다(예: 3).
  3. 사용자 인증 정보를 가져옵니다.

    gcloud container clusters get-credentials CLUSTER_1_NAME \
        --location CLUSTER_1_ZONE \
        --project=PROJECT_ID
    

    다음을 바꿉니다.

    • PROJECT_ID: 프로젝트 ID입니다.
    • CLUSTER_1_NAME: 첫 번째 클러스터의 이름입니다(예: gke-west).
    • CLUSTER_1_ZONE: 첫 번째 클러스터의 영역입니다(예: europe-west3-c).
  4. 첫 번째 클러스터에서 Hugging Face 토큰의 보안 비밀을 만듭니다.

    kubectl create secret generic hf-token \
        --from-literal=token=HF_TOKEN
    

    HF_TOKEN을 Hugging Face 액세스 토큰으로 바꿉니다.

  5. 첫 번째 클러스터와 다른 리전에 두 번째 클러스터를 만듭니다.

    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.
    

    다음을 바꿉니다.

    • LOCATION: 두 번째 클러스터의 리전입니다. 이는 첫 번째 클러스터와 다른 리전이어야 합니다. 예를 들면 us-east4입니다.
    • PROJECT_ID: 프로젝트 ID입니다.
    • GKE_VERSION: 사용할 GKE 버전입니다(예: 1.34.1-gke.1127000).
    • MACHINE_TYPE: 클러스터 노드의 머신 유형(예: c2-standard-16)
    • DISK_TYPE: 클러스터 노드의 디스크 유형입니다(예: pd-standard).
  6. 두 번째 클러스터의 H100 노드 풀을 만듭니다.

    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 immediately
    

    다음을 바꿉니다.

    • PROJECT_ID: 프로젝트 ID입니다.
    • CLUSTER_2_ZONE: 두 번째 클러스터의 영역입니다(예: us-east4-a).
    • CLUSTER_2_NAME: 두 번째 클러스터의 이름입니다(예: gke-east).
    • NODE_POOL_MACHINE_TYPE: 노드 풀의 머신 유형(예: a3-highgpu-2g)
    • NUM_NODES: 노드 풀의 노드 수입니다(예: 3).
  7. 두 번째 클러스터의 경우 사용자 인증 정보를 가져오고 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_TOKEN
    

    다음을 바꿉니다.

    • CLUSTER_2_NAME: 두 번째 클러스터의 이름입니다(예: gke-east).
    • CLUSTER_2_ZONE: 두 번째 클러스터의 영역입니다(예: us-east4-a).
    • PROJECT_ID: 프로젝트 ID입니다.
    • HF_TOKEN: Hugging Face 액세스 토큰입니다.

Fleet에 클러스터 등록

멀티 클러스터 GKE 추론 게이트웨이와 같은 멀티 클러스터 기능을 사용 설정하려면 클러스터를 Fleet에 등록하세요.

  1. 등록 중에 mTLS 문제가 발생하지 않도록 API 엔드포인트 재정의를 설정합니다.

    gcloud config set api_endpoint_overrides/container https://container.googleapis.com/
    
  2. 두 클러스터를 모두 프로젝트의 Fleet에 등록합니다.

    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_ID
    

    다음을 바꿉니다.

    • CLUSTER_1_NAME: 첫 번째 클러스터의 이름입니다(예: gke-west).
    • CLUSTER_1_ZONE: 첫 번째 클러스터의 영역입니다(예: europe-west3-c).
    • PROJECT_ID: 프로젝트 ID입니다.
    • CLUSTER_2_NAME: 두 번째 클러스터의 이름입니다(예: gke-east).
    • CLUSTER_2_ZONE: 두 번째 클러스터의 영역입니다(예: us-east4-a).
  3. 단일 게이트웨이가 여러 클러스터의 트래픽을 관리하도록 하려면 멀티 클러스터 인그레스 기능을 사용 설정하고 구성 클러스터를 지정하세요.

    gcloud container fleet ingress enable \
        --config-membership=projects/PROJECT_ID/locations/global/memberships/CLUSTER_1_NAME
    

    다음을 바꿉니다.

    • PROJECT_ID: 프로젝트 ID입니다.
    • CLUSTER_1_NAME: 첫 번째 클러스터의 이름입니다(예: gke-west).

프록시 전용 서브넷 만들기

내부 게이트웨이의 경우 각 리전에 프록시 전용 서브넷을 만듭니다. 내부 게이트웨이의 Envoy 프록시는 이러한 전용 서브넷을 사용하여 VPC 네트워크 내에서 트래픽을 처리합니다.

경고: Google Cloud 는 각 VPC 네트워크의 리전당 하나의 프록시 전용 서브넷만 허용합니다. 타겟 리전에 purpose=REGIONAL_MANAGED_PROXY 설정이 있는 프록시 전용 서브넷이 이미 포함되어 있으면 GLOBAL_MANAGED_PROXY 서브넷을 만들 수 없습니다. 먼저 기존 리전 프록시 전용 서브넷을 삭제해야 합니다. 리전 프록시 전용 서브넷을 삭제하면 해당 서브넷을 사용하는 리전 Envoy 기반 부하 분산기에 영향을 미치므로 이에 따라 변경을 계획하세요.

  1. 첫 번째 클러스터의 리전에 서브넷을 만듭니다.

    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_ID
    
  2. 두 번째 클러스터의 리전에 서브넷을 만듭니다.

    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_ID
    

    다음을 바꿉니다.

    • PROJECT_ID: 프로젝트 ID입니다.
    • CLUSTER_1_REGION: 첫 번째 클러스터의 리전(예: europe-west3)
    • CLUSTER_2_REGION: 두 번째 클러스터의 리전(예: us-east4)

필수 CustomResourceDefinitions 설치

멀티 클러스터 GKE Inference Gateway는 InferencePool 및 InferenceObjective와 같은 커스텀 리소스를 사용합니다. GKE Gateway API 컨트롤러는 InferencePool CustomResourceDefinition을 관리합니다. 하지만 클러스터에 알파 버전인 InferenceObjective CustomResourceDefinition을 수동으로 설치해야 합니다.

  1. 클러스터의 컨텍스트 변수를 정의합니다.

    CLUSTER1_CONTEXT="gke_PROJECT_ID_CLUSTER_1_ZONE_CLUSTER_1_NAME"
    CLUSTER2_CONTEXT="gke_PROJECT_ID_CLUSTER_2_ZONE_CLUSTER_2_NAME"
    

    다음을 바꿉니다.

    • PROJECT_ID: 프로젝트 ID입니다.
    • CLUSTER_1_ZONE: 첫 번째 클러스터의 영역입니다(예: europe-west3-c).
    • CLUSTER_1_NAME: 첫 번째 클러스터의 이름입니다(예: gke-west).
    • CLUSTER_2_ZONE: 두 번째 클러스터의 영역입니다(예: us-east4-a).
    • CLUSTER_2_NAME: 두 번째 클러스터의 이름입니다(예: gke-east).
  2. 두 클러스터 모두에 InferenceObjective CustomResourceDefinition을 설치합니다.

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.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.5.0/config/crd/bases/inference.networking.x-k8s.io_inferenceobjectives.yaml --context=$CLUSTER2_CONTEXT
    

대상 클러스터에 리소스 배포

각 클러스터에서 AI/ML 추론 워크로드를 사용할 수 있도록 모델 서버 및 InferenceObjective 커스텀 리소스와 같은 필수 리소스를 배포합니다.

참고: 이 문서의 예에서는 vLLM을 사용하지만 멀티 클러스터 추론 게이트웨이는 모델 서버 플랫폼에 독립적이며 SGLang과 같은 다른 모델 서버와도 작동합니다. 다른 모델 서버를 사용하는 경우 다음 설정을 조정하세요.

  • 제공 포트 InferencePool 타겟 포트, HealthCheckPolicy 포트, AutoscalingMetric 엔드포인트 포트를 모델 서버의 제공 포트로 설정합니다. 예를 들어 SGLang은 기본적으로 포트 8000이 아닌 포트 30000에서 제공됩니다.
  • 측정항목 이름 측정항목 이름은 각 모델 서버에 따라 다릅니다. 예를 들어 SGLang은 KV 캐시 사용률을 vllm:kv_cache_usage_perc 측정항목 대신 sglang:token_usage 측정항목으로 보고합니다. 모델 서버의 측정항목을 AutoscalingMetric 리소스의 kv-cache 내보내기 이름에 매핑합니다. vLLM 이외의 모델 서버의 맞춤 측정항목 추출에는 호환되는 엔드포인트 선택기 (EPP) 이미지가 필요합니다. 지원되는 최신 차트 버전을 사용하세요.
  • 다중 노드 모델 서빙 하나의 모델 복제본이 여러 노드에 걸쳐 있는 경우 (예: LeaderWorkerSet API를 사용하여 대규모 모델을 제공하는 경우) 리더 포드 (순위 0)만 API를 제공합니다. InferencePool modelServers.matchLabels 선택기가 리더 포드만 일치하도록 구성합니다(예: apps.kubernetes.io/pod-index: "0" 라벨 추가). 선택기가 작업자 포드와도 일치하는 경우 게이트웨이는 요청을 처리할 수 없는 포드로 요청을 라우팅하고 이러한 요청은 HTTP 404 Not Found 상태 코드로 실패합니다.
  1. 두 클러스터에 모델 서버를 배포합니다.

    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/manifests/vllm/gpu-deployment.yaml --context=$CLUSTER1_CONTEXT
    
    kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/gateway-api-inference-extension/v1.5.0/config/manifests/vllm/gpu-deployment.yaml --context=$CLUSTER2_CONTEXT
    
  2. 두 클러스터에 InferenceObjective 리소스를 배포합니다. 다음 샘플 매니페스트를 inference-objective.yaml이라는 파일에 저장합니다.

    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferenceObjective
    metadata:
      name: food-review
    spec:
      priority: 10
      poolRef:
        name: vllm-qwen3-32b
        group: "inference.networking.k8s.io"
    
  3. 두 클러스터에 모두 매니페스트를 적용합니다.

    kubectl apply -f inference-objective.yaml --context=$CLUSTER1_CONTEXT
    kubectl apply -f inference-objective.yaml --context=$CLUSTER2_CONTEXT
    

    다음을 바꿉니다.

    • $CLUSTER1_CONTEXT: 첫 번째 클러스터의 컨텍스트입니다(예: gke_my-project_europe-west3-c_gke-west).
    • $CLUSTER2_CONTEXT: 두 번째 클러스터의 컨텍스트입니다(예: gke_my-project_us-east4-a_gke-east).
  4. Helm을 사용하여 두 클러스터에 InferencePool 리소스를 배포합니다.

      helm install vllm-qwen3-32b \
      --kube-context $CLUSTER1_CONTEXT \
      --set inferencePool.modelServers.matchLabels.app=vllm-qwen3-32b \
      --set provider.name=gke \
      --set inferenceExtension.monitoring.gke.enabled=true \
      --version v1.5.0 \
      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
    
    helm install vllm-qwen3-32b \
      --kube-context $CLUSTER2_CONTEXT \
      --set inferencePool.modelServers.matchLabels.app=vllm-qwen3-32b \
      --set provider.name=gke \
      --set inferenceExtension.monitoring.gke.enabled=true \
      --version v1.5.0 \
      oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
    

    위 명령어는 이 설정에 권장되는 버전인 Helm 차트 버전 v1.5.0를 사용합니다. Helm 차트는 단일 클러스터용으로 설계된 GCPBackendPolicy 커스텀 리소스와 HealthCheckPolicy 커스텀 리소스도 설치합니다.

    InferencePool Helm 차트의 v1.1.0 버전에서는 --set inferencePool.targetPortNumber 플래그가 무시될 수 있으며 대상 포트가 기본적으로 8000로 설정됩니다. 모델 서버가 다른 포트에서 수신 대기하는 경우 (예: SGLang은 기본적으로 포트 30000에서 제공됨) 설치 후 포트를 확인합니다.

    kubectl get inferencepool POOL_NAME -o jsonpath='{.spec.targetPorts}' \
        --context=CLUSTER_CONTEXT
    

    포트가 잘못된 경우 내보내기 전에 InferencePool 커스텀 리소스를 패치합니다.

    kubectl patch inferencepool POOL_NAME --type=merge \
        -p '{"spec":{"targetPorts":[{"number":TARGET_PORT}]}}' \
        --context=CLUSTER_CONTEXT
    
  5. 두 클러스터에서 InferencePool 리소스를 내보낸 것으로 표시합니다. 이 주석을 사용하면 구성 클러스터에서 InferencePool을 가져올 수 있으며 이는 멀티 클러스터 라우팅에 필요한 단계입니다.

    kubectl annotate inferencepool vllm-qwen3-32b networking.gke.io/export="True" \
        --context=$CLUSTER1_CONTEXT
    
    kubectl annotate inferencepool vllm-qwen3-32b networking.gke.io/export="True" \
        --context=$CLUSTER2_CONTEXT
    

구성 클러스터에 리소스 배포

등록된 모든 클러스터의 InferencePool 리소스 간에 트래픽이 라우팅되고 부하가 분산되는 방식을 정의하려면 Gateway, HTTPRoute, HealthCheckPolicy 리소스를 배포하세요. 이러한 리소스는 이 문서에서 gke-west인 지정된 구성 클러스터에만 배포합니다.

  1. 다음 콘텐츠로 mcig.yaml이라는 파일을 만듭니다.

    ---
    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-qwen3-32b-default
    spec:
      parentRefs:
      - name: cross-region-gateway
        kind: Gateway
      rules:
      - backendRefs:
        - group: networking.gke.io
          kind: GCPInferencePoolImport
          name: vllm-qwen3-32b
    ---
    apiVersion: networking.gke.io/v1
    kind: HealthCheckPolicy
    metadata:
      name: health-check-policy
      namespace: default
    spec:
      targetRef:
        group: "networking.gke.io"
        kind: GCPInferencePoolImport
        name: vllm-qwen3-32b
      default:
        config:
          type: HTTP
          httpHealthCheck:
            requestPath: /health
            port: 8000
    
  2. 매니페스트를 적용합니다.

    kubectl apply -f mcig.yaml --context=$CLUSTER1_CONTEXT
    

맞춤 측정항목 보고 사용 설정

커스텀 측정항목 보고를 사용 설정하고 교차 리전 부하 분산을 개선하려면 모든 클러스터에서 KV 캐시 사용량 측정항목을 내보냅니다. 부하 분산기는 내보낸 KV 캐시 사용 데이터를 맞춤 부하 신호로 사용합니다. 이 맞춤 부하 신호를 사용하면 각 클러스터의 실제 워크로드에 따라 더 지능적인 부하 분산 결정을 내릴 수 있습니다.

  1. 다음 콘텐츠로 metrics.yaml이라는 파일을 만듭니다.

    apiVersion: autoscaling.gke.io/v1beta1
    kind: AutoscalingMetric
    metadata:
      name: gpu-cache
      namespace: default
    spec:
      selector:
        matchLabels:
          app: vllm-qwen3-32b
      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-old
    
  2. 두 클러스터 모두에 측정항목 구성을 적용합니다.

    kubectl apply -f metrics.yaml --context=$CLUSTER1_CONTEXT
    kubectl apply -f metrics.yaml --context=$CLUSTER2_CONTEXT
    

부하 분산 정책 구성

AI/ML 추론 요청이 GKE 클러스터에 분산되는 방식을 최적화하려면 부하 분산 정책을 구성하세요. 적절한 균형 모드를 사용하면 리소스 사용률을 효율적으로 유지하고 개별 클러스터의 과부하를 방지하며 추론 서비스의 성능과 응답성을 개선할 수 있습니다.

제한 시간 구성

요청이 오래 지속될 것으로 예상되는 경우 부하 분산기의 제한 시간을 더 길게 구성합니다. GCPBackendPolicy에서 timeoutSec 필드를 예상 P99 요청 지연 시간의 2배 이상으로 설정합니다. 동시성이 높은 긴 컨텍스트 추론 워크로드의 경우 최대 3600초의 제한 시간이 필요할 수 있습니다. 예를 들어 다음 매니페스트는 부하 분산기 제한 시간을 600초로 설정합니다.

apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: my-backend-policy
spec:
  targetRef:
    group: "networking.gke.io"
    kind: GCPInferencePoolImport
    name: vllm-qwen3-32b
  default:
    timeoutSec: 600
    balancingMode: CUSTOM_METRICS
    trafficDuration: LONG
    customMetrics:
      - name: gke.named_metrics.kv-cache
        dryRun: false
        maxUtilizationPercent: 60

자세한 내용은 멀티 클러스터 게이트웨이 제한사항을 참고하세요.

맞춤 측정항목전송 중인 요청 부하 분산 모드는 상호 배타적이므로 GCPBackendPolicy에서 이러한 모드 중 하나만 구성하세요.

배포의 부하 분산 모드를 선택합니다.

커스텀 측정항목

최적의 부하 분산을 위해 대상 사용률을 60%로 시작하세요. 이 타겟을 달성하려면 GCPBackendPolicycustomMetrics 구성에서 maxUtilizationPercent: 60를 설정하세요.

  1. 다음 콘텐츠로 backend-policy.yaml이라는 파일을 만들어 kv-cache 맞춤 측정항목을 기반으로 부하 분산을 사용 설정합니다.

    apiVersion: networking.gke.io/v1
    kind: GCPBackendPolicy
    metadata:
      name: my-backend-policy
    spec:
      targetRef:
        group: "networking.gke.io"
        kind: GCPInferencePoolImport
        name: vllm-qwen3-32b
      default:
        balancingMode: CUSTOM_METRICS
        trafficDuration: LONG
        customMetrics:
          - name: gke.named_metrics.kv-cache
            dryRun: false
            maxUtilizationPercent: 60
    
  2. 새 정책을 적용합니다.

    kubectl apply -f backend-policy.yaml --context=$CLUSTER1_CONTEXT
    

진행 중인 요청

진행 중인 요청 분산 모드를 사용하려면 각 백엔드에서 처리할 수 있는 진행 중인 요청 수를 추정하고 용량 값을 명시적으로 구성하세요.

  1. 다음 콘텐츠로 backend-policy.yaml이라는 파일을 만들어 진행 중인 요청 수를 기반으로 부하 분산을 사용 설정합니다.

    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: my-backend-policy
    spec:
      targetRef:
        group: "networking.gke.io"
        kind: GCPInferencePoolImport
        name: vllm-qwen3-32b
      default:
        balancingMode: IN_FLIGHT
        trafficDuration: LONG
        maxInFlightRequestsPerEndpoint: 1000
        dryRun: false
    
  2. 새 정책을 적용합니다.

    kubectl apply -f backend-policy.yaml --context=$CLUSTER1_CONTEXT
    

배포를 확인합니다.

내부 부하 분산기는 비공개 IP 주소를 사용하므로 내부 부하 분산기를 확인하려면 VPC 네트워크 내에서 요청을 보내야 합니다. 클러스터 중 하나 내에서 임시 포드를 실행하여 VPC 네트워크에서 요청을 보내고 내부 부하 분산기를 확인합니다.

  1. 새 셸에서 게이트웨이 IP 주소를 가져옵니다.

    GW_IP=$(kubectl get gateway/cross-region-gateway -n default --context=$CLUSTER1_CONTEXT -o jsonpath='{.status.addresses[0].value}')
    
  2. 클러스터 내 임시 포드에서 테스트 요청을 전송합니다.

    kubectl run -it --rm --image=curlimages/curl curly --context=$CLUSTER1_CONTEXT -- \
      curl -i -X POST ${GW_IP}:80/v1/completions -H 'Content-Type: application/json' -d '{
      "model": "Qwen/Qwen3-32B",
      "prompt": "What is the best pizza in the world?",
      "max_tokens": 100,
      "temperature": 0
      }'
    

다음 단계