一、Pod 生命周期整体概述

Pod 的生命周期是从创建到终止的完整过程,核心包括:

  1. 初始化阶段:由init容器完成启动前的准备工作
  2. 运行阶段主容器运行核心业务,同时通过探针监控容器状态
  3. 终止阶段:通过钩子处理关闭前的清理工作

每个阶段都有特定的组件参与,下面逐个讲解并实操。
在这里插入图片描述

二、init 容器(initContainer)

概念理解

init 容器是在主容器启动之前运行的专用容器,用于完成主容器启动前的准备工作(如初始化配置、等待依赖服务就绪、下载文件等)。

  • 特点:
    • 按定义顺序依次运行,前一个完成后才启动下一个
    • 所有 init 容器成功结束后,主容器才会启动
    • 若 init 容器失败,Pod 会重启直到 init 容器成功
实操练习:使用 init 容器初始化配置

场景:通过 init 容器创建一个配置文件,主容器启动后读取该文件。

步骤 1:编写 YAML 配置(init-demo.yaml)
apiVersion: v1
kind: Pod
metadata:
  name: init-demo  # Pod名称
spec:
  initContainers:  # init容器列表(按顺序执行)
  - name: init-config  # 第一个init容器名称
    image: busybox:1.35  # 使用busybox镜像(轻量Linux工具集)
    command:  # 容器启动命令:创建配置文件
    - sh
    - -c
    - "echo 'hello from init container' > /work-dir/config.txt; sleep 5"  # 写入内容并等待5秒(模拟耗时操作)
    volumeMounts:  # 挂载存储卷到容器内的/work-dir目录
    - name: workdir  # 存储卷名称(需与下方volumes对应)
      mountPath: /work-dir  # 容器内挂载路径

  containers:  # 主容器列表
  - name: main-app  # 主容器名称
    image: busybox:1.35
    command:  # 主容器启动命令:读取init容器创建的文件并持续运行
    - sh
    - -c
    - "cat /work-dir/config.txt; sleep 3600"  # 读取文件后休眠1小时(保持容器运行)
    volumeMounts:  # 同样挂载存储卷,以便读取init容器的文件
    - name: workdir
      mountPath: /work-dir

  volumes:  # 定义存储卷(emptyDir类型:Pod生命周期内存在的临时目录)
  - name: workdir
    emptyDir: {}
配置详解:
  • initContainers:数组类型,定义 1 个 init 容器init-config,通过command创建config.txt文件,并用volumeMounts将文件写入临时存储卷。
  • containers:定义主容器main-app,同样挂载存储卷,读取 init 容器创建的文件。
  • volumes:使用emptyDir作为临时存储,让 init 容器和主容器共享文件。
步骤 2:创建 Pod 并观察过程
  1. 执行创建命令:

    kubectl apply -f init-demo.yaml
    

    在这里插入图片描述

  2. 查看 Pod 状态(重点观察 init 容器的执行过程):

    kubectl get pods init-demo -w  # -w:实时监控状态变化
    

    在这里插入图片描述

    • 初始状态为Init:0/1(表示 1 个 init 容器,0 个完成)
    • 5 秒后(init 容器的sleep 5结束),状态变为Running(主容器启动)
步骤 3:验证 init 容器的效果

进入主容器,查看是否存在config.txt文件:

kubectl exec -it init-demo -c main-app -- sh  # -c:指定进入主容器
# 执行以下命令查看文件内容
cat /work-dir/config.txt  # 输出:hello from init container
exit  # 退出容器

在这里插入图片描述

步骤 4:清理环境

删除当前 Pod,避免占用资源:

kubectl delete pod init-demo

三、主容器(main Container)

概念理解

主容器是 Pod 中运行核心业务的容器,一个 Pod 可以有多个主容器(但通常推荐一个 Pod 一个主容器,多容器用于辅助业务)。

  • 特点:
    • 所有 init 容器完成后,主容器并行启动(若多个)
    • 主容器的生命周期决定 Pod 的生命周期(任意主容器失败,Pod 可能重启)
实操练习:多主容器协作

场景:一个主容器运行 Web 服务,另一个辅助容器定期生成日志文件。

步骤 1:编写 YAML 配置( )
apiVersion: v1
kind: Pod
metadata:
  name: main-containers-demo
