AIBrix 本地模式(Local Mode)实战指南:无 Docker/Kubernetes 运行 Envoy 与 gateway-plugin 双进程网关
2026/9/18 13:24:21 网站建设 项目流程

AIBrix 本地模式(Local Mode)实战指南:无 Docker/Kubernetes 运行 Envoy 与 gateway-plugin 双进程网关

【免费下载链接】aibrixCost-efficient and pluggable Infrastructure components for GenAI inference项目地址: https://gitcode.com/GitHub_Trending/ai/aibrix

导读

AIBrix 本地模式(Local Mode)将 AIBrix 网关拆解为 Envoy 与 gateway-plugin 两个裸进程,通过静态配置直接发现 vLLM 推理引擎,无需 Docker 容器与 Kubernetes 集群即可运行。本文以 deployment/local/README.md 为骨架,结合仓库内启动脚本、Envoy 配置与路由算法源码,完整讲解本地模式的架构原理、环境准备、启动停止、配置项与排障方法,帮助你在单机环境快速调试 AIBrix 的路由与网关行为。

本地模式是什么:适用场景与能力边界

本地模式的核心思想是去掉一切容器与编排依赖,只保留网关本身。它以两个原生二进制进程运行:

  • Envoy:负责接收 HTTP 请求,并通过 ext_proc 外部处理过滤器与插件通信,最终把请求路由到选定的后端;
  • gateway-plugin:以--standalone模式运行,从静态endpoints.yaml中读取 vLLM 后端地址,用配置的路由算法选出最佳后端并返回给 Envoy。

这一模式最典型的适用场景是:

  • 本地开发与调试路由算法(无需每次改动都重新构建镜像、拉起 Pod);
  • 单节点测试,避免容器与编排层的额外开销;
  • 快速验证网关行为(路由选择、请求转发、健康检查等)。

需要注意的能力边界:本地模式不包含 AIBrix controller 的编排能力。原文档明确提示"Local Mode does not include AIBrix controller orchestration, they can not run without Kubernetes"——即 PodAutoscaler、ModelAdapter、KV Cache 等由 controller 管理的编排逻辑依赖 Kubernetes,在本地模式下不会生效。

架构与请求流转:ext_proc + target-pod + ORIGINAL_DST

本地模式的整体请求链路如下(源自 deployment/local/README.md 的架构图):

┌────────────────────────┐ curl :10080 │ gateway-plugin │ │ │ (gRPC :50052) │ ▼ │ │ ┌─────────────┐ ext_proc gRPC │ --standalone │ │ Envoy │ ───────────────► │ --endpoints-config │ │ (:10080) │ │ │ │ │ ◄─ target-pod ── │ selects best backend │ │ ORIGINAL │ header └────────────────────────┘ │ _DST │ │ cluster │ ──── route to ──► vLLM engine(s) └─────────────┘ selected IP (e.g., 127.0.0.1:8000)

完整流转过程为:客户端向 Envoy 的 10080 端口发送 HTTP 请求 → Envoy 通过 ext_proc gRPC 将请求头/请求体转发给 gateway-plugin(监听 50052)→ 插件从请求中提取模型名,在endpoints.yaml中查找可用后端 → 使用配置的路由算法选出最佳后端 → 通过target-pod响应头把目标地址返回给 Envoy → Envoy 使用ORIGINAL_DST类型集群将请求路由到该地址。

这一机制在 deployment/local/configs/envoy.yaml 中有完整的静态配置印证。其中original_destination_cluster集群的配置如下:

- name: original_destination_cluster type: ORIGINAL_DST lb_policy: CLUSTER_PROVIDED original_dst_lb_config: use_http_header: true http_header_name: "target-pod" connect_timeout: 30s

即 Envoy 通过读取target-pod请求头来决定上游地址,而不是依赖 DNS 或 EDS 服务发现,这正是裸进程模式下无需注册中心即可动态路由的关键。

ext_proc 过滤器的处理模式也值得关注(见 envoy.yaml):

