4、K8s核心概念回顾:Pod、Deployment、Service、Ingress、ConfigMap、Secret
说实话,很多刚接触K8s的朋友,一上来就被各种概念搞懵了。Pod、Deployment、Service……这些到底都是干嘛的?
我个人习惯,把K8s理解成一个「数据中心操作系统」。Pod就是进程,Deployment就是进程管理器,Service就是负载均衡器。这么一想,是不是清晰多了?
咱们这节课,就把这些核心概念再过一遍。不是为了背概念,而是为了后面部署vLLM时,你知道该用哪个、怎么用。
4.1 Pod:最小的调度单元
Pod是K8s里最小的部署单元。一个Pod可以包含一个或多个容器,这些容器共享网络栈和存储卷。
我遇到过有人问:「为什么不直接跑容器,非要包一层Pod?」
原因很简单:有些场景下,你需要把两个进程「绑在一起」运行。比如一个主服务加一个日志收集的Sidecar,它们必须同生共死,共享网络。Pod就是干这个的。
核心要点:
- Pod内的容器通过localhost通信
- Pod是临时性的,随时可能被销毁重建
- 不要直接创建Pod,用Deployment管理它
# 一个简单的Pod定义
apiVersion: v1
kind: Pod
metadata:
name: vllm-pod
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
ports:
- containerPort: 8000
4.2 Deployment:声明式更新
Deployment说白了,就是Pod的「管家」。你告诉它「我要3个Pod跑vLLM」,它就会帮你维持3个副本。Pod挂了,它自动重建。
我曾经在生产环境遇到过一个问题:手动删了一个Pod,结果Deployment立刻又拉起一个。当时我还纳闷,后来才反应过来——这就是声明式API的威力。你只管描述期望状态,K8s负责达成。
我的经验:Deployment的滚动更新策略一定要配好。默认是25% max surge和25% max unavailable,对于GPU推理服务来说,这个值可能太大了。我一般会调小一些,避免服务抖动。
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-deployment
spec:
replicas: 3
selector:
matchLabels:
app: vllm
template:
metadata:
labels:
app: vllm
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
ports:
- containerPort: 8000
4.3 Service:稳定的网络入口
Pod是动态的,IP会变。那客户端怎么访问?Service就是来解决这个问题的。
Service为一组Pod提供稳定的虚拟IP和DNS名称。你访问Service,它把流量转发到后端的Pod上。
| Service类型 | 适用场景 |
|---|---|
| ClusterIP | 集群内部访问,默认类型 |
| NodePort | 外部通过节点IP+端口访问 |
| LoadBalancer | 云厂商提供的负载均衡器 |
对于vLLM推理服务,我通常先用ClusterIP,再配合Ingress对外暴露。为什么?因为NodePort直接暴露节点端口,安全性差一些。
apiVersion: v1
kind: Service
metadata:
name: vllm-service
spec:
selector:
app: vllm
ports:
- port: 8000
targetPort: 8000
type: ClusterIP
4.4 Ingress:七层路由
Service只能做四层转发(IP+端口)。如果你需要根据域名、路径来路由流量,就得用Ingress。
Ingress相当于K8s里的「反向代理」。你可以配置:api.example.com/v1 转到Service A,api.example.com/v2 转到Service B。
注意:Ingress本身只是一个资源定义,真正干活的是Ingress Controller(比如Nginx Ingress Controller、Traefik)。记得先部署Controller,再创建Ingress资源。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vllm-ingress
spec:
rules:
- host: inference.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vllm-service
port:
number: 8000
4.5 ConfigMap & Secret:配置管理
这两个都是用来管理配置的,但用途不同。
- ConfigMap:存非敏感信息,比如模型路径、日志级别
- Secret:存敏感信息,比如API密钥、数据库密码
我遇到过有人把数据库密码直接写死在镜像里,结果每次改密码都要重新构建镜像。这其实是不对的。正确的做法是用Secret挂载进去,改密码只需要更新Secret对象,重启Pod即可。
# ConfigMap示例
apiVersion: v1
kind: ConfigMap
metadata:
name: vllm-config
data:
model_name: "llama-2-7b"
max_tokens: "2048"
# Secret示例
apiVersion: v1
kind: Secret
metadata:
name: vllm-secret
type: Opaque
data:
api_key: bXktc2VjcmV0LWtleQ== # base64编码
小技巧:Secret的value是base64编码的,但这只是编码,不是加密。真正生产环境,建议用外部密钥管理服务(如Vault、AWS Secrets Manager),再通过CSI驱动挂载到Pod里。
4.6 知识体系总览
下面这张图,把今天讲的几个概念串起来了。你想想看,一个请求从外部进来,是怎么到达vLLM容器的?
嗯,这张图其实已经说清楚了。外部请求 → Ingress(域名路由)→ Service(负载均衡)→ Deployment(管理Pod)→ Pod(跑vLLM)。ConfigMap和Secret则负责给Pod注入配置。
这些概念,是后面所有操作的基础。你想想看,后面我们要做自动扩缩容,其实就是调整Deployment的replicas数量,或者用HPA(Horizontal Pod Autoscaler)自动调整。但前提是,你得先理解这些基础组件是怎么配合的。
好了,这节课就到这里。把这些概念吃透,后面咱们的实战才会顺手。