pod应用实战1

K8s Pod 核心完整笔记(概念、流程、状态、重启策略、Pause、Init、Hook)

一、Pod 核心介绍

1、Pod 是什么

Pod 是 Kubernetes 集群中最小的可调度、可部署工作单元,是 K8s 资源调度的核心基础。一个 Pod 内部可以封装一个或多个业务容器,所有容器统一由 Pod 管理调度。

2、为什么需要 Pod(Pod 的核心价值)

K8s 不直接管理单个容器,而是通过 Pod 封装容器,核心优势有两点:

  1. 屏蔽容器差异化:统一底层容器运行规范,屏蔽不同容器引擎、应用的底层差异,统一集群调度管理逻辑。
  2. 实现容器共享机制:同一个 Pod 内的所有容器,默认共享网络名称空间和存储卷,容器之间通信、数据共享极其便捷。

3、Pod 的分类(两大类、三小种)

(1)普通 Pod(经由 APIServer 创建)

用户通过 YAML 资源清单提交创建请求,请求先经过 APIServer 校验处理,再分发至对应节点 kubelet 执行创建。分为两种:

① 裸 Pod / 自主式 Pod

  • 资源清单 kind: Pod,不依附任何控制器(Deployment、ReplicaSet 等)
  • 容器崩溃:根据 restartPolicy 策略重启容器
  • 自愈能力不完善:Pod 被手动删除、所在节点宕机/失联时,不会在其他节点重新拉起 Pod

② 控制器管理的 Pod

  • 由 Deployment、ReplicaSet、DaemonSet、Job 等控制器管理创建
  • 自愈能力完善:若 Pod 删除、节点故障导致副本数不足,控制器会通过调谐机制,自动在健康节点重建 Pod,保证副本数量达标

(2)静态 Pod(直接由 kubelet 创建)

  • 创建方式:通过节点本地配置文件或 HTTP 配置创建
  • 核心特点:不经过 APIServer,由当前节点的 kubelet 直接管理生命周期
  • 一般用于集群核心组件(kube-apiserver、etcd 等)的本地部署

二、Pod 完整创建生命周期流程

完整梳理 Pod 从创建、运行、监控到销毁的全流程,是 K8s 核心面试重点:

  1. 用户提交 Pod 创建请求,APIServer 接收并校验资源清单,调度器将 Pod 调度到合适的工作节点
  2. 目标节点 kubelet 接收任务,优先创建 Pause 基础容器,为整个 Pod 提供共享网络、共享存储名称空间
  3. 串行执行所有 Init 初始化容器,必须全部执行成功,才会进入下一步
  4. 启动业务主容器,容器启动瞬间异步执行 PostStart 生命周期钩子
  5. 通过 startupProbe 启动探针,检测容器是否启动成功、是否可用
  6. 容器运行期间,持续通过 livenessProbe 存活探针、readinessProbe 就绪探针监控容器状态
  7. Pod/容器终止前,优先执行 PreStop 优雅终止钩子,执行完毕或超时后,终止容器进程
  8. kubelet 实时上报 Pod 运行状态、资源信息到 APIServer,最终持久化存储到 etcd
  9. etcd 写入成功后,APIServer 确认结果,同步信息至对应节点 kubelet,完成整个创建流程

补充说明:K8s 官方没有「主容器」概念,日常使用中,我们将承担核心业务功能的容器,习惯性称为主容器。

# 基础业务容器模板示例
containers:
- name: web
  image: nginx:v1.18
  imagePullPolicy: Always
  command: ['tail', '-f', '/dev/null']

三、Pod 状态详解

1、状态查询命令

# 查看 Pod 状态字段官方解释
kubectl explain pod.status.phase

# 查看单个 Pod 详细状态、事件、异常原因
kubectl describe pod xxx

2、Pod 核心运行状态

  • Pending:Pod 正在调度、等待节点资源,尚未开始创建容器
  • Init:Error:Init 初始化容器启动失败、执行报错
  • ContainerCreating:容器创建中,包含拉取镜像、挂载存储卷、初始化容器配置等操作
  • ErrImagePull / ImagePullBackOff:镜像拉取失败(镜像不存在、权限不足、网络不通、镜像仓库异常)
  • Completed:Pod 内所有容器正常执行完毕并退出,无异常,不会自动重启
  • Unknown:节点状态异常(节点宕机、kubelet 挂掉、节点网络故障),无法上报 Pod 状态
  • Evicted:Pod 被节点驱逐,核心原因是节点不可压缩资源不足(磁盘、内存耗尽)
  • OOMKilled:内存溢出被杀死,分为两种:
    • 系统级 OOM:系统全局内存耗尽,杀死服务器任意进程
    • K8s 级 OOM:Pod 容器内存使用量超过资源清单中 limits 限制,被集群主动终止
  • Running:所有容器创建完成,且至少有一个容器正在正常运行
  • Succeeded:所有容器正常运行完成并退出,任务结束,不再重启
  • Failed:所有容器终止,且至少一个容器异常退出(报错、崩溃、超时)
  • Terminating:Pod 正在销毁,包含两个动作:终止节点容器进程、清理 etcd 中的 Pod 资源数据

