一、Pod 生命周期:从创建到销毁的完整旅程

Pod 的生命周期由 Phase(阶段)Conditions(条件) 共同描述。

📈 Pod Phase(宏观状态)

Phase 说明
Pending Pod 已被 API Server 接受,但容器未创建(镜像拉取中、调度中)
Running Pod 已绑定到节点,所有容器已创建,至少一个容器正在运行或重启
Succeeded 所有容器正常退出(适用于 Job)
Failed 至少一个容器以非零状态退出
Unknown 无法获取 Pod 状态(通常因节点通信中断)

🔍 Pod Conditions(细粒度状态)

通过 kubectl describe pod 查看:

Conditions:
  Type              Status
  Initialized       True    # Init Containers 是否完成
  Ready             True    # 是否通过 Readiness 探针
  ContainersReady   True    # 所有容器是否就绪
  PodScheduled      True    # 是否已调度到节点

⏳ 生命周期关键阶段图解

graph LR
A[Pod 创建] --> B{Init Containers}
B -->|全部成功| C[主容器启动]
C --> D{Startup Probe}
D -->|通过| E{Readiness Probe}
E -->|通过| F[加入 Service 后端]
C --> G{Liveness Probe}
G -->|失败| H[重启容器]
F --> I[运行中]
I --> J{收到终止信号]
J --> K[执行 PreStop 钩子]
K --> L[发送 SIGTERM]
L --> M[等待 terminationGracePeriodSeconds]
M --> N[强制 SIGKILL]
N --> O[Pod 删除]

重要:Pod 一旦被删除,不会重建(需由控制器如 Deployment 管理)。


二、初始化容器(Init Containers):确保前置条件满足

Init Containers 在主容器启动前按顺序执行,常用于:

  • 等待依赖服务就绪(数据库、API)
  • 执行数据库迁移
  • 下载配置文件或密钥
  • 权限修复(chown / chmod)

📄 YAML 示例:等待数据库 + 执行初始化脚本

apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
  - name: wait-for-db
    image: busybox:1.36
    command: ['sh', '-c']
    args:
      - |
        until nc -z mydb-svc 3306; do
          echo "Waiting for MySQL...";
          sleep 3;
        done;
        echo "MySQL is ready!"

  - name: run-migrations
    image: mysql:8.0
    command: ['sh', '-c']
    args:
      - |
        mysql -h mydb-svc -u root -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS appdb;"

    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password

  containers:
  - name: main-app
    image: myapp:1.2
    ports:
    - containerPort: 8080

  restartPolicy: OnFailure

特性

  • 按定义顺序串行执行;
  • 失败会根据 restartPolicy 重试;
  • 可访问主容器的 Volumes(用于传递数据)。

三、Pod 容器探针(Probes):健康状态的“守门人”

Kubernetes 通过三种探针判断容器状态:

探针类型 作用 失败后果
Liveness Probe 判断容器是否存活 重启容器
Readiness Probe 判断容器是否就绪(可接收流量) 从 Service 后端移除
Startup Probe 判断容器是否启动完成(用于慢启动应用) 在启动期间禁用 Liveness/Readiness

🔧 探针支持的检测方式

  • exec:执行命令(退出码 0 表示成功)
  • httpGet:发送 HTTP 请求(状态码 2xx/3xx 成功)
  • tcpSocket:尝试 TCP 连接(连接成功即成功)

📄 YAML 示例:完整探针配置

containers:
- name: web-app
  image: nginx
  livenessProbe:
    httpGet:
      path: /healthz
      port: 8080
    initialDelaySeconds: 10   # 容器启动后延迟 10s 开始探测
    periodSeconds: 15         # 每 15s 探测一次
    timeoutSeconds: 5         # 超时时间
    failureThreshold: 3       # 连续 3 次失败才重启

  readinessProbe:
    exec:
      command: ["/bin/sh", "-c", "curl -s http://localhost:8080/ready"]
    initialDelaySeconds: 5
    periodSeconds: 10

  startupProbe:
    tcpSocket:
      port: 8080
    failureThreshold: 30      # 允许最多 30*10=300s 启动时间
    periodSeconds: 10

💡 最佳实践

  • 慢启动应用(Java/Spring Boot)必须配置 Startup Probe,避免被 Liveness 误杀;
  • Readiness 探针应检查业务依赖(如 DB 连接池是否初始化完成)。

四、事件处理函数:生命周期钩子(Lifecycle Hooks)

通过 lifecycle 字段定义容器启动后和终止前的回调。

📌 两种钩子

  • postStart:容器创建后异步执行(不保证先于 ENTRYPOINT)
  • preStop:容器终止前同步执行(阻塞 SIGTERM)

📄 YAML 示例:优雅关闭 Web 服务

containers:
- name: nginx
  image: nginx
  lifecycle:
    postStart:
      exec:
        command: ["/bin/sh", "-c", "echo 'Pod started at $(date)' >> /var/log/lifecycle.log"]
    preStop:
      exec:
        command: ["/bin/sh", "-c", "nginx -s quit; while pgrep nginx; do sleep 1; done"]

⚠️ 注意

  • postStart 失败会导致 Pod 进入 Failed 状态;
  • preStop 超时(默认 30s)会被强制 kill,可通过 terminationGracePeriodSeconds 延长。

五、Pod 资源配额与限额:防止资源滥用

1. 容器级资源请求与限制

containers:
- name: app
  image: myapp
  resources:
    requests:
      memory: "64Mi"
      cpu: "250m"    # 250m = 0.25 核
    limits:
      memory: "128Mi"
      cpu: "500m"
字段 作用
requests 调度依据(节点必须满足总 requests)
limits 运行时上限(超过会被 OOMKilled 或 CPU Throttled)

黄金法则
requests <= 实际使用 <= limits
生产环境建议 limits = 1.5~2 * requests

2. QoS(服务质量)等级

Kubernetes 根据 requests/limits 自动划分 QoS:

QoS 类型 条件 OOM 优先级
Guaranteed requests == limits(且不为 0) 最低(最后被杀)
Burstable requests < limits 或只设 requests 中等
BestEffort 未设置 requests/limits 最高(最先被杀)

六、全局资源管理:Namespace 级配额控制

单个 Pod 的资源控制不够,需在 Namespace 层面实施治理。

1. ResourceQuota:限制 Namespace 总资源

# quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: prod-quota
  namespace: production
spec:
  hard:
    requests.cpu: "10"
    requests.memory: 20Gi
    limits.cpu: "20"
    limits.memory: 40Gi
    pods: "50"
    persistentvolumeclaims: "10"

应用后,该 Namespace 内所有 Pod 的资源总和不能超过配额。

2. LimitRange:设置默认/最小/最大值

# limitrange.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: development
spec:
  limits:
  - type: Container
    defaultRequest:
      cpu: "100m"
      memory: "64Mi"
    default:
      cpu: "200m"
      memory: "128Mi"
    min:
      cpu: "50m"
      memory: "32Mi"
    max:
      cpu: "1"
      memory: "1Gi"

作用

  • 未指定 resources 的 Pod 自动应用 default
  • 超出 min/max 的 Pod 创建会被拒绝。

更多推荐