@alexa_griffith_: Red Hat AI博客系列第三部分现已发布!本部分重点介绍Red Hat的托管Kubernetes AI推理如何使用llm-d...

X AI KOLs Timeline 新闻

摘要

Red Hat的AI博客系列第三部分详细介绍了在他们的托管Kubernetes平台(Amazon EKS)中,llm-d如何利用Kubernetes资源和Envoy集成来路由模型推理流量,并做出实时决策。

Red Hat AI博客系列第三部分现已发布!本部分重点介绍Red Hat的托管Kubernetes AI推理平台如何使用llm-d。https://developers.redhat.com/articles/2026/08/13/how-llm-d-routes-model-inference-traffic-amazon-eks#… @RedHat_AI @_llm_d_ https://youtu.be/RbNfxFU8Qh8?si=x1sHu6TeuHGueRrz…
查看原文
查看缓存全文

缓存时间: 2026/08/18 00:21

Red Hat AI博客系列第三部分现已发布!

本部分重点介绍Red Hat的托管Kubernetes上的AI推理平台如何利用llm-d实现模型推理流量路由。
https://developers.redhat.com/articles/2026/08/13/how-llm-d-routes-model-inference-traffic-amazon-eks#…
@RedHat_AI @llm_d https://youtu.be/RbNfxFU8Qh8?si=x1sHu6TeuHGueRrz…


llm-d如何在Amazon EKS上路由模型推理流量 | Red Hat Developer

来源:https://developers.redhat.com/articles/2026/08/13/how-llm-d-routes-model-inference-traffic-amazon-eks

Kubernetes资源追踪:llm-d模型服务一文中,我们生成了llm-d模型服务所需的自定义资源。但当提示词到达集群时,内部实际发生了什么?本文将跟踪从入口网关到各个vLLM Pod的请求流程,揭示Kubernetes自定义资源如何实现实时路由决策。

若偏爱视觉概览,请观看以下视频,了解KServe与llm-d如何设置后端资源、追踪KV缓存局部性并路由入站流量。

llm-d端点选择器

调度器配置会创建端点选择器Pod。调度器Pod运行端点选择器——负责决定每个请求应由哪个vLLM Pod处理的进程。其资源名称为test-kserve-router-scheduler

kubectl get pod -n llm-test -l app.kubernetes.io/component=llminferenceservice-router-scheduler  
NAME                                    READY   STATUS    RESTARTS   AGE  
test-kserve-router-scheduler            2/2     Running   0          5m  

调度器Pod内部包含两个容器:

容器1:主容器(调度器)

  • 镜像:registry.redhat.io/rhoai/odh-llm-d-inference-scheduler-rhel9
  • 运行端点选择器(EPP),决定使用哪个后端Pod
  • 在端口9002上暴露gRPC服务
  • 实现路由插件:queue-scorerprefix-cache-scorermax-score-picker

容器2:分词器(KV缓存追踪器)

  • 镜像:registry.redhat.io/rhoai/odh-llm-d-kv-cache-rhel9
  • 追踪所有vLLM副本的前缀缓存状态
  • 帮助调度器将请求路由到具有匹配缓存的Pod,以降低延迟

