容器退出码 137、143、139 分别是什么意思?这篇逐个把它们复现出来,并说明哪些是程序自己返回的、哪些是被信号杀死的、哪些是 docker 本身报的错,以及如何区分同样是 137 的 OOM 和手动 kill。
exit 0:docker run 退出码 0;Status=exited State.ExitCode=0 OOMKilled=False exit 3:docker run 退出码 3;Status=exited State.ExitCode=3 OOMKilled=False 命令不存在:docker run 退出码 127;Status=created State.ExitCode=127 OOMKilled=False 文件存在但不可执行(/etc/hostname):docker run 退出码 126;Status=created State.ExitCode=126 OOMKilled=False sh -c 里调用不存在的命令:docker run 退出码 127;Status=exited State.ExitCode=127 OOMKilled=False
exit N 就是 N。命令找不到是 127,找到但不能执行是 126——这两种情况容器根本没有真正启动,Status 是 created。在 sh -c 里调用不存在的命令,也是 127,但容器已经启动并 exited。
不存在的选项 --foo:docker run 退出码 125;(没有创建出容器)
docker run 自己的错误(例如不存在的选项)是 125,不会创建容器。
python 自己 SIGSEGV:docker run 退出码 139;Status=exited State.ExitCode=139 OOMKilled=False python os.abort()(SIGABRT):docker run 退出码 139;Status=exited State.ExitCode=139 OOMKilled=False PID 1 的 sh 里依次起子 sh 并让它向自己发信号,子进程的退出状态($?):TERM -> 143;INT -> 130;ABRT -> 134;SEGV -> 139;KILL -> 137;Terminated;Aborted;Segmentation fault;Killed docker kill(默认 SIGKILL):Status=exited State.ExitCode=137 OOMKilled=False docker kill -s TERM,PID 1 是 sleep(没装处理程序):Status=running State.ExitCode=0 OOMKilled=False docker stop -t 2,PID 1 是 sleep:Status=exited State.ExitCode=137 OOMKilled=False --init 下 docker stop,子进程 sleep 被 SIGTERM 杀死:Status=exited State.ExitCode=143 OOMKilled=False --init 下 docker kill -s INT:Status=exited State.ExitCode=130 OOMKilled=False
被信号杀死的进程的退出码是 128 加信号编号。PID 1 是特殊的:没有安装信号处理程序时,内核不会让它被 TERM 杀死,docker stop 要等满超时后用 KILL,于是得到 137;加 --init 后由 init 转发,子进程被 TERM 杀死,得到 143。python 的 os.abort() 我预期是 134,实际得到 139,原因我没有查。
内存限制 20m,python 一直申请内存:docker run 退出码 137;Status=exited State.ExitCode=137 OOMKilled=True
137 既可能是 OOM,也可能是 kill。看 docker inspect 的 State.OOMKilled:内存限制下被杀是 True,docker kill 是 False。