Linux系统中有哪些潜在暗坑需要特别注意?
摘要:TL;DR:conntrack 表满了、ARP 邻居表溢出、内核参数被静默重置、listen 队列丢包……这些 Linux 内核层的"沉默杀手"不会出现在你的 Grafana 大盘上,但能
TL;DR:conntrack 表满了、ARP 邻居表溢出、内核参数被静默重置、listen 队列丢包……这些 Linux 内核层的"沉默杀手"不会出现在你的 Grafana 大盘上,但能让你的线上服务在几秒内崩溃。本文拆解 8 个真实暗坑,每个都附带故障原理和监控方案。
故事:K8s 集群丢包两天,最后是 conntrack 的锅
某天凌晨,值班收到告警:部分 Pod 间歇性超时。
打开 Grafana——CPU 正常,内存正常,网络带宽正常,磁盘 IO 正常。四大金指标一片绿色。
开始排查:抓包发现 SYN 发出去了,但对端没回 SYN-ACK。换个 Pod 试试,好了。再试一次,又超时了。像是某种随机故障。
排查了两天。最后在 dmesg 里找到了一行不起眼的日志:
nf_conntrack: table full, dropping packet.
conntrack 表满了。 新连接被内核在网络栈底层静默丢弃,SYN 包根本没到达目标进程。
这条信息不在 Prometheus 的任何 exporter 里,不在 Grafana 的任何 dashboard 里,不在任何告警规则里。它安静地躺在 dmesg 的日志洪流中,等着某个老运维碰巧想到去看一眼。
这就是"沉默杀手"——内核层的故障,没人监控,出事了也没人能一眼看出来。
你的监控栈有一大片盲区
大多数团队的监控架构长这样:
Prometheus + Node-Exporter → Grafana Dashboard → AlertManager → 通知
这套体系非常优秀——用来做指标采集和趋势展示。
但它有一个根本性的盲区:Node-Exporter 采的是指标(metrics),不是异常判定(checks)。
什么意思?举个例子:
Node-Exporter 会告诉你 node_nf_conntrack_entries = 131072,但它不知道 nf_conntrack_max 也是 131072——表已经满了
它会告诉你 node_network_receive_errs_total = 15847,但这是一个累计值,你需要自己算增量、设阈值、写 PromQL 告警规则
它采了 node_sockstat_TCP_tw 告诉你 TIME_WAIT 数量,但你需要自己判断"多少算多"
指标在那里,但没人把它们变成告警。
不是 Node-Exporter 的问题,而是"指标采集"和"异常检测"是两件不同的事。大多数团队做完了前者,跳过了后者——尤其是在内核层面。
接下来我们拆解 8 个最常见的 Linux "沉默杀手"。
暗坑 1:conntrack 表溢出——所有连接静默失败
故事
NAT 网关、K8s Node、高并发负载均衡器——只要启用了 iptables/nftables NAT 或 connection tracking,内核就会为每条连接维护一个 conntrack 条目。默认上限通常是 65536 或 131072。
表满之后的行为不是报错,不是拒绝连接,而是静默丢包。SYN 发出去了,没有任何响应。客户端看到的是连接超时,而服务端的进程对此完全无感——包根本没到达应用层。
原理
新连接 → 内核网络栈 → nf_conntrack 尝试创建条目
↓
表满 → 直接 DROP → 没有 RST,没有 ICMP unreachable
↓
客户端等到超时 → 报 connection timeout
唯一的证据是 dmesg 中的 nf_conntrack: table full, dropping packet,以及 /proc/net/stat/nf_conntrack 中 drop 计数器的增长。
监控方案
catpaw 的 conntrack 插件读取 /proc/sys/net/netfilter/nf_conntrack_count(当前条目数)和 nf_conntrack_max(上限),计算使用率百分比:
# conf.d/p.conntrack/conntrack.toml
[[instances]]
[instances.conntrack_usage]
warn_ge = 75.0
critical_ge = 90.0
nf_conntrack 模块未加载时自动跳过,不会误报。
暗坑 2:ARP 邻居表满——新 IP 无法通信,旧 IP 正常
故事
大规模 K8s 集群,上千个 Pod 分布在同一个大二层网络。运行几天后,新创建的 Pod 无法和某些节点通信,但已经在运行的 Pod 之间通信正常。