processing_mode: request_header_mode: SEND request_body_mode: BUFFERED response_header_mode: SEND response_body_mode: STREAMED request_trailer_mode: SKIP response_trailer_mode: SKIP message_timeout: 600s failure_mode_allow: false

请求体采用 BUFFERED(缓冲后整体发送),响应体采用 STREAMED(流式转发,适合 LLM 的流式输出场景);failure_mode_allow: false表示插件处理失败时请求直接失败,避免无谓地放行到错误后端。

前置准备:Go、gateway-plugin、Envoy、vLLM

1. 安装 Go(1.22+)

Linux:

wget https://go.dev/dl/go1.22.5.linux-amd64.tar.gz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf go1.22.5.linux-amd64.tar.gz echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc source ~/.bashrc go version

macOS:

brew install go

2. 构建 gateway-plugin 二进制

make build-gateway-plugins-nozmq

该命令在 Makefile 中定义(build-gateway-plugins-nozmq: manifests generate fmt vet ## Build gateway-plugins binary without ZMQ (for standalone mode).),产物为bin/gateway-plugins——一个纯 Go 二进制,不依赖 ZMQ/CGO。由于本地模式下没有 KV 事件同步等 ZMQ 相关需求,这个构建目标是 standalone 模式的专用产物,也避免了交叉编译 CGO 的麻烦。

3. 安装 Envoy

Linux(x86_64):

ENVOY_VERSION=1.37.1 wget -O envoy https://github.com/envoyproxy/envoy/releases/download/v${ENVOY_VERSION}/envoy-${ENVOY_VERSION}-linux-x86_64 chmod +x envoy sudo mv envoy /usr/local/bin/ envoy --version

macOS:

brew install envoy

4. 启动 vLLM 引擎

# 示例:在 8000 端口启动 vLLM vllm serve Qwen/Qwen3.5-4B --port 8000

本地模式下 vLLM 可以与 Envoy 运行在同一台机器(127.0.0.1:8000),也可以运行在局域网内其他机器(用可达的 IP 或主机名即可)。

5. (可选)Redis

Redis 在本地模式不是必需的。没有 Redis 时,限流(rate limiting)功能会被禁用,但路由功能正常工作。只有当你需要测试限流能力时才需要启动:

redis-server

快速启动:一键脚本与手动方式

仓库提供了两个管理脚本,但它们仅支持 Linux(内部依赖setsidsspgrep等 Linux 工具)。macOS 用户需要手动启动两个进程。

Linux 一键启动

cd deployment/local # 编辑 endpoints 以匹配你的 vLLM 配置 vim configs/endpoints.yaml # 启动 ./run-local.sh # 测试 curl http://localhost:10080/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "Qwen/Qwen3.5-4B", "messages": [{"role": "user", "content": "Hello"}] }' # 停止 ./stop-local.sh

macOS 手动启动

# macOS: start manually bin/gateway-plugins --standalone --endpoints-config=deployment/local/configs/endpoints.yaml & envoy -c deployment/local/configs/envoy.yaml --use-dynamic-base-id --log-level warn &

macOS 手动停止

手动启动时可用jobs/kill结束对应进程;Linux 场景下直接运行./stop-local.sh即可,脚本会读取deployment/local/.pids文件中的两个 PID 并逐一终止,同时清理/dev/shm/envoy_shared_memory_*共享内存文件,避免重启时因 Envoy base_id 冲突而启动失败。

run-local.sh 做了什么

阅读 run-local.sh 可以了解脚本的完整逻辑,这对理解本地模式的进程管理非常有帮助:

  • 依次检查 gateway-plugin 二进制、envoy命令、Envoy 配置与 endpoints 配置是否存在,缺失时给出明确的修复提示;
  • 通过setsid --fork启动 gateway-plugin(--standalone --endpoints-config --grpc-bind-address=:50052 --http-bind-address=:8080),日志重定向到logs/gateway-plugin.log
  • 轮询等待 gateway gRPC 端口 50052 就绪(最多 30 秒),失败则打印日志并退出;
  • 再启动 Envoy(-c configs/envoy.yaml --use-dynamic-base-id --log-level warn),日志写入logs/envoy.log,轮询等待 HTTP 端口 10080 就绪(最多 10 秒);
  • 最后把两个 PID 写入.pids文件,并打印所有可用的端点地址与测试命令。

配置详解

Endpoints 配置(configs/endpoints.yaml)

deployment/local/configs/endpoints.yaml 定义了网关可路由的 vLLM 后端地址,支持三种形态。

单后端(最简形态):

models: - name: "Qwen/Qwen3.5-4B" engine: "vllm" # optional: vllm, sglang, trtllm endpoints: - "127.0.0.1:8000"

多后端(网关在其间做负载路由):

models: - name: "Qwen/Qwen2.5-1.5B-Instruct" engine: "vllm" endpoints: - "192.168.1.10:8000" - "192.168.1.11:8000"

P/D 分离部署(prefill/decode 角色分离):

models: - name: "Qwen/Qwen2.5-72B" engine: "vllm" rolesets: - name: default prefill: - "192.168.1.10:8000" decode: - "192.168.1.11:8000"

字段说明:

  • name:模型名,必须与请求体中的model字段完全一致,否则路由无法命中;
  • engine:可选字段,取值vllmsglangtrtllm,用于标识后端引擎类型(从源码看,PD 分离场景下的引擎处理在 pkg/plugins/gateway/algorithms/pd/engine/ 目录分别实现了vllmsglangtrtllm等处理器);
  • endpoints:后端地址列表(ip:port),多地址时由路由算法选择;
  • rolesets:P/D 分离模式下的角色集合,prefilldecode分别列出两类工作节点的地址。

注意:endpoints.yaml中的地址应使用本机可达的真实 IP 或主机名(配置注释中明确说明 "Use real IP addresses or hostnames reachable from this machine")。

Envoy 配置(configs/envoy.yaml)

deployment/local/configs/envoy.yaml 是裸进程模式的完整 Envoy 静态配置,几个关键点:

  • Admin 接口绑定127.0.0.1:9901,可用于查看 stats 与 config dump;
  • HTTP 监听器绑定0.0.0.0:10080,针对 LLM 长请求设置了stream_idle_timeout: 300srequest_timeout: 600s,避免推理耗时长导致连接被过早回收;
  • 路由规则
    • /v1/models→ 转发到gateway_http集群(由 gateway-plugin 的 HTTP 服务兜底返回模型列表,因为本地模式没有 metadata 服务);
    • /v1/→ 转发到original_destination_cluster(核心推理路径,timeout: 600sidle_timeout: 300s);
    • /healthz→ 直接返回{"status":"ok"}
    • /metrics→ 转发到gateway_http
    • 其余路径 → 404 并提示使用/v1/chat/completions/v1/messages/v1/models
  • 三个静态集群gateway_ext_proc(指向127.0.0.1:50052,HTTP/2,用于 ext_proc gRPC)、gateway_http(指向127.0.0.1:8080,用于 metrics 与模型列表)、original_destination_clusterORIGINAL_DST类型,读取target-pod头)。