重点注意: 强制删除 Pod(kubectl delete pod xxx --force --grace-period=0),仅会清理 etcd 中的资源数据,节点上的容器进程不会立即终止,存在残留进程风险;
若 Pod 长期处于 Terminating 状态,大概率是目标节点 kubelet 异常、失联。

四、Pod 重启策略 restartPolicy

1、三种重启策略

  • Always:默认策略,容器无论正常/异常退出,都会自动重启
  • OnFailure:仅容器异常退出(非0退出码)**时重启,正常退出不重启
  • Never:容器退出后,无论是否异常,均不重启

2、不同类型 Pod 的策略限制

  1. 静态 Pod:不支持自定义 restartPolicy,由 kubelet 固定管理
  2. 控制器管理的 Pod
    3. Deployment、ReplicaSet、DaemonSet:保障服务常驻运行,仅支持 Always
    4. Job(一次性任务控制器):任务执行即结束,仅支持 OnFailure / Never
  3. 裸 Pod:支持三种所有策略,但生产环境不推荐使用裸 Pod,无自愈能力

五、Pause 容器核心原理与应用

Pause 容器是 Pod 的基础核心容器,每个 Pod 启动时最先创建,常驻不退出,不处理业务逻辑,仅负责提供共享环境。

1、Pause 核心能力:实现 Pod 内容器共享

(1)共享网络名称空间

同一个 Pod 所有容器共享 Pause 容器的网卡、IP、端口、网络栈,Pod 内所有容器 IP 完全一致,容器之间可直接通过本地网卡通信,无需跨网络转发。

(2)共享存储卷

存储卷是Pod 级别资源,只需在 Pod 模板中定义一次 volumes,挂载到 Pod 内多个不同容器的不同路径,即可实现多容器数据共享。

2、实战案例:单 Pod 双容器共享存储

场景:容器1循环写入日志,容器2实时读取日志,通过共享 hostPath 卷实现数据互通

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  strategy: {}
  template:
    metadata:
      labels:
        app: web
    spec:
      volumes:
        - name: mylog
          hostPath:
            path: /var/log/web
      containers:
        - name: container1
          image: busybox
          args:
            - /bin/sh
            - -c
            - >
              i=0;
              while true;
              do
                echo "$i:$(date)" >> /var/log/run.log;
                i=$((i+1));
                sleep 1;
              done
          volumeMounts:
            - name: mylog
              mountPath: /var/log
        - name: container2
          image: busybox
          args: ["/bin/sh","-c","tail -n+1 -f /opt/log/run.log"]
          volumeMounts:
            - name: mylog
              mountPath: /opt/log

验证命令:

kubectl apply -f web.yaml
# 查看 c2 容器实时日志输出
kubectl logs -f web-xxxx -c container2

3、Sidecar 边车设计模式(Pause 核心应用)

依托 Pod 共享网络、共享存储特性,将辅助功能容器与业务容器部署在同一个 Pod,实现业务无侵入扩展功能,这就是 Sidecar 模式。

(1)基于共享存储:日志收集

业务容器负责正常业务运行并输出日志,Sidecar 容器专门读取共享卷中的日志,过滤、整理后推送至 ELK、ES 等日志系统,不侵入业务代码。

(2)基于共享网络:流量代理/染色

Sidecar 容器拦截、代理业务容器的所有进出流量,实现流量监控、染色、限流、熔断、加密等功能,业务容器无需感知流量处理逻辑。

Sidecar 核心原则:只有网络、存储、业务高度耦合的辅助容器,才适合放入同一个 Pod;不可将无关业务容器强行合并到一个 Pod。

4、Pod 容器划分核心原则

网络互通、数据共享、生命周期一致、强耦合的多个容器,归为一个 Pod;独立业务、独立扩容、无耦合的容器,拆分不同 Pod。

POD 组成结构:Pod = Pause基础容器 + 多个Init初始化容器 + 多个业务/边车容器

六、Init 初始化容器详解

Init 容器是 Pod 启动阶段的前置串行执行容器,专门用于完成业务容器启动前的初始化工作。

1、Init 容器核心特点

  • 执行时机:优先于所有业务容器启动,多个 Init 容器串行执行,前一个执行成功,才会执行下一个
  • 执行次数:Pod 不重建的情况下,Init 容器仅执行一次;Pod 重建,Init 容器必然重新执行
  • 异常机制:Init 容器执行失败,会根据 Pod 重启策略重启,直至执行成功
  • 配置规范:Init 容器一般无需配置健康探针,探针仅用于业务容器

