如何在 Docker 容器中禁用核心文件转储

26

我的PHP容器运行puppeteer生成PDF文档,但同时也在我的容器内创建了两个核心转储文件。我不确定它们实际来自哪里。

主机/服务器是CentOS 7。

我已经做了以下检查:

  1. 没有应用程序错误日志,Browsershot/puppeteer无任何错误。
  2. /var/log/messages中未找到任何错误日志(例如段错误)

我尝试禁用核心转储

按照https://linux-audit.com/understand-and-configure-core-dumps-work-on-linux/的“禁用核心转储”部分,我已执行以下操作:

  1. 将以下内容添加到/etc/security/limits.conf
* soft core 0
* hard core 0
  1. 使用以下命令创建disable-core-dumps.sh文件: echo “ulimit -c 0 > /dev/null 2>&1” > /etc/profile.d/disable-coredumps.sh

  2. 将以下内容添加到/etc/systemd/coredump.conf文件中

[Coredump]

Storage=none
ProcessSizeMax=0
  1. 重新启动服务器和容器。

  2. 我还尝试在容器(alpine)中设置ulimit -c 0

上述所有技巧都对我不起作用。每次 puppeteer 生成 PDF 时都会创建两个核心转储文件,如下所示:

core.131 core.52

核心文件看起来像:

核心转储文件内容

有人可以帮我禁用核心转储吗?非常感谢。


我认为你需要在主机上禁用核心转储,而不是容器,或者将容器运行为特权容器。 - LinPy
@LinPy 我已经按照 https://linux-audit.com/understand-and-configure-core-dumps-work-on-linux 的指示在主机上禁用了核心转储。尝试在主机和容器上都禁用核心转储,但都没有成功。 - Jonathan
1
如果您想找到这些核心转储的根本原因而不是禁用它们,那么我建议您更深入地了解puppeteer。由于puppeteer使用nodejs,并且核心转储中有nodejs模块/库,因此似乎像是一个出现故障的nodejs进程。有一些调试选项可以使用,例如禁用puppeteer的无头模式或启用详细日志记录。这里是更多信息的链接:https://github.com/puppeteer/puppeteer#debugging-tips。 - ahasbini
尝试在容器内编辑/etc/security/limits.conf和/etc/systemd/coredump.conf,例如在描述如何构建镜像的Docker文件中。 - Ryabchenko Alexander
@ahasbini,奇怪的是PDF文件被完美地生成了。我已经启用了调试模式,但并没有找到任何有用的信息,只是核心转储文件。 - Jonathan
好的,那让我们看看核心转储里面有什么。基于这个链接:https://www.javascriptjanuary.com/blog/nodejs-postmortem-debugging-for-fun-and-production,我认为正确的做法是这样的: lldb node -c <path-to-coredump-file> 然后输入 bt 并在您的问题中发布输出 - ahasbini
4个回答

15

为了禁用coredumps,您需要使用选项--ulimit core=0启动容器。

参考: https://docs.docker.com/engine/reference/commandline/run/#set-ulimits-in-container---ulimit

示例

在主机上,为了验证,请暂时将coredump路径设置为/tmp

echo '/tmp/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern

按照通常的方式启动一个容器并强制生成核心转储:

docker run --rm -it bash
(inside the container)
# yes > /dev/null &
# kill -SIGABRT $(pidof yes)
# ls /tmp
(shows core.yes.<pid>)

现在,加上--ulimit core=0:

docker run --ulimit core=0 --rm -it bash
(inside the container)
# yes > /dev/null &
# kill -SIGABRT $(pidof yes)
# ls /tmp
(No entries)

1
谢谢你的回答。我正在使用Compose,并尝试通过将软限制和硬限制设置为0来配置ulimit。但仍然无法正常工作。docker run --ulimit core=0与设置Compose的ulimit为0是相同的吗? - Jonathan
我认为应该将其添加到 entrypoint.sh 中,与启动 PHP 应用程序的相同命令中。 - ahasbini

11

对于使用docker-compose的用户,在.yml文件中设置ulimits

services:
    app:
        ulimits:
            core:
                hard: 0
                soft: 0

3
我在docker swarm服务中也遇到了这个问题,但是--ulimit core=0在swarm服务中不起作用;我使用了以下命令,在docker swarm服务中它对我起了作用!
sysctl -w kernel.core_pattern=/dev/null

1
如果您正在使用containerd运行时引擎运行容器,则需要在containerd服务文件中更新ulimit。默认情况下,该文件位于路径/usr/lib/systemd/system/containerd.service。
将LimitCORE参数的值从无限更新为零,并重新启动containerd服务。
sed -i 's/LimitCORE=infinity/LimitCORE=0/g' /usr/lib/systemd/system/containerd.service; systemctl daemon-reload; systemctl restart containerd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接