关于/v1/models在本地模式下由插件直接应答这一点,源码中有直接注释印证:pkg/plugins/gateway/gateway.go 中 "In local/standalone mode, Envoy routes /v1/models here since there is no metadata service";同时 pkg/plugins/gateway/gateway.go 中 "Skip validation in standalone mode (no gateway client)" 说明 standalone 模式下插件跳过对 Kubernetes 网关客户端的依赖,这正是它能脱离集群运行的原因。

路由算法配置

路由算法通过环境变量在启动前设置:

ROUTING_ALGORITHM=round_robin ./run-local.sh

run-local.sh 中给出了默认值ROUTING_ALGORITHM="${ROUTING_ALGORITHM:-random}",即不设置时默认使用random;该变量会透传给 gateway-plugin 进程。更完整的变量说明可参考 pkg/plugins/gateway/ENV_VARS.md(其中记录了ROUTING_ALGORITHM作为无 per-request 覆盖时的默认路由算法)。

原文档列出的可用算法包括randomround_robinleast_requestprefix_cache_aware等。需要说明的是:从源码中的注册表看,pkg/plugins/gateway/algorithms/ 目录下实际注册的算法名采用 kebab-case(连字符命名),包括但不限于:

算法名(源码注册名)实现文件说明
randomrandom.go随机选择后端
least-requestleast_request.go选择当前活跃请求最少的后端
prefix-cacheprefix_cache.go优先选择命中前缀缓存的后端
least-latencyleast_latency.go选择预估延迟最低的后端
power-of-twopower_of_two.go两随机候选择优
load-balanceload_balance.go基于待处理时间与 KV 缓存使用率的负载均衡
throughputthroughput.go基于吞吐量的路由
pdpd_disaggregation.goP/D 分离场景专用
least-busy-timeleast-gpu-cacheleast-kv-cacheleast-utilprefix-cache-preble对应同名文件分别面向忙时、GPU/KV 缓存余量、利用率、带直方图的 Prefix Cache 等场景