spec:
  containers:
  - name: web-server  # 主容器1:模拟Web服务
    image: nginx:alpine  # nginx轻量镜像(提供Web服务)
    ports:
    - containerPort: 80  # 暴露80端口
    volumeMounts:
    - name: log-volume  # 挂载日志存储卷
      mountPath: /usr/share/nginx/html/logs  # nginx的日志目录

  - name: log-generator  # 主容器2:辅助生成日志
    image: busybox:1.35
    command:  # 每10秒生成一个日志文件
    - sh
    - -c
    - "while true; do echo 'access log: '$(date) >> /logs/access.log; sleep 10; done"
    volumeMounts:
    - name: log-volume  # 与web-server共享存储卷
      mountPath: /logs  # 辅助容器的日志目录

  volumes:  # 共享存储卷(emptyDir)
  - name: log-volume
    emptyDir: {}
配置详解:
  • 两个主容器web-serverlog-generator通过log-volume共享存储卷。
  • log-generator每 10 秒向/logs/access.log写入日志,web-server可通过/usr/share/nginx/html/logs/access.log访问该文件(因为挂载了同一个卷)。
步骤 2:创建 Pod 并验证
  1. 创建 Pod:

    kubectl apply -f main-containers-demo.yaml
    

    在这里插入图片描述

  2. 查看 Pod 状态(两个容器都启动后状态为Running):

    kubectl get pod main-containers-demo
    

    在这里插入图片描述

  3. 验证日志共享:

    • 进入

      log-generator
      

      容器,查看日志生成:

      kubectl exec -it main-containers-demo -c log-generator -- tail -f /logs/access.log
      

      会看到每 10 秒新增一条日志(按Ctrl+C退出)。

      在这里插入图片描述

    • 进入web-server容器,确认能访问相同日志:

      kubectl exec -it main-containers-demo -c web-server -- cat /usr/share/nginx/html/logs/access.log
      

      在这里插入图片描述

步骤 3:清理环境
kubectl delete pod main-containers-demo

四、启动前钩子(postStart)

概念理解

postStart是主容器启动后立即执行的钩子(回调函数),用于容器启动后的初始化操作(如注册服务到注册中心)。

  • 注意:
    • 不保证在容器的ENTRYPOINT之后执行(可能并行)
    • 若钩子执行失败,容器会被杀死并重启
实操练习:使用 postStart 创建启动标识文件

场景:主容器启动后,通过 postStart 创建一个started.flag文件,标记容器已启动。

步骤 1:编写 YAML 配置(poststart-demo.yaml)
apiVersion: v1
kind: Pod
metadata:
  name: poststart-demo
spec:
  containers:
  - name: main-app
    image: busybox:1.35
    command: ["sh", "-c", "sleep 3600"]  # 主容器休眠1小时
    lifecycle:  # 定义生命周期钩子
      postStart:  # 启动后钩子
        exec:  # 执行命令(创建标识文件)
          command: ["sh", "-c", "echo 'container started' > /tmp/started.flag"]
配置详解:
  • lifecycle.postStart:定义启动后钩子,通过exec执行命令,在容器的/tmp目录下创建started.flag文件。
步骤 2:创建 Pod 并验证
  1. 创建 Pod:

    kubectl apply -f poststart-demo.yaml
    

    在这里插入图片描述

  2. 进入容器验证文件是否存在:

    kubectl exec -it poststart-demo -- sh
    cat /tmp/started.flag  # 输出:container started
    exit
    

    在这里插入图片描述

步骤 3:清理环境
kubectl delete pod poststart-demo

五、关闭前钩子(preStop)

概念理解

preStop是主容器终止前执行的钩子,用于优雅关闭(如保存数据、通知其他服务)。

  • 注意:
    • 在容器收到终止信号(SIGTERM)前执行
    • 钩子执行完成后,容器才会被终止
实操练习:使用 preStop 保存关闭时间

场景:容器终止前,通过 preStop 将关闭时间写入文件。

步骤 1:编写 YAML 配置(prestop-demo.yaml)
apiVersion: v1
kind: Pod
metadata:
  name: prestop-demo
spec:
  containers:
  - name: main-app
    image: busybox:1.35
    command: ["sh", "-c", "sleep 3600"]  # 主容器休眠1小时
    lifecycle:
      preStop:  # 关闭前钩子
        exec:
          command: ["sh", "-c", "echo 'container stopped at '$(date) > /tmp/stopped.flag; sleep 5"]  # 写入时间并等待5秒(模拟清理耗时)
    volumeMounts:
    - name: temp-volume
      mountPath: /tmp
  volumes:
  - name: temp-volume
    emptyDir: {}  # 用emptyDir保存文件,避免容器终止后文件丢失(验证时需快速操作)
