3. Kubernetes核心概念:Pod、Service、Deployment、Namespace详解

好,咱们直接进入正题。Kubernetes 里概念不少,但真正每天都要打交道的,其实就是 Pod、Service、Deployment 和 Namespace 这四个。我刚开始学 K8s 的时候,总觉得 Pod 不就是个容器嘛,Service 不就是个负载均衡嘛…… 后来踩了坑才发现,每个概念背后都有它存在的道理。

3.1 Pod:最小的调度单元

Pod 是 K8s 里你能创建和管理的最小单位。说白了,它就是一个或多个容器的“共享沙箱”。

为什么需要 Pod?

你想想看,有时候两个进程需要共享网络栈,比如一个写日志的 sidecar 和一个主业务容器。它们需要共用同一个 IP、同一个端口空间。如果把它们拆成两个独立的容器去调度,网络配置就复杂了。Pod 就是来解决这个问题的。

核心要点:Pod 内的容器共享 Network Namespace、IPC Namespace,以及可选的共享存储卷。

我在项目中遇到过这样一个场景:一个 Java 应用需要收集指标数据,但不想改业务代码。我们就在同一个 Pod 里加了一个 Prometheus exporter 的 sidecar 容器。两个容器通过 localhost 通信,部署起来特别省事。

Pod 的典型 YAML 定义

apiVersion: v1
kind: Pod
metadata:
  name: my-app-pod
  labels:
    app: my-app
spec:
  containers:
  - name: app-container
    image: nginx:1.21
    ports:
    - containerPort: 80
  - name: sidecar-container
    image: busybox
    command: ["sh", "-c", "while true; do echo hello; sleep 10; done"]

嗯,这里要注意:Pod 里的容器是“生死与共”的。任何一个容器挂了,整个 Pod 都会被重启(取决于 restartPolicy)。所以不要把两个生命周期完全独立的进程硬塞到一个 Pod 里。

3.2 Service:稳定的网络入口

Pod 是脆弱的。它随时可能因为节点故障、资源不足而被销毁重建。每次重建,IP 都会变。那问题来了——谁来记住这些 Pod 的地址?

Service 就是干这个的。它提供了一组 Pod 的稳定访问入口,不管后端 Pod 怎么变,Service 的 IP 和端口始终不变。

个人经验:我建议所有需要对外暴露的服务,都通过 Service 来暴露。直接访问 Pod IP 是开发环境里的坏习惯,到了生产环境会吃大亏。

Service 的类型

类型 说明 适用场景
ClusterIP 集群内部可访问,外部不可达 内部微服务间调用
NodePort 在每个节点上开放一个端口,外部可通过节点 IP + 端口访问 开发测试、小规模暴露
LoadBalancer 云厂商提供负载均衡器,自动分配公网 IP 生产环境对外暴露
ExternalName 将 Service 映射到外部 DNS 名称 访问集群外部的服务

我曾经犯过一个错:在生产环境用了 NodePort 来暴露数据库管理界面。结果安全扫描一过,直接被运维叫去喝茶。NodePort 说白了就是开了一个“后门”,适合调试,不适合生产。

Service 如何找到 Pod?

靠标签选择器(selector)。Service 通过 label 匹配 Pod,然后自动维护一个端点列表(Endpoints)。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

这个 Service 会把流量转发给所有带有 app: my-app 标签的 Pod 的 8080 端口。注意,port 是 Service 的端口,targetPort 是 Pod 的端口。这两个可以不一样,我经常利用这个特性来做端口映射。

3.3 Deployment:声明式应用管理

Pod 是“一次性”的,Service 是“稳定入口”,那谁来管 Pod 的“生老病死”?谁来保证我想要的 3 个副本一直存在?

Deployment 就是干这个的。它声明了你想要的应用状态,然后 K8s 负责把实际状态调整到期望状态。

核心思想:你告诉 Deployment “我要 3 个 nginx 副本,版本 1.21”,剩下的扩容、缩容、滚动更新、回滚,它全包了。

Deployment 的典型用法

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

我个人习惯把 Deployment 和 Service 分开定义。虽然可以写在一起,但分开管理更清晰。Deployment 管“有多少个 Pod”,Service 管“怎么访问这些 Pod”。

滚动更新与回滚

更新镜像版本时,Deployment 会逐步替换旧 Pod。你可以控制更新速度,比如一次只替换 25% 的 Pod。

kubectl set image deployment/nginx-deployment nginx=nginx:1.22
kubectl rollout status deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment  # 回滚到上一个版本

我记得有一次上线新版本,结果发现有个接口不兼容。当时心里一紧,但马上执行了 rollout undo,十几秒就恢复了。要是没有 Deployment,手动换 Pod 镜像,那场面…… 不敢想。

避坑指南:我曾经在更新 Deployment 时忘了改 selector.matchLabels,结果新 Pod 创建不出来,旧 Pod 也删不掉。记住:selector 一旦创建就不能修改,除非删掉重建 Deployment。

3.4 Namespace:逻辑隔离的利器

一个集群里可能有多个团队、多个环境(开发、测试、生产)。如果所有资源都混在一起,管理起来就是一场灾难。

Namespace 就是用来做逻辑隔离的。它把集群划分成多个虚拟空间,每个空间里的资源名称可以重复,互不干扰。

Namespace 的常见用途

  • 环境隔离:dev、test、prod 各一个 Namespace
  • 团队隔离:team-a、team-b 各一个 Namespace
  • 权限控制:结合 RBAC,限制每个 Namespace 的访问权限
  • 资源配额:给每个 Namespace 设置 CPU、内存上限

操作示例

# 创建 Namespace
kubectl create namespace dev

# 在指定 Namespace 中创建资源
kubectl run nginx --image=nginx -n dev

# 查看所有 Namespace 的资源
kubectl get pods --all-namespaces

嗯,这里有个小细节:很多初学者忘了加 -n 参数,结果资源创建到了 default 命名空间里。我建议在 kubeconfig 里设置默认 Namespace,或者用 kubens 工具快速切换。

个人建议:不要把所有东西都丢到 default 命名空间。哪怕是小项目,也至少分一个 dev 和一个 prod。等集群规模大了再想拆分,成本就高了。

3.5 四个概念的关系总结

这四个概念的关系,我用一句话总结:

Deployment 管理 Pod 的副本和生命周期,Service 为 Pod 提供稳定的访问入口,Namespace 为这一切提供隔离环境。

你想想看,一个典型的微服务部署流程就是:

  1. 写一个 Deployment YAML,定义你要的 Pod 副本数和镜像版本
  2. 写一个 Service YAML,定义如何访问这些 Pod
  3. 把它们部署到指定的 Namespace 里
  4. K8s 自动完成剩下的工作

我在做多云容器编排时,经常利用 Namespace 来区分不同的云环境。比如 aws-prodgcp-staging,每个 Namespace 里都有相同的 Deployment 和 Service 定义,但底层资源来自不同的云厂商。这种模式在多云场景下特别实用。

好了,这一章的内容就到这里。Pod、Service、Deployment、Namespace 这四个概念,是 K8s 的基石。理解透了,后面的集群管理、网络策略、存储编排学起来就顺了。