一、Init 容器(初始化容器)⭐重点
1. 概念
Init 容器是 Pod 内特殊初始化容器,pause 容器启动完成之后,业务容器启动之前执行。
执行规则:
- 多个 init 容器按 yaml 定义顺序串行执行;
- 全部 init 容器必须正常退出(exit 0),才会启动主业务容器;
- 某一个 init 容器失败,kubelet 会反复重试,主容器永远不会启动。
Pod 完整启动顺序
- pause 基础设施容器(最先启动,构建共享命名空间)
- init 容器【串行依次执行,全部成功退出】
- 主业务容器【并行启动】
2.Init 容器典型使用场景
- 依赖等待:等待 MySQL、Redis 等外部服务就绪,再启动业务;
- 环境 / 目录准备:创建目录、修改文件权限;
- 生成配置文件:基于模板动态生成业务配置;
- 数据准备:下载静态资源、初始化数据;
- 一次性任务:数据库迁移脚本执行。
3.yaml 简单示例
apiVersion: v1
kind: Pod
metadata:
name: test-initpod
spec:
initContainers:
- name: init-myservice
image: busybox:1.28.4
command: ['sh','-c','echo init1完成 && sleep 3']
- name: init-mydb
image: busybox:1.28.4
command: ['sh','-c','echo init2完成']
containers:
- name: myapp
image: nginx:1.22.1
故障现象:init 容器失败,Pod 状态显示
Init:1/2,不断重启失败 init 容器,业务容器永远不启动。 排查:kubectl logs pod-name -c init容器名 -p查看上一次失败日志。
二、Pod 生命周期与 Pod 基础状态
Pod 五大基础阶段(Phase)
表格
| 状态 | 含义 | 典型产生原因 |
|---|---|---|
| Pending | Pod 已经被集群接收,还没有完全就绪 | 资源不足、镜像拉取中、init 容器执行中、存储未挂载、调度失败 |
| Running | Pod 已经绑定节点,至少一个容器处于运行 / 重启中 | 只要有一个容器正常运行,哪怕其他容器不断崩溃重启,状态依旧 Running! |
| Succeeded | 全部容器正常终止,不会再重启 | 一次性任务脚本执行成功(exit 0),restartPolicy: Never |
| Failed | 全部容器终止,至少一个容器异常退出 (非 0 退出码) | 脚本报错、命令错误、OOM 杀死,restartPolicy: Never |
| Unknown | Master 无法获取 Pod 状态 | 节点宕机、kubelet 断开、节点网络中断 |
⚠️重要误区:
Running不等于应用全部健康,只是 Pod 存活,需要配合探针判断业务是否正常。
调度 & 初始化中间状态
PodScheduled:调度器已经把 Pod 分配到某个节点;Unschedulable:没有节点满足 Pod 资源 / 亲和性要求,无法调度,Pod 停留在 Pending;PodInitializing:正在执行 init 容器;Initialized:所有 init 容器全部执行完成,马上启动业务容器。
容器内部状态
Waiting:容器等待(拉取镜像、等待依赖)ContainerCreating:正在创建容器(拉镜像、挂载存储)Running:容器正常运行Terminated:容器已经退出(正常 0 / 异常非 0)
高频异常状态(⭐)
表格
| 异常状态 | 根因 |
|---|---|
ImagePullBackOff / ErrImagePull | 镜像名字错误、网络不通、私有仓库认证失败,拉镜像失败 |
CrashLoopBackOff | 容器反复启动立刻崩溃,陷入循环重启;业务命令错误、OOM、配置错误 |
InvalidImageName | 镜像名称格式非法 |
CreateContainerConfigError | 配置引用错误,如找不到 configmap、secret |
RunContainerError | 容器启动失败,镜像内部 PID1 进程无法启动 |
Pod 重启策略 restartPolicy
写在 Pod 的 spec 层级,不是 containers 下面!
表格
| 重启策略 | 说明 | 适用场景 |
|---|---|---|
Always | 默认值,容器退出无论成功失败,永远重启 | 长期运行业务(Nginx、Java 微服务) |
OnFailure | 只有容器异常退出(非 0)才重启;正常退出不重启 | 离线作业 |
Never | 容器退出,无论成功失败绝不重启 | 一次性脚本任务(Job) |
Succeeded/Failed 状态的 Pod,一般使用
restartPolicy:Never。
三、三大探针 Probe⭐
探针执行返回结果:
Success成功 /Failure失败 /Unknown未知,不执行动作。
通用探针公共配置字段
表格
| 字段 | 作用 | 默认值 |
|---|---|---|
initialDelaySeconds | 容器启动后,多久第一次开始探测 | 0,建议业务设置,避免应用还没启动就探测 |
periodSeconds | 探测执行间隔,多久检查一次 | 10s |
timeoutSeconds | 探测超时时间 | 1s |
failureThreshold | 连续失败多少次,判定故障,执行对应动作 | 3 次 |
successThreshold | 连续成功多少次判定健康;livenessProbe 必须 = 1 | 1 |
探针三种探测方式:
- exec:在容器内部执行命令;返回 exit 0 代表成功。
- httpGet:发 http get 请求;返回 2xx/3xx 为成功,适合 web 服务。
- tcpSocket:尝试建立 tcp 连接;端口连通代表成功,适合数据库、缓存。
1. LivenessProbe 存活探针(保活)
核心:检测容器进程是否 “活着”,解决假死卡死
- 失败动作:kill 杀死容器,按照 restartPolicy 重启容器
- 使用场景:进程卡死、死锁、内存泄漏,进程还在但业务完全不工作。
yaml 片段示例
livenessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 30
periodSeconds: 10
2. ReadinessProbe 就绪探针(流量开关)
核心:检测应用是否准备好接收用户流量
- ⚠️失败动作:不会重启容器!仅仅把该 Pod 从 Service 的 Endpoints 列表移除,不再转发流量;探测恢复成功后,重新加回 Endpoints 接收流量。
- 使用场景:应用启动慢,JVM 预热、等待数据库连接,启动完一段时间才能对外提供服务。
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
3. StartupProbe 启动探针(慢启动保护罩)
核心:专门保护启动耗时很长的应用
- 规则:startupProbe 探测成功之前,liveness、readiness 探针全部禁用,不会执行;等 startup 成功,才开启另外两个探针。
- 场景:Java、ES、数据库等启动耗时几十秒甚至几分钟,防止还没启动完就被 liveness 探针误杀重启。
startupProbe:
httpGet:
path: /
port:80
failureThreshold:20
periodSeconds:5
三者对比总结 | 探针 | 失败后动作 | 作用 | |—|—|—| |livenessProbe | 杀死容器,重启 | 判断容器是否存活,故障就重启恢复 | |readinessProbe | 摘除流量,不重启容器 | 判断能不能接收业务流量 | |startupProbe | 探测失败会杀死重启;成功后才启用另外两个探针 | 慢启动应用保护,屏蔽启动阶段其他探针 |
四、Pod 资源请求 requests & 资源限制 limits⭐重点
单位说明: CPU:
100m=100 毫核 = 0.1 核; 内存:Mi、Gi。
requests(资源请求)
调度器使用!调度依据
- 含义:Pod 运行需要的最小资源保障;
- scheduler 调度 Pod 的时候,会筛选节点,节点剩余资源必须≥requests,才可以调度到该节点;
- 容器运行的时候,允许超过 requests 使用资源。
limits(资源上限限制)
运行时 cgroup 强制约束,容器最大可以使用资源
- CPU 超过 limits:CPU 会被节流限流 (throttling),不会杀死容器;
- 内存超过 limits:容器触发 OOM Kill,内核直接杀死容器,根据重启策略重启。
yaml 完整示例
apiVersion: v1
kind: Pod
metadata:
name: oom-demo
spec:
containers:
- name: stress
image: polinux/stress:latest
command: ["stress"]
args: ["--vm","1","--vm-bytes","150M","--vm-hang","0"]
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
最佳实践:生产环境每个容器同时配置 requests 和 limits,不要只写一个。
现象:内存超过 limits,Pod 事件会出现
OOMKilled,RESTARTS 计数器增加。
作用总结
- requests:保证调度,让 Pod 落到资源充足节点;
- limits:隔离故障,防止单个 Pod 耗尽节点 CPU 内存,避免 “邻居噪声”,保护整个节点所有 Pod。
五、汇总
- Pod 完整启动顺序? pause 容器启动 → init 容器串行全部执行完成 → 业务容器并行启动。init 容器任意一个失败,业务容器永远不启动。
- Pod Pending 常见原因? ① 资源不足 CPU / 内存不满足 requests;② 镜像拉取失败;③ PVC 存储无法挂载;④ 节点 NotReady;⑤ 污点 Taint 不匹配;⑥ 亲和性 / 反亲和性条件不满足。
- CrashLoopBackOff 是什么?产生原因? 容器反复启动立刻崩溃循环重启; 原因:启动命令错误、程序异常退出、OOM 内存溢出、liveness 探针持续失败、配置文件错误、依赖服务不可达。
- livenessProbe 和 readinessProbe 区别
- liveness 存活探针:判断容器是否活着,失败杀死重启容器,解决卡死假死;
- readiness 就绪探针:判断是否可以接收流量;失败不重启容器,只是摘除 Service 流量。
- startupProbe 作用? 专门给启动很慢的应用;在 startupProbe 成功之前,禁用 liveness 和 readiness 探针;防止应用还没初始化完成就被存活探针误杀掉。
- requests 和 limits 的区别,超过会发生什么?
requests:调度器判断节点资源是否满足 Pod 的最小资源需求,调度阶段生效,运行时不限制使用;limits:容器资源最大上限,运行时 cgroup 强制管控。- CPU 超过 limits:CPU 被限流;
- 内存超过 limits:OOM Kill 杀死容器。
- 目的:资源隔离,防止单个 Pod 抢占全部节点资源。
- Pod 状态 Running 是否代表业务正常?不是!Running 只代表 Pod 里面至少一个容器在运行,不能代表业务应用健康。必须依靠探针 liveness/readiness 检测业务真实状态。
- restartPolicy 三个策略和适用场景? Always:默认,长期运行服务; OnFailure:异常退出才重启; Never:一次性任务,成功失败均不重启,Succeeded/Failed 状态 Pod。
六、排错命令汇总
kubectl get pod -w # 实时观察Pod状态
kubectl describe pod <podname> # 看Events事件,排错核心!
kubectl logs <podname> -c <容器名> [-p] # 查看日志,-p查看上一次崩溃容器日志
kubectl exec -it <podname> -c <容器名> -- sh # 进入容器调试
加视频功能
升级网站