❝翻译自 《Exit Codes in Containers and Kubernetes – The Complete Guide》 原文链接:https://komodor.com/learn/exit-codes-in-containers-and-kubernetes-the-complete-guide/ ❞
当容器终止时,容器引擎使用退出码来报告容器终止的原因。如果您是 Kubernetes 用户,容器故障是 pod 异常最常见的原因之一,了解容器退出码可以帮助您在排查时找到 pod 故障的根本原因。
以下是容器使用的最常见的退出码:
退出码 | 名称 | 含义 |
---|---|---|
0 | 正常退出 | 开发者用来表明容器是正常退出 |
1 | 应用错误 | 容器因应用程序错误或镜像规范中的错误引用而停止 |
125 | 容器未能运行 | docker run 命令没有执行成功 |
126 | 命令调用错误 | 无法调用镜像中指定的命令 |
127 | 找不到文件或目录 | 找不到镜像中指定的文件或目录 |
128 | 退出时使用的参数无效 | 退出是用无效的退出码触发的(有效代码是 0-255 之间的整数) |
134 | 异常终止 (SIGABRT) | 容器使用 abort() 函数自行中止 |
137 | 立即终止 (SIGKILL) | 容器被操作系统通过 SIGKILL 信号终止 |
139 | 分段错误 (SIGSEGV) | 容器试图访问未分配给它的内存并被终止 |
143 | 优雅终止 (SIGTERM) | 容器收到即将终止的警告,然后终止 |
255 | 退出状态超出范围 | 容器退出,返回可接受范围之外的退出代码,表示错误原因未知 |
下面我们将解释如何在宿主机和 Kubernetes 中对失败的容器进行故障排除,并提供有关上面列出的所有退出代码的更多详细信息。
为了更好地理解容器故障的原因,让我们先讨论容器的生命周期。以 Docker 为例 —— 在任何给定时间,Docker 容器都会处于以下几种状态之一:
docker create
后但实际运行容器之前的状态)docker start
或 docker run
时会发生这种情况,使用 docker start
或 docker run
可能会发生这种情况。docker pause
命令时会发生这种情况当一个容器达到 Exited 状态时,Docker 会在日志中报告一个退出码,告诉你容器发生了什么导致它退出。
下面我们将更详细地介绍每个退出码。
退出代码 0 由开发人员在任务完成后故意停止容器时触发。从技术上讲,退出代码 0 意味着前台进程未附加到特定容器。
退出代码 1 表示容器由于以下原因之一停止:
退出码 125 表示该命令用于运行容器。例如 docker run
在 shell 中被调用但没有成功执行。以下是可能发生这种情况的常见原因:
docker run --abcd
;docker start
而不是 docker run
;退出码 126 表示无法调用容器镜像中使用的命令。这通常是用于运行容器的持续集成脚本中缺少依赖项或错误的原因。
退出码 127 表示容器中指定的命令引用了不存在的文件或目录。
与退出码 126 相同,识别失败的命令,并确保容器镜像中引用的文件名或文件路径真实有效。
退出码 128 表示容器内的代码触发了退出命令,但没有提供有效的退出码。Linux exit
命令只允许 0-255 之间的整数,因此如果进程以退出码 3.5 退出,则日志将报告退出代码 128。
exit
命令,并更正它以提供有效的退出代码。退出码 134 表示容器自身异常终止,关闭进程并刷新打开的流。此操作是不可逆的,类似 SIGKILL
(请参阅下面的退出码 137)。进程可以通过执行以下操作之一来触发 SIGABRT
:
libc
库中的 abort()
函数;assert()
宏,用于调试。如果断言为假,则该过程中止。SIGABRT
信号;退出码 137 表示容器已收到来自主机操作系统的 SIGKILL
信号。该信号指示进程立即终止,没有宽限期。可能的原因是:
docker kill
命令时;kill -9
命令触发;docker inspect
命令将指示 OOMKilled
错误。SIGKILL
之前是否之前收到过 SIGTERM
信号(优雅终止);SIGTERM
信号,请检查您的容器进程是否处理 SIGTERM
并能够正常终止;SIGTERM
并且容器报告了 OOMKilled
错误,则排查主机上的内存问题。退出码 139 表示容器收到了来自操作系统的 SIGSEGV
信号。这表示分段错误 —— 内存违规,由容器试图访问它无权访问的内存位置引起。SIGSEGV
错误有三个常见原因:
SIGSEGV
。在 Linux 和 Windows 上,您都可以处理容器对分段错误的响应。例如,容器可以收集和报告堆栈跟踪;SIGSEGV
进行进一步的故障排除,您可能需要将操作系统设置为即使在发生分段错误后也允许程序运行,以便进行调查和调试。然后,尝试故意造成分段错误并调试导致问题的库;退出码 143 表示容器收到来自操作系统的 SIGTERM
信号,该信号要求容器正常终止,并且容器成功正常终止(否则您将看到退出码 137)。该退出码可能的原因是:
docker stop
或 docker-compose down
命令时;检查主机日志,查看操作系统发送 SIGTERM
信号的上下文。如果您使用的是 Kubernetes,请检查 kubelet 日志,查看 pod 是否以及何时关闭。
一般来说,退出码 143 不需要故障排除。这意味着容器在主机指示后正确关闭。
当您看到退出码 255 时,意味着容器的 entrypoint 以该状态停止。这意味着容器停止了,但不知道是什么原因。