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容器的?

K8s核心概念关系图 外部用户 Ingress Service Deployment Pod (vLLM容器) ConfigMap / Secret 图例: 外部 路由 服务发现 管理 运行 配置

嗯,这张图其实已经说清楚了。外部请求 → Ingress(域名路由)→ Service(负载均衡)→ Deployment(管理Pod)→ Pod(跑vLLM)。ConfigMap和Secret则负责给Pod注入配置。

这些概念,是后面所有操作的基础。你想想看,后面我们要做自动扩缩容,其实就是调整Deployment的replicas数量,或者用HPA(Horizontal Pod Autoscaler)自动调整。但前提是,你得先理解这些基础组件是怎么配合的。

好了,这节课就到这里。把这些概念吃透,后面咱们的实战才会顺手。


专注资料整理