一、项目全景与架构设计:K8s多租户vLLM推理项目
1.1 这个项目到底要解决什么问题?
说实话,我见过太多团队在LLM推理上踩坑了。你想想看,一个团队训练好了大模型,想对外提供推理服务,结果发现——
- GPU资源利用率低得可怜,有的租户占着卡不用,有的排队排到天荒地老
- 模型版本管理混乱,A组用v1.0,B组用v1.2,运维起来想骂人
- 流量一上来,服务直接崩,扩缩容全靠人工盯着
这个项目的目标很明确:在Kubernetes上搭建一套多租户的vLLM推理平台。说白了,就是让多个团队能安全、高效、隔离地共享同一批GPU资源,同时还能按需扩缩容。
我个人习惯把这类项目叫做「推理中台」——它不生产模型,只是模型的搬运工。但搬运工也得有技术含量,对吧?
1.2 整体架构长什么样?
先看一张我手绘的架构图,这张图基本概括了整个项目的核心逻辑。
这张图其实就讲了一件事:用户请求进来,经过网关路由到对应的vLLM实例,然后根据负载自动扩缩容。每一层各司其职,互不干扰。
1.3 技术选型:为什么是这些组件?
选型这事儿,我踩过不少坑。下面这张表是我个人觉得比较靠谱的组合:
| 组件 | 选型理由 | 我在项目中踩过的坑 |
|---|---|---|
| Kubernetes | 容器编排的事实标准,资源隔离、调度、自愈能力都很成熟 | 曾经因为没配好资源配额,一个租户把整个集群的GPU都占满了 |
| vLLM | 推理速度比HuggingFace Transformers快2-4倍,PagedAttention技术确实牛 | 早期版本对多GPU支持不太好,后来升级到0.4.0才稳定 |
| Istio | 多租户路由、流量管理、mTLS安全通信,一套搞定 | 默认配置下内存占用太高,后来调了sidecar资源限制才解决 |
| Kubeflow | 模型版本管理、Pipeline编排,适合模型上线流程 | 说实话,如果只是推理服务,Kubeflow有点重,但团队有MLOps需求就值得上 |
| HPA + KEDA | HPA做基础扩缩容,KEDA支持自定义指标(如请求队列长度) | 纯HPA在突发流量下反应太慢,加了KEDA的Prometheus指标后好多了 |
核心思路: 每个租户独立部署vLLM实例,通过Istio的VirtualService做路由分发。资源隔离靠K8s的Namespace + ResourceQuota,弹性伸缩靠KEDA监听自定义指标。
1.4 多租户怎么实现?
嗯,这里要注意。多租户不是简单地把几个vLLM Pod扔到不同Namespace就完事了。我见过有人这么干,结果租户A的流量跑到了租户B的Pod上,数据泄露了都不知道。
正确的做法是:
- Namespace隔离:每个租户一个独立的Namespace,资源配额互不干扰
- 网络隔离:Istio的AuthorizationPolicy控制跨Namespace访问
- 模型隔离:每个租户挂载独立的模型存储卷,或者用模型名称做路由
- 监控隔离:每个租户的指标单独采集,方便做计费和容量规划
避坑指南: 我曾经在配置Istio时忘了加RequestAuthentication,结果租户A直接伪造了租户B的JWT token。后来强制要求每个请求都携带有效的JWT,并在网关层做校验,才堵住这个漏洞。
1.5 弹性伸缩:HPA vs KEDA
说实话,HPA在CPU/内存指标上表现不错,但LLM推理服务的瓶颈往往不在CPU上。你想想看,GPU利用率、请求队列长度、推理延迟——这些才是关键指标。
KEDA的优势就在这里:
- 支持Prometheus、Kafka、RabbitMQ等30+种指标源
- 可以自定义扩缩容阈值,比如「当请求队列超过100时,增加2个Pod」
- 支持缩容到0,节省资源
我个人习惯的做法是:HPA做基础保障,KEDA做精细化调度。比如HPA保证至少2个Pod在线,KEDA根据请求量动态调整副本数。
注意: 缩容到0虽然省钱,但冷启动时间可能长达1-2分钟(加载模型到GPU)。建议设置最小副本数为1,或者用KEDA的「预热」策略提前拉起Pod。
1.6 技术栈全景图
最后,我用一张SVG图把整个技术栈串起来。这张图我画了好几个版本,最终觉得这个最清晰:
这张图基本涵盖了项目的所有核心组件。你可能会问:「为什么不用Ray Serve?」嗯,Ray Serve也是个好选择,但我们的团队对K8s更熟悉,而且Istio的多租户能力更成熟。选型这事儿,没有绝对的对错,适合团队的就是最好的。
公众号:蓝海资料掘金营,微信deep3321