如图1所示,调度器Pod包含两个容器,通过ZeroMQ共享状态。主容器在gRPC端口9002上运行EPP调度器,分词器容器则通过ZeroMQ端口5557追踪KV缓存状态。
(https://developers.redhat.com/sites/default/files/figure-1_39.png)
图1:调度器Pod的两个容器——主容器(端点选择器)和分词器(KV缓存追踪器),通过ZeroMQ共享缓存状态

Envoy外部处理

调度器作为Envoy外部处理器运行。ext-proc功能允许Envoy调用外部gRPC服务,并在继续处理请求前根据响应执行操作。
实际流程是:当请求到达网关时,Envoy处理该请求,通过gRPC调用调度器询问应使用哪个后端,然后将请求转发到调度器选定的Pod。
Envoy与调度器之间的ext-proc交互如图2所示:Envoy网关暂停入站客户端请求,通过gRPC端口9002查询EPP调度器,接收选定的Pod后转发流量。
(https://developers.redhat.com/sites/default/files/figure-2_35.png)
图2:Envoy暂停请求,通过gRPC询问调度器使用哪个Pod,然后转发请求

推理资源

为进行智能路由决策,调度器使用以下资源回答两个问题:可路由的目标Pod有哪些?不同请求应如何分配优先级?
调度器通过读取各自的Kubernetes自定义资源获取答案:

  • InferencePool:可供选择的后端Pod集合,将模型的vLLM Pod组合为单一目标
  • InferenceObjective(可选):定义流量优先级。此基础部署未创建InferenceObjective,因此每个请求获得相同处理。调度器已具备监视权限,当大规模部署时优先级设置将生效

图3展示了EPP调度器如何读取这两种自定义资源以确定路由决策:端点选择器调度器从InferencePool资源读取候选Pod,从InferenceObjective资源读取流量优先级。
(https://developers.redhat.com/sites/default/files/figure-3_32.png)
图3:调度器(EPP)读取InferencePool获取候选Pod,读取InferenceObjective获取流量优先级

当需要流量优先级时(例如在负载条件下使延迟敏感请求优先于批处理作业),可添加InferenceObjective。该目标按请求生效而非全局生效。客户端通过设置x-gateway-inference-objective头(例如high-priority)选择目标。调度器在选择端点时应用该目标的优先级,因此在池负载较高时,高优先级请求会获得优待。省略该头的请求将回退到默认处理。

添加InferenceObjective需应用以下配置:

apiVersion: inference.networking.x-k8s.io/v1alpha2  
kind: InferenceObjective  
metadata:  
  name: high-priority  
  namespace: llm-test  
spec:  
  priority: 100  # 数值越高,关键性越强  
  poolRef:  
    name: test-inference-pool  
    group: inference.networking.k8s.io  

InferenceObjective在集群中定义路由优先级,入站请求通过传递自定义头来调用:

x-gateway-inference-objective: high-priority  

调度器读取该头,查找匹配的InferenceObjective,并使用其优先级决定优先调度哪个排队请求。未指定目标的请求默认为优先级零,因此本部署中所有请求获得相同处理。

网关监视权限

调度器Role具有监视权限,可直接从Kubernetes API读取两种资源,这展示了Gateway API推理扩展如何与Istio协同工作。网关Pod无权访问这些资源。Istio控制平面(istiod)从Kubernetes读取InferencePool并将其编译为网关配置。网关Pod本身从不读取Kubernetes API。该编译后的配置指示网关调用调度器。

表:调度器直接监视InferencePool和InferenceObjective,istiod仅监视InferencePool,网关Pod无直接Kubernetes API访问权限

组件InferencePoolInferenceObjective直接Kubernetes API访问
调度器(EPP) test-kserve-router-scheduler监视监视是(RBAC)
istiod Istio控制平面监视,编译
网关Pod(Envoy) inference-gateway-istio通过istiod配置

在建立调度器和InferencePool后,我们来分析其配置与实现细节。

InferencePool

InferencePool是配置资源,告知Envoy调用哪个端点选择器,并包含选择器以识别可用后端Pod。

kubectl get inferencepool test-inference-pool -n llm-test -o yaml  
apiVersion: inference.networking.k8s.io/v1  
kind: InferencePool  
metadata:  
  name: test-inference-pool  
  namespace: llm-test  
spec:  
  endpointPickerRef:  
    failureMode: FailOpen  
    kind: Service  
    name: test-router-epp-service  
    port:  
      number: 9002  
  selector:  
    matchLabels:  
      app.kubernetes.io/name: test  
      kserve.io/component: workload  
  targetPorts:  
  - number: 8000  

InferencePool与调度器的关系如图4所示:InferencePool将网关连接到端口9002的EPP调度器,同时通过标签匹配目标vLLM Pod。
(https://developers.redhat.com/sites/default/files/figure-4_28.png)
图4:InferencePool的endpointPickerRef字段将网关指向调度器,其selector定义调度器选择的vLLM Pod

故障模式

设置failureMode: FailOpen时,若端点选择器不可达,网关将回退到标准负载均衡。这确保即使智能路由中断,系统仍保持可用。
另一选项为FailClose:若端点选择器不可用则丢弃请求。当必须确保请求仅在调度器决策下才能被服务时选择FailClose,以可用性换取该保证。

Service

InferencePool会创建动态Service资源。

kubectl get svc -n llm-test | grep inference-pool  
test-inference-pool-ip     ClusterIP   None         8000/TCP    5m  

InferencePool拥有自己的后端Service,使网关获得池的稳定集群内地址——即使路由决策本身由调度器做出。

路由请求

HTTPRoute将入站请求连接到正确后端。它匹配请求的URL路径并将其转发到InferencePool,后者将网关指向调度器。这也是共享网关组件的接入点。

图5演示了HTTPRoute如何匹配并重写入站请求URL路径:
HTTPRoute匹配路径前缀,应用URLRewrite过滤器,将请求传递给InferencePool和调度器。
(https://developers.redhat.com/sites/default/files/figure-5_22.png)
图5:HTTPRoute匹配请求的URL路径,进行重写后转发到InferencePool,后者将网关指向调度器

将外部URL路径映射到InferencePool使模型可通过可预测地址(如/llm-test/test-router/v1/chat/completions)访问,而非内部Pod IP。
注意我们在YAML中指定了route: {},控制器自动生成了路由规则:

kubectl get httproute test-kserve-route -n llm-test -o yaml  
apiVersion: gateway.networking.k8s.io/v1  
kind: HTTPRoute  
metadata:  
  name: test-kserve-route  
  namespace: llm-test  
spec:  
  parentRefs:  
  - group: gateway.networking.k8s.io  
    kind: Gateway  
    name: inference-gateway  
    namespace: redhat-ods-applications  
  rules:  
  - matches:  
    - path:  
        type: PathPrefix  
        value: /llm-test/test-router/v1/chat/completions  
    backendRefs:  
    - group: inference.networking.k8s.io  
      kind: InferencePool  
      name: test-inference-pool  
      port: 8000  
    filters:  
    - type: URLRewrite  
      urlRewrite:  
        path:  
          replacePrefixMatch: /v1/chat/completions  

URL重写的作用

外部客户端调用http://loadbalancer/llm-test/test-router/v1/chat/completions,然后HTTPRoute剥离命名空间和服务前缀,将请求转发给Envoy。Envoy调用InferencePool配置的EPP选择后端(如http://pool:8000/v1/chat/completions)。
HTTPRoute附加到平台的inference-gateway(在第1部分中配置):

kubectl get gateway inference-gateway -n redhat-ods-applications -o yaml  
apiVersion: gateway.networking.k8s.io/v1  
kind: Gateway  
metadata:  
  name: inference-gateway  
  namespace: redhat-ods-applications  
spec:  
  gatewayClassName: istio  
  listeners:  
  - name: http  
    port: 80  
    protocol: HTTP  
    allowedRoutes:  
      namespaces:  
        from: All  
status:  
  addresses:  
  - type: Hostname  
    value: inference-gateway-xyz.elb.us-east-1.amazonaws.com  
  listeners:  
  - attachedRoutes: 1  
    conditions:  
    - type: Programmed  
      status: "True"  
    name: http  

状态块中有两个字段需关注:

  1. addresses字段显示云服务商分配给网关的外部主机名,客户端向此主机名发送请求
  2. attachedRoutes: 1字段确认您创建的HTTPRoute已正确注册到网关

完整的基础设施请求路径如图6所示:
从外部客户端经AWS ELB、LoadBalancer Service到Istio Envoy网关再到vLLM Pod的完整请求路径,包含对EPP的旁路调用。
(https://developers.redhat.com/sites/default/files/figure-6_19.png)
图6:从客户端到AWS负载均衡器再到Kubernetes Service、Istio Envoy Pod最后到vLLM Pod的完整请求路径,调度器作为旁路请求被调用

让我们解析网关层次:

  • 网关资源(inference-gateway)包含配置及上述外部地址状态
  • 网关配置被Istio Envoy Pod使用(通过inference-gateway-istioDeployment)
  • Istio Envoy Pod是接收入站流量并应用HTTPRoute规则的代理
  • Istio Envoy Pod前端是类型为LoadBalancer的Kubernetes Service
  • LoadBalancer类型触发云控制器配置外部负载均衡器(此处为AWS ELB)
  • 外部负载均衡器的主机名出现在网关状态中

结果是一个网关,多个HTTPRoute资源:

  • 集群中的每个推理服务都将其HTTPRoute附加到此共享网关
  • Envoy代理评估每条路由
  • 当匹配路由的后端是InferencePool时,Envoy代理调用端点选择器调度器
  • 调度器响应时选择适当端点
  • Envoy代理随后转发到选定的Pod

图7展示了Gateway资源及其底层基础设施层:
结构层次图显示Gateway资源控制着AWS ELB和Kubernetes Service下方的Istio Envoy代理Pod。
(https://developers.redhat.com/sites/default/files/figure-7_12.png)
图7:Gateway资源及其所处的层次——外部负载均衡器、LoadBalancer Service以及应用HTTPRoute规则的Istio Envoy Pod

端点选择器Service

端点选择器调度器Pod的Service为网关提供稳定的ClusterIP地址。EndpointSlice包含Service背后活跃的Pod IP列表,使发送到稳定地址的流量能够到达运行中的调度器Pod。

kubectl get svc test-router-epp-service -n llm-test -o wide  
NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE  
test-router-epp-service   ClusterIP   172.20.243.216  <none>        9002/TCP,9003/TCP,9090/TCP,5557/TCP   5m  

端口说明:

  • 9002:gRPC端点选择器调度器
  • 9003:健康检查
  • 9090:Prometheus指标
  • 5557:调度器(主容器)与KV缓存追踪器(分词器)共享前缀缓存状态的ZeroMQ通道

图8展示了ServiceEndpointSlice资源如何将稳定IP地址映射到后端Pod:
Kubernetes Service将稳定的ClusterIP地址映射到追踪vLLM Pod和调度器Pod实时IP的EndpointSlice。
(https://developers.redhat.com/sites/default/files/figure-8_10.png)
图8:每个Service拥有稳定的ClusterIP,其EndpointSlice保存背后活跃的Pod IP列表

流量策略(Istio)

DestinationRule是Istio资源,用于设置流量到达服务后的处理策略。三条规则配置Istio如何处理到调度器、工作负载和影子服务的流量:

kubectl get destinationrule -n llm-test  
NAME                       HOST                                AGE  
test-kserve-scheduler      test-kserve-scheduler               5m  
test-kserve-shadow-svc     test-kserve-shadow-svc              5m  
test-kserve-workload-svc   test-kserve-workload-svc            5m  

这些DestinationRule资源在后台管理连接池、熔断器和双向TLS。Istio在负载条件下保持Pod间流量加密稳定,无需手动调优。

注意

shadow-svc规则覆盖影子流量。Istio可将实时请求镜像到另一目标而不影响真实响应,适用于A/B测试。平台设置策略;仅在启用时才会进行镜像。

身份与安全

调度器通过…

相似文章

@tomas_hk: 是的,我们在此分享了我们的经验:

X AI KOLs Following

这是一份全面指南,解释了模型路由技术,该技术能够智能地为每个请求选择最合适的AI模型,以优化成本、质量和延迟。文章将模型路由与AI网关进行了对比,并强调了其在代理型AI工作负载中的重要性。