4、K8s基础概念回顾:Pod、Deployment、Service、ConfigMap、Secret、PersistentVolumeClaim
说实话,很多刚接触K8s的朋友,一上来就被各种概念砸晕了。Pod、Deployment、Service……这些名词看着就头疼。我当年也是这么过来的。
但你要部署vLLM多副本,这些概念绕不开。说白了,它们就是K8s世界的“积木块”。你只要搞懂每块积木是干嘛的,怎么拼在一起,就能搭出稳定的推理服务。
这一章,我就带你快速过一遍。不扯太深的理论,只讲你真正用得上的东西。
4.1 Pod:最小的部署单元
Pod是K8s里你能创建和管理的“最小单位”。你可以把它理解成一个“容器盒子”。这个盒子里可以放一个或多个容器,它们共享网络和存储。
我习惯把Pod比作“豆荚”——名字就是这么来的。里面的容器就像豆子,紧紧挨在一起。
核心要点:
- 一个Pod通常只跑一个主容器(比如vLLM推理进程)
- Pod里的容器共享IP和端口空间,用localhost就能通信
- Pod是“临时”的——它随时可能被销毁、重建
我在项目中遇到过一个问题:有人把两个需要独立端口的服务塞进同一个Pod,结果端口冲突了。嗯,记住——Pod内的容器要协调好端口,不然会打架。
4.2 Deployment:声明式的“管家”
你直接创建Pod行不行?行。但Pod挂了谁帮你重启?没人。
Deployment就是来解决这个问题的。它像一个“管家”,你告诉它“我要3个vLLM副本”,它就帮你盯着。少了一个,它立刻补一个。
说白了,Deployment管理的是Pod的“期望状态”。你只管声明,它负责实现。
我的经验: 生产环境永远用Deployment,别直接操作Pod。我曾经图省事直接创建Pod,结果节点宕机后服务全挂了——Deployment会自动调度到其他节点,Pod不会。
Deployment还支持滚动更新。你更新镜像时,它会逐个替换Pod,保证服务不中断。这个在vLLM版本升级时特别有用。
4.3 Service:稳定的“入口”
Pod的IP是动态的。今天这个Pod在,明天它挂了重建,IP就变了。那客户端怎么访问?
Service就是干这个的。它提供一个固定的虚拟IP和DNS名称,背后自动负载均衡到一组Pod。
你想想看,如果没有Service,每次Pod重启你都得改客户端配置——这谁受得了?
Service类型速查:
| 类型 | 用途 | 适用场景 |
|---|---|---|
| ClusterIP | 集群内访问 | 内部服务调用(默认) |
| NodePort | 节点端口暴露 | 测试或小规模外网访问 |
| LoadBalancer | 云厂商LB | 生产环境对外暴露 |
部署vLLM时,我建议用ClusterIP配合Ingress,或者直接用LoadBalancer。NodePort适合临时调试,别用在生产上。
4.4 ConfigMap:配置与代码分离
你的vLLM启动参数、模型路径、环境变量……这些配置如果硬编码在镜像里,每次改参数都得重新打包镜像——太蠢了。
ConfigMap就是用来存配置的。它把配置从容器里抽出来,以文件或环境变量的方式注入到Pod里。
我常用的方式: 把vLLM的启动参数写成配置文件,挂载到Pod里。这样改配置只需更新ConfigMap,然后重启Pod就行,不用动镜像。
举个例子,你的vLLM需要指定模型路径和GPU数量:
apiVersion: v1
kind: ConfigMap
metadata:
name: vllm-config
data:
model_name: "llama-2-7b"
tensor_parallel_size: "2"
max_model_len: "4096"
然后在Deployment里引用它,Pod启动时就能读到这些值。
4.5 Secret:敏感信息的“保险箱”
ConfigMap存的是非敏感配置。那API密钥、数据库密码、Hugging Face Token呢?
这些得用Secret。它和ConfigMap很像,但数据会做Base64编码(注意,这只是编码,不是加密)。K8s还会对Secret做更严格的权限控制。
警告: Secret的Base64编码不是真正的加密。如果你需要强加密,得用外部工具(如Sealed Secrets、Vault)或开启K8s的加密静态存储。我在一个项目里见过有人直接把明文密码放Secret里——嗯,这比放ConfigMap好不了多少。
部署vLLM时,如果你需要从Hugging Face下载私有模型,就得把Token存到Secret里:
apiVersion: v1
kind: Secret
metadata:
name: hf-secret
type: Opaque
data:
token: <你的Base64编码后的Token>
4.6 PersistentVolumeClaim:持久化存储的“申请单”
Pod是临时的,但数据不能丢。比如你下载的模型文件、推理日志、缓存数据——这些需要持久化存储。
PersistentVolumeClaim(PVC)就是用来申请存储资源的。你告诉K8s“我要10GB的SSD存储”,K8s就会帮你分配一个PersistentVolume(PV)来满足这个请求。
我习惯把PVC理解成“存储的声明式请求”。你不需要关心底层存储是NFS、Ceph还是云盘,K8s会自动匹配。
vLLM部署中的典型用法:
- 模型文件放在共享存储上,多个Pod都能读取
- 推理日志写入持久卷,方便排查问题
- 缓存目录挂载到PVC,避免每次重启重新下载
我曾经踩过一个坑:PVC的访问模式没配对。多个Pod要同时读模型文件,得用ReadOnlyMany模式。如果用了ReadWriteOnce,第二个Pod就挂载不上——服务直接起不来。
4.7 它们怎么配合?一张图看懂
说了这么多,你可能觉得每个概念都懂了,但串不起来。别急,我画了张图,你看完就明白了。
你看,Deployment管Pod的数量和健康,Service管流量接入,ConfigMap和Secret管配置注入,PVC管数据持久化。各司其职,配合默契。
4.8 小结
这六个概念,是K8s的“基本功”。你不需要背下来,但得理解它们各自扮演的角色。
部署vLLM时,你会反复用到它们:用Deployment管理推理副本,用Service暴露API,用ConfigMap配模型参数,用Secret存Hugging Face Token,用PVC存模型文件。
嗯,概念讲完了。下一章我们开始动手——把这些概念变成真正的YAML文件。
公众号:蓝海资料掘金营,微信deep3321