2、Init 容器执行触发规则

  • 裸 Pod:仅更新业务容器镜像/配置,不会重启 Pod,不重新执行 Init 容器
  • 裸 Pod:仅更新 Init 容器配置,也不会触发 Pod 重启,不重新执行
  • 控制器管理的 Pod:更新任何 Pod 模板配置,会重建 Pod,强制重新执行 Init 容器
  • Pause 容器异常/挂掉,Pod 重建,Init 容器必然重跑

3、Init 容器典型应用场景

  1. 业务启动前置依赖检测:检测上下游服务、数据库、端口是否就绪
  2. 环境初始化:创建目录、初始化配置文件、数据库初始化数据
  3. 注册配置:Pod 启动前,将自身信息注册到配置中心、注册中心
  4. 资源拉取:提前下载业务所需静态资源、页面文件、依赖包

4、实战案例:Init 容器初始化 Nginx 页面数据

逻辑:Init 容器提前下载静态页面,通过共享 emptyDir 卷挂载给 Nginx 业务容器,实现页面初始化

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  initContainers:
  - name: install
    image: busybox
    command: ["/bin/sh","-c","wget -O /work-dir/index.html http://egonlin.com/1.txt"]
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  dnsPolicy: Default
  volumes:
  - name: workdir
    emptyDir: {}

七、Pod 生命周期钩子 PostStart / PreStop

1、钩子触发主体

所有生命周期钩子均由节点 kubelet 进程监听、触发并执行,不属于容器内部进程。

2、两大核心钩子详解

(1)PostStart 启动钩子

  • 运行时机:与业务容器启动异步并发执行,无严格先后顺序
  • 核心作用:容器启动后,完成非强依赖的初始化操作
  • 失败影响:钩子执行失败,容器会被杀死,并根据重启策略重启,容器无法进入 Running 状态

关键区分: 业务强依赖的初始化操作(必须启动前完成)→ 用 Init 容器
非强依赖、启动后辅助初始化 → 用 PostStart 钩子

(2)PreStop 终止钩子

  • 运行时机:容器终止、Pod 删除之前强制执行
  • 核心作用:业务优雅关闭、资源清理、连接断开、日志落盘、集群注销等
  • 超时机制:默认超时时间 30s,超时未执行完成,系统强制终止容器
  • 失败影响:钩子执行失败,直接强制销毁 Pod

3、钩子两种执行方式

  1. Exec 方式:执行自定义 Shell 命令,资源消耗计入当前容器配额
  2. HTTP 方式:向容器内指定接口发送 HTTP 请求,触发回调逻辑

4、PostStart 实战案例

容器启动后自动写入日志文件

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: centos
  name: centos
spec:
  containers:
  - image: registry.cn-shanghai.aliyuncs.com/egon-k8s-test/busybox:v1.0
    name: centos
    command: ["tail","-f","/dev/null"]
    lifecycle:
      postStart:
        exec:
          command:
            - '/bin/sh'
            - '-c'
            - 'echo Hello from the postStart handler > /tmp/1.log'
  dnsPolicy: ClusterFirst
  restartPolicy: Always

5、PreStop 实战案例

案例1:Nginx 优雅退出

apiVersion: v1
kind: Pod
metadata:
  name: hook-demo1
spec:
  containers:
  - name: hook-demo1
    image: nginx:1.18
    lifecycle:
      preStop:
        exec:
          command: ['/usr/sbin/nginx', '-s', 'quit'] # 优雅退出
          # command: ['sleep', '31'] # 模拟30s超时场景

案例2:终止前写入记录日志到宿主机

apiVersion: v1
kind: Pod
metadata:
  name: hook-demo2
spec:
  volumes:
  - name: message
    hostPath:
      path: /opt
  containers:
  - name: hook-demo2
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: message
      mountPath: /mnt
    lifecycle:
      preStop:
        exec:
          command:
            - '/bin/sh'
            - '-c'
            - 'echo Hello from the preStop Handler > /mnt/1.txt'

6、Pod 销毁核心原理补充

kubectl --force --grace-period=0 delete pod xxxx 用于强制删除etcd数据。

  • 事件1:终止目标进程
  • 事件2:删除etcd数据
  1. 正常删除 Pod:先执行 PreStop 钩子 → 发送 SIGTERM 信号优雅终止pod进程 → 等待默认30s宽限期 → 超时发送 SIGKILL 强制杀死pod进程 → 清理 etcd 资源数据
  2. 强制删除 Pod(grace-period=0):直接清理 etcd 数据,节点容器进程可能残留,存在隐患
  3. Pod 长期 Terminating:大概率目标节点 kubelet 宕机、失联、异常
posted @ 2026-07-08 19:13  cuckooyang  阅读(36)  评论(0)    收藏  举报