kgateway部署实录,统一管控云端API和本地模型服务
2026/8/28 17:15:28 网站建设 项目流程

部署前的架构考量

去年团队决定把分散在各处的 LLM 调用收拢到统一入口时,我对比过几种方案。自研网关太重,通用 API 网关又缺少对 Token 计量、模型路由这类 LLM 场景的原生支持。kgateway 吸引我的点在于它把云原生基因和 LLM 场景做了深度结合——基于 Envoy 扩展、原生支持 Kubernetes 部署,同时内置了 OpenAI 协议兼容、多供应商管理和成本管控能力。

这次部署的目标很明确:在 K8s 集群内搭建一个能同时调度云端 OpenAI 和本地 vLLM 实例的统一网关,让上游业务方只认一个地址、一把密钥,背后的模型切换和故障转移对调用方完全透明。

基础环境准备与镜像部署

我们的集群运行的是 Kubernetes 1.28,节点已预先装好 containerd。kgateway 提供官方 Helm Chart,但为了更精细地控制配置,我选择先以 Docker Compose 模式在测试环境验证,再迁移到 K8s。

测试机是一台 8C16G 的 Ubuntu 22.04,Docker 和 Docker Compose 已就绪。先创建目录结构:

mkdir -p /opt/kgateway/{config,data,logs} cd /opt/kgateway

核心配置文件config/gateway-config.yaml是整场的关键,后面会逐段拆解。这里先把最小化的 Docker Compose 文件放出来:

# docker-compose.yml version: '3.8' services: kgateway: image: ghcr.io/kgateway/kgateway:v0.7.2 container_name: kgateway restart: unless-stopped ports: - "8080:8080" - "9090:9090" environment: - OPENAI_API_KEY=${OPENAI_API_KEY} - LOCAL_VLLM_KEY=${LOCAL_VLLM_KEY:-EMPTY} volumes: - ./config/gateway-config.yaml:/etc/kgateway/config.yaml:ro - ./data:/data - ./logs:/var/log/kgateway command: ["serve", "--config", "/etc/kgateway/config.yaml"]

.env文件单独存放敏感信息,已加入.gitignore

OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LOCAL_VLLM_KEY=EMPTY

启动命令很简洁:

docker-compose up -d docker logs -f kgateway --tail 100

看到Server started on :8080Metrics exposed on :9090两条日志,说明服务已正常拉起。

三段核心配置详解

kgateway 的配置采用 YAML 单文件驱动,结构清晰。我重点展开providersroutingrate_limiting三段,这也是实际踩坑最多的地方。

providers:双供应商并存配置

providers: - name: "openai-prod" provider_type: "openai" api_key: "${OPENAI_API_KEY}" api_base: "https://api.openai.com/v1" timeout_ms: 30000 models: - name: "gpt-4o" cost_per_token: input: 0.000005 output: 0.000015 - name: "gpt-4o-mini" cost_per_token: input: 0.00000015 output: 0.0000006 - name: "vllm-local" provider_type: "openai" # vLLM 兼容 OpenAI 协议 api_key: "${LOCAL_VLLM_KEY}" api_base: "http://vllm-service.internal:8000/v1" timeout_ms: 60000 models: - name: "llama-3-70b-instruct" cost_per_token: input: 0 output: 0

这里有两个细节值得注意。一是 vLLM 的api_key字段不能省略,即使本地服务无鉴权也要填任意非空字符串,否则会触发配置校验失败。二是cost_per_token对本地模型设为 0,便于后续成本报表中区分"真实支出"和"内部核算"。

routing:模型路由与故障转移

routing: default_timeout_ms: 45000 rules: - path: "/v1/chat/completions" allowed_models: - "gpt-4o" - "gpt-4o-mini" - "llama-3-70b-instruct" default_provider: "openai-prod" default_model: "gpt-4o-mini" # 基于请求头的智能路由 header_rules: - header_name: "x-prefer-local" header_value: "true" target_provider: "vllm-local" target_model: "llama-3-70b-instruct" # 模型级故障转移 fallback_chain: - model: "gpt-4o" provider: "openai-prod" - model: "llama-3-70b-instruct" provider: "vllm-local" - path: "/v1/embeddings" allowed_models: - "text-embedding-3-small" default_provider: "openai-prod" default_model: "text-embedding-3-small" cache_enabled: true

header_rules是我们用得最顺手的特性。业务方在请求头里带x-prefer-local: true,就能强制路由到本地 vLLM,适合处理涉密文档或需要离线运行的场景。fallback_chain则保障了当 OpenAI 返回 429 或超时时的自动降级——实际测试中,我把网络断掉模拟故障,请求在 2.3 秒内切换到了 vLLM,对调用方完全透明。

rate_limiting:Token 级限流与预算拦截

rate_limiting: enabled: true global_rps: 200 # 基于 API Key 的细粒度限流 per_key_limits: - key_pattern: "sk-prod-*" rps: 50 token_budget: daily_input_tokens: 10000000 daily_output_tokens: 5000000 action_on_exceed: "reject_with_429" - key_pattern: "sk-dev-*" rps: 10 token_budget: daily_input_tokens: 500000 daily_output_tokens: 200000 action_on_exceed: "reject_with_429" # 全局 Token 消耗速率保护 token_rate_protection: enabled: true max_tokens_per_minute: 5000000

token_budget是老板最关心的功能。我们为生产环境密钥配置了每日 1000 万输入 Token 的上限,超限即返回 429 并附带X-Budget-Exceeded响应头,前端可以据此引导用户联系管理员扩容。这个设计避免了月底收到天价账单的尴尬。

环境变量注入的安全实践

API Key 管理是生产环境的命门。我们的做法分三层:

第一层,运行时注入。如前面的 Compose 文件所示,密钥从不写死在任何配置里,全部通过环境变量传入。K8s 迁移后,改用 Secret 资源挂载:

env: - name: OPENAI_API_KEY valueFrom: secretKeyRef: name: kgateway-secrets key: openai-key

第二层,配置分离gateway-config.yaml中所有敏感字段统一使用${VAR_NAME}占位符,配合 CI/CD 中的环境变量替换,确保同一份配置模板能在 dev、staging、prod 三环境复用。

第三层,密钥轮换。kgateway 支持热加载配置,更新 Secret 后发送 SIGHUP 信号即可生效,无需重启 Pod。我们配合 Vault 的动态 Secret 功能,实现了 24 小时自动轮换。

验证与指标观测

服务启动后的验证分两步走。先用健康检查确认存活:

curl -s http://localhost:8080/health | jq . # 期望输出: {"status":"healthy","version":"v0.7.2"}

再用实际请求验证路由和转发:

# 测试云端模型 curl http://localhost:8080/v1/chat/completions \ -H "Authorization: Bearer sk-prod-abc123" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-4o-mini", "messages": [{"role": "user", "content": "解释kgateway的routing规则"}], "max_tokens": 200 }' # 测试强制路由到本地 curl http://localhost:8080/v1/chat/completions \ -H "Authorization: Bearer sk-prod-abc123" \ -H "x-prefer-local: true" \ -H "Content-Type: application/json" \ -d '{ "model": "llama-3-70b-instruct", "messages": [{"role": "user", "content": "同样的问题"}] }'

Prometheus 指标在 9090 端口暴露,关键指标包括:

指标名用途
kgateway_request_total按模型、状态码分类的请求总量
kgateway_token_input_total累计输入 Token 数,用于成本核算
kgateway_token_output_total累计输出 Token 数
kgateway_cache_hit_ratioEmbedding 缓存命中率
kgateway_fallback_count故障转移触发次数

我们在 Grafana 中配置了大盘,实时监控各模型的 Token 消耗趋势。上周发现 gpt-4o 的调用量突增,通过kgateway_request_total{model="gpt-4o"}下钻分析,定位到某个新上线的内部工具错误地硬编码了模型名称,修复后成本回归正常。

Embedding 缓存的降本效果

知识库场景的 Embedding 请求有个特点:大量重复文本。kgateway 的缓存层对/v1/embeddings路径做了专门优化:

cache: enabled: true type: "redis" redis_url: "redis://redis.internal:6379/0" ttl_seconds: 86400 embedding_cache: similarity_threshold: 0.98 # 语义相似度阈值 max_entries: 100000

开启缓存两周后,Embedding 请求的缓存命中率达到 67%,对应 OpenAI 账单下降约 62%。这个收益远超预期,因为内部知识库的文档更新频率本身不高,大量查询集中在固定的一批 FAQ 上。

从单点到高可用的演进

测试环境验证通过后,向 K8s 生产环境的迁移水到渠成。我们的演进路径分三个阶段:

第一阶段:单实例部署。直接用一个 Deployment + Service 暴露,快速验证业务兼容性。此时配置文件通过 ConfigMap 挂载,Secret 通过环境变量注入。

第二阶段:多实例无状态化。kgateway 本身不保存请求状态,完全适合水平扩展。我们将副本数调到 3,前置 Nginx Ingress 做负载均衡。配置统一迁移到独立的配置服务,支持热更新。

第三阶段:多可用区部署。利用 K8s 的拓扑分布约束,确保 Pod 分散在不同节点和可用区:

topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: kgateway

同时,vLLM 后端也做了多副本部署,配合 kgateway 的fallback_chain实现跨可用区的故障转移。最近一次机房网络抖动中,这个架构保证了核心业务的零中断。

回头看这次部署,最大的体会是:LLM 网关的价值不只是"转发请求",而是把模型管理、成本控制、稳定性保障这些分散在各处的工程问题,收敛到一个云原生的统一控制面上。kgateway 的 YAML 驱动配置虽然初期需要仔细打磨,但一旦跑顺,后续的新模型接入、策略调整都变得非常轻量。团队现在新增一个模型供应商,平均只需 15 分钟配置加验证,这在以前是不敢想的效率。

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

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

立即咨询