配置详解:
  • lifecycle.preStop:定义关闭前钩子,执行命令将关闭时间写入/tmp/stopped.flag,并休眠 5 秒(模拟清理操作)。
步骤 2:创建 Pod 并验证
  1. 创建 Pod:

    kubectl apply -f prestop-demo.yaml
    

    在这里插入图片描述

  2. 手动删除 Pod(触发 preStop):

    kubectl delete pod prestop-demo
    
  3. 快速查看钩子执行结果(由于 Pod 会被删除,需在删除过程中查看):

    • 打开新终端,执行以下命令监控 Pod 状态,当状态变为Terminating时:

      kubectl get pods prestop-demo -w
      
    • 在原终端执行(趁 Pod 还在终止中):

      kubectl exec -it prestop-demo -- cat /tmp/stopped.flag
      

      在这里插入图片描述

      会看到类似输出:在这里插入图片描述

      container stopped at Wed Nov 5 12:00:00 UTC 2025
      
步骤 3:确认环境清理

Pod 删除后,执行以下命令确认已移除:

kubectl get pods prestop-demo  # 应输出:No resources found

六、存活探针(livenessProbe)

概念理解

存活探针用于检测容器是否运行正常,若探测失败,kubelet 会杀死容器并根据重启策略重启(确保业务持续可用)。

  • 常用探测方式:
    • exec:执行命令,返回码 0 为成功
    • httpGet:发送 HTTP 请求,状态码 200-399 为成功
    • tcpSocket:TCP 连接成功为成功
实操练习:用存活探针检测服务可用性

场景:主容器运行一个脚本,30 秒后故意 “挂掉”(创建/tmp/unhealthy文件),存活探针检测到后重启容器。

步骤 1:编写 YAML 配置(liveness-demo.yaml)
apiVersion: v1
kind: Pod
metadata:
  name: liveness-demo
spec:
  containers:
  - name: main-app
    image: busybox:1.35
    command:  # 主容器逻辑:30秒后创建unhealthy文件(模拟故障)
    - sh
    - -c
    - "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; touch /tmp/unhealthy; sleep 600"
    livenessProbe:  # 存活探针配置
      exec:  # 通过执行命令探测
        command: ["test", "-f", "/tmp/healthy"]  # 检查/healthy文件是否存在(存在则成功)
      initialDelaySeconds: 5  # 容器启动后5秒开始探测
      periodSeconds: 5  # 每5秒探测一次
配置详解:
  • 主容器前 30 秒存在/tmp/healthy文件(正常状态),30 秒后删除该文件并创建/tmp/unhealthy(故障状态)。
  • 存活探针每 5 秒执行test -f /tmp/healthy,若命令失败(文件不存在),则判定容器不健康,kubelet 会重启容器。
