AI推理赫尔墨斯路由插件开发指南
特性介绍
Hermes-router是一个Kubernetes(K8s)原生的AI推理智能路由方案,用于接收用户推理请求并转发至合适的推理服务后端。
作为GIE框架下的EPP插件,Hermes-router仅关注请求的转发过程,本指南介绍开发者如何基于EPP框架进行自定义路由策略开发。
约束与限制
推理引擎限制
Hermes-router对推理引擎的支持与GIE保持一致。 但部分插件依赖cache-indexer计算全局KVCache命中率,而cache-indexer在v25.12版本仅支持vLLM,因此现阶段这些插件间接地仅能在推理引擎为vLLM时使用,插件如下:
- scorer-aggregate-kv-cache-aware
- scorer-pd-kv-cache-aware
其他插件在理论上支持多种推理引擎,但目前仅验证了vLLM作为推理引擎的场景。
开发限制
在本文档中,一个EPP实例代表一种路由策略,一个路由策略通常由多个类型的插件组成,插件开发需遵循GIE框架规范。
部署限制
- 仅支持在Kubernetes环境中部署运行。
- 插件需在本地完成开发,构建为镜像后才可部署运行。
- 如需变更路由策略配置,需在修改配置后重启EPP方可生效。
环境准备
环境要求
硬件要求
Hermes-router开发环境对硬件无特殊要求,建议按照如下进行配置。
- CPU:4核及以上
- 内存:8GB及以上
- 磁盘:20GB及以上可用空间
软件要求
- 操作系统:Linux
- Go环境:Go 1.21或更高版本
- Docker:Docker 20.10+或兼容的容器运行时(如nerdctl)
- Kubernetes集群:用于部署和测试
- kubectl:用于与K8s集群交互
- Helm:3.0+版本,用于部署Hermes-router
依赖组件
基础依赖
- 开源网关:需支持Gateway API Inference Extension,如Istio v1.28。
额外依赖
若要使用Hermes-router提供的KVCache aware相关路由策略进行开发,有如下额外依赖:
- KVCache全局管理组件:提供全局KVCache感知与命中率计算,如cache-indexer v25.12。
搭建环境
克隆代码仓库。
bash# 克隆hermes-router主仓库 git clone https://gitcode.com/openFuyao/hermes-router.git cd hermes-router配置Go开发环境。
bash# 检查Go版本 go version # 设置Go代理(可选,加速依赖下载) go env -w GOPROXY=https://goproxy.cn,direct安装Istio和GIE框架。
bash# 下载Istio curl -L https://istio.io/downloadIstio | sh - cd istio-* # 安装Istio(启用GIE支持) istioctl install -y \ --set tag=<ISTIO_TAG> \ --set hub=gcr.io/istio-testing \ --set values.pilot.env.ENABLE_GATEWAY_API_INFERENCE_EXTENSION=true # 安装Gateway API CRDs kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml # 安装GIE CRDs(根据实际版本调整) kubectl apply -f <GIE_CRDs_YAML>构建hermes-router镜像。
bashcd hermes-router # 构建镜像 docker build -t hermes-router:dev -f Dockerfile.epp . # 或使用nerdctl nerdctl build -t hermes-router:dev -f Dockerfile.epp .
验证环境
验证Istio安装。
bash# 检查Istio组件 kubectl get pods -n istio-system # 预期输出:所有Pod状态为Running验证GIE CRDs。
bash# 检查InferencePool CRD kubectl get crd inferencepools.inference.networking.x-k8s.io部署hermes-router进行验证。
bashcd hermes-router # 更新Helm依赖 helm dependency update examples/1_pd_bucket/charts/hermes-router # 部署hermes-router(使用最简单的配置) helm upgrade --install vllm-qwen-qwen3-8b \ examples/1_pd_bucket/charts/hermes-router \ --namespace hermes-test --create-namespace \ -f examples/profiles/epp-random-pd-bucket.yaml \ --set inferencepool.provider.name=istio \ --set image.repository=hermes-router \ --set image.tag=dev # 检查部署状态 kubectl get pods -n hermes-test kubectl get svc -n hermes-test
预期结果:
- Pod状态为Running。
- Service正常创建。
- 无错误日志。
[root@master hermes-router]# kd get all
NAME READY STATUS RESTARTS
pod/vllm-pd-decode-5bb99b6764-cs52k 1/1 Running 0
pod/vllm-pd-prefill-6db4c89f78-f7csp 1/1 Running 0
pod/vllm-pd-proxy-5f8bfcf495-p5vpj 1/1 Running 0
pod/vllm-qwen-qwen3-8b-epp-5fd87d6d59-r2xpv 1/1 Running 0
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/vllm-pd-proxy ClusterIP ****** <none> 8000/TCP,5557/TCP 16h
service/vllm-qwen-qwen3-8b-epp ClusterIP ****** <none> 9002/TCP,9090/TCP 83s
NAME READY UP-TO-DATE AVAILABLE
deployment.apps/vllm-pd-decode 1/1 1 1
deployment.apps/vllm-pd-prefill 1/1 1 1
deployment.apps/vllm-pd-proxy 1/1 1 1
deployment.apps/vllm-qwen-qwen3-8b-epp 1/1 1 1
NAME DESIRED CURRENT READY
replicaset.apps/vllm-pd-decode-5bb99b6764 1 1 1
replicaset.apps/vllm-pd-prefill-6db4c89f78 1 1 1
replicaset.apps/vllm-pd-proxy-5f8bfcf495 1 1 1
replicaset.apps/vllm-qwen-qwen3-8b-epp-5fd87d6d59 1 1 1开发自定义路由策略
使用场景概述
当预置的路由策略无法满足特定业务需求时,开发者可以通过实现自定义插件来扩展路由能力。典型场景包括:
- 业务特定路由规则:根据业务标签、用户ID等自定义属性进行路由。
- 性能优化需求:针对特定硬件或网络环境优化路由算法。
- 混合架构支持:支持聚合架构和PD分离架构的混合部署。
系统架构
Hermes-router采用插件化架构,通过不同类型的插件协同工作来实现智能路由。插件主要分为四类:Filter插件用于过滤候选端点,Scorer插件用于对端点进行评分,Picker插件用于从评分结果中选择最终端点,PreRequest插件用于在请求转发前修改请求。各类插件的详细说明如下:
表1 Hermes-router插件类型说明
| 插件类型 | 功能描述 | 示例 |
|---|---|---|
| Filter插件 | 过滤候选端点列表 | filter-by-pd-label:根据PD标签过滤。 |
| Scorer插件 | 对端点进行评分 | scorer-aggregate-kv-cache-aware:基于KV Cache评分。scorer-pd-bucket:基于Bucket负载评分。 |
| Picker插件 | 从评分结果中选择最终端点 | picker-min-random:选择评分最低的随机实例picker-pd-kv-cache-aware:PD架构的智能选择插件。 |
| PreRequest插件 | 在请求转发前修改请求 | pd-header-handler:添加PD架构所需的请求头。 |
插件执行流程
插件按照在schedulingProfiles中配置的顺序执行:
- Filter阶段:所有Filter插件依次执行,逐步缩小候选端点范围。
- Scorer阶段:所有Scorer插件对候选端点进行评分(可配置权重)。
- Picker阶段:Picker插件根据评分结果选择最终端点。
- PreRequest阶段:PreRequest插件修改请求后转发。
以下链接提供了开发自定义路由策略所需的相关文档:
- hermes-router代码仓库:Hermes-router的源代码仓库,包含所有插件实现示例和开发框架,开发者可参考现有插件代码进行开发。
- GIE框架规范:Gateway API Inference Extension(GIE)的官方规范文档,定义了EPP插件的接口规范和开发标准,是开发EPP插件必须遵循的规范。
- EPP Architecture Proposal:Endpoint Picker Plugin(EPP)架构提案,详细说明了EPP插件的架构设计、执行流程和扩展机制,帮助开发者深入理解插件工作原理。
开发步骤
设计路由策略。
开发者自行设计路由策略与具体的插件,本指南略过此步骤。
开发路由插件。
开发者在完成路由策略的设计后,需要将处理流程拆分为若干EPP规范的插件并实现,主要插件类型为Filter、Scorer、Picker、PreRequest等。
下面以用于过滤
Pod的Filter插件为例,展示EPP插件开发流程:2.1. 创建Filter代码文件。
Hermes-router将EPP插件分类存放,建议在
pkg/plugins/filter下创建新的Filter插件。2.2. 定义Filter插件结构体。
gotype MyFilter struct { typedName plugins.TypedName // ... 其他成员变量 }2.3. 实现结构体构造函数。
gofunc NewMyFilter(...){ // ... 初始化成员变量 return &MyFilter{...} }2.4. 实现工厂函数。
gofunc ByMyFilterFactory(...){ // ... 根据GIE传入参数初始化Filter成员变量 return NewMyFilter(...) }2.5. 实现
Filter接口中的Filter()方法。gofunc (m *MyFilter) Filter(_ context.Context, _ *types.CycleState, _ *types.LLMRequest, pods []types.Pod) []types.Pod {}2.6. 在
pkg/plugins/register.go中注册新增Filter。gofunc RegisterAllPlugins() { plugins.Register(filter.MyFilter, filter.ByMyFilterFactory) // ... 其他插件 }至此一个Filter插件开发完成,开发者可以按照相同流程开发其他类型的EPP插件。
定义路由策略。
为应用路由策略,开发者需要在资源类型为InferencePool的yaml文件中进行配置:
- 在inferenceExtension.pluginsConfigFile字段声明路由策略名称。
- 在inferenceExtension.pluginsCustomConfig字段声明路由策略具体配置。
yaml# example-strategy 路由策略的配置示例 inferencepool: inferenceExtension: pluginsConfigFile: "example_strategy.yaml" pluginsCustomConfig: exaexample_strategymple.yaml: | apiVersion: inference.networking.x-k8s.io/v1alpha1 kind: EndpointPickerConfig plugins: # ... plugins
至此开发者已完成路由策略的开发。
调测验证
使用kubectl port-forward进行端口转发。
执行如下命令,查找Gateway Service名称。
shellkubectl get svc -n <NAMESPACE> -l gateway.networking.k8s.io/gateway-name=inference-gateway执行如下命令,设置端口转发。
shellkubectl port-forward -n <NAMESPACE> service/<gateway-service-name> 8000:80执行如下命令,发送请求。
shellcurl -X POST http://localhost:8000/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen/Qwen3-8B", "messages": [ {"role": "user", "content": "你好"} ], "max_tokens": 100, "temperature": 0.7, "stream": false }'
开发完成后,请参照《用户指南》中的安装章节进行部署及验证工作。