Load balancing tradisional yang mengandalkan alokasi traffic sederhana sering kali tidak memadai untuk menangani permintaan kompleks dan beban traffic dinamis pada layanan inferensi large language model (LLM) di kluster Kubernetes. Topik ini menjelaskan cara menggunakan komponen Gateway with Inference Extension untuk mengonfigurasi ekstensi layanan inferensi guna mencapai routing cerdas dan manajemen traffic yang efisien.
Latar Belakang
KV cache
Prosedur
Diagram berikut menggambarkan alur kerja.
-
Pada inference-gateway, port 8080 menggunakan entri rute HTTP standar untuk meneruskan permintaan ke layanan inferensi backend. Port 8081 meneruskan permintaan melalui ekstensi LLM Route, yang kemudian meneruskannya ke layanan yang sama.
-
Dalam entri rute HTTP, Anda menggunakan resource
InferencePooluntuk mendeklarasikan kelompok workload layanan inferensi LLM dan resourceInferenceModeluntuk menentukan kebijakan distribusi traffic bagi suatu model dalamInferencePooltersebut. Konfigurasi ini mengarahkan permintaan dari port 8081 inference-gateway ke workload layanan inferensi LLM yang ditentukan dengan menggunakan algoritma penyeimbangan beban yang ditingkatkan khusus untuk layanan inferensi.
Prasyarat
Anda memiliki kluster ACK yang dikelola dengan kelompok node GPU. Anda juga dapat menginstal komponen ACK Virtual Node di kluster ACK yang dikelola untuk menggunakan daya komputasi GPU ACS.
Prosedur
Langkah 1: Deploy layanan inferensi contoh
-
Buat file bernama vllm-service.yaml dengan konten berikut.
CatatanUntuk image ini, kami merekomendasikan penggunaan kartu A10 di kluster ACK dan kartu L20 (GN8IS) di Alibaba Cloud Container Compute Service.
Selain itu, karena ukuran image LLM besar, kami merekomendasikan untuk mendorongnya ke Container Registry dan menariknya menggunakan alamat internal. Menarik image langsung dari jaringan publik bisa lambat karena kecepatannya dibatasi oleh bandwidth alamat IP elastis (EIP) kluster.
-
Deploy layanan inferensi contoh.
kubectl apply -f vllm-service.yaml
Langkah 2: Instal komponen Gateway with Inference Extension
atau Instal komponen Gateway with Inference Extension, dan pastikan Enable Gateway API Inference Extension (Requires a deployed inference service) dipilih.

