[Doc] Refresh Kthena integration guide (#57314)

Signed-off-by: Zhou Zihang <z@mcac.cc> Co-authored-by: Jee Jee Li <pandaleefree@gmail.com>

Zhou Zihang committed Sep 21, 2026 at 09:42 UTC 3e67044972939772ef6cd06957bf3199a41b5139
1 file changed +32 -27
docs/deployment/integrations/kthena.md
+32 -27
@@ -2,7 +2,9 @@
2
3 [**Kthena**](https://github.com/volcano-sh/kthena) is a Kubernetes-native LLM inference platform that transforms how organizations deploy and manage Large Language Models in production. Built with declarative model lifecycle management and intelligent request routing, it provides high performance and enterprise-grade scalability for LLM inference workloads.
4
5 -This guide shows how to deploy a production-grade, **multi-node vLLM** service on Kubernetes.
5 +Kthena manages inference workloads through `ModelServing` and provides model-aware request routing through `ModelServer` and `ModelRoute`.
6 +
7 +This guide shows how to deploy a **multi-node vLLM** service on Kubernetes using `ModelServing` and expose it through a Kubernetes Service.
8
9 We’ll:
10
@@ -18,7 +20,7 @@ You need:
20
21 - A Kubernetes cluster with **GPU nodes**.
22 - `kubectl` access with cluster-admin or equivalent permissions.
21 -- **Volcano** installed for gang scheduling.
23 +- **Volcano 1.14 or later** for the role-level gang scheduling used in this example.
24 - **Kthena** installed with the `ModelServing` CRD available.
25 - A valid **Hugging Face token** if loading models from Hugging Face Hub.
26
@@ -30,21 +32,22 @@ helm repo update
32 helm install volcano volcano-sh/volcano -n volcano-system --create-namespace
33 ```
34
33 -This provides the gang-scheduling and network topology features used by Kthena.
35 +Volcano provides the gang scheduling used in this example. It is optional for Kthena deployments that do not use Volcano scheduling.
36
37 ### 1.2 Install Kthena
38
39 ```bash
38 -helm install kthena oci://ghcr.io/volcano-sh/charts/kthena --version v0.1.0 --namespace kthena-system --create-namespace
40 +helm install kthena oci://ghcr.io/volcano-sh/charts/kthena --version v1.0.0 --namespace kthena-system --create-namespace
41 ```
42
43 - The `kthena-system` namespace is created.
42 -- Kthena controllers and CRDs, including `ModelServing`, are installed and healthy.
44 +- Kthena controllers and CRDs, including `ModelServing`, are installed.
45
46 Validate:
47
48 ```bash
47 -kubectl get crd | grep modelserving
49 +kubectl get pods -n kthena-system
50 +kubectl get crd modelservings.workload.serving.volcano.sh
51 ```
52
53 You should see:
@@ -57,7 +60,7 @@ modelservings.workload.serving.volcano.sh ...
60
61 ## 2. The Multi-Node vLLM `ModelServing` Example
62
60 -Kthena provides an example manifest to deploy a **multi-node vLLM cluster running Llama**. Conceptually this is equivalent to the vLLM production stack Helm deployment, but expressed with `ModelServing`.
63 +Kthena provides an example manifest to deploy a **multi-node vLLM cluster running Llama**. Each role replica contains an entry pod and its worker pods.
64
65 A simplified version of the example (`llama-multinode`) looks like:
66
@@ -116,10 +119,9 @@ Commands:
119 - -c
120 - >
121 bash /vllm-workspace/examples/ray_serving/multi-node-serving.sh
119 - leader --ray_cluster_size=2; python3 -m
120 - vllm.entrypoints.launchers.api_server.entry --port 8080 --model
121 - meta-llama/Llama-3.1-405B-Instruct --tensor-parallel-size 8
122 - --pipeline-parallel-size 2
122 + leader --ray_cluster_size=2;
123 + vllm serve meta-llama/Llama-3.1-405B-Instruct --port 8080 --tensor-parallel-size 8
124 + --pipeline-parallel-size 2 --distributed-executor-backend ray
125 ```
126
127 Worker:
@@ -166,9 +168,9 @@ Save one of the following manifests to `modelserving.yaml`:
168 restartGracePeriodSeconds: 60
169 gangPolicy:
170 minRoleReplicas:
169 - 405b: 1
171 + llama-405b: 1
172 roles:
171 - - name: 405b
173 + - name: llama-405b
174 replicas: 2
175 entryTemplate:
176 spec:
@@ -256,9 +258,9 @@ Save one of the following manifests to `modelserving.yaml`:
258 restartGracePeriodSeconds: 60
259 gangPolicy:
260 minRoleReplicas:
259 - 405b: 1
261 + llama-405b: 1
262 roles:
261 - - name: 405b
263 + - name: llama-405b
264 replicas: 2
265 entryTemplate:
266 spec:
@@ -275,7 +277,7 @@ Save one of the following manifests to `modelserving.yaml`:
277 - sh
278 - -c
279 - "bash /vllm-workspace/examples/ray_serving/multi-node-serving.sh leader --ray_cluster_size=2;
278 - vllm serve meta-llama/Llama-3.1-405B-Instruct --port 8080 --tensor-parallel-size 8 --pipeline-parallel-size 2"
280 + vllm serve meta-llama/Llama-3.1-405B-Instruct --port 8080 --tensor-parallel-size 8 --pipeline-parallel-size 2 --distributed-executor-backend ray"
281 resources:
282 limits:
283 nvidia.com/gpu: "8"
@@ -383,24 +385,24 @@ kubectl get pod -owide -l modelserving.volcano.sh/name=llama-multinode
385 Example output (from docs):
386
387 ```text
386 -NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE ...
387 -default llama-multinode-0-405b-0-0 1/1 Running 0 15m 10.244.0.56 192.168.5.12 ...
388 -default llama-multinode-0-405b-0-1 1/1 Running 0 15m 10.244.0.58 192.168.5.43 ...
389 -default llama-multinode-0-405b-1-0 1/1 Running 0 15m 10.244.0.57 192.168.5.58 ...
390 -default llama-multinode-0-405b-1-1 1/1 Running 0 15m 10.244.0.53 192.168.5.36 ...
388 +NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE ...
389 +default llama-multinode-0-llama-405b-0-0 1/1 Running 0 15m 10.244.0.56 192.168.5.12 ...
390 +default llama-multinode-0-llama-405b-0-1 1/1 Running 0 15m 10.244.0.58 192.168.5.43 ...
391 +default llama-multinode-0-llama-405b-1-0 1/1 Running 0 15m 10.244.0.57 192.168.5.58 ...
392 +default llama-multinode-0-llama-405b-1-1 1/1 Running 0 15m 10.244.0.53 192.168.5.36 ...
393 ```
394
395 Pod name pattern:
396
397 - `llama-multinode-<group-idx>-<role-name>-<replica-idx>-<ordinal>`.
398
397 -The first number indicates `ServingGroup`. The second (`405b`) is the `Role`. The remaining indices identify the pod within the role.
399 +The first index identifies the `ServingGroup`, followed by the role name (`llama-405b`), role replica index, and pod index.
400
401 ---
402
401 -## 6. Accessing the vLLM OpenAI-Compatible API
403 +## 5. Accessing the vLLM OpenAI-Compatible API
404
403 -Expose the entry via a Service:
405 +Save the following Service as `service.yaml` to expose the entry pods:
406
407 ```yaml
408 apiVersion: v1
@@ -412,7 +414,6 @@ spec:
414 selector:
415 modelserving.volcano.sh/name: llama-multinode
416 modelserving.volcano.sh/entry: "true"
415 - # optionally further narrow to leader role if you label it
417 ports:
418 - name: http
419 port: 80
@@ -420,9 +421,10 @@ spec:
421 type: ClusterIP
422 ```
423
423 -Port-forward from your local machine:
424 +Apply the Service, then port-forward from your local machine:
425
426 ```bash
427 +kubectl apply -f service.yaml
428 kubectl port-forward svc/llama-multinode-openai 30080:80 -n default
429 ```
430
@@ -450,11 +452,12 @@ You should see an OpenAI-style response from vLLM.
452
453 ---
454
453 -## 7. Clean Up
455 +## 6. Clean Up
456
457 To remove the deployment and its resources:
458
459 ```bash
460 +kubectl delete -f service.yaml
461 kubectl delete modelserving llama-multinode -n default
462 ```
463
@@ -464,3 +467,5 @@ If you’re done with the entire stack:
467 helm uninstall kthena -n kthena-system # or your Kthena release name
468 helm uninstall volcano -n volcano-system
469 ```
470 +
471 +For model-aware routing and prefill-decode disaggregation, see the [Kthena documentation](https://kthena.volcano.sh/docs/user-guide/router-routing).