Linux 系统为何产生大量的 core 文件?

文章讲述了在DockerSwarm集群中遇到的大规模core文件占用磁盘空间的问题,分析了core文件的产生原因,核心文件在Linux系统中的作用,以及如何通过调整ulimit和配置核心转储策略来管理和解决这个问题。

image1-57

Author:rab



一、问题分析

上一篇刚讲到《Docker 配置基础优化》,这里再补充一下。就在中秋+国庆这段小长假里,接收到了线上服务器磁盘告警通知,线上服务器架构是一个 Docker Swarm 集群,该集群上运行了多个服务。于是就登录服务上去看个究竟,结果发现 Docker 业务日志数据量都是正常的,因此第一个想到的就是 Docker 的存储驱动目录 /<yourpath>/overlay2 占用大小,进去看结果发现有一个文件(目录)数据大小异常(这里忘记截图了 - 大概 140 多 G),然后就根据这个目录名称找到归属的具体容器,看看是哪个容器产生的数据。以下是查看命令:

docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep "fe9eecfd2fc5f5c2289bd19194900c0c707d67e05e54ea55721c4d3c3ba8cc03"

image-20231006154139301

确定目标容器后,就进入容器去看一下,结果在运行程序(xxx.jar)主目录(即同级目录)下发现有大量的 core 文件,且每个文件的大小均为 105M,粗略统计了一下大概占用了 143G 左右的大小。

cip

那这些 Core 文件是什么文件?又是怎么产生的呢?

首先我们要知道 core file 是什么文件?在Linux系统中,“core file”(核心文件)是指在程序异常崩溃(如段错误、非法指令等)时生成的文件,它包含了程序在崩溃瞬间的内存状态信息,帮助开发人员进行调试和分析问题,我们一般使用调试器工具(如GDB)来分析核心文件,以便定位和解决问题。

核心文件的名称通常是 “core”,并且会与崩溃的进程相关联,因此它可能具有类似于 “core.<进程ID>” 的名称,其中 “<进程ID>” 是崩溃的进程的实际ID。核心文件通常会生成在程序崩溃的当前工作目录中,但也可以通过调整系统的核心转储设置来指定其他位置。

核心文件包含了程序的内存映像,包括堆栈、寄存器的状态以及其他与程序状态相关的信息。这些文件通常很大,因此在默认情况下,许多 Linux 系统都会禁用核心文件的生成,以节省磁盘空间。要启用核心文件生成,可以使用 ulimit 命令或 /proc/sys/kernel/core_pattern 文件进行配置。

默认情况下:Host 宿主机是限制生成 core 文件的(即禁用的),但是容器中却是无限制的(因其独立的 namespace),因此当容器中程序异常时就会生成 core 文件,而且是无限制的,这样一来就会耗尽我们 Host 宿主机的磁盘空间。

image-20231006152336223

接着查看该容器的资源利用情况:

image-20231007115436186

image-20231007115536670

可见容器的 CPU 波动非常大(非常不稳定),因为持续时间很短,所以并没有达到监控告警的条件,但是我没可以通过 core 文件来分析导致 CPU 浮动的原因。

二、解决方案

如果需要分析这些 Core 文件,可先下载到本地其他服务器进行分析,从运维角度来说,可进入容器直接删除这些 Core 文件即可。但为了避免后续的问题,应将这些 core 文件交给开发人员进行程序异常分析,并做后续优化。

1、进入容器内部

docker exec -it <容器名> bash

2、删除 core 文件

rm -rf core.*

切记!!!不要在/<yourpath>/overlay2目录下进行任何增删操作,否则可能会导致容器内部程序异常。

其实这只是临时解决的,如果要解决根源问题,需要开发人员优化代码(解决 CPU 波动问题)或把容器中“core dump(核心转存)”关闭,关闭步骤如下:只需在 Docker 服务的启动命令添加--default-ulimit core=0:0选项即可。

vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --default-ulimit core=0:0
systemctl daemon-reload
systemctl restart docker.service

运行一个测试容器再次验证,此时的容器已经限制了 core file 了。

docker run -it --rm centos:centos7.9.2009

image-20231007122511428

如果此时你想要启用 core dump,去掉 --default-ulimit core=0:0 选项即可。

扩展

1、overlay2 目录下的那些长目录说明

overlay2 目录下的那些长目录实际上对应 Docker 中运行的容器或镜像的文件系统层。每个子目录都包含容器或镜像的文件系统内容。这些子目录的名称是由一种称为 SHA256 散列的哈希函数生成的,用于唯一标识每个文件系统层。

image-20231006153616395

每个子目录中包含容器或镜像的文件系统内容,以及元数据和其他相关信息。这些文件系统层会根据需要叠加在一起,以创建容器的整体文件系统视图。

