
部署前的架构考量去年团队决定把分散在各处的 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.04Docker 和 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文件单独存放敏感信息已加入.gitignoreOPENAI_API_KEYsk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx LOCAL_VLLM_KEYEMPTY启动命令很简洁docker-compose up -d docker logs -f kgateway --tail 100看到Server started on :8080和Metrics exposed on :9090两条日志说明服务已正常拉起。三段核心配置详解kgateway 的配置采用 YAML 单文件驱动结构清晰。我重点展开providers、routing、rate_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: trueheader_rules是我们用得最顺手的特性。业务方在请求头里带x-prefer-local: true就能强制路由到本地 vLLM适合处理涉密文档或需要离线运行的场景。fallback_chain则保障了当 OpenAI 返回 429 或超时时的自动降级——实际测试中我把网络断掉模拟故障请求在 2.3 秒内切换到了 vLLM对调用方完全透明。rate_limitingToken 级限流与预算拦截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: 5000000token_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{modelgpt-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 分钟配置加验证这在以前是不敢想的效率。