🐧内核:异常收集[译]

type
status
date
slug
summary
tags
category
icon
password

1. 简介

在业务使用过程中,经常遇到服务器概率性崩溃(准确来说是内核崩溃),重启后一切 ok,但是这种隐藏的 bug 在商业领域是不可接受的,宕机出现即是大问题。因此内核提供了一种保留崩溃现场的机制,保存内核崩溃的现场信息在硬盘等下电不易失的存储介质,方便程序员可以分析崩溃原因:
  • Kernel Panic
  • Non Maskable Interrupts (NMI)
  • Machine Check Exceptions (MCE)
  • Hardware failure
  • Manual intervention
对于其中一些事件(panic,NMI),内核将自动做出反应,并通过‎‎kexec‎‎触发故障转储机制。在其他情况下,需要手动干预才能捕获内存。每当发生上述事件之一时,重要的是要找出根本原因,以防止它再次发生。原因可以通过检查复制的内存内容来确定。

2. kdump 机制

‎当发生内核崩溃时,内核依靠‎‎ kexec‎‎ 机制在系统引导时,分配的预留内存,快速重新引导内核的新实例(见下文)。这允许现有内存区域保持不变,以便安全地将其内容复制到存储中。‎

2.1. 安装

注意:‎从 16.04 开始,默认情况下启用内核故障转储机制。在安装过程中,系统将提示您以下对话框。‎
选择 Yes 来为所有重启拉起 kexec-tools 工具。
选择 Yes 来启用 kdupm-tools。
‎如果需要手动启用该功能,可以使用 dpkg-reconfigure kexec-tools 或 dpkg-reconfigure kdump-tools 命令并对问题回答 "Yes",也可以直接编辑和设置 /etc/default/kexec 的参数:
也可以编辑文件 /etc/default/kdump-tools 添加下面的行来启用 kdump:
安装 linux-crashdump 包后‎‎,需要重新启动才能激活 crashkernel=xxxx 的 boot 参数。重新启动后,kdump-tools 将启用并处于活动状态。‎如果在重启之后使能 kdump-tools,则需要运行 kdump-config load 来激活 kdump 机制。
可以使用 kdump-config show 命令查看当前配置状态:
这里告诉我们,我们可以在 /var/crash 下 发现 core dumps 文件。

3. 配置

‎除了本地转储之外,现在还可以使用使用‎‎ SSH‎ ‎或 ‎‎NFS ‎‎协议将内核故障转储发送到远程服务器。‎

3.1. 本地 kdump

本地转储是自动配置的,除非选择了远程协议,否则它们将继续使用。文件中存在许多配置选项,并已全面记录在 ‎/etc/default/kdump-tools 文件中。

3.2. 使用 SSH 协议远程 kdump

要使用 ‎‎SSH‎‎ 协议启用远程转储,必须按以下方式修改 ‎/etc/default/kdump-tools 配置:
唯一要定义的必需变量是 SSH。它必须包含使用 {username}@{远程服务器} 格式,包含远程服务器的用户名和主机名。‎‎SSH_KEY 可用于提供要使用的现有私钥,否则 ‎kdump-config propagate 命令将创建一个新的密钥对。HOSTTAG 变量可用于使用系统的主机名作为要创建的远程目录的前缀,而不是 IP 地址。
‎ 下面的示例演示如何使用 kdump-config propagate 创建新密钥对并将其传播到远程服务器:‎
‎需要远程服务器上使用的帐户的密码才能成功将公钥发送到服务器‎中。
kdump-config show 该命令可用于确认 kdump 已正确配置为使用 SSH 协议:‎

3.3. 使用 NFS 协议远程 kdump

‎要使用 ‎‎NFS‎ ‎协议启用远程转储,‎/etc/default/kdump-tools 必须按以下方式进行修改:
‎与 SSH 协议一样,HOSTTAG 变量可用于将 IP 地址替换为主机名作为远程目录的前缀。‎
‎kdump-config show 命令可用于确认 kdump 已正确配置为使用 NFS 协议:‎

4. 认证

要确认内核转储机制是否已启用,需要验证一些事项。首先,确认‎‎crashkernel‎‎ boot 参数是否存在:
crashkernel 参数遵循如下格式:
range=start-[end] 是左闭右开的形式。因此,对于在 /proc/cmdline 中找到的 crashkernel 参数,我们将拥有:
以上值表示:
如果 RAM 小于 384M,则不要保留任何内容(这是 "救援" 情况);
如果 RAM 大小在 386M 和 2G 之间(独占),则保留 64M;
如果内存大小大于 2G,则预留 128M;
所以通过以下方式验证内核是否为 kdump 内核保留了请求的内存区域:
最后,如前所述,kdump-config show 命令显示 kdump 工具配置的当前状态:

5. 测试故障转储机制

警告测试故障转储机制将导致系统重新启动。在某些情况下,如果系统负载过重,这可能会导致数据丢失。如果要测试该机制,请确保系统处于空闲状态或负载非常轻。
通过查看 /proc/sys/kernel/sysrq 的内核参数的值来验证是否启用了 SysRQ 机制:
如果返回值 0,则禁用转储,然后重新启动功能。大于 1 的值表示启用了 sysrq 功能的子集。有关选项和默认值的详细说明,请参阅 /etc/sysctl.d/10-magic-sysrq.conf 。启用转储,然后使用以下命令重新启动测试:
完成此操作后,您必须成为root,因为仅使用 sudo 是不够的。作为 root 用户,您必须发出 echo c > /proc/sysrq-trigger 命令 。如果您使用的是网络连接,您将失去与系统的联系。这就是为什么最好在连接到系统控制台时进行测试的原因。这具有使内核转储进程可见的优点。典型的测试输出应如下所示:
输出的其余部分被截断,但您应该看到系统重新启动,并且在日志中的某个位置,您将看到以下行:
完成后,系统将重新启动到其正常运行模式。然后,您将在 /var/crash 目录中找到内核故障转储文件和相关子目录:
如果转储由于 OOM(内存不足)错误而无法正常工作,请尝试通过编辑 /etc/default/grub.d/kdump-tools.cfg 来增加保留的内存量。例如,要保留 512 MB:
运行 sudo update-grub ,然后重新启动,然后再次测试。

6. 资源

内核故障转储是一个庞大的主题,需要对 Linux 内核有很好的了解。您可以在此处找到有关该主题的更多信息:
  • Kdump 内核文档
  • 分析 Linux 内核崩溃
基于Fedora,它仍然提供了内核转储分析的良好演练)

7. 参考链接

中年码农的困境log-001-我与计算机