如何解决系统报错:nf_conntrack: table full, dropping packets

系统日志出现 nf_conntrack: table full, dropping packets,通常说明连接跟踪表已接近或达到上限。本文说明如何判断、临时调大、持久化配置,并用 Categraf 或日志监控提前发现风险。

作者 秦晓辉@快猫星云

核心要点

  • nf_conntrack: table full, dropping packet 表示 Linux 连接跟踪表已经满了,新连接可能被丢弃。
  • 先同时查看 nf_conntrack_maxnf_conntrack_count,确认是容量接近上限,而不是只看日志下结论。
  • 临时调大 nf_conntrack_max 可以快速止血,持久化配置需要写入 /etc/sysctl.conf
  • 调大上限会消耗更多系统资源,不能替代对连接数、超时、业务流量和异常连接的分析。
  • 生产环境建议同时监控 conntrack 使用率和系统日志关键字,前者用于趋势预警,后者用于兜底告警。

问题

在系统日志中(/var/log/messages),有时会看到大面积的下面的报错:

nf_conntrack: table full, dropping packet

这说明系统接到了大量的连接请求,但是系统的连接跟踪表已经满了,无法再记录新的连接了。这时候,系统会丢弃新的连接请求。

在 CentOS 下,默认的连接跟踪表大小是 65536,可以通过下面的命令查看:

cat /proc/sys/net/netfilter/nf_conntrack_max

如果流量比较小,这个值是没问题的,但如果流量巨大,这个值可能就有点太小了。

解决方法

先判断连接跟踪表是否真的接近上限,再决定是否调大最大值。只要 nf_conntrack_count 接近 nf_conntrack_max,并且系统日志持续出现 table full,就可以把调大上限作为止血动作。

检查项 命令或现象 判断
当前上限 cat /proc/sys/net/netfilter/nf_conntrack_max 看系统允许记录多少连接跟踪项
当前使用量 cat /proc/sys/net/netfilter/nf_conntrack_count 看活跃连接跟踪项数量
系统日志 nf_conntrack: table full, dropping packet 表示新连接可能已经被丢弃
使用率 nf_conntrack_count / nf_conntrack_max 接近 1 时需要处理,生产中可提前预警

调大最大值可以承接更多连接,但也意味着要耗费更多资源,这点要注意。不要把这个动作理解成无成本扩容。

查看当前有多少活跃连接:

cat /proc/sys/net/netfilter/nf_conntrack_count

如果这个值跟上面介绍的 nf_conntrack_max 已经很接近了,就说明快满了,需要调大 nf_conntrack_max。可以使用下面的命令临时调大:

echo 524288 > /proc/sys/net/netfilter/nf_conntrack_max

如果不想每次重启都要重新设置,可以修改 /etc/sysctl.conf,加入下面的配置:

net.netfilter.nf_conntrack_max = 524288

为了缓解大量连接的问题,您可能还需要考虑减少服务器等待连接关闭/超时的时间。在 /etc/sysctl.conf 中加入下面的配置:

net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 60

调整超时时间要结合业务连接模型判断。短连接很多、连接状态堆积明显时,缩短部分 TCP 状态的超时时间有帮助;如果业务依赖长连接或连接保持时间较长,就不要盲目压低超时参数。

如何监控

生产环境建议把 conntrack 监控前置,而不是等系统日志刷屏之后再处理。平时使用 Categraf 监控就可以了,Categraf 提供了 input.conntrack 采集插件,可以采集 conntrack 的信息,建议采集配置如下:

conf/input.conntrack/conntrack.toml:

files = [
    "ip_conntrack_count",
    "ip_conntrack_max",
    "nf_conntrack_count",
    "nf_conntrack_max"
]

dirs = [
    "/proc/sys/net/ipv4/netfilter",
    "/proc/sys/net/netfilter"
]

# ignore errors
quiet = true

完事配置一个类似下面的监控规则即可:

conntrack_ip_conntrack_count / ip_conntrack_max > 0.8

这条规则的含义是:连接跟踪表使用率超过 80% 时预警。具体阈值可以根据业务流量波动调整,但思路是提前发现容量逼近,而不是只在丢包后报警。

另一个监控方案,是直接监控系统日志,算是一个兜底监控方案,可以采用 catpaw 来监控,catpaw 提供了 journaltail 采集插件,可以读取近期系统日志,grep 关键字,如果出现异常关键字就告警,配置如下:

conf.d/p.journaltail/journaltail.toml:

[[instances]]
# journalctl -S -${time_span}
time_span = "1m"
# relationship: or
keywords = ["Out of memory", "nf_conntrack: table full, dropping packets"]
# check rule name
check = "Critical System Errors"
# # gather interval
interval = "30s"

[instances.alerting]
## Enable alerting or not
enabled = true
## Same functionality as Prometheus keyword 'for'
for_duration = 0
## Minimum interval duration between notifications
repeat_interval = "5m"
## Maximum number of notifications
repeat_number = 3
## Whether notify recovery event
recovery_notification = true
## Choice: Critical, Warning, Info
default_severity = "Warning"

catpaw 的入门使用,可以参考文章:《太卷了,史上最简单的监控系统 catpaw 简介

常见问题

只调大 nf_conntrack_max 就够了吗?

不一定。调大上限是常见止血动作,但如果连接数异常增长来自业务流量突增、异常重试、攻击流量或连接泄漏,还需要继续分析连接来源和业务行为。

为什么同时建议监控指标和日志?

指标能提前看到使用率趋势,适合做容量预警;日志能捕捉已经发生的丢包现象,适合作为兜底告警。两者一起用更稳。

ip_conntrack_*nf_conntrack_* 都要采集吗?

不同内核和发行版暴露的路径可能不同,示例配置同时包含两类文件,是为了兼容更多系统环境。

小结

nf_conntrack: table full, dropping packet 的本质是连接跟踪表容量不足,新连接可能被系统丢弃。处理顺序是先确认 count 是否接近 max,再临时调大上限止血,随后持久化配置,并通过 Categraf 指标和系统日志告警提前发现下一次风险。

联系我们交流

延伸路径

继续看解决方案和产品对比

如果你正在做监控、可观测性或故障定位相关选型,建议从解决方案和产品对比继续往下看。

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云