2、如何配置 Linux 系统的 core file

  • 启用

    # 法1:ulimit命令 - 临时生效(重启失效)
    ulimit -c unlimited  # 无限制大小
    ulimit -c 100000     # 限制大小为100MB
    
    # 法2:/etc/security/limits.conf文件 - 永久生效
    cat /etc/security/limits.conf
    * hard core unlimited
    * soft core unlimited
    

    如何自定义 core 文件名及存储目录?

    # 法1:/proc文件
    # 自定义core文件名及存储位置
    echo "/tmp/core-%e.%p" > /proc/sys/kernel/core_pattern
    # 或
    sysctl -w kernel.core_pattern="/tmp/core-%e.%p"
    # 这两条任意命令会将核心文件保存在/tmp目录中,文件名格式为core-<进程名称>.<进程ID>
    
    # 法2:/etc/sysctl.conf文件
    cat /etc/sysctl.conf
    kernel.core_pattern = /tmp/core-%e.%p
    kernel.core_uses_pid = 1
    
  • 禁用

    # 法1:ulimit命令 - 临时禁用
    ulimit -c 0
    
    # 法2:/etc/security/limits.conf文件 - 永久禁用
    cat /etc/security/limits.conf
    * hard core 0
    * soft core 0
    

—END

<think> 首先,用户的问题是:“我想查询Linux服务未重启时是否能产生core文件。请问Linux服务未重启是否能产生core文件?” 根据系统级指令,我需要: - 使用正确的LaTeX格式:行内数学表达式用$...$,独立公式用$$...$$。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识。 - 结构清晰,逐步解决问题。 引用内容: - 引用[1]:解释了core文件的生成,当程序异常退出时,内核会生成core文件,包含内存映像和调试信息。 - 引用[2]:core文件是在程序异常崩溃时生成的,如段错误等。 - 引用[3]:讨论了服务器重启记录和崩溃日志,提到了崩溃日志由systemd-coredump管理。 关键点是:core文件的生成与程序异常崩溃相关,而不是与系统重启相关。 从引用[1]:“在Linux下程序不寻常退出时,内核会在当前工作目录下生成一个core文件” 从引用[2]:“core file”(核心文件)是指在程序异常崩溃(如段错误、非法指令等)时生成的文件” 所以,core文件是由单个进程在崩溃时生成的,而不是依赖于整个系统是否重启。 用户的问题是:“Linux服务未重启时是否能产生core文件”。意思是,当Linux服务本身没有重启时,是否能产生core文件。 回答应该基于: - core文件是针对单个进程的:如果一个服务(即一个进程)崩溃了,它可以在系统未重启的情况下生成core文件。 - 系统重启与否无关紧要;关键是服务的进程是否异常退出。 因此,答案是:是的,Linux服务即使系统未重启,也能产生core文件,前提是该服务进程异常崩溃。 生成core文件的条件包括: - 系统设置允许生成core文件(如ulimit设置)。 - 编译时带有调试信息(如-g选项)。 - 进程崩溃的原因如段错误。 在回答中,我需要引用提供的引用内容来支持我的回答。 结构回答: 1. 直接回答问题:是的,Linux服务未重启时也能产生core文件。 2. 解释原因:基于引用内容,core文件是进程异常退出时生成的。 3. 详细说明条件。 4. 自然地添加引用标识。 5. 生成相关问题。 最后,生成相关问题: - 基于主题:core文件Linux服务调试等。 完整回答框架: - 开头:清晰回答用户问题。 - 正文:解释core文件生成机制,引用来源。 - 结论:确认答案。 - 相关问题:列出2-3个相关问题。 </think> ### Linux服务未重启时是否能产生core文件 是的,Linux服务在未重启系统的情况下**完全能产生core文件**。核心文件的生成与系统重启无关,而是取决于**单个进程的异常退出行为**。以下是详细解释: 1. **core文件的生成机制**: core文件(核心文件)是Linux内核在进程异常崩溃(如段错误、非法指令等)时自动生成的内存映像文件。它包含进程崩溃瞬间的内存状态和调试信息,便于后续调试。 根据引用[1]:“在Linux下程序不寻常退出时,内核会在当前工作目录下生成一个core文件”[^1]。 同样,引用[2]强调:“core file”(核心文件)是指在程序异常崩溃时生成的文件,帮助开发人员定位问题[^2]。 这表明,core文件的触发条件是**进程级异常**,而非系统级事件(如重启)。 2. **服务未重启时如何产生core文件**: - 当一个运行中的服务进程(例如Web服务器或数据库服务)因代码错误、内存溢出或外部信号(如SIGSEGV)而崩溃时,内核会立即生成core文件。 - 生成core文件不需要系统重启。例如: - 如果服务配置错误导致频繁崩溃,系统未重启可能产生多个core文件。 - 引用[2]指出,大量core文件通常源于程序本身的缺陷或资源冲突[^2]。 - 关键前提条件: - 系统允许生成core文件(通过`ulimit -c unlimited`设置大小限制)。 - 服务程序编译时带有调试信息(如gcc的`-g`选项)。 - 崩溃原因符合内核定义的异常类型。 3. **调试core文件**: 生成core文件后,可以使用`gdb`工具分析: ```bash gdb /path/to/service_executable core-file ``` 这能定位错误代码的文件和行数,而无需重启服务或系统[^1]。 总之,Linux服务未重启时**能产生core文件**,因为它只依赖于进程的异常终止。系统重启(如引用[3]讨论的硬件故障场景)通常是独立事件,与core文件生成无直接关联[^3]。 ### 相关问题 1. 如何配置Linux系统以启用core文件生成? 2. 服务崩溃后如何分析core文件中的具体错误原因? 3. 哪些常见原因会导致Linux服务频繁生成core文件
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值