3、K8s核心概念:Pod、Service、Deployment、Namespace、ConfigMap、Secret

说实话,刚接触K8s那会儿,我被这一堆概念搞得有点晕。Pod、Service、Deployment……名字都挺像,到底谁管谁?

后来我总结了一句话:Pod是跑程序的,Deployment是管Pod的,Service是暴露服务的,Namespace是分环境的,ConfigMap和Secret是存配置的。

嗯,就这么简单。咱们一个一个拆开聊。

核心逻辑图:K8s六大概念关系

K8s 核心概念关系图 Namespace(命名空间) Deployment 管理 Pod 的期望状态 Pod 最小调度单元(容器组) Service 稳定的网络访问入口 ConfigMap / Secret 配置与敏感信息存储 Pod 是基础,Deployment 管生命周期,Service 管网络,ConfigMap/Secret 管配置

3.1 Pod:K8s里最小的“小盒子”

Pod 是 K8s 里你能直接操作的最小单元。说白了,它就是一个或多个容器的“合租屋”。

我习惯把 Pod 想象成一个“进程组”。里面可以只住一个容器(最常见),也可以住多个容器(比如一个跑业务,一个做日志收集)。

我的经验:刚开始我总想着一个 Pod 里塞很多容器,觉得省资源。后来发现这样调试特别麻烦,日志混在一起,端口也容易冲突。现在我基本遵循“一个 Pod 一个主容器”的原则,除非有明确的 sidecar 需求。

Pod 有几个关键特点:

  • 共享网络:同一个 Pod 里的容器共享 IP 和端口空间,用 localhost 就能互相访问。
  • 共享存储:可以挂载同一个 Volume,数据共享很方便。
  • 生命周期短暂:Pod 挂了就挂了,K8s 不会自动重启它——这就是为什么我们需要 Deployment。
# 一个最简单的 Pod YAML
apiVersion: v1
kind: Pod
metadata:
  name: my-vllm-pod
spec:
  containers:
  - name: vllm
    image: vllm/vllm-openai:latest
    ports:
    - containerPort: 8000

你看,就这么几行。但实际生产里我几乎不会直接创建 Pod,都是用 Deployment 来管。

3.2 Deployment:Pod 的“保姆”

Deployment 是干嘛的?它负责保证你想要的 Pod 数量一直在线。

我记得有一次,集群里一个节点挂了,上面跑了 3 个 vLLM Pod。如果是裸 Pod,那就全没了。但因为有 Deployment,它自动在另一个节点上重新拉起了 3 个新 Pod。整个过程我连个告警都没收到——嗯,这就是 K8s 的魅力。

核心能力:声明式更新、滚动升级、回滚、自动扩缩容。

# Deployment 示例
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

这里有个坑:selector.matchLabels 必须和 template.metadata.labels 一致。我曾经手抖写错过,结果 Deployment 找不到 Pod,一直报错。排查了半小时才发现是标签没对上。

3.3 Service:稳定的“门牌号”

Pod 是会飘的。今天在 node1,明天可能就在 node2。IP 也会变。那客户端怎么访问?

Service 就是来解决这个问题的。它提供一个固定的虚拟 IP(ClusterIP),不管 Pod 怎么变,客户端只管访问这个 IP 就行。

注意:Service 默认是 ClusterIP 类型,只能在集群内部访问。如果想对外暴露,需要用 NodePort 或 LoadBalancer 类型。

# Service 示例
apiVersion: v1
kind: Service
metadata:
  name: vllm-service
spec:
  selector:
    app: vllm
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8000
  type: ClusterIP

我个人习惯把 Service 的名字取得有规律,比如 vllm-svcapi-svc。这样在集群里通过 DNS 访问时,直接 http://vllm-svc 就能找到,特别方便。

3.4 Namespace:集群里的“隔间”

Namespace 就是用来做逻辑隔离的。你可以把它理解成一套房子里的不同房间。

我在项目中通常这样划分:

  • dev:开发环境,随便折腾
  • test:测试环境,跑自动化测试
  • prod:生产环境,严格管控

我的建议:千万别把所有东西都丢在 default 命名空间里。时间一长,你根本分不清哪个 Pod 是干嘛的。我曾经接手过一个项目,default 里躺着 200 多个 Pod……那叫一个乱。

# 创建 Namespace
kubectl create namespace vllm-prod

# 在指定 Namespace 下创建资源
kubectl apply -f deployment.yaml -n vllm-prod

3.5 ConfigMap 与 Secret:配置的“保险柜”

这两个东西都是用来存配置的。区别在于:

特性 ConfigMap Secret
存储内容 明文配置(如端口、日志级别) 敏感信息(如密码、API Key)
编码方式 明文 Base64(仅编码,非加密)
使用场景 环境变量、配置文件挂载 数据库密码、Token

我曾经犯过一个错:把数据库密码直接写在了 ConfigMap 里。后来安全审计被点名批评。记住,敏感信息一定要用 Secret

# ConfigMap 示例
apiVersion: v1
kind: ConfigMap
metadata:
  name: vllm-config
data:
  MODEL_NAME: "Qwen2.5-7B-Instruct"
  MAX_TOKENS: "2048"

# Secret 示例
apiVersion: v1
kind: Secret
metadata:
  name: vllm-secret
type: Opaque
data:
  API_KEY: bXktc2VjcmV0LWtleQ==  # 这是 "my-secret-key" 的 Base64

重要提醒:Secret 只是 Base64 编码,不是加密。如果你需要真正的加密,请使用外部密钥管理工具(如 HashiCorp Vault)或 K8s 的 Encryption at Rest。

好了,这六个概念就是 K8s 的基石。你想想看,Pod 跑服务,Deployment 管生命周期,Service 管网络,Namespace 管隔离,ConfigMap 和 Secret 管配置——一套完整的应用部署体系就搭起来了。

下一章我们会把这些概念串起来,真正部署一个 vLLM 服务。到时候你就知道,这些概念不是孤立的,它们配合起来才叫 K8s。


专注资料整理