4

理解 Docker 容器退出码

 2 years ago
source link: https://os.51cto.com/article/715142.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
67e08bd34495f4652b954992276d2032bcb970.jpg

为什么我的容器没有运行?

回答这个问题需要知道 Docker 容器为什么退出,退出码会提示容器停止运行的情况。

  • 这些退出码是什么意思?
  • 导致该退出码的动作是什么?

exit code:代表一个进程的返回码,通过系统调用 exit_group 来触发。在 POSIX 中,0 代表正常的返回码,而 1-255 代表异常返回码,不过一般错误码都是 1。这里有一张附表 Appendix E. Exit Codes With Special Meanings

如何查看退出码

方法一:查看 pod 中的容器退出码

$ kubectl describe pod xxx
46356c945ca1da9f6ff025668f988d8713c732.jpg

方法二:用 Docker 查看

$ docker ps --filter "status=exited"
$ docker inspect <container-id> --format='{{.State.ExitCode}}'

方法三:手动输出

$ docker container run alpine sh -c "exit 1"
$ docker container ls -a
CONTAINER ID   IMAGE    COMMAND            CREATED              STATUS                        
61c688005b3a   alpine   "sh -c 'exit 1'"   About a minute ago   Exited (1) 3 seconds ago

常见退出码

Exit Code 0

  • 退出代码0表示特定容器没有附加前台进程。
  • 该退出代码是所有其他后续退出代码的例外。
  • 这不一定意味着发生了不好的事情。如果开发人员想要在容器完成其工作后自动停止其容器,则使用此退出代码。

如果你执行 docker run hello-world, 你会得到“Hello from docker!”,但查看容器的时候docker ps -a | grep hello-world,会发现状态码为 0

f1ba1c6339a2ae415bd0330f98e392ecdf3334.jpg

Exit Code 1

  • 程序错误,或者 Dockerfile 中引用不存在的文件,如 entrypoint 中引用了错误的包
  • 程序错误可以很简单,例如 “除以0”,也可以很复杂,比如空引用或者其他程序 crash

Exit Code 137

  • 表明容器收到了 SIGKILL 信号,进程被杀掉,对应 kill -9
  • 引发 SIGKILL 的是 Docker Kill。这可以由用户或由 Docker 守护程序来发起,手动执行:docker kill
  • 137 比较常见,如果 pod 中的 limit 资源设置较小,会运行内存不足导致 OOMKilled,此时 state 中的 "OOMKilled" 值为 true,你可以在系统的 dmesg 中看到 oom 日志

Exit Code 139

  • 表明容器收到了 SIGSEGV 信号,无效的内存引用,对应 kill -11
  • 一般是代码有问题,或者 docker 的基础镜像有问题

Exit Code 143

  • 表明容器收到了 SIGTERM 信号,终端关闭,对应 kill -15
  • 一般对应 docker stop  命令
  • 有时 docker stop 也会导致 Exit Code 137。发生在与代码无法处理 SIGTERM 的情况下,docker 进程等待十秒钟然后发出 SIGKILL 强制退出。

不常用的一些 Exit Code

  • Exit Code 126: 权限问题或命令不可执行
  • Exit Code 127: Shell 脚本中可能出现错字且字符无法识别的情况
  • Exit Code 1 或 255:因为很多程序员写异常退出时习惯用 exit(1) 或 exit(-1),-1 会根据转换规则转成 255。这个一般是自定义 code,要看具体逻辑。

退出状态码的区间

  • 必须在 0-255 之间,0 表示正常退出
  • 外界将程序中断退出,状态码在 129-255
  • 程序自身异常退出,状态码一般在 1-128
  • 假如写代码指定的退出状态码时不在 0-255 之间,例如: exit(-1),这时会自动做一个转换,最终呈现的状态码还是会在 0-255 之间。我们把状态码记为 code,当指定的退出时状态码为负数,那么转换公式如下:256 – (|code| % 256)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK