2、K8s核心概念速览:Pod、Service、Deployment、Namespace、ConfigMap、Secret
好,咱们直接进入正题。Kubernetes 的概念其实不少,但真正天天打交道的,就是这六个。我刚开始接触 K8s 时,也被一堆术语搞得头晕。后来发现,你只要把这六个东西搞明白,日常运维基本就能上手了。
说白了,K8s 就是一个「管家」。你告诉它你想跑什么、跑几个、怎么暴露出去,它帮你搞定。而这六个概念,就是你和管家沟通的「语言」。
2.1 Pod:最小调度单元
Pod 是 K8s 里你能创建的最小单位。你可以把它理解成「一个容器 + 它的邻居」。为什么这么说?因为一个 Pod 里可以跑多个容器,它们共享网络和存储。
我个人习惯把 Pod 比作「豆荚」——里面包着几颗豆子(容器)。这些豆子共享同一个 IP、同一块存储卷。比如你的应用容器和一个日志采集容器,就可以放在同一个 Pod 里。
核心要点:
- Pod 是短暂的,随时可能被销毁重建
- 同一个 Pod 内的容器通过 localhost 通信
- Pod 的 IP 是不固定的,重启就会变
我在项目中遇到过一个问题:有同事把两个需要独立扩缩容的服务放在同一个 Pod 里,结果一个服务负载高了,另一个也被迫跟着扩容。嗯,这里要注意——Pod 是原子调度单位,要么一起起,要么一起挂。
2.2 Service:稳定的网络入口
刚才说了,Pod 的 IP 会变。那问题来了——你的客户端怎么找到它?Service 就是干这个的。
Service 给一组 Pod 提供一个固定的虚拟 IP(ClusterIP),并且负责负载均衡。你想想看,如果没有 Service,每次 Pod 重启你都得改配置,那运维就成噩梦了。
apiVersion: v1
kind: Service
metadata:
name: vllm-service
spec:
selector:
app: vllm-server
ports:
- protocol: TCP
port: 8000
targetPort: 8000
type: ClusterIP
上面这个 YAML 定义了一个 Service,它会找到所有带 app: vllm-server 标签的 Pod,然后把流量转发到它们的 8000 端口。我曾经踩过一个坑:忘了写 selector,结果 Service 创建成功了,但后端 Pod 一个都连不上。排查了半天,发现就是标签没对上。
小技巧:调试时可以用 kubectl get endpoints 查看 Service 后端是否有 Pod。如果 Endpoints 为空,说明 selector 没匹配上。
2.3 Deployment:声明式更新
Deployment 是我用得最多的资源。它负责管理 Pod 的「生老病死」——创建、更新、回滚、扩缩容。
说白了,你告诉 Deployment「我要跑 3 个副本,镜像版本是 v2.0」,它就会帮你搞定。如果某个 Pod 挂了,它会自动再起一个。这就是声明式——你只管说「要什么」,不用管「怎么做」。
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-deployment
spec:
replicas: 3
selector:
matchLabels:
app: vllm-server
template:
metadata:
labels:
app: vllm-server
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
ports:
- containerPort: 8000
我记得有一次线上发布,新版本有 bug,导致 Pod 启动后一直 CrashLoopBackOff。幸好 Deployment 支持回滚,一条 kubectl rollout undo 就回到了上一个稳定版本。嗯,这个功能救过我好几次。
注意:Deployment 的更新策略默认是 RollingUpdate,会逐个替换 Pod。如果你的应用不支持多版本共存,记得改成 Recreate。
2.4 Namespace:逻辑隔离
Namespace 就是 K8s 里的「虚拟集群」。同一个集群里,你可以用 Namespace 把不同环境、不同团队隔离开。
我个人习惯这样分:
prod:生产环境staging:预发布环境dev:开发环境vllm-system:vLLM 相关组件
为什么要用 Namespace?你想想看,如果没有它,所有人的资源都混在一起,你都不知道哪个 Pod 是谁的。而且 Namespace 可以配合 RBAC 做权限控制——开发只能看 dev 空间,运维才能看 prod 空间。
常用命令:
kubectl get ns:查看所有 Namespacekubectl get pods -n vllm-system:查看指定 Namespace 的 Podkubectl create ns vllm-system:创建 Namespace
2.5 ConfigMap:配置注入
ConfigMap 用来存储非敏感的配置信息。比如你的 vLLM 服务需要配置模型路径、日志级别、超时时间等,这些都可以放在 ConfigMap 里。
为什么不用环境变量硬编码?因为环境不同配置不同——开发环境用测试模型,生产环境用正式模型。把配置抽出来,镜像就可以做到「一次构建,到处运行」。
apiVersion: v1
kind: ConfigMap
metadata:
name: vllm-config
data:
model_name: "Qwen2.5-7B-Instruct"
max_model_len: "8192"
log_level: "info"
然后在 Deployment 里通过 envFrom 或者挂载卷的方式引用。我曾经见过有人把数据库密码写在 ConfigMap 里——嗯,这是个危险操作。密码应该用 Secret,不是 ConfigMap。
2.6 Secret:敏感信息
Secret 和 ConfigMap 很像,但它是用来存敏感信息的——密码、Token、证书等。数据会做 Base64 编码,但注意,这只是编码不是加密。
重要提醒:Base64 编码不等于加密。任何人只要有 etcd 的访问权限,就能解码看到明文。生产环境建议开启 etcd 加密,或者使用外部密钥管理服务(如 Vault)。
apiVersion: v1
kind: Secret
metadata:
name: vllm-secret
type: Opaque
data:
api-key: bXktc2VjcmV0LWFwaS1rZXk= # 这是 "my-secret-api-key" 的 Base64
我在项目中遇到过一个问题:有同事把 Secret 的 YAML 文件直接提交到了 Git 仓库。虽然内容是 Base64 的,但解码后就是明文。后来我们强制用 kubectl create secret 命令创建,并且把 Secret 加到 .gitignore 里。
最佳实践:使用 kubectl create secret generic 命令从文件创建,避免 YAML 中明文暴露。或者用 SealedSecret、External Secrets Operator 这类工具。
好了,这六个概念就是 K8s 的「六脉神剑」。Pod 是基础,Deployment 管生命周期,Service 管网络,Namespace 管隔离,ConfigMap 和 Secret 管配置。把这六个搞明白,你就能在 K8s 里跑起你的 vLLM 服务了。
公众号:蓝海资料掘金营,微信deep3321