分析ExitCode定位Pod异常退出原因
使用kubectl describe pod <pod name>
查看异常 pod 的状态:
Containers :
kubedns :
Container ID :
docker ://5fb8adf9ee62afc6d3f6f3d9590041818750b392dff015d7091eaaf99cf1c945
Image: ccr.ccs.tencentyun.com/library/kubedns-amd64:1.14.4
Image ID: docker-pullable://ccr.ccs.tencentyun.com/library/kubedns- amd64@sha256:40790881bbe9ef4ae4ff7fe8b892498eecb7fe6dcc22661402f271e03f7de344
Ports: 10053/UDP, 10053/TCP, 10055/TCP
Host Ports: 0/UDP, 0/TCP, 0/TCP
Args:
--domain=cluster.local.
--dns-port=10053
--config-dir=/kube-dns-config
--v=2
State: Running
Started: Tue, 15 Aug 2022 10:58:49 +0800
Last State: Terminated
Reason: Error
Exit Code: 255
Started: Tue, 15 Aug 2022 10:40:42 +0800
Finished: Tue, 15 Aug 2022 10:58:27 +0800
Ready: True
Restart Count: 1
在容器列表里看 Last State
字段,其中 ExitCode
即程序上次退出时的状态码,如果不为 0,表示异常退出,我们可以分析下原因。
退出状态码的区间
- 必须在 0-255 之间
- 0 表示正常退出
- 外界中断将程序退出的时候状态码区间在 129-255,(操作系统给程序发送中断信号,比如
kill -9
是SIGKILL
,ctrl+c
是SIGINT
) - 一般程序自身原因导致的异常退出状态区间在 1-128 (这只是一般约定,程序如果一定要用 129-255的状态码也是可以的)
假如写代码指定的退出状态码时不在 0-255 之间,例如: exit(-1)
,这时会自动做一个转换,最 终呈现的状态码还是会在 0-255 之间。我们把状态码记为 code
- 当指定的退出时状态码为负数,那么转换公式如下:
256 - (|code| % 256)
- 当指定的退出时状态码为正数,那么转换公式如下:
code % 256
常见异常状态码
- 137 (被
SIGKILL
中断信号杀死)- 此状态码一般是因为 pod 中容器内存达到了它的资源限制(
resources.limits
),一般 是内存溢出(OOM),CPU达到限制只需要不分时间片给程序就可以。因为限制资源是通过 linux 的 cgroup 实现的,所以 cgroup 会将此容器强制杀掉,类似于kill -9
, 此时在describe pod
中可以看到 Reason 是 OOMKilled - 还可能是宿主机本身资源不够用了(OOM),内核会选取一些进程杀掉来释放内存
- 不管是 cgroup 限制杀掉进程还是因为节点机器本身资源不够导致进程死掉,都可以从系 统日志中找到记录:ubuntu 的系统日志在
/var/log/syslog
,centos 的系统日志在/var/log/messages
,都可以用journalctl -k
来查看系统日志 - 也可能是 livenessProbe (存活检查) 失败,kubelet 杀死的 pod
- 还可能是被恶意木马进程杀死
- 此状态码一般是因为 pod 中容器内存达到了它的资源限制(
- 1 和 255
- 这种可能是一般错误,具体错误原因只能看容器日志,因为很多程序员写异常退出时习惯用
exit(1)
或exit(-1)
,-1 会根据转换规则转成 255
- 这种可能是一般错误,具体错误原因只能看容器日志,因为很多程序员写异常退出时习惯用
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 J.のblog!
评论