文章转自https://komodor.com/learn/exit-codes-in-containers-and-kubernetes-the-complete-guide/,并做了一些补充
容器退出码
Docker退出码是指在容器内运行的命令或应用程序退出时返回给Docker守护进程的状态码。
下面是一些常见的Docker退出码:
状态码 | 名称 | 含义 |
---|---|---|
0 | 正常退出 | 表示命令或应用程序成功退出。 |
1 | 应用错误 | 容器因应用程序错误或镜像规范中的错误引用而停止 |
2 | 启动命令无效 | 表示无效的命令或参数错误 |
125 | 容器未能运行 | docker run 命令没有执行成功,docker本身有错误。 |
126 | 命令调用错误 | 表示不可执行的命令,可能由于文件权限或路径问题导致 |
127 | 找不到文件或目录 | 表示命令未找到,通常是由于路径问题或未安装所需的依赖项 |
128 | 退出参数无效 | 表示无效的退出参数或异常终止 |
130 | 用户终止 | 表示命令被用户终止,通常是通过Ctrl+C发送SIGINT信号 |
134 | 异常终止(SIGABRT) | 容器使用 abort() 函数自行中止 |
137 | 立即终止(SIGKILL) | 表示命令被强制终止,通常是因为超过了容器的内存限制 |
139 | 分段错误 (SIGSEGV) | 表示命令被强制终止,通常是因为超过了容器的内存限制 |
143 | 优雅终止(SIGTERM) | 表示命令被强制终止,通常是通过发送SIGTERM信号 |
255 | 退出状态超出范围 | 容器退出,返回可接受范围之外的退出代码,表示错误原因未知 |
退出码详情
退出码 0:正常退出
退出代码 0 由开发人员在任务完成后故意停止容器时触发。从技术上讲,退出代码 0 意味着前台进程未附加到特定容器。
如果容器以退出码 0 终止怎么办?
- 查容器日志,确定哪个库导致容器退出;
- 查看现有库的代码,并确定它触发退出码 0 的原因,以及它是否正常运行。
退出码 1:应用错误
退出代码 1 表示容器由于以下原因之一停止:
- 应用程序错误:这可能是容器运行的代码中的简单编程错误,例如“除以零”,也可能是与运行时环境相关的高级错误,例如 Java、Python 等;
- 无效引用:这意味着镜像规范引用了容器镜像中不存在的文件。
如果容器以退出码 1 终止怎么办?
- 检查容器日志以查看是否找不到映像规范中列出的文件之一。如果这是问题所在,请更正镜像以指向正确的路径和文件名。
- 如果您找不到不正确的文件引用,请检查容器日志以查找应用程序错误,并调试导致错误的库。
退出码 2:启动命令无效
Docker退出码2通常表示无效的命令或参数错误。当在Docker容器中执行的命令或应用程序使用了无效的命令或提供了无效的参数时,会导致退出码2的返回。
下面是一些可能导致退出码2的情况:
- 命令或应用程序使用了错误的命令或命令拼写错误。
- 提供给命令或应用程序的参数无效或缺失。
- 命令或应用程序在特定环境中无法正常工作,可能缺少依赖项或配置错误。
要解决退出码2的问题,您可以检查命令或应用程序的使用方式、提供的参数是否正确,并确保所需的依赖项已正确安装和配置。还可以查看相关的日志或错误信息以获取更具体的问题描述。
退出码 125:容器未能运行
退出码 125 表示该命令用于运行容器。例如 docker run 在 shell 中被调用但没有成功执行。以下是可能发生这种情况的常见原因:
- 命令中使用了未定义的 flag,例如 docker run --abcd;
- 镜像中用户的定义命令在本机权限不足;
- 容器引擎与宿主机操作系统或硬件不兼容。
如果容器以退出码 125 终止怎么办?
- 检查运行容器的命令语法是否正确;
- 检查运行容器的用户,或者镜像中执行命令的上下文,是否有足够的权限在宿主机上创建容器;
- 如果您的容器引擎提供了运行容器的 option,请尝试它们。例如,在 Docker 中,尝试 docker start 而不是 docker run;
- 测试您是否能够使用相同的用户名或上下文在主机上运行其他容器。如果不能,重新安装容器引擎,或者解决容器引擎和主机设置之间的底层兼容性问题。
退出码 126:命令调用错误
退出码 126 表示无法调用容器镜像中使用的命令。这通常是用于运行容器的持续集成脚本中缺少依赖项或错误的原因。
如果容器以退出码 126 终止怎么办?
- 检查容器日志,查看无法调用哪个命令;
- 尝试在没有命令的情况下运行容器以确保隔离问题;
- 对命令进行故障排除以确保您使用正确的语法,并且所有依赖项都可用;
- 更正容器规范并重试运行容器。
退出码 127:找不到文件或目录
退出码 127 表示容器中指定的命令引用了不存在的文件或目录。
如果容器以退出码 127 终止怎么办?
与退出码 126 相同,识别失败的命令,并确保容器镜像中引用的文件名或文件路径真实有效。
退出码 128:退出时使用的参数无效
退出码 128 表示容器内的代码触发了退出命令,但没有提供有效的退出码。Linux exit 命令只允许 0-255 之间的整数,因此如果进程以退出码 3.5 退出,则日志将报告退出代码 128。
如果容器以退出码 128 终止怎么办?
- 检查容器日志以确定哪个库导致容器退出。
- 确定有问题的库在哪里使用了 exit 命令,并更正它以提供有效的退出代码。
退出码 130:用户终止
Docker退出码130通常表示命令被用户终止。当在Docker容器中执行命令时,如果用户通过Ctrl+C发送了SIGINT信号,命令将被终止,并返回退出码130给Docker守护进程。
SIGINT信号是一个中断信号,通常由用户在终端中按下Ctrl+C键触发。它用于通知正在运行的程序立即终止执行,这可能是因为用户希望提前退出命令或程序。
因此,当命令或程序在容器内部收到SIGINT信号并被终止时,Docker会将退出码130返回给守护进程。
如果您看到退出码130,意味着命令或程序被用户主动终止,而不是由于错误或异常导致的退出。
退出码 134:异常终止 (SIGABRT)
退出码 134 表示容器自身异常终止,关闭进程并刷新打开的流。此操作是不可逆的,类似 SIGKILL(请参阅下面的退出码 137)。进程可以通过执行以下操作之一来触发 SIGABRT:
- 调用 libc 库中的 abort() 函数;
- 调用 assert() 宏,用于调试。如果断言为假,则该过程中止。
如果容器以退出码 134 终止怎么办?
- 检查容器日志,查看哪个库触发了 SIGABRT 信号;
- 检查中止进程是否是预期内的(例如,因为库处于调试模式),如果不是,则对库进行故障排除,并修改以避免中止容器。
退出码 137:立即终止 (SIGKILL)
退出码 137 表示容器已收到来自主机操作系统的 SIGKILL 信号。该信号指示进程立即终止,没有宽限期。可能的原因是:
- 当通过容器引擎杀死容器时触发,例如使用 docker kill 命令时;
- 由 Linux 用户向进程发送 kill -9 命令触发;
- 在尝试终止容器并等待 30 秒的宽限期后由 Kubernetes 触发(默认情况下);
- 由主机自动触发,通常是由于内存不足。在这种情况下,docker inspect 命令将指示 OOMKilled 错误。
如果容器以退出码 137 终止怎么办?
- 检查主机上的日志,查看在容器终止之前发生了什么,以及在接收到 SIGKILL 之前是否之前收到过 SIGTERM 信号(优雅终止);
- 如果之前有 SIGTERM 信号,请检查您的容器进程是否处理 SIGTERM 并能够正常终止;
- 如果没有 SIGTERM 并且容器报告了 OOMKilled 错误,则排查主机上的内存问题。
退出码 139:分段错误 (SIGSEGV)
退出码 139 表示容器收到了来自操作系统的 SIGSEGV 信号。这表示分段错误 —— 内存违规,由容器试图访问它无权访问的内存位置引起。SIGSEGV 错误有三个常见原因:
- 编码错误:容器进程没有正确初始化,或者它试图通过指向先前释放的内存的指针来访问内存
- 二进制文件和库之间不兼容:容器进程运行的二进制文件与共享库不兼容,因此可能会尝试访问不适当的内存地址
- 硬件不兼容或配置错误:如果您在多个库中看到多个分段错误,则主机上的内存子系统可能存在问题或系统配置问题
如果容器以退出码 139 终止怎么办?
- 检查容器进程是否处理 SIGSEGV。在 Linux 和 Windows 上,您都可以处理容器对分段错误的响应。例如,容器可以收集和报告堆栈跟踪;
- 如果您需要对 SIGSEGV 进行进一步的故障排除,您可能需要将操作系统设置为即使在发生分段错误后也允许程序运行,以便进行调查和调试。然后,尝试故意造成分段错误并调试导致问题的库;
- 如果您无法复现问题,请检查主机上的内存子系统并排除内存配置故障。
退出码 143:优雅终止 (SIGTERM)
退出码 143 表示容器收到来自操作系统的 SIGTERM 信号,该信号要求容器正常终止,并且容器成功正常终止(否则您将看到退出码 137)。该退出码可能的原因是:
- 容器引擎停止容器时触发,例如使用 docker stop 或 docker-compose down 命令时;
- 由 Kubernetes 将 Pod 设置为 Terminating 状态触发,并给容器 30 秒的时间以正常关闭。
如果容器以退出码 143 终止怎么办?
检查主机日志,查看操作系统发送 SIGTERM 信号的上下文。如果您使用的是 Kubernetes,请检查 kubelet 日志,查看 pod 是否以及何时关闭。
一般来说,退出码 143 不需要故障排除。这意味着容器在主机指示后正确关闭。
退出码 255:退出状态超出范围
当您看到退出码 255 时,意味着容器的 entrypoint 以该状态停止。这意味着容器停止了,但不知道是什么原因。
如果容器以退出码 255 终止怎么办?
- 如果容器在虚拟机中运行,首先尝试删除虚拟机上配置的 overlay 网络并重新创建它们。
- 如果这不能解决问题,请尝试删除并重新创建虚拟机,然后在其上重新运行容器。
- 如果上述操作失败,则 bash 进入容器并检查有关 entrypoint 进程及其失败原因的日志或其他线索。