若你想组合多个算法并分配权重,router.go 中的ParseMultiRouterConfig支持"prefix-cache:2,least-latency:1,least-request"这样的格式(权重为 0~1000000 的整数,缺省为 1,权重 0 表示跳过)。实际使用哪个命名风格,建议以当前仓库源码注册名为准,并在本地实测验证。

端点一览

启动成功后,本地模式提供以下端点:

端点端口说明
HTTP API10080推理请求入口(如/v1/chat/completions
Envoy Admin9901Envoy 管理接口(stats、config dump)
Gateway Metrics8080gateway-plugin 的 Prometheus 指标
Health Check10080/healthzEnvoy 健康检查

另外,模型列表接口为http://localhost:10080/v1/models,指标地址为http://localhost:8080/metrics,二者在 run-local.sh 启动成功后的输出中都会打印。

日志

本地模式下两个进程的日志分别落盘:

tail -f deployment/local/logs/gateway-plugin.log tail -f deployment/local/logs/envoy.log
  • gateway-plugin.log:gateway-plugin 的启动与运行日志,插件崩溃、路由算法初始化失败等都会记录在这里;
  • envoy.log:Envoy 的运行日志(--log-level warn级别),端口冲突、配置错误等问题会体现在这里。

排障指南

报错/现象原因与排查
"no healthy upstream"vLLM 后端在endpoints.yaml中配置的地址不可达。确认引擎确实在运行、地址端口正确且本机可连通
"ext_proc gRPC error"gateway-plugin 未运行或已崩溃。检查logs/gateway-plugin.log确认插件状态
Envoy won't start查看logs/envoy.log。最常见的原因是 10080 或 9901 端口被占用
Routing not working检查请求中的model字段是否与endpoints.yaml中的name完全一致(含大小写),不一致时无法命中后端

除以上原文档列出的常见问题外,结合 stop-local.sh 的实现还可以补充一点:重启前若残留/dev/shm/envoy_shared_memory_*,可能导致 Envoy base_id 冲突而无法启动,Linux 下请优先使用./stop-local.sh正常停止,脚本会代为清理。

小结

本地模式以最小的依赖(Go + Envoy + gateway-plugin 二进制)复现了 AIBrix 网关的核心路径:ext_proc 请求外发、模型名解析、路由算法选后端、target-pod头回传、ORIGINAL_DST集群转发。它适合路由算法的本地迭代与单机验证;当需要 PodAutoscaler、ModelAdapter、KV Cache 等编排能力时,则需要切换到完整的 Kubernetes 部署形态(参考 config/default/kustomization.yaml 与 deployment/standalone/README.md)。建议读者在动手前先通读 run-local.sh、envoy.yaml 与 endpoints.yaml 三份核心文件,再结合本文逐步实践。

【免费下载链接】aibrixCost-efficient and pluggable Infrastructure components for GenAI inference项目地址: https://gitcode.com/GitHub_Trending/ai/aibrix

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询