pod应用实战1
K8s Pod 核心完整笔记(概念、流程、状态、重启策略、Pause、Init、Hook)
一、Pod 核心介绍
1、Pod 是什么
Pod 是 Kubernetes 集群中最小的可调度、可部署工作单元,是 K8s 资源调度的核心基础。一个 Pod 内部可以封装一个或多个业务容器,所有容器统一由 Pod 管理调度。
2、为什么需要 Pod(Pod 的核心价值)
K8s 不直接管理单个容器,而是通过 Pod 封装容器,核心优势有两点:
- 屏蔽容器差异化:统一底层容器运行规范,屏蔽不同容器引擎、应用的底层差异,统一集群调度管理逻辑。
- 实现容器共享机制:同一个 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 核心面试重点:
- 用户提交 Pod 创建请求,APIServer 接收并校验资源清单,调度器将 Pod 调度到合适的工作节点
- 目标节点 kubelet 接收任务,优先创建 Pause 基础容器,为整个 Pod 提供共享网络、共享存储名称空间
- 串行执行所有 Init 初始化容器,必须全部执行成功,才会进入下一步
- 启动业务主容器,容器启动瞬间异步执行 PostStart 生命周期钩子
- 通过
startupProbe启动探针,检测容器是否启动成功、是否可用 - 容器运行期间,持续通过
livenessProbe存活探针、readinessProbe就绪探针监控容器状态 - Pod/容器终止前,优先执行 PreStop 优雅终止钩子,执行完毕或超时后,终止容器进程
- kubelet 实时上报 Pod 运行状态、资源信息到 APIServer,最终持久化存储到 etcd
- 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 的策略限制
- 静态 Pod:不支持自定义 restartPolicy,由 kubelet 固定管理
- 控制器管理的 Pod
3. Deployment、ReplicaSet、DaemonSet:保障服务常驻运行,仅支持 Always
4. Job(一次性任务控制器):任务执行即结束,仅支持 OnFailure / Never - 裸 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 容器典型应用场景
- 业务启动前置依赖检测:检测上下游服务、数据库、端口是否就绪
- 环境初始化:创建目录、初始化配置文件、数据库初始化数据
- 注册配置:Pod 启动前,将自身信息注册到配置中心、注册中心
- 资源拉取:提前下载业务所需静态资源、页面文件、依赖包
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、钩子两种执行方式
- Exec 方式:执行自定义 Shell 命令,资源消耗计入当前容器配额
- 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数据
- 正常删除 Pod:先执行 PreStop 钩子 → 发送 SIGTERM 信号优雅终止pod进程 → 等待默认30s宽限期 → 超时发送 SIGKILL 强制杀死pod进程 → 清理 etcd 资源数据
- 强制删除 Pod(grace-period=0):直接清理 etcd 数据,节点容器进程可能残留,存在隐患
- Pod 长期 Terminating:大概率目标节点 kubelet 宕机、失联、异常

浙公网安备 33010602011771号