CoreOS:tcpdump神秘地解决了网络问题(使用的套接字数量过多)


14

我今天对你有一个谜。我们在Azure上运行基于CoreOS(2023.5.0 / Linux 4.19.25-coreos)的小型三节点Elasticsearch群集。Elasticsearch在主机网络模式下在docker容器内运行。在运行了几乎完全免费的维护一年之后,我们一直看到机器进入一种非常有趣的状态。

更新资料

通过修复Linux内核中的驱动程序可以解决此问题。请参阅下面的答案。

病征

基本上,受影响的计算机与其他两个节点之间的网络连接消失。所有这些都位于同一虚拟网络和同一子网中,并且通常可以与其他服务器通信。仍然可以从其他子网(我可以将其连接到该子网)和其他对等虚拟网络访问受影响的节点。该计算机还具有(非常多)互联网连接,但是大多数请求只是超时。

我们已经观察到,在受影响的节点上,报告的“已使用套接字”的/proc/net/sockstat数量非常高(在正常节点上为〜4.5k,而不是〜300)。监视显示,此数目从节点不可用的那一刻起迅速增加。

有趣的是,我们似乎无法识别这些二手插座的来源:

# cat /proc/net/sockstat
sockets: used 4566
TCP: inuse 2 orphan 0 tw 2 alloc 98 mem 4
UDP: inuse 1 mem 0
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0

# cat /proc/net/sockstat6
TCP6: inuse 98
UDP6: inuse 1
UDPLITE6: inuse 0
RAW6: inuse 1
FRAG6: inuse 0 memory 0

除此之外,机器看起来还不错。没有可运行的进程在运行,CPU使用率降至最低,并且有大量可用内存。

在同一个子网中对“无法访问的” VM进行Ping操作会导致对的一些EAGAIN响应recvmsg,然后越过并ENOBUFS返回sendmsgstrace ping输出在这里

我已经收集了一些其他输出(在对系统进行任何修改之前)并将其发布在以下要点中:https : //gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c

分析

我们试图关闭我们在服务器上可以想到的所有内容,其中Elasticsearch是第一个可疑的对象。但是,关闭elasticsearch容器并不会释放使用过的套接字。对于所有与CoreOS相关的进程(更新引擎,锁匠等),甚至整个Docker运行时或Azure特定的东西,都是相同的。似乎没有任何帮助。

但是现在变得更奇怪了:我们试图tcpdump在计算机上运行以查看发生了什么。并且可以看到:问题已自行解决,连接已恢复。我们的理论是tcpdump执行某种可解决该问题的系统调用。我们使用gdb运行tcpdump并在所有syscall上设置断点。在逐步处理断点负载之后,我们最终发现,在捕获套接字(特别是libpcap中的这一行)上设置混杂模式的行为是重置已用套接字的计数器并使我们返回到正常状态的事情。

其他发现

  • 我们已经验证了运行tcpdump带有-p/--no-promiscuous-mode标志的操作不会清除使用的套接字计数器,并使机器返回可用状态。
  • 运行将ifconfig eth0 txqueuelen 1001重置使用的套接字计数器,但无法恢复连接。
  • 手动设置混杂模式ip link set eth0 promisc on也不会恢复连接。
    • net.ipv4.xfrm4_gc_thresh 设置为32768并稍微增加它不能解决问题。

使用的插座

我们一直与Azure保持联系,而我们对此感到困惑。我了解这可能不是问题,而只是症状。但这是我到目前为止发现的唯一有形的东西。我的希望是,通过了解症状,我可以更接近根本原因。Azure上的网络接口与此网络驱动程序一起运行。

也许应该归咎于CoreOS /内核?

从时间轴来看,问题始于2019-03-11,这是CoreOS自动更新到最新版本的那一天。根据发行说明,此更新包含4.15.23到4.19.25内核更新。我仍在浏览变更日志,以查看是否有任何问题。到目前为止,我只发现hyperv网络驱动程序在最近几个月中收到了很多更新,但似乎不是4.19.25的一部分。CoreOS应用于4.19.25的补丁集并不令人印象深刻,但是引入了伪造的nf_conntrack_ipv4模块的补丁是新的。

更新:可能相关的传入内核补丁?

救命!

到目前为止,我们有以下问题:

  • 是什么导致该“使用过的套接字”指标飙升?我已通读了有关该指标的内核源代码,它似乎只是一个计数器,没有提及它们实际上是哪种套接字或创建它们的原因。

  • 为什么数字保持在4.5k左右?哪个限制会导致这种情况?

  • 4.14.96和4.19.25内核之间有什么重大变化吗?

  • 为什么setsockopt()libpcap 中的调用会重置状态?

相关的CoreOS错误:https//github.com/coreos/bugs/issues/2572


套接字打开是一个导致的问题,而不是根本问题恕我直言。在桥设备上具有macvlan设备(具有自己的mac地址)的linux系统上,我有这种行为。将网桥设置为promisc可使macvlan设备正常工作。我不知道coreos或azure。问题是底层不知道上层的mac地址。
AndreasM

感谢您的评论!我意识到使用大量的套接字并不是根本原因,我只是坚持要坚持一件事,将其确定为机器上的异常。
斯蒂芬·克莱因

嗨,斯蒂芬。任何新闻?请报告1)是否启用WOL?2)sysctl -w net.ipv4.route.flush = 1是否可以解析?3)什么是没有工作状态的ARP缓存?在工作状态?
马西莫

Answers:


4

首先,感谢您提出的书面问题!

由于您所描述的详细程度很高,并且您已经处于gdb级别,因此我认为我的回答对您来说不会有太大用处。无论如何,这是一个尝试:

  • 大概您已经尝试过类似ss -aelsof -n吗?
  • dmesg发生这种情况时,是否返回任何有趣的东西?
  • 您在服务器上使用iptables吗?
  • 如果您使用tcpdump(例如ip link set [interface] promisc on)以外的其他方式设置混杂模式,这是否也可以解决问题?
  • 您是否检查了任何可疑的进程,文件或其他奇怪的活动?只是认为也许某些不请自来的令人讨厌的过程正隐藏在自己隐藏的阴影中,并且在设置了混杂模式时变得沉默了?
  • 如果使tcpdump处于运行状态,是否会再次出现此问题?

我希望这有帮助。


1
谢谢您的回复!我确实已经收集了您引用的某些命令的输出。现在,它们也链接到了问题(gist.github.com/privatwolke/e7e2e7eb0272787765f5d3726f37107c)。奇怪的是,GET方式少报套接字从sslsofnetstat不是从“用插座” /proc/net/sockstat。只有总数(似乎只是从该文件读取)是相同的。 iptables运行但没有特殊规则(请参见要点),我没有尝试自己设置混杂模式或连续运行tcpdump。下次会做。
斯蒂芬·克莱因

我将输出添加ss -aepi到我的输出集合中:gist.github.com/privatwolke/…-不幸的是,dmesg在发生这种情况时不返回任何内容。实际上,事件之前的最新条目为5天。
斯蒂芬·克莱因


我已经证实,ip link set eth0 promisc on仅此一项并不能将计算机还原到可用状态。
斯蒂芬·克莱因

您好,您看过本网站的另一个问题吗?serverfault.com/questions/614453/… 似乎暗示您可能正在耗尽xfrm4 dest缓存。您可以使用以下内核设置来增加它: xfrm4_gc_thresh - INTEGER The threshold at which we will start garbage collecting for IPv4 destination cache entries. At twice this value the system will refuse new allocations. 据我所知,它与IPsec有关,不过您似乎也没有在这里运行。
佩德罗·佩雷斯

0

这是由Linux内核中的hv_netsvc驱动程序中的错误引起的。我们可以与Microsoft开发人员一起解决此问题,并设法将修复程序应用到上游。

我在这里引用提交消息,因为它很好地总结了问题:

当环形缓冲区由于RX完成消息而几乎已满时,TX数据包可能会到达“低水位标记”并导致队列停止。如果TX完成早于队列停止到达,则可能会错过唤醒。

此补丁将检查最后一个挂起的数据包,使其覆盖EAGAIN和成功案例,因此在必要时将可靠地唤醒队列。

为了将来参考,解决此问题的提交是https://github.com/torvalds/linux/commit/6d9cfab853ca60b2f77b5e4c40443216988cba1f

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.