在 Cumulus Linux 交换机上将 netconsole 与 syslog 结合使用

netconsole 是一项 Linux 功能,允许您使用 UDP 将来自 dmesg 的内核消息输出重定向到网络上的位置。您可以在 syslog 服务器上捕获和存储这些消息,以调查生成 dmesg 输出的 Cumulus Linux 交换机上的问题。当物理控制台未连接并且您需要调试内核事件(例如系统崩溃和意外重启)时,这非常有用。

netconsole 不是物理控制台的替代品。它不提供与交换机的交互式控制台;它仅是一项远程日志服务。netconsole 在启动时网络初始化之前也无法使用。启动周期早期的日志数据不会被捕获。只要物理控制台不可用,就使用 netconsole 记录数据。

配置 netconsole 模块

您必须在此过程结束时重启交换机以应用更改。

要在 Cumulus Linux 交换机上配置 netconsole 模块

  1. 设置 netconsole 内核模块以在启动时加载

    cumulus@switch:~$ echo netconsole | sudo tee /etc/modules-load.d/netconsole.conf
    
  2. 配置 netconsole 内核模块选项以指向您的 syslog 服务器。

    cumulus@switch:~$ echo 'options netconsole netconsole=[...]' | sudo tee /etc/modprobe.d/netconsole.conf
    

    在上述命令中,将 [...] 替换为所需的配置。选项的格式如下(括号中为默认值)

    netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
       where
             +            if present, enable extended console support
             src-port     source UDP port (6665)
             src-ip       source IP address (<dev> interface address)
             dev          network interface (eth0)
             tgt-port     UDP port of the syslog server (6666)
             tgt-ip       IP address of the syslog server
             tgt-macaddr  Ethernet MAC address of the next hop to the syslog server (broadcast)
    
    • netconsole 模块仅需要 tgt-ip 参数;如果未指定其他参数,则使用其默认值。
    • 由于 netconsole 模块可能会在您配置 dev 之前加载,因此您必须指定 src-ip
    • 如果 syslog 服务器与源设备不在同一以太网段上,则必须指定 tgt-macaddr
    • 指定 tgt-macaddr 比使用默认值(以太网广播)更有效。

    要确定值 devtgt-macaddr,请使用以下过程。运行命令时,请替换尖括号 (< >) 之间的值以匹配您的配置。

    1. 使用 ip route get 确定 syslog 服务器的接口和下一跳 IP 地址。

      如果 syslog 服务器可通过前面板端口访问,请运行

      cumulus@switch:~$ ip route get <tgt-ip>
      

      如果 syslog 服务器可通过管理端口 (mgmt VRF) 访问,请运行

      cumulus@switch:~$ ip route get <tgt-ip> vrf mgmt
      

      查看 ip route get 命令的输出。如果它采用以下格式(没有 via 关键字),则 syslog 服务器位于同一以太网段上。用于 dev 参数的值是输出中报告的 dev 值,在本例中为 eth0下一跳 IP 是第一个字段。

      10.230.130.20 dev eth0 table mgmt src 10.230.130.211 uid 1000
      

      如果 ip route get 命令的输出采用以下格式(带有 via 关键字),则您通过网关到达了 syslog 服务器。用于 dev 参数的值是输出中报告的 dev 值,在本例中为 eth0下一跳 IPvia 值,在本例中为 10.230.130.1。

      10.230.15.31 via 10.230.130.1 dev eth0 table mgmt src 10.230.130.211 uid 1000
      
    2. 使用 arping 命令确定下一跳 MAC 地址

      cumulus@switch:~$ sudo arping -i <dev> -c1 -r <nexthop ip>
      

      用于 tgt-macaddr 参数的值是上一个命令的输出。

      例如,要配置交换机,使其使用 netconsole 记录到 IP 地址为 10.230.15.31 和端口 514 的 syslog 服务器,请运行以下命令

      cumulus@switch:~$ ip route get 10.230.15.31 vrf mgmt
      10.230.15.31 via 10.230.130.1 dev eth0 table mgmt src 10.230.130.211 uid 0
          cache
      cumulus@switch:~$ sudo arping -i eth0 -c1 -r 10.230.130.1
      d8:c4:97:b5:be:b7
      cumulus@switch:~$ ip -4 addr show dev eth0
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master mgmt state UP group default qlen 1000
          inet 10.230.130.211/24 brd 10.230.130.255 scope global dynamic eth0
             valid_lft 6855sec preferred_lft 6855sec
      cumulus@switch:~$ echo netconsole > /etc/modules-load.d/netconsole.conf
      cumulus@switch:~$ echo 'options netconsole netconsole=@10.230.130.211/eth0,514@10.230.15.31/d8:c4:97:b5:be:b7' > /etc/modprobe.d/netconsole.conf
      cumulus@switch:~$ sudo reboot
      
  3. 您可以增加或减少要记录的数据量。

    • 要增加内核记录的数据量(请参阅 linuxconfig.org 上的 Linux 内核日志级别简介),请调整日志级别。默认情况下,Cumulus Linux 交换机在级别 3 (KERN_ERR) 记录内核数据。尝试调试问题时,记录所有数据可能很有用。为此,请将内核 printk 值增加到 7,在 /etc/systctl.d/99-sysctl.conf 文件中
    $ echo 'kernel.printk = 7 4 1 7' | sudo tee -a /etc/sysctl.d/99-sysctl.conf
    
    • 要将数据限制为仅内核崩溃日志,请将内核模块选项 oops_only 设置为 1,方法是将 oops_only=1 附加到您在 /etc/modprobe.d/netconsole.conf 中使用的 options netconsole 行。

      cumulus@switch:~$ echo 'options netconsole netconsole=@10.230.130.211/eth0,514@10.230.15.31/d8:c4:97:b5:be:b7 oops_only=1' | sudo tee /etc/modprobe.d/netconsole.conf
      
  4. 重启交换机。启动序列将应用这些设置。

    cumulus@switch:~$ sudo reboot
    

