Install with Istio Gateway
This guide provides step-by-step instructions for deploying the vLLM Semantic Router (vsr) with Istio Gateway on Kubernetes. Istio Gateway uses Envoy under the covers so it is possible to use vsr with it. However there are differences between how different Envoy based Gateways process the ExtProc protocol, hence the deployment described here is different from the deployment of vsr alongwith other types of Envoy based Gateways as described in the other guides in this repo. There are multiple architecture options possible to combine Istio Gateway with vsr. This document describes one of the options.
Architecture Overview
The deployment consists of:
- vLLM Semantic Router: Provides intelligent request routing and processing decisions to Envoy based Gateways
- Istio Gateway: Istio's implementation of Kubernetes Gateway API that uses an Envoy proxy under the covers
- Gateway API Inference Extension: Additional APIs to extend the Gateway API for Inference via ExtProc servers
- Two instances of vLLM serving 1 model each: Example backend LLMs for illustrating semantic routing in this topology
Prerequisites
Before starting, ensure you have the following tools installed:
- Docker - Container runtime
- minikube - Local Kubernetes
- kind - Kubernetes in Docker
- kubectl - Kubernetes CLI
Either minikube or kind works to deploy a local kubernetes cluster needed for this exercise so you only need one of these two. We use minikube in the description below but the same steps should work with a Kind cluster once the cluster is created in Step 1.
We will also deploy two different LLMs in this exercise to illustrate the semantic routing and model routing function more clearly so you ideally you should run this on a machine that has GPU support to run the two models used in this exercise and adequate memory and storage for these models. You can also use equivalent steps on a smaller server that runs smaller LLMs on a CPU based server without GPUs.
Step 1: Create Minikube Cluster
Create a local Kubernetes cluster via minikube (or equivalently via Kind).
# Create cluster
$ minikube start \
--driver docker \
--container-runtime docker \
--gpus all \
--memory no-limit \
--cpus no-limit
# Verify cluster is ready
$ kubectl wait --for=condition=Ready nodes --all --timeout=300s
Step 2: Deploy LLM models
In this exercise we deploy two LLMs viz. a llama3-8b model (meta-llama/Llama-3.1-8B-Instruct) and a phi4-mini model (microsoft/Phi-4-mini-instruct). We serve these models using two separate instances of the vLLM inference server running in the default namespace of the kubernetes cluster. You may choose any other inference engines as long as they expose OpenAI API endpoints. First install a secret for your HuggingFace token previously stored in env variable HF_TOKEN and then deploy the models as shown below. Note that the file path names used in the example kubectl clis in this guide are expected to be executed from the top folder of this repo.
kubectl create secret generic hf-token-secret --from-literal=token=$HF_TOKEN
# Create vLLM service running llama3-8b
kubectl apply -f deploy/kubernetes/istio/vLlama3.yaml
This may take several (10+) minutes the first time this is run to download the model up until the vLLM pod running this model is in READY state. Similarly also deploy the second LLM (phi4-mini) and wait for several minutes until the pod is in READY state.
# Create vLLM service running phi4-mini
kubectl apply -f deploy/kubernetes/istio/vPhi4.yaml
At the end of this you should be able to see both your vLLM pods are READY and serving these LLMs using the command below. You should also see Kubernetes services exposing the IP/ port on which these models are being served. In the example below the llama3-8b model is being served via a kubernetes service with service IP of 10.108.250.109 and port 80.
# Verify that vLLM pods running the two LLMs are READY and serving
kubectl get pods
NAME READY STATUS RESTARTS AGE
llama-8b-57b95475bd-ph7s4 1/1 Running 0 9d
phi4-mini-887476b56-74twv 1/1 Running 0 9d
# View the IP/port of the Kubernetes services on which these models are being served
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 36d
llama-8b ClusterIP 10.108.250.109 <none> 80/TCP 18d
phi4-mini ClusterIP 10.97.252.33 <none> 80/TCP 9d