一张图讲透 Pod

Pod 是 Kubernetes 中最小的部署和调度单元,所有容器工作负载的基础

☸️ Kubernetes · 深度原理解析
🔷 什么是 Pod?
📦

定义

Pod 是 Kubernetes 中最小的可部署、调度和管理单元。一个 Pod 代表集群中一个运行的工作单元,可以包含一个或多个容器。

🧬

本质

Pod 本质上是一组共享网络命名空间(Network Namespace)和存储卷(Volume)的容器集合。这组容器紧密耦合,协同完成一项任务。

🌐

共享网络

Pod 内所有容器共享同一个 Network Namespace,拥有相同的 IP 和端口空间。容器间通过 localhost 通信,无需跨网络。

💾

共享存储

Pod 内容器可以挂载相同的 Volume,实现数据共享与持久化。Volume 的生命周期与 Pod 绑定,而非与单个容器绑定。

⏱️

生命周期一致

Pod 内所有容器同时创建、同时终止。Kubernetes 始终将 Pod 整体作为原子单元进行调度,不会拆开调度到不同 Node。

🏗️ Pod 结构示意
CONTAINER A
🐳 nginx:1.25
应用主进程
port: 80
CONTAINER B
🔧 busybox:1.36
Sidecar 辅助进程
tail -f /dev/null
🔗
共享 Network Namespace 同一 IP(如 10.244.1.5)· localhost 互通
📂
共享 Volume(/data) emptyDir · ConfigMap · PVC 等
📍 NODE 节点(运行环境)
⚙️ Kubelet 管理 Pod 生命周期
🔀 kube-proxy 网络规则
🐳 Container Runtime containerd / CRI-O
⚙️ 实现原理

🧩 Pause 容器(Infra Container)— Pod 的基础设施核心

每个 Pod 启动时,Kubernetes 会首先创建一个特殊的 Pause 容器(镜像 pause:3.x)。 它的唯一职责是持有并维护 Pod 的 Network Namespace 和 IPC Namespace, 业务容器都 join 到它的 Namespace 中,从而实现共享网络与通信。

📌 为什么需要 Pause?
避免 Namespace 随某个容器退出而销毁。Pause 容器永远运行,充当 Namespace 的"锚点"。
🔗 网络共享原理
业务容器通过 --net=container:pause 加入 Pause 的网络命名空间,共享同一套网卡和 IP。
💾 存储共享原理
Volume 由 Kubelet 挂载到 Pod 沙箱目录,各业务容器按声明的 mountPath 绑定挂载(bind mount)进去。

🛡️ Linux Namespace 隔离

Pod 利用 Linux 内核 Namespace 实现隔离:

  • Network NS → Pod 内容器共享,与外部隔离
  • PID NS → 可选共享(默认独立)
  • IPC NS → Pod 内共享,支持共享内存/信号量
  • Mount NS → 独立,按 volumeMount 挂载

📊 cgroups 资源限制

每个容器有独立的 cgroup,受 resources 字段控制:

  • requests → 调度时的最低资源保证
  • limits → 运行时的最大资源上限
  • CPU limit 通过 cpu.cfs_quota_us 实现节流
  • 内存 limit 超限触发 OOMKilled
🔄 Pod 工作流程(从创建到运行)
1
📝
创建 Pod
用户提交 YAML,kubectl 发送到 API Server;API Server 写入 etcd 存储
2
⚖️
调度
Scheduler Watch 到未绑定 Pod,经过过滤(Filter)和打分(Score)选最优 Node
3
📌
绑定 Node
Scheduler 将结果写回 API Server,Pod.spec.nodeName 字段被赋值
4
🚀
Kubelet 启动
目标 Node 的 Kubelet Watch 到绑定事件,调用 CRI 拉取镜像、创建 Pause 容器
5
▶️
运行中
Init 容器顺序运行完毕后,业务容器并行启动,持续上报健康状态
6
🛑
终止
收到删除信号,先 preStop Hook → SIGTERM → 等待宽限期 → SIGKILL,资源释放

🔍 调度算法细节

  • Predicates(过滤):资源是否足够、亲和性、污点/容忍
  • Priorities(打分):选负载最轻、镜像已存在等 Node
  • Bind:发送 Binding 对象,写入 Pod.spec.nodeName

🔁 Kubelet 同步循环

  • Watch API Server 中属于本 Node 的 Pod 变化
  • 调用 CRI(containerd)管理容器生命周期
  • 执行 Liveness/Readiness/Startup Probe 探针
  • 将 Pod 状态上报回 API Server
♻️ Pod 生命周期(Phase)
Pending
已创建,等待调度或拉取镜像
▶️
Running
已调度至节点,容器运行中
Succeeded
所有容器正常退出(exit 0)
▶️
Running
运行中
Failed
容器异常退出(非 0)
·
Unknown
节点失联,状态未知

🔬 健康探针(Probe)

  • Liveness Probe — 检测容器是否存活;失败则重启
  • Readiness Probe — 检测是否可接收流量;失败则从 Service Endpoints 摘除
  • Startup Probe — 应用启动阶段保护,超时前不执行其他探针
探针方式:httpGet · tcpSocket · exec · grpc