创建运行配置

以下过程仅影响交换机上的运行内核(也称为非持久配置)。交换机重启后,您将丢失这些设置。

要在 Cumulus Linux 交换机上创建运行配置

  1. 增加内核日志记录级别(可选)。

    cumulus@switch:~$ sudo dmesg -n 7
    
  2. 加载带有适当选项的 netconsole 内核模块。

    如果 syslog 服务器可通过管理 VRF 访问,则在运行时加载 netconsole 模块时,<dev> 必须是管理 VRF 接口的名称,即 mgmt

    cumulus@switch:~$ sudo modprobe netconsole netconsole=@10.20.30.40/eth0,6666@10.20.30.255/00:22:33:aa:bb:cc
    

    使用与上述相同的配置

    cumulus@switch:~$ sudo modprobe netconsole netconsole=@10.230.130.211/mgmt,514@10.230.15.31/d8:c4:97:b5:be:b7
    

    要使用 oops_only 设置,请将此选项附加到 modprobe 命令

    cumulus@switch:~$ sudo modprobe netconsole netconsole=@10.230.130.211/mgmt,514@10.230.15.31/d8:c4:97:b5:be:b7 oops_only=1
    

配置 rsyslog 服务器以接收控制台日志数据

以下步骤展示了如何配置 rsyslog 服务器以从两台设备接收端口 6666 上的 UDP 流量,并为每台设备创建单独的日志文件。您可以将其添加到您现有的 rsyslog 配置中。

您必须是服务器上的 root(超级)用户才能执行这些步骤。

  1. 使用您喜欢的编辑器创建一个特定的配置文件

    cumulus@switch:~$ sudo vi /etc/rsyslog.d/remote-netconsole.conf
    
  2. 将以下内容添加到文件中。更改 IP 地址以匹配您的交换机的 IP 地址和适当的目标日志文件。

    $ModLoad imudp
    
    $RuleSet remote
    # Modify the following template according to the devices on which you want to
    # store logs. Change the IP address and subdirectory name on each
    # line. Add or remove "else if" lines according to the number of your
    # devices.
    if $fromhost-ip=='10.20.30.40' then /var/log/remote/spineswitch1/console.log
    else if $fromhost-ip=='10.20.30.41' then /var/log/remote/leafswitch1/console.log
    else if $fromhost-ip=='10.20.30.42' then /var/log/remote/leafswitch2/console.log
    else /var/log/remote/other/console.log
    & stop
    
    $InputUDPServerBindRuleset remote
    $UDPServerRun 6666
    
    $RuleSet RSYSLOG_DefaultRuleset
    
  3. 创建一个目录来存储日志文件。以下示例创建了一个名为 /var/log/remote 的目录。

    # mkdir /var/log/remote
    
  4. 重启 rsyslog

    # systemctl restart rsyslog.service
    

测试设置

您可以通过以下两种方式之一测试此设置

  • 将数据追加到内核日志
  • 故意使交换机崩溃(这会导致交换机发生灾难性故障)

将数据追加到内核日志

要创建新的内核日志消息并验证 syslog 服务器是否已记录它,请在配置了 netconsole 的交换机上运行以下命令

cumulus@switch:~$ echo "<0>test message $(date +%s)" | sudo tee /dev/kmsg

确认此命令输出的相同消息也记录在 syslog 服务器上。

使交换机崩溃

这会导致交换机发生灾难性故障,并导致立即重启。确保您的网络已为此做好准备,并且您了解后果。

要调用内核崩溃以测试该过程,请登录到您要崩溃的交换机并运行以下命令

cumulus@switch:~$ echo c | sudo tee /proc/sysrq-trigger

如果该过程正常工作,您将看到发送到 rsyslog 服务器的日志数据。

日志文件示例输出

以下是来自 rsyslog 服务器的一些示例输出

May 12 17:13:59 leafswitch1.network.com [17593.272492] sysrq: SysRq :
May 12 17:13:59 Trigger a crash
May 12 17:13:59 leafswitch1.network.com [17593.277181] BUG: unable to handle kernel
May 12 17:13:59 NULL pointer dereference
May 12 17:13:59 leafswitch1.network.com  at           (null)
May 12 17:13:59 leafswitch1.network.com [17593.285951] IP:
May 12 17:13:59 leafswitch1.network.com  [<ffffffff81496256>] sysrq_handle_crash+0x16/0x20
May 12 17:13:59 leafswitch1.network.com [17593.292773] PGD 4cb06067
May 12 17:13:59 PUD 4ca44067
May 12 17:13:59 PMD 0
May 12 17:13:59 leafswitch1.network.com
May 12 17:13:59 leafswitch1.network.com [17593.297566] Oops: 0002 [#1]
May 12 17:13:59 SMP
...