从0到1搭一个云原生大模型推理平台:FastAPI + vLLM + Kubernetes + Prometheus
最近我做了一个小型的云原生大模型推理平台项目,主要目的是把大模型服务从“能调用”往“能部署、能治理、能观测”推进一步。
项目地址:https://github.com/ycx666994/llm-inference-platform
这个项目不是简单写一个接口去调用大模型 API,而是围绕大模型推理服务搭了一层网关,支持 OpenAI 兼容接口、API Key 鉴权、限流、Prometheus 指标、Grafana 监控、Kubernetes 部署和 k6 压测。
一:我为什么做这个项目
刚开始接触大模型应用时,很多 Demo 都是直接调用 API,比如写个聊天机器人、RAG 问答系统之类的。这些当然很有价值,但如果从AI Infra 或平台工程角度看,还缺少一个关键问题:
模型服务真正上线以后,怎么部署?怎么限流?怎么鉴权?怎么监控?怎么压测?怎么迁移到 Kubernetes?
所以我想做一个更偏底层一点的项目,不重点展示“模型回答得多聪明”,而是展示一个大模型推理服务背后的工程化能力。
二:项目整体架构
项目的核心结构大概是这样:
Client / k6
|
v
FastAPI Gateway
|-- API Key Auth
|-- Rate Limit
|-- Prometheus Metrics
|
v
mock-vLLM / real vLLM
|
v
Prometheus + Grafana
三:项目里主要的部分
gateway/ FastAPI 推理网关
mock-vllm/ OpenAI 兼容的 mock 后端
k8s/ Kubernetes 部署文件
monitoring/ Prometheus 和 Grafana 配置
benchmark/ k6 压测脚本
scripts/ 本地和 K8s 部署脚本
docs/ 架构说明、运行手册、压测报告
四:Gateway 的设计
Gateway 是这个项目的核心。因为客户端不会直接请求 vLLM,而是先请求 Gateway。
这样做的好处是,很多和模型无关但上线必须要有的能力,都可以放在 Gateway 层做,比如说:
1.API Key 鉴权
2.请求限流
3.请求转发
4.默认模型补全
5.Prometheus 指标采集
6.上游错误处理
五:接口的设计
接口设计上,我做成了 OpenAI 兼容格式:POST /v1/chat/completions
这样客户端侧可以比较自然地迁移,不需要重新适配一套奇怪的协议。
六:健康检查和指标接口分别是
GET /healthz
GET /metrics
七:API Key 鉴权
鉴权逻辑比较简单,通过请求头里的 Bearer Token 判断是否合法:Authorization: Bearer sk-demo
如果没有带 token,返回 401;如果 token 不在允许列表里,返回 403。
这块虽然不复杂,但在推理服务里很重要。因为模型推理通常是高成本资源,不可能随便暴露一个无鉴权接口给外部访问。
八:限流设计
我的项目里实现了一个内存版的 per-key 限流器。每个API Key都有自己的请求窗口。
当前实现适合本地 Demo 和单实例场景。如果要上生产,可以继续改成 Redis 版本,这样多个 Gateway 副本之间也能共享限流状态。
这个地方我没有一开始就上复杂方案,因为项目目标是先把完整链路跑通。工程项目里我觉得很重要的一点是:先做出可验证的最小闭环,再逐步替换关键组件。
九:mock-vLLM 和 real vLLM
我的这个项目支持两种后端模式:
第一种是 mock 模式。这个模式不需要 GPU,适合本地开发、接口测试、Kubernetes 部署验证。
第二种是真实 vLLM 模式。我本地用的是 facebook/opt-125m 作为测试模型。由于本地 kind 集群没有暴露 nvidia.com/gpu,所以真实 vLLM 是跑在宿主机 Docker 里的,Kubernetes 里的 Gateway 再通过 host.docker.internal:8000去访问它。
然后这个方案不是最标准的生产架构,但很适合本地演示:Client -> K8s Gateway -> host Docker vLLM
当然,如果我后续有真正的 GPU Kubernetes 节点,应该可以直接使用项目里的 k8s/real-vllm 部署文件,再把 vLLM 放进集群里运行。
十:Prometheus 和 Grafana 监控
Gateway 暴露了 Prometheus 指标,包括请求数、请求延迟、上游请求状态等。
比如:
gateway_requests_total
gateway_request_latency_seconds
gateway_upstream_requests_total
Prometheus 负责采集指标,Grafana 用来展示 Dashboard。
这样做之后,我们就可以看到接口是否正常、请求延迟大概是多少、上游 vLLM 是否有错误。
我必须强调一句:对大模型推理服务来说,监控非常关键。因为一次推理请求可能耗时比较长, 也可能因为模型加载、显存、网络、并发等原因出现问题。但如果没有指标的话,就很难判断问题到底发生在哪里。
十一:k6 压测
项目里也加了 k6 压测脚本,然后我是想用它来测试 Gateway 到后端推理服务的整体表现。
然后目前 README 里已经记录了两组结果:
这里的数值不是为了追求多高的性能,而是为了证明整个链路可以被压测、可以被量化。
大家请注意:一个平台项目如果只有“能跑”,其实还不够。最好还能说明它在一定压力下表现怎么样。
十二:单元测试和 CI:
后面我又补了一些测试,主要覆盖:
1./healthz 健康检查
2.缺少 Bearer Token
3.API Key 非法
4.请求转发到上游
5.默认模型补全
6.per-key 限流
7./metrics 指标暴露
本地测试结果:6 passed
同时项目中也加了 GitHub Actions,这样,每次 push 或 pull request 都会自动安装依赖并运行测试。主要是我想方便展示给大家。别人打开仓库时,能看到项目不是只写了一堆代码,而是有基本的工程质量保障。
十三:本地快速验证
如果只想验证 Gateway 的基本行为,不需要 Docker、Kubernetes 或 GPU,可以直接跑测试:
cd C:\Users\HP\llm-inference-platform
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r gateway\requirements.txt -r requirements-dev.txt
$env:PYTHONPATH="gateway"
pytest -q
启动Gateway:
$env:PYTHONPATH="gateway"
uvicorn app.main:app --host 127.0.0.1 --port 8080
测试健康检查:
Invoke-RestMethod -Method Get -Uri "http://127.0.0.1:8080/healthz"
查看指标:
Invoke-WebRequest -Uri "http://127.0.0.1:8080/metrics" -UseBasicParsing
如果要测试完整的 chat completions 转发,就需要先启动 mock-vLLM 或真实 vLLM。
十四:收获
我说说我的收获。
其实,这个项目我最大的收获不是 FastAPI 怎么写,也不是 Kubernetes YAML 怎么写,而是我对“大模型推理服务工程化”有了更完整的理解。
以前看大模型项目,更多关注模型本身,比如参数量、推理效果、上下文长度。做完这个项目之后会发现,真正上线时还有很多模型外的问题:
1.请求入口怎么统一
2.用户怎么鉴权
3.不同用户怎么限流
4.服务挂了怎么发现
5.延迟变高怎么定位
6.本地怎么测试
7.Kubernetes 里怎么部署
8.GPU 不可用时怎么做 fallback 或 mock
这些问题单独看都不算特别难,但把它们串成一个完整系统,就很接近真实平台工程的工作方式。
十五:总结
这个项目可以理解为一个小型的大模型推理平台雏形。
它没有追求复杂的业务功能,而是把重点放在推理服务的工程化链路上:Gateway、鉴权、限流、监控、压测、Kubernetes 部署和CI。
如果只是做大模型应用,直接调用 API 就够了。但如果想往 AI Infra、云原生、平台工程方向深入,就必须理解模型服务背后的这些基础设施能力。
这个项目也算是我对这条技术路线的一次实践。后面我会继续完善它(因为还有很多的东西需要完善),然后我争取把它从 Demo 项目逐步打磨成一个更完整的 LLM Serving Platform。
欢迎大家留言以及欢迎大家来开源贡献。