步骤 2:创建 Pod 并观察
  1. 创建 Pod:

    kubectl apply -f liveness-demo.yaml
    
  2. 监控 Pod 事件(查看探针触发重启的过程):

    kubectl describe pod liveness-demo
    

    在这里插入图片描述

    • 前 30 秒:探针成功(Liveness probe success
    • 30 秒后:探针失败(Liveness probe failed),随后出现Killing containerStarted container(容器被重启)
步骤 3:验证重启次数
kubectl get pod liveness-demo

输出中RESTARTS字段会从 0 变为 1(表示容器已重启)。

在这里插入图片描述

步骤 4:清理环境
kubectl delete pod liveness-demo

七、就绪探针(readinessProbe)

概念理解

就绪探针用于检测容器是否可以接收请求,若探测失败,Pod 会从服务(Service)的 endpoints 中移除(避免请求发送到未就绪的容器)。

  • 与存活探针的区别:
    • 存活探针:检测容器是否 “活着”,失败则重启
    • 就绪探针:检测容器是否 “就绪”,失败则暂时隔离(不重启)
实操练习:用就绪探针控制服务就绪状态

场景:主容器启动后 10 秒内未就绪(无/tmp/ready文件),就绪探针失败;10 秒后创建文件,探针成功,Pod 加入服务。

步骤 1:编写 YAML 配置(readiness-demo.yaml)
apiVersion: v1
kind: Pod
metadata:
  name: readiness-demo
spec:
  containers:
  - name: main-app
    image: busybox:1.35
    command:  # 主容器逻辑:10秒后创建ready文件(模拟初始化过程)
    - sh
    - -c
    - "sleep 10; touch /tmp/ready; sleep 3600"
    readinessProbe:  # 就绪探针配置
      exec:
        command: ["test", "-f", "/tmp/ready"]  # 检查/ready文件是否存在
      initialDelaySeconds: 5  # 5秒后开始探测
      periodSeconds: 5  # 每5秒探测一次
配置详解:
  • 主容器启动后前 10 秒无/tmp/ready文件(未就绪),10 秒后创建文件(就绪)。
  • 就绪探针每 5 秒检测文件,未就绪时 Pod 状态为RunningREADY字段为0/1(不可接收请求);就绪后READY变为1/1
步骤 2:创建 Pod 并观察
  1. 创建 Pod:

    kubectl apply -f readiness-demo.yaml
    
  2. 监控 Pod 状态:

    kubectl get pod readiness-demo -w
    
    • 前 10 秒:状态为RunningREADY0/1(未就绪)
    • 10 秒后:READY变为1/1(就绪)

    在这里插入图片描述

步骤 3:清理环境
kubectl delete pod readiness-demo

八、启动探针(startupProbe)

概念理解

启动探针用于检测容器是否完成启动(适用于启动慢的容器,如 Java 应用),若启动探针未成功,存活 / 就绪探针不会执行;若启动失败,容器会被重启。

  • 解决问题:避免存活探针在容器启动过程中误判为故障(例如,应用需要 3 分钟启动,存活探针每 10 秒检测,会频繁触发重启)。
实操练习:用启动探针处理慢启动容器

场景:主容器需要 20 秒启动完成(创建/tmp/started文件),启动探针在 30 秒内检测到文件则判定启动成功,否则重启。

步骤 1:编写 YAML 配置(startup-demo.yaml)
apiVersion: v1
kind: Pod
metadata:
  name: startup-demo
spec:
  containers:
  - name: main-app
    image: busybox:1.35
    command:  # 主容器逻辑:20秒后创建started文件(模拟慢启动)
    - sh
    - -c
    - "sleep 20; touch /tmp/started; sleep 3600"
    startupProbe:  # 启动探针配置
      exec:
        command: ["test", "-f", "/tmp/started"]  # 检测启动完成标识
      failureThreshold: 6  # 失败6次后判定启动失败
      periodSeconds: 5  # 每5秒探测一次(6*5=30秒超时)
    livenessProbe:  # 启动探针成功后才会执行存活探针
      exec:
        command: ["test", "-f", "/tmp/started"]
      periodSeconds: 5
配置详解:
  • 启动探针总超时时间为failureThreshold * periodSeconds = 30秒,足够覆盖 20 秒的启动时间。
  • 启动成功(20 秒后),存活探针开始执行;若启动超时(如主容器需要 40 秒),则 30 秒后判定失败并重启。
步骤 2:创建 Pod 并观察
  1. 创建 Pod:

    kubectl apply -f startup-demo.yaml
    
  2. 监控启动过程:

    kubectl describe pod startup-demo -w
    

    在这里插入图片描述

    • 前 20 秒:启动探针失败(Startup probe failed
    • 20 秒后:启动探针成功(Startup probe success),随后存活探针开始执行
步骤 3:清理环境
kubectl delete pod startup-demo

总结

通过以上练习,可掌握 Pod 生命周期的核心组件:

  • initContainer:启动前准备(顺序执行)
  • 主容器:运行核心业务(并行启动)
  • postStart/preStop:启动后 / 关闭前的钩子操作
    20 秒后),存活探针开始执行;若启动超时(如主容器需要 40 秒),则 30 秒后判定失败并重启。
步骤 2:创建 Pod 并观察
  1. 创建 Pod:

    kubectl apply -f startup-demo.yaml
    
  2. 监控启动过程:

    kubectl describe pod startup-demo -w
    

    [外链图片转存中…(img-BMExI0DA-1762330858540)]

    • 前 20 秒:启动探针失败(Startup probe failed
    • 20 秒后:启动探针成功(Startup probe success),随后存活探针开始执行
步骤 3:清理环境
kubectl delete pod startup-demo

总结

Pod 生命周期的核心组件:

  • initContainer:启动前准备(顺序执行)
  • 主容器:运行核心业务(并行启动)
  • postStart/preStop:启动后 / 关闭前的钩子操作
  • 探针:liveness(保活)、readiness(就绪)、startup(启动检测)
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