🔄 重启策略(restartPolicy)

  • Always — 容器退出后始终重启(默认,适合 Deployment)
  • OnFailure — 只有异常退出才重启(适合 Job)
  • Never — 从不重启(适合一次性任务)
重启使用 指数退避策略(10s→20s→40s…最大 5min)
🔧 Init Container & Sidecar

🔧 Init Container

在业务容器启动前顺序执行的初始化容器,全部成功后业务容器才启动。

Init-1
配置初始化
Init-2
等待依赖就绪
App Container
业务启动
典型用途:下载配置文件、等待数据库就绪、数据库 schema 迁移

🔀 Sidecar 模式

与主容器并行运行的辅助容器,增强主容器能力而不侵入业务代码。

Main App
业务逻辑
Sidecar
日志/代理/监控
典型场景:Envoy 服务网格代理、Fluentd 日志收集、Prometheus 指标 exporter
📄 Pod YAML 资源清单(完整注释版)
# Pod 资源清单示例
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
  namespace: default
  labels:
    app: demo           # 标签,供 Service/Deployment 选择器匹配
    version: v1.0
spec:
  restartPolicy: Always  # 重启策略:Always / OnFailure / Never

  # Init 容器(顺序执行,全部成功后业务容器才启动)
  initContainers:
  - name: init-db-wait
    image: busybox:1.36
    command: ["sh", "-c", "until nc -z mysql 3306; do sleep 2; done"]

  # 业务容器列表
  containers:
  # --- 主容器 ---
  - name: web
    image: nginx:1.25
    ports:
    - containerPort: 80   # 声明性,实际由 Service 暴露
    resources:
      requests:           # 调度时的最低资源保证
        cpu: "100m"
        memory: "128Mi"
      limits:             # 运行时最大上限,超 memory 则 OOMKilled
        cpu: "500m"
        memory: "512Mi"
    volumeMounts:
    - name: shared-data
      mountPath: /data
    livenessProbe:      # 存活探针,失败则重启容器
      httpGet:
        path: /healthz
        port: 80
      initialDelaySeconds: 15
      periodSeconds: 10
    readinessProbe:     # 就绪探针,失败则从 Service 摘除
      httpGet:
        path: /ready
        port: 80
      periodSeconds: 5
    lifecycle:
      preStop:            # 删除 Pod 前执行,确保优雅退出
        exec:
          command: ["/bin/sh", "-c", "sleep 5"]

  # --- Sidecar 容器(日志收集)---
  - name: log-collector
    image: fluent/fluent-bit:latest
    volumeMounts:
    - name: shared-data
      mountPath: /data   # 同一 Volume,读取主容器的日志

  # Volume 定义
  volumes:
  - name: shared-data
    emptyDir: {}        # 随 Pod 生命周期的临时目录

  # 调度控制
  nodeSelector:
    disktype: ssd        # 只调度到有此标签的 Node
  tolerations:          # 容忍 taint,可调度到特殊节点
  - key: "dedicated"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"
📊 Pod vs Container 对比
对比项 Container(容器) Pod(容器组)
管理对象 Docker 单个容器,直接操控 Kubernetes 中最小调度单元,K8s 感知不到单个容器
网络 独立 IP,端口映射才可访问 共享 IP 和端口空间(同一 Network Namespace)
存储 独立拥有,容器销毁即丢失 共享 Volume,生命周期由 Pod 控制
生命周期 独立创建和销毁 所有容器同时创建和销毁,原子调度
使用场景 单进程应用 多进程协作:Sidecar、Init Container、协同容器等
配置中心 docker run 参数 / Compose 文件 Pod Spec YAML(由 K8s API Server 管理)
🎯 典型使用场景
🖥️ 主容器 + 辅助容器

Nginx 主容器 + 日志采集 Sidecar,共享 /var/log Volume 实现无侵入日志收集。

日志收集文件同步代理注入
🔀 Service Mesh Sidecar

Istio 自动向 Pod 注入 Envoy 代理容器,实现流量管理、熔断、mTLS 等,业务代码零感知。

IstioEnvoy服务网格
🔧 Init Container 初始化

启动主服务前,Init 容器自动完成:等待依赖就绪、拉取远程配置、执行数据库迁移等前置任务。

数据库迁移配置注入依赖等待
📊 监控 Exporter

业务容器旁注入 Prometheus Exporter Sidecar,通过 localhost 采集指标,无需修改业务代码。

Prometheus监控可观测性
💡 Pod 设计思想
⌨️ 常用 kubectl 命令速查
# 查看 Pod 列表
kubectl get pods -n default -o wide

# 查看 Pod 详细信息(Events 排错必用)
kubectl describe pod <pod-name>

# 查看容器日志
kubectl logs <pod-name> -c <container-name> --tail=100 -f

# 进入容器 Shell
kubectl exec -it <pod-name> -c <container-name> -- /bin/sh

# 从 YAML 创建 Pod
kubectl apply -f pod.yaml

# 删除 Pod(立即强制)
kubectl delete pod <pod-name> --grace-period=0 --force

# 端口转发(本地调试)
kubectl port-forward pod/<pod-name> 8080:80

# 查看 Pod 资源占用
kubectl top pod <pod-name> --containers