概述
阿里云云栖号发布了一篇分析Pod异常的文章,非常全面,在此推荐阅读并记录下摘要。
Pod状态分析
Pod的5 Phase
Pod.PodStatus.Phase 字段记录了Pod Phase,最常见的是Pending和Running
- Pending:理解为Running之前就是Pending
- Running:所有容器都started,至少有一个容器还在运行
- Succeeded:所有容器成功退出
- Failed:至少有一个容器以非0退出
- Unkonwn:v1.21被废弃了
Pod的Condition
Pod.PodStatus.Conditions 记录了一个[]PodCondition,PodCondition最重要的字段是Type、Status、Reason和Message。常见的Type如下
- Ready/NotReady:Ready为False其实就是NotReady
- Initialized
- PodScheduled/Unscheduled
容器的3 State
Pod.PodStatus.ContainerStatuses/InitContainerStatuses.State 包含了3个State结构体指针
- Waiting:Reason、Message,比如ImagePullBackOff
- Running:StartedAt
- Terminated:ExitCode、Reason、Message等
Pod Pending
- 节点资源不足
- Resource Quota 对 Namespace 不足
- NodeSelector 不满足
- 硬亲和性不满足
- 节点存在污点
- Node NotReady/Unscheduable
Container Creating
ImagePull
- 镜像名字写错
- 免密失败:Pod 指定 ImagePullSecrets,或者将 Secret 嵌入 ServicAccount,让 Pod 使用对应的 ServiceAccount
- 网络不通:无法访问内网仓库,无法访问海外仓库
- 镜像拉取超时:适当调整 Kubelet 的 --image-pull-progress-deadline 和 --runtime-request-timeout 选项
- 多个Pod在拉取镜像,触发了并行度控制
Pod Configuration
- PV挂载错误:RW配置错误,挂到了/proc等非法路径
- ConfigMap/Secret挂载:CM不存在
需要注意,上述错误可能会自动恢复,例如CM被创建出来了,此时Pod会继续正常运行
Pod启动
- 违反集群的安全策略,比如违反了 PodSecurityPolicy
- 容器无权操作集群内的资源
- 缺少启动命令
- 命令行args配置错误
容器退出
立即退出
- 启动命令找不到,因为忘记配置PATH
- 启动命令失败
- 启动命令没有+x权限
- 容器没有前台进程
对于容器启动后立即退出的情况,通常因为容器直接消失,无法获取其输出流日志,很难直接通过现场定位问题。一个简易的排查方式是,通过设置特殊的启动命令卡住容器(比如使用 tail -f /dev/null),然后进到容器中手动执行命令看看结果,确认问题原因。
运行一段时间后退出
一般为进程Crash或者被系统Kill
| Code | 含义 |
|---|---|
| 0 | 正常退出 |
| 137 | kill -9,例如OOMKilled |
| 139 | Segment Fault |
| 143 | 优雅退出,收到SIGTERM信号,一般为docker stop,Pod缩容 |
Pod驱逐/抢占
- 节点有资源压力,导致Pod被驱逐
- Pod被其他Pod抢占
Pod无法被删除
- finalizer未完成
- Pod对中断信号不响应
- 节点或kubelet故障