Langkah 3: Menerapkan perutean inferensi
Langkah ini membuat resource InferencePool dan InferenceModel.
-
Buat file
inference-pool.yaml.apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferencePool metadata: name: vllm-qwen-pool spec: targetPortNumber: 8000 selector: app: qwen extensionRef: name: inference-gateway-ext-proc --- apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceModel metadata: name: inferencemodel-qwen spec: modelName: /model/qwen criticality: Critical poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-qwen-pool targetModels: - name: /model/qwen weight: 100 -
Deploy routing inferensi.
kubectl apply -f inference-pool.yaml
Langkah 4: Deploy dan verifikasi gateway
Pada langkah ini, Anda membuat gateway yang mendengarkan pada port 8080 dan 8081.
-
Buat file bernama
inference-gateway.yaml.apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: qwen-inference-gateway-class spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: qwen-inference-gateway spec: gatewayClassName: qwen-inference-gateway-class listeners: - name: http protocol: HTTP port: 8080 - name: llm-gw protocol: HTTP port: 8081 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: qwen-backend spec: parentRefs: - name: qwen-inference-gateway sectionName: llm-gw rules: - backendRefs: - group: inference.networking.x-k8s.io kind: InferencePool name: vllm-qwen-pool matches: - path: type: PathPrefix value: / --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: qwen-backend-no-inference spec: parentRefs: - group: gateway.networking.k8s.io kind: Gateway name: qwen-inference-gateway sectionName: http rules: - backendRefs: - group: "" kind: Service name: qwen port: 8000 weight: 1 matches: - path: type: PathPrefix value: / --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: name: backend-timeout spec: timeout: http: requestTimeout: 1h targetRef: group: gateway.networking.k8s.io kind: Gateway name: qwen-inference-gateway -
Deploy gateway.
kubectl apply -f inference-gateway.yamlKonfigurasi ini membuat namespace bernama
envoy-gateway-systemdan layanan bernamaenvoy-default-inference-gateway-645xxxxxdi kluster. -
Ambil alamat IP publik gateway.
export GATEWAY_HOST=$(kubectl get gateway/qwen-inference-gateway -o jsonpath='{.status.addresses[0].value}') -
Verifikasi bahwa gateway meneruskan permintaan ke layanan inferensi menggunakan routing HTTP standar pada port 8080.
curl -X POST ${GATEWAY_HOST}:8080/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "/model/qwen", "max_completion_tokens": 100, "temperature": 0, "messages": [ { "role": "user", "content": "Write as if you were a critic: San Francisco" } ] }'Output yang diharapkan:
{"id":"chatcmpl-aa6438e2-d65b-4211-afb8-ae8e76e7a692","object":"chat.completion","created":1747191180,"model":"/model/qwen","choices":[{"index":0,"message":{"role":"assistant","reasoning_content":null,"content":"San Francisco, a city that has long been a beacon of innovation, culture, and diversity, continues to captivate the world with its unique charm and character. As a critic, I find myself both enamored and occasionally perplexed by the city's multifaceted personality.\n\nSan Francisco's architecture is a testament to its rich history and progressive spirit. The iconic cable cars, Victorian houses, and the Golden Gate Bridge are not just tourist attractions but symbols of the city's enduring appeal. However, the","tool_calls":[]},"logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":39,"total_tokens":139,"completion_tokens":100,"prompt_tokens_details":null},"prompt_logprobs":null} -
Verifikasi bahwa gateway meneruskan permintaan ke layanan inferensi menggunakan ekstensi layanan inferensi pada port 8081.
curl -X POST ${GATEWAY_HOST}:8081/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "/model/qwen", "max_completion_tokens": 100, "temperature": 0, "messages": [ { "role": "user", "content": "Write as if you were a critic: Los Angeles" } ] }'Output yang diharapkan:
{"id":"chatcmpl-cc4fcd0a-6a66-4684-8dc9-284d4eb77bb7","object":"chat.completion","created":1747191969,"model":"/model/qwen","choices":[{"index":0,"message":{"role":"assistant","reasoning_content":null,"content":"Los Angeles, the sprawling metropolis often referred to as \"L.A.,\" is a city that defies easy description. It is a place where dreams are made and broken, where the sun never sets, and where the line between reality and fantasy is as blurred as the smog that often hangs over its valleys. As a critic, I find myself both captivated and perplexed by this city that is as much a state of mind as it is a physical place.\n\nOn one hand, Los","tool_calls":[]},"logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":39,"total_tokens":139,"completion_tokens":100,"prompt_tokens_details":null},"prompt_logprobs":null}
(Opsional) Langkah 5: Konfigurasi metrik observabilitas dan dasbor
Anda harus mengaktifkan dan mengonfigurasi Managed Service for Prometheus untuk kluster Anda, yang dapat menimbulkan biaya tambahan.
-
Anda dapat menambahkan anotasi Prometheus ke pod layanan vLLM untuk mengaktifkan pengumpulan metrik. Instans Prometheus kemudian dapat menggunakan mekanisme penemuan layanan default-nya untuk mengambil metrik layanan vLLM dan memantau status internal layanan tersebut.
... annotations: prometheus.io/path: /metrics # Jalur HTTP tempat metrik diekspos. prometheus.io/port: "8000" # Port untuk mengekspos metrik, yaitu port pendengar server vLLM. prometheus.io/scrape: "true" # Apakah akan mengambil metrik dari pod saat ini. ...Tabel berikut menjelaskan beberapa metrik pemantauan yang disediakan oleh layanan vLLM:
Metrik
Deskripsi
vllm:gpu_cache_usage_perc
Persentase cache GPU yang digunakan oleh vLLM. Saat vLLM dimulai, ia secara preemptif mengalokasikan sebanyak mungkin memori video GPU untuk cache KV. Untuk server vLLM, pemanfaatan yang lebih rendah berarti GPU memiliki ruang yang cukup untuk permintaan baru.
vllm:request_queue_time_seconds_sum
Total waktu yang dihabiskan permintaan dalam antrian tunggu. Setelah permintaan inferensi LLM tiba di server vLLM, permintaan tersebut mungkin tidak diproses segera. Sebaliknya, permintaan harus menunggu untuk dijadwalkan oleh penjadwal vLLM untuk prefill dan decode.
vllm:num_requests_running
vllm:num_requests_waiting
vllm:num_requests_swapped
Jumlah permintaan yang sedang berjalan, menunggu, atau dialihkan ke memori. Anda dapat menggunakan metrik ini untuk menilai beban permintaan saat ini pada layanan vLLM.
vllm:avg_generation_throughput_toks_per_s
vllm:avg_prompt_throughput_toks_per_s
Jumlah token yang dikonsumsi per detik selama tahap prefill dan jumlah token yang dihasilkan per detik selama tahap decode.
vllm:time_to_first_token_seconds_bucket
Latensi antara mengirim permintaan ke layanan vLLM dan menerima token pertama. Umumnya dikenal sebagai Time to First Token (TTFT), metrik ini mengukur waktu antara klien mengirim permintaan dan menerima bagian pertama respons. TTFT merupakan indikator penting pengalaman pengguna LLM.
Anda dapat menetapkan aturan alert berdasarkan metrik ini untuk memantau layanan vLLM dan mendeteksi anomali secara real-time.
-
Konfigurasikan dasbor Grafana untuk pemantauan waktu nyata layanan inferensi LLM. Anda dapat menggunakan dasbor ini untuk:
-
Memantau laju permintaan dan throughput total token layanan LLM.
-
Memantau status internal workload inferensi.
Pastikan instans Prometheus yang digunakan sebagai sumber data untuk Grafana telah mengumpulkan metrik pemantauan vLLM. Untuk membuat dasbor, impor konten JSON berikut ke Grafana.

Pratinjau:

-
-
Di kluster ACK, gunakan vllm benchmark untuk melakukan uji stres terhadap layanan inferensi dan membandingkan load balancing antara HTTP Route dan LLM Route.
-
Deploy workload benchmark.
kubectl apply -f- <<EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: vllm-benchmark name: vllm-benchmark namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app: vllm-benchmark strategy: rollingUpdate: maxSurge: 25% maxUnavailable: 25% type: RollingUpdate template: metadata: creationTimestamp: null labels: app: vllm-benchmark spec: containers: - command: - sh - -c - sleep inf image: registry-cn-hangzhou.ack.aliyuncs.com/dev/llm-benchmark:random-and-qa imagePullPolicy: IfNotPresent name: vllm-benchmark resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 EOF -
Jalankan uji stres.
-
Ambil alamat IP internal Gateway.
export GW_IP=$(kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=qwen-inference-gateway -o jsonpath='{.items[0].spec.clusterIP}') -
Jalankan uji stres.
HTTP route
kubectl exec -it deploy/vllm-benchmark -- env GW_IP=${GW_IP} python3 /root/vllm/benchmarks/benchmark_serving.py \ --backend vllm \ --model /models/DeepSeek-R1-Distill-Qwen-7B \ --served-model-name /model/qwen \ --trust-remote-code \ --dataset-name random \ --random-prefix-len 10 \ --random-input-len 1550 \ --random-output-len 1800 \ --random-range-ratio 0.2 \ --num-prompts 3000 \ --max-concurrency 200 \ --host $GW_IP \ --port 8080 \ --endpoint /v1/completions \ --save-result \ 2>&1 | tee benchmark_serving.txtLLM route
kubectl exec -it deploy/vllm-benchmark -- env GW_IP=${GW_IP} python3 /root/vllm/benchmarks/benchmark_serving.py \ --backend vllm \ --model /models/DeepSeek-R1-Distill-Qwen-7B \ --served-model-name /model/qwen \ --trust-remote-code \ --dataset-name random \ --random-prefix-len 10 \ --random-input-len 1550 \ --random-output-len 1800 \ --random-range-ratio 0.2 \ --num-prompts 3000 \ --max-concurrency 200 \ --host $GW_IP \ --port 8081 \ --endpoint /v1/completions \ --save-result \ 2>&1 | tee benchmark_serving.txt
-
Setelah menyelesaikan kedua pengujian, lihat dasbor untuk membandingkan performa routing antara HTTP Route dan LLM Route.

Dasbor menunjukkan bahwa workload HTTP Route memiliki distribusi Cache Utilization yang tidak merata, sedangkan workload LLM Route memiliki distribusi normal.
-
Operasi terkait
mendukung strategi load balancing berbeda untuk berbagai kasus penggunaan layanan inferensi. Untuk mengonfigurasi strategi load balancing bagi permintaan inferensi yang diarahkan ke pod dalam InferencePool, tambahkan anotasi inference.networking.x-k8s.io/routing-strategy ke resource InferencePool.
Contoh berikut menggunakan selektor app: vllm-app untuk memilih pod layanan inferensi dan menetapkan strategi load balancing ke strategi default berbasis metrik.
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferencePool
metadata:
name: vllm-app-pool
annotations:
inference.networking.x-k8s.io/routing-strategy: "DEFAULT"
spec:
targetPortNumber: 8000
selector:
app: vllm-app
extensionRef:
name: inference-gateway-ext-proc
Strategi load balancing berikut didukung:
|
Strategi |
Deskripsi |
|
DEFAULT |
Strategi load balancing berbasis metrik. Strategi ini mengevaluasi status internal server inferensi menggunakan metrik multidimensi, seperti panjang antrian permintaan dan pemanfaatan cache GPU. Kemudian, strategi ini mendistribusikan traffic ke beberapa workload server inferensi berdasarkan status tersebut. |
|
PREFIX_CACHE |
Strategi load balancing yang menggunakan pencocokan awalan permintaan. Strategi ini berusaha mengarahkan permintaan yang memiliki awalan umum ke pod server inferensi yang sama. Strategi ini ideal untuk skenario dengan volume permintaan tinggi yang berbagi awalan, terutama ketika server inferensi telah mengaktifkan auto prefix caching. Kasus penggunaan khas meliputi:
|