Debian Stretch VM 每隔几天就会变得准无响应

Debian Stretch VM 每隔几天就会变得准无响应

受影响的计算机是在 vSphere 中运行的虚拟机,并且是生产服务器,因此一旦问题浮出水面,故障排除时间通常不存在。重新启动后问题就消失了,并且系统在大约一周后似乎稳定运行。我正在寻找一些关于在这种情况再次发生时该怎么做或寻找的想法(如果当前模式成立,可能在本周四或周五左右)。

VM 对 ping 响应正常,并且仍然倾听用于但不响应 http/s 请求 (apache2)。它还侦听 SSH,但在关闭会话之前从不提示进行身份验证。

“本地”控制台在提交命令后立即挂起。在那之前,您可以输入任何您想要的内容;仅当您尝试要求系统它停止工作了。这包括尝试使用制表符完成文件名等。我可以切换到其他虚拟终端之一并输入用户名和密码......但随后系统再次挂起。

/var/log 中的任何日志中都没有有关崩溃的信息(是否有其他地方可以查看的指针?)。任何日志文件中的最后一条消息都是在实际问题发生之前很久写入的。

附加信息:

发生此问题时,虚拟机的“本地控制台”上不会打印任何内容。该虚拟机有一个通过 LSI Logic Parallel vSCSI 连接的 1TB 卷(厚置备、延迟置零)。数据存储本身是一个大型 NAS,它还为其他一些 ESXi 主机提供服务,并且发生这种情况时其他来宾都不会受到影响。

发生此问题时,vCenter/vSphere 不会显示异常高的 CPU 或内存利用率。

至少有一次,挂起已经持续了 8 小时以上,然后才被试图通过 SFTP 访问服务器的人注意到。

根据 sourcejedi 的建议,我现在已将控制台日志记录的阈值降低到 5,并确认我可以在虚拟机的本地控制台上看到发送到 /dev/kmsg 的消息。在我进行更改之前,这些消息并未显示,因此内核可能试图说些什么,但我从未看到过。

由于我在 ESXi 主机上有空闲资源,因此我还克隆了虚拟机并将其放在单独的隔离网络上。如果出现这个问题,我将有更多时间进行故障排除,而不必担心在此过程中生产服务出现故障。

我会在获得更多信息后进行更新,但感谢迄今为止提供帮助的所有人!

答案1

  1. 假设
  2. 指示
  3. 一个愚蠢的黑客(假设你的任务挂在文件系统/磁盘访问上)

1. 假设

1.1) 默认情况下,Linux 内核具有报告各种类型的崩溃或挂起的代码。

它们都可以显示当前的问题并在“本地控制台”上打印调用链。它可能无法显示根本原因,并且此代码永远不可能 100% 可靠。但通常你会得到一些东西,而且比什么都没有好得多。

因此,您应该仔细检查是否能够在控制台上看到这些内核日志消息!详细信息在下一节中。

1.2)由于内核本身仍在响应您的按键和网络数据包,因此我真的希望挂起任务检测器能够在这里工作。

听起来内核线程和中断仍在运行,但用户空间进程正在挂起。当进程尝试访问物理文件系统时,这些症状听起来与挂起一致。当进程挂起几分钟时,内核会打印“挂起任务”消息和调用链。

1.3) 另外,也许用户进程没有完全挂起,但它们是非常缓慢,而且你没有等待“足够长的时间”来看到他们取得进展。

如果您有使用带有机械 HDD 的 Linux PC 的经验,您可能会熟悉这个故事:-)。但由于这不是您桌上的 PC,因此您不会注意到硬盘噪音很大或磁盘活动指示灯永久亮起:-)。

我在管理服务器方面没有经验。但我认为您应该使用监控软件来尝试检测此类问题。理想情况下,甚至在它们造成用户可见的问题之前:-)。

举一个例子,如果您监视系统内存使用情况,它可以显示您是否出现逐渐的“内存泄漏”并且系统开始自行交换直至死亡。我希望你没有这个问题。例如,如果login已被换出,那么控制台登录将会很慢,甚至提示您输入密码。

如果您有足够细粒度的监控,也许您会在观察到的故障发生前几秒内检测到磁盘 IO 的增加。

2. 使用说明

2.1)“本地控制台”是否已记录或至少是持久的,以便您会注意到上面是否打印了内核崩溃?确实应该如此,但我不确定如果您使用模拟的 vSphere 等将如何工作连续剧安慰。如果您只是使用模拟视频显示,那么它已经是持久的了。

这篇 VMWare 文章似乎依赖于相同的假设。

2.2) 确保您没有禁用控制台日志记录。 运行这个命令:

sudo sh -c "echo '<3>test' >/dev/kmsg"

它应该在控制台上显示“测试”。另请参阅下面,我在其中讨论堆栈跟踪。

如果这是模拟视频显示,则部分崩溃消息可能会滚出屏幕顶部。如果内核有坠毁,则无法使用shift+PageUp向上滚动。原则上,拥有一个实现回滚的模拟串行控制台会更有用。

对于内核崩溃,上面的 VMWare 链接中还有一些其他崩溃转储建议。

2.3) 输入密码后挂起听起来磁盘已变得无响应。我认为Linux SCSI操作在一段时间后会超时,并且超时将被记录为内核错误,因此Linux会将它们打印在控制台上。 您的文件系统是使用 SCSI 协议还是其他协议挂载的?

2.4) 另外,默认情况下内核会检测挂起的任务并打印一条消息:task bash:999 blocked for more than 120 seconds。接下来是调用链(“堆栈跟踪”)。尽管如此,我认为调用链部分是使用内核的“默认日志级别”进行记录的,这通常意味着级别 4(警告)。

如果您想查看挂起任务消息的调用链部分,您可能需要提高控制台日志级别多于4 级,例如dmesg -n 5

要检查您是否尚未禁用挂起的任务消息: cat /proc/sys/kernel/hung_task_timeout_secs应显示正数,例如120

不打印挂起的任务消息网络文件系统挂起 仅当挂起任务“不可中断”且“不可终止”时才会打印它们。 挂在 NFS 上的进程可以被终止。如果您使用的网络文件系统可能导致此挂起,您可能已经考虑到了这一点。 (以及以某种方式测试连接到 NFS 服务器,而不是只是使用 测试挂起的虚拟机ping,然后您就会在问题中提到所有这些:-)。如果 NFS 服务器显示对其他虚拟机有响应,但您在此虚拟机上没有看到挂起任务消息,我想您可以尝试使用sysrq+T 进行调查(见下文)。

在 Debian Linux 版本上默认启用挂起任务消息。 (出于某种原因,我的 Fedora Linux 内核在构建时根本不包含挂起任务检测器。尽管它似乎包含在 RHEL 和 SLES 内核中。FIXME)。

当我搜索挂起的任务消息时,我注意到挂起的服务器和 IO 错误消息似乎是一个共同的主题:-)。

还有Linux sysrq。如果您有一个串行控制台,但只能捕获连接到它后打印的输出,您可以尝试使用 sysrq+T 查找挂起的任务。这会转储有关的信息每一个系统上的任务,因此它会生成一个很多输出到控制台。因此,当您的控制台是视频显示器时,这可能不太有用。而且您不应该在工作的生产系统上测试它!出于物理安全原因,某些发行版sysrq默认禁用。 Debian 保持sysrq启用状态。当然,您可能已经使用了安全检查表来告诉您禁用sysrq.

2.4)最初的问题没有引用任何对“响应性”的定量监控,无论是在观察到的故障之前,还是为了表明系统并不经常过载(这可能只是最终的扩展)。

考虑对各种服务的服务“响应性”进行定量监控的价值 - 这可能包括登录到 ssh 服务器。还有系统利用率水平、延迟和每秒网络数据包。

PS 两者磁盘忙%“CPU 等待”可能会被诅咒。我还想监控当前的磁盘延迟和 IOPS。 (不过,当前的 Debian 9.x 内核应该对磁盘繁忙百分比相对敏感)。

上面的答案和 VMware 链接描述了一些您应该了解的标准工具,或者至少知道它们的存在。

3. 一个愚蠢的黑客(假设你的任务挂在文件系统/磁盘访问上)

下面的细节是一个愚蠢的黑客。有时你需要的是一个愚蠢的黑客。我只是说,如果你不得不诉诸于此,这可能表明你的工作方式存在一些缺陷,你需要解决:-P。

如果您有一些 shell 测试,并且希望在系统“准无响应”时运行,您可以尝试运行 mlock() 的busyboxshell。例如运行一个使用静态链接的busybox这个 LD_PRELOAD mlock 黑客。然后使用例如运行 busybox 命令(exec -a ls /proc/self/exe /)。可能最安全的做法是:

# prevent you running any normal program by mistake!
OLDPATH="$PATH"
PATH=

# run a busybox builtin
b() (
  local command="$1"
  shift
  exec -a "$command" /proc/self/exe "$@"
)

# run normal program in the background, in case it hangs
p() {
  local PATH="$OLDPATH"
  exec "$@" &
}

这应该可以让您运行b dmesg,而不需要读取任何未缓存的文件:-)。

(如果某人同时具有以下两种情况,则此情况会崩溃:1)设法挂载挂起的文件系统2)将其挂载在/或上/proc,这样您甚至无法/proc在不挂起的情况下访问。我认为这种可能性不大,而且防御起来会更痛苦。)

b ps -o stat,pid,args将显示进程状态;D意味着“不间断睡眠”——通常等待磁盘或网络文件系统。然后b cat /proc/999/stack将显示 PID 999 在内核中等待的位置。

cd /sys/class/block/ && b grep -H . */inflight将显示每个磁盘的正在进行的读取和写入计数。

相关内容