2、K8s核心概念速览:Pod、Service、Deployment、Namespace、ConfigMap、Secret

好,咱们直接进入正题。Kubernetes 的概念其实不少,但真正天天打交道的,就是这六个。我刚开始接触 K8s 时,也被一堆术语搞得头晕。后来发现,你只要把这六个东西搞明白,日常运维基本就能上手了。

说白了,K8s 就是一个「管家」。你告诉它你想跑什么、跑几个、怎么暴露出去,它帮你搞定。而这六个概念,就是你和管家沟通的「语言」。

K8s 核心概念速览 Kubernetes 核心概念 Pod 最小调度单元 Service 网络访问入口 Deployment 声明式更新 Namespace 逻辑隔离 ConfigMap 配置注入 Secret 敏感信息 Pod 是基础,Deployment 管生命周期,Service 管网络,Namespace 管隔离,ConfigMap/Secret 管配置

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:查看所有 Namespace
  • kubectl get pods -n vllm-system:查看指定 Namespace 的 Pod
  • kubectl 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