- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
本指南讲解如何在 Kubernetes 集群中,将 vLLM Semantic Router(vSR)与 Istio 及 Gateway API Inference Extension(GIE)组合部署:vSR 负责按请求语义选择模型,GIE 的InferencePool负责在模型副本间做负载感知调度,Istio 则以ext_proc方式为整条链路提供流量入口。读完本文,你将掌握从零搭建 kind 集群、安装 Istio 与 GIE CRD、部署 vLLM 后端与 vSR、编写Gateway/HTTPRoute/EnvoyFilter路由资源,以及通过 OpenAI 兼容接口验证"显式模型路由"与"语义自动路由"两条路径的完整实战能力。
架构总览
整套部署由三个核心组件构成:
- vLLM Semantic Router(vSR):决策"大脑",负责基于请求内容(prompt)做语义分类,判定请求应交给哪个模型;
- Istio & Gateway API:服务网格与集群流量入口,
Gateway是面向客户端的"前门",EnvoyFilter负责把流量交给 vSR 的ext_procgRPC 服务处理; - Gateway API Inference Extension(GIE):一套 Kubernetes 原生 API(
InferencePool等),用于管理、调度与扩缩容自托管的模型后端。
从仓库中 deploy/kubernetes/istio/README.md 与 deploy/kubernetes/llmd-base/README.md 可以清晰地看到两条决策链路的分工:
client -> Istio Gateway -> HTTPRoute -> InferencePool -> llm-d EPP -> replica | +-> ext_proc -> Semantic Router(模型选择)也就是说,请求到达网关后先经过 vSR 的ext_proc调用完成模型级选择,再由HTTPRoute依据 vSR 注入的x-selected-model请求头把流量导流到对应的InferencePool;InferencePool内部的端点选择器(Endpoint Picker,简称 EPP)再完成副本级负载感知选择。两层决策各司其职,一次请求、一跳完成。
集成收益:为什么把 vSR 与 GIE 组合在一起
1. Kubernetes 原生 LLM 管理
模型、路由与扩缩容策略全部以 CRD 形式暴露,直接通过kubectl管理,无需为模型服务另起一套控制平面。仓库中 deploy/kubernetes/llmd-base/inferencepool-llama.yaml 与 deploy/kubernetes/llmd-base/inferencepool-phi4.yaml 就是典型的InferencePool声明式清单。
2. 智能模型与副本双层路由
vSR 依据 prompt 语义选择模型,GIE 依据 GPU 负载与队列深度选择最健康的副本,两者叠加后请求不仅被送到"正确的模型",还会被送到"最健康的那一个副本",全程单跳完成。
3. 防过载保护
GIE 内置的调度器持续跟踪 GPU 负载与请求队列,高负载时自动"卸载"(shed)流量,避免模型服务在高并发下被打崩。从仓库中 EPP 的默认调度配置可以直观看到这一机制:queue-scorer(队列深度)、kv-cache-utilization-scorer(KV 缓存利用率)、prefix-cache-scorer(前缀缓存命中)三个插件按权重参与副本打分(详见下文"路由链路剖析")。
4. 深度可观测性
既可以通过 Gateway 层获取统一入口的指标,也可以从 vSR 获得更细粒度的性能数据(token 用量、分类准确率等),用于监控与排查整个 AI 技术栈。仓库中 deploy/kubernetes/istio/deployment.yaml 暴露了三个端口:50051(gRPCext_proc)、9190(metrics)、8080(classify-api),deploy/kubernetes/istio/service.yaml 中对应提供了semantic-router与semantic-router-metrics两个 Service,后者即供 Prometheus 抓取。
5. 安全多租户
借助标准 Kubernetes namespace 与HTTPRoute即可隔离租户工作负载,在共享的安全网关设施上叠加限流等策略。
支持的模型后端
该架构面向所有暴露OpenAI 兼容 API的自托管模型设计。本文演示用 vLLM 分别服务 Llama3(llama3-8b)与 Phi-4(phi4-mini)两个模型作为后端,实际部署时可直接替换为你自己的模型服务。
前置条件与版本验证
开始前请确保以下工具就绪:
- Docker 或其他容器运行时;
- kind v0.22+,或任意 Kubernetes 1.29+ 集群;
- kubectl v1.30+;
- Helm v3.14+;
- istioctl v1.28+;
- 环境变量
HF_TOKEN中存放 Hugging Face 访问令牌(演示用的 vLLM 部署需要从 HF 拉取 gated 模型权重)。
可用以下命令快速验证工具链版本:
kind version kubectl version --client --short helm version --short istioctl version --remote=false注意:文中涉及的 vLLM 后端清单会请求
nvidia.com/gpu: 1并创建 40 GiB / 20 GiB 的 PVC,deploy/kubernetes/istio/README.md 明确提示需要两个 GPU 节点(或按集群实际情况修改资源请求),同时建议先核对镜像 tag、storageClass 与模型访问权限后再应用。
Step 1:创建 Kind 集群(可选)
没有现成集群时,先用 kind 建一个本地测试集群:
kind create cluster --name vsr-gie # 等待节点就绪 kubectl wait --for=condition=Ready nodes --all --timeout=300sStep 2:安装 Istio
安装支持 Gateway API 与外部处理(external processing)的 Istio。若尚未安装 istioctl,请参照其官方安装脚本下载对应版本并加入PATH,然后执行:
export ISTIO_VERSION=1.29.0 istioctl install -y --set profile=minimal --set values.pilot.env.ENABLE_GATEWAY_API=true # 验证 istiod 可用 kubectl wait --for=condition=Available deployment/istiod -n istio-system --timeout=300s这里以profile=minimal安装最小化 Istio 控制面,并通过values.pilot.env.ENABLE_GATEWAY_API=true打开 Kubernetes Gateway API 支持。
Step 3:安装 Gateway API 与 GIE CRDs
分别安装标准 Gateway API 与 Inference Extension 的 CRD。请从对应上游发布页下载standard-install.yaml(v1.2.0)与manifests.yaml(v1.1.0)后执行:
# 安装 Gateway API CRDs kubectl apply -f standard-install.yaml # 安装 Gateway API Inference Extension CRDs kubectl apply -f manifests.yaml # 验证 CRD 已安装 kubectl get crd | grep 'gateway.networking.k8s.io' kubectl get crd | grep 'inference.networking.k8s.io'gateway.networking.k8s.io前缀对应Gateway/HTTPRoute等标准资源,inference.networking.k8s.io前缀对应InferencePool等扩展资源。若后续出现no matches for kind "InferencePool"一类错误,几乎可以断定是这一步的 CRD 未装上。
Step 4:部署演示 LLM 后端
部署两个 vLLM 实例(Llama3 与 Phi-4)作为后端,权重会自动从 Hugging Face 下载。仓库中的后端清单 deploy/kubernetes/istio/vLlama3.yaml 与 deploy/kubernetes/istio/vPhi4.yaml 未显式指定 namespace(应用时默认落入当前命名空间,仓库默认流程为default),请与后续的InferencePool/HTTPRoute保持同一命名空间,否则 pool 的 selector 将匹配不到后端 Pod。清单内容与本指南原文档中的命名存在一处差异:vLLM Deployment 通过secretKeyRef引用的 secret 名为hf-token-secret(参见 vLlama3.yaml),因此创建 secret 时应使用同名,以保证应用清单后能正常取到令牌:
# 创建模型命名空间与 Hugging Face 令牌 secret kubectl create namespace llm-backends --dry-run=client -o yaml | kubectl apply -f - kubectl create secret generic hf-token-secret \ --from-literal=token="$HF_TOKEN" # 部署模型服务(按上面提示统一到与后续路由资源相同的命名空间) kubectl apply -f deploy/kubernetes/istio/vLlama3.yaml kubectl apply -f deploy/kubernetes/istio/vPhi4.yaml # 等待模型就绪(首次下载权重可能需要数分钟) kubectl wait --for=condition=Available deployment/llama-8b --timeout=20m kubectl wait --for=condition=Available deployment/phi4-mini --timeout=20m以 vLlama3.yaml 为例,其关键实现细节值得展开:
- PVC:名为
llama-8b的 40 GiBReadWriteOncePVC,挂载到/root/.cache/huggingface,避免每次重启都重新下载权重; - 启动命令:
vllm serve meta-llama/Llama-3.1-8B-Instruct --served-model-name llama3-8b ... --enable-chunked-prefill --max_num_batched_tokens 1024,其中--served-model-name llama3-8b定义了对外模型别名,该别名必须与后续HTTPRoute的x-selected-model头匹配值一致; - GPU 资源:
limits与requests均声明nvidia.com/gpu: "1"; - 健康检查:
livenessProbe与readinessProbe均以/health为探针路径,initialDelaySeconds: 600(给模型加载留足时间),periodSeconds分别为 10 与 5; - Service:名为
llama-8b的 ClusterIP Service,port: 80转发到容器targetPort: 8000,selector 为app: vllm-llama3-8b-instruct。
若你替换后端模型,需要同步修改 deploy/kubernetes/istio/config.yaml 中的模型端点与对应HTTPRoute的头匹配值。
Step 5:部署 vLLM Semantic Router
使用官方 Helm chart 部署 vSR,它会以ext_proc服务器的形态运行,供 Istio 在做路由决策时调用:
helm upgrade -i semantic-router oci://ghcr.io/vllm-project/charts/semantic-router \ --version v0.0.0-latest \ --namespace vllm-semantic-router-system \ --create-namespace \ -f deploy/kubernetes/ai-gateway/semantic-router-values/values.yaml # 等待 Router 就绪 kubectl wait --for=condition=Available deploy/semantic-router \ -n vllm-semantic-router-system --timeout=10m仓库内 deploy/kubernetes/ai-gateway/semantic-router-values/values.yaml 是该 Helm 发布的默认值,几个关键结构值得注意:
gateway.mode: extproc:明确声明 vSR 以ext_proc模式运行,供 Istio 网关调用;config.providers.models:声明可用模型(base-model指向vllm-llama3-8b-instruct.default.svc.cluster.local:8000等);config.routing.decisions:一组决策规则,每条由priority、rules(operator: OR+domain/keyword条件)、modelRefs与可选plugins(如system_prompt替换、response_cache)构成;config.signals:定义domains(业务/法律/心理学/数学等 14 个领域)与keywords(如urgent/immediate/think触发thinking决策);global.router.strategy: priority:决策采用优先级策略;global.stores.response_cache默认开启(backend_type: memory、similarity_threshold: 0.8、eviction_policy: fifo、embedding 模型mmbert)。
如果你不使用 Helm 而希望以 kustomize 方式部署,仓库 deploy/kubernetes/istio/kustomization.yaml 提供了另一条完整路径:它把 deploy/kubernetes/istio/namespace.yaml、serviceaccount.yaml、deploy/kubernetes/istio/rbac.yaml、pv-models.yaml、deploy/kubernetes/istio/deployment.yaml、deploy/kubernetes/istio/service.yaml 组装到vllm-semantic-router-system命名空间,并将 deploy/kubernetes/istio/config.yaml 与tools_db.json生成 ConfigMap。值得展开的细节包括:
- deployment.yaml 中有一个
model-downloaderinitContainer,会先把 vSR 所需的分类/嵌入模型(all-MiniLM-L12-v2、category_classifier_modernbert-base_model、pii_classifier_modernbert-base_model、jailbreak_classifier_modernbert-base_model、Qwen3-Embedding-0.6B等)下载到 PVC,若已存在则跳过下载,显著缩短启动时间; - 主容器
args: ["--secure=true"],readinessProbe/livenessProbe探测50051端口且initialDelaySeconds: 300(等待模型加载); - 环境变量
VLLM_SR_K8S_CONFIGMAP_NAME/NAMESPACE允许 vSR 的配置写入 API 直接通过 Kubernetes API 更新 ConfigMap(见 rbac.yaml,其中 Role 被精确限定到semantic-router-config这一个 ConfigMap)。
Step 6:部署 Gateway 与路由逻辑
最后应用一组资源,把面向客户端的Gateway、GIE 的InferencePool、做流量匹配的HTTPRoute以及 Istio 的EnvoyFilter串起来。以下命令直接指向仓库内的清单文件(与原文档的远端 URL 等价,可离线审阅):
# 应用全部网关与路由资源 kubectl apply -f deploy/kubernetes/istio/gateway.yaml kubectl apply -f deploy/kubernetes/llmd-base/inferencepool-llama.yaml kubectl apply -f deploy/kubernetes/llmd-base/inferencepool-phi4.yaml kubectl apply -f deploy/kubernetes/llmd-base/httproute-llama-pool.yaml kubectl apply -f deploy/kubernetes/llmd-base/httproute-phi4-pool.yaml kubectl apply -f deploy/kubernetes/istio/destinationrule.yaml kubectl apply -f deploy/kubernetes/istio/envoyfilter.yaml # 验证 Gateway 已被 Istio 编程 kubectl wait --for=condition=Programmed gateway/inference-gateway --timeout=120s各资源的职责与关键字段:
gateway.yaml:声明名为inference-gateway的Gateway(gatewayClassName: istio),监听 HTTP 80 端口,allowedRoutes.namespaces.from: All允许所有命名空间的HTTPRoute绑定。
inferencepool-llama.yaml 与 inferencepool-phi4.yaml:声明两个InferencePool(vllm-llama3-8b-instruct与vllm-phi4-mini)。每个 pool 通过selector.matchLabels锁定对应后端 Pod(app: vllm-llama3-8b-instruct/app: phi4-mini),targetPorts指向模型服务端口 8000,endpointPickerRef引用同名的 llm-d EPP Service(kind: Service、port: 9002)。清单同时还部署了 EPP Deployment(镜像ghcr.io/llm-d/llm-d-router-endpoint-picker:v0.10.0,参数含--pool-name、--pool-namespace default、--grpc-port 9002、--grpc-health-port 9003、--config-file /config/default-plugins.yaml)以及配套的 ServiceAccount、Role/RoleBinding(只读 pods 与 inference 资源)。
httproute-llama-pool.yaml 与 httproute-phi4-pool.yaml:HTTPRoute把inference-gateway的流量按请求头x-selected-model(type: Exact)分流:值为llama3-8b时backendRefs指向InferencePool vllm-llama3-8b-instruct,值为phi4-mini时指向InferencePool vllm-phi4-mini,并统一设置timeouts.request: 300s。注意:应用 llmd-base 的这些 pool 路由后,不要再同时应用istio 目录里直连 Service 的路由(httproute-llama3-8b.yaml / httproute-phi4-mini.yaml),两者匹配相同的x-selected-model值会造成归属歧义。
destinationrule.yaml:为semantic-router.vllm-semantic-router-system.svc.cluster.local声明DestinationRule,trafficPolicy.tls.mode: DISABLE——即 vSR 的ext_procgRPC 使用明文连接。
envoyfilter.yaml:这是把 vSR 接入网关的关键。它通过workloadSelector选中打了gateway.networking.k8s.io/gateway-name: inference-gateway标签的网关 Pod,以INSERT_FIRST方式注入envoy.filters.http.ext_proc过滤器,配置要点:
mutation_rules.allow_expression限制 ext_proc 只能改写x-envoy-(upstream-rq-timeout-ms|upstream-rq-per-try-timeout-ms|max-retries|retry-on|retriable-status-codes)这些请求头(路由可靠性相关头),不能触碰其它x-envoy-*头;failure_mode_allow: true:ext_proc 故障时放行流量(fail-open),避免路由组件故障导致网关整体不可用;message_timeout: 300s:等待 vSR 决策的超时上限;processing_mode:request_header_mode: SEND、response_header_mode: SEND、request_body_mode: BUFFERED、response_body_mode: NONE——vSR 需要读取完整请求体(prompt)才能做语义分类;grpc_service.cluster_name:outbound|50051||semantic-router.vllm-semantic-router-system.svc.cluster.local,即向 vSR 的 gRPC Service 发起ext_proc调用。
若修改了网关名或 vSR Service 名,需同步更新该EnvoyFilter。
验证部署
方法一:端口转发
网关对外 Service 名为inference-gateway-istio,位于default命名空间:
kubectl port-forward svc/inference-gateway-istio 8080:80发送测试请求
端口转发生效后,即可向localhost:8080发送 OpenAI 兼容请求。
测试 1:显式指定模型(绕过语义路由)
指定"model": "llama3-8b"时,请求直接落到对应的模型池,不经过 vSR 的语义判断:
curl -sS http://localhost:8080/v1/chat/completions \ -H 'Content-Type: application/json' \ -d '{ "model": "llama3-8b", "messages": [{"role": "user", "content": "Summarize the Kubernetes Gateway API in three sentences."}] }'测试 2:让语义路由自动选择模型
设置"model": "auto"时,vSR 会对 prompt 做分类:下面这个数学题会被识别为math领域,vSR 在响应头中写入x-selected-model: phi4-mini,HTTPRoute据此把请求路由到vllm-phi4-mini池:
curl -sS http://localhost:8080/v1/chat/completions \ -H 'Content-Type: application/json' \ -d '{ "model": "auto", "messages": [{"role": "user", "content": "What is 2+2 * (5-1)?"}], "max_tokens": 64 }'在 minikube 等环境中,也可以动态获取网关地址后再发送:
GATEWAY_URL="$(minikube service inference-gateway-istio --url)" curl --fail-with-body "$GATEWAY_URL/v1/chat/completions" \ -H 'Content-Type: application/json' \ -d '{"model": "auto", "messages": [{"role": "user", "content": "What is 2 + 2?"}], "max_tokens": 32, "temperature": 0}'路由链路源码级剖析
结合仓库源码,可以把这条链路的每个环节落实到具体文件:
- 语义分类:vSR 读取完整请求体,按 deploy/kubernetes/istio/config.yaml 中的
routing.decisions判定领域。该配置里math决策的modelRefs指向phi4-mini,这正好解释了"数学题 →x-selected-model: phi4-mini"的测试预期;business/law/psychology等其余决策均指向llama3-8b。注意这与 Helm 默认的 values.yaml(base-model+ LoRA 专家变体)是两套等价可选的决策配置,测试行为以后者为准时需相应调整; - 注入路由头:vSR 以
ext_proc身份把决策结果写入x-selected-model请求头(envoyfilter.yaml的mutation_rules仅放行x-envoy-*白名单,x-selected-model属普通头不受限); - 池级转发:
HTTPRoute按x-selected-model精确匹配到InferencePool; - 副本级调度:
InferencePool的endpointPickerRef指向 EPP Service(9002 端口)。EPP 的调度策略来自plugins-configConfigMap 中的default-plugins.yaml:queue-scorer(权重 2)、kv-cache-utilization-scorer(权重 2)、prefix-cache-scorer(权重 3)共同参与副本打分,metrics-data-source负责从模型/metrics拉取指标——这正是"跟踪 GPU 负载与请求队列、自动卸载流量"的底层实现; - e2e 佐证:仓库 e2e/testcases/llmd_inference_gateway_health.go 注册了
llm-d-inference-gateway-health测试用例,通过 dynamic client 以inference.networking.k8s.io/v1的inferencepoolsGVR 与gateway.networking.k8s.io/v1的httproutesGVR 校验 HTTPRoute、InferencePool、调度器与网关接线的健康状态,可作为本部署的自动化回归参考。
故障排查
问题:CRD 缺失
出现no matches for kind "InferencePool"之类错误时,先确认 GIE CRD 是否安装:
kubectl get crd | grep inference.networking.k8s.io问题:Gateway 未就绪
kubectl port-forward失败或请求超时,检查 Gateway 状态,Programmed条件应为True:
kubectl get gateway inference-gateway -o yaml kubectl describe gateway inference-gateway kubectl describe httproute vsr-llama8b问题:vSR 未被调用
请求能通但路由结果不对时,查看 Istio 网关 Pod 中ext_proc相关日志:
export ISTIO_GW_POD=$(kubectl get pod -l istio=ingressgateway -o jsonpath='{.items[0].metadata.name}') kubectl logs $ISTIO_GW_POD -c istio-proxy | grep ext_proc常见原因:网关标签与EnvoyFilter的workloadSelector不一致,或 vSR gRPC Service 名/端口与cluster_name不匹配(对照 envoyfilter.yaml 检查)。
问题:请求持续失败
分别查看 vSR 与后端模型的日志:
# vSR 日志 kubectl logs deploy/semantic-router -n vllm-semantic-router-system # Llama3 后端日志 kubectl logs -n llm-backends -l app=vllm-llama3-8b-instruct- 后端超时:从集群内直连后端 Service 探活,并确认模型
readiness为就绪; - vSR 启动缓慢:检查
model-downloaderinitContainer 与模型 PVC(参考 deployment.yaml); - 请求绕过了 pool:确认没有同时存在直连 Service 的同名路由(见上文 Step 6 提醒)。
清理
按依赖倒序删除本指南创建的全部资源:
# 1. 删除全部 Kubernetes 资源 kubectl delete -f deploy/kubernetes/istio/gateway.yaml kubectl delete -f deploy/kubernetes/llmd-base/inferencepool-llama.yaml kubectl delete -f deploy/kubernetes/llmd-base/inferencepool-phi4.yaml kubectl delete -f deploy/kubernetes/llmd-base/httproute-llama-pool.yaml kubectl delete -f deploy/kubernetes/llmd-base/httproute-phi4-pool.yaml kubectl delete -f deploy/kubernetes/istio/destinationrule.yaml kubectl delete -f deploy/kubernetes/istio/envoyfilter.yaml kubectl delete -f deploy/kubernetes/istio/vPhi4.yaml kubectl delete -f deploy/kubernetes/istio/vLlama3.yaml kubectl delete ns llm-backends # 2. 卸载 Helm release helm uninstall semantic-router -n vllm-semantic-router-system # 3. 卸载 Istio istioctl uninstall -y --purge # 4. 删除 kind 集群(可选) kind delete cluster --name vsr-gie若只保留 kustomize 路径的资源,也可按 deploy/kubernetes/istio/README.md 中的清理顺序逐条kubectl delete -f;只有当本指南是唯一使用该 Istio 安装的工作负载时,才执行istioctl uninstall --purge。
下一步
- 定制路由规则:修改 vSR 配置(Helm 的 values.yaml 或 kustomize 的 config.yaml),定义自己的分类领域、决策优先级与插件(
system_prompt、response_cache等); - 接入自有模型:用任意 OpenAI 兼容模型服务替换演示的 Llama3 / Phi-4 部署,同步更新后端 Service 名/端口、
InferencePoolselector、HTTPRoute头匹配与 vSR 模型卡,四者作为一个整体契约修改; - 探索 GIE 高级特性:引入
InferenceObjective实现更精细的自动扩缩容与调度策略(如基于吞吐、延迟目标的副本伸缩); - 监控与可观测:把 Gateway 与 vSR(
semantic-router-metricsService 的9190端口)接入 Prometheus 与 Grafana 构建监控面板;需要分布式追踪时可参考 values.yaml 中的global.services.observability.tracing配置(OTLP exporter 指向jaeger:4317)。
- 后端
- API网关
- 模型推理服务
- AI Agent
【免费下载链接】semantic-router
An open, programmable decision layer for models and compute.
相关推荐
vLLM Semantic Router × Gateway API Inference Extension 部署指南:基于 Istio 的 Kubernetes 原生负载感知 LLM 路由
vLLM Semantic Router × Gateway API Inference Extension 部署指南:基于 Istio 的 Kubernete
后端API网关模型推理服务AI AgentvLLM Semantic Router 与 Gateway API Inference Extension 集成部署指南:基于 Istio 的负载感知 LLM 路由
vLLM Semantic Router 与 Gateway API Inference Extension 集成部署指南:基于 Istio 的负载感知 LLM
后端API网关模型推理服务AI AgentAibrix 与 Envoy AI Gateway 集成指南:基于 Gateway API Inference Extension 部署多模型推理网关
Aibrix 与 Envoy AI Gateway 集成指南:基于 Gateway API Inference Extension 部署多模型推理网关 本指南以
人工智能大模型云原生模型推理服务LLM 网关API网关弹性伸缩
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考