我今天对你有一个谜。我们在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
返回sendmsg
。strace 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