Linux 出现 “nf_conntrack: table full, dropping packet” 如何快速释放并永久调优

10次阅读

nf_conntrack: table full 是因连接跟踪表满导致丢包,主因是 nf_conntrack_max 过小或连接回收慢;可临时用 conntrack -F 清空,长期需调大上限、缩短超时、启用 GC 并优化容器与内核兼容性。

Linux 出现 “nf_conntrack: table full, dropping packet” 如何快速释放并永久调优为什么会出现 nf_conntrack: table full, dropping packet

这是内核.netfilter 的连接跟踪表(conntrack table)被填满导致的丢包,常见于高并发短连接场景(如 http 轮询、NAT 网关、kubernetes Service 流量),或连接未及时回收(TIME_WaiT 过长、客户端不主动关闭等)。本质不是“内存不够”,而是 nf_conntrack_max 设定值太小,或连接生命周期过长导致条目积。

如何快速清空 conntrack 表并验证是否生效

紧急情况下先缓解丢包,再调参:

  • 执行 sudo conntrack -F 清空当前所有连接跟踪条目(注意:会中断所有已建立的 NAT/iptables 相关连接,生产环境慎用)
  • 查看实时使用量:conntrack -C(返回数字,如 65432);对比上限:cat /proc/sys/net/netfilter/nf_conntrack_max
  • 观察是否还在丢包:dmesg -T | grep "nf_conntrack: table full",清空后短期内不应再出现
  • 若需只删特定协议/状态(更安全),例如删掉所有 INVALID 状态:sudo conntrack -D --state INVALID

永久调优:增大上限 + 缩短超时 + 防止泛洪

仅改 nf_conntrack_max 不够,必须配合超时参数和连接清理策略,否则新表很快又满:

  • 增大最大连接数:写入 /etc/sysctl.conf,例如 net.netfilter.nf_conntrack_max = 131072(建议设为内存 MB 数 × 16,但不超过 655360)
  • 缩短非活跃连接存活时间:net.netfilter.nf_conntrack_tcp_timeout_established = 43200(默认 432000 秒=5 天,可缩到 12 小时)
  • 对短连接更激进些:降低 FIN_WAIT 和 TIME_WAIT 超时,例如 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
  • 启用自动垃圾回收(关键):net.netfilter.nf_conntrack_gc_interval = 30(每 30 秒触发一次扫描清理)
  • 应用配置:sudo sysctl -p,确认生效:sysctl net.netfilter.nf_conntrack_max

容易被忽略的隐患点

很多运维只调大 nf_conntrack_max,却没意识到:

  • 容器环境(如 docker、Kubernetes)默认共享宿主机 conntrack 表,一个 Pod 的大量连接就能打爆整个节点 —— 建议在 kube-proxy 中启用 --conntrack-max-per-core 或直接切换到 IPVS 模式
  • nf_conntrack_buckets(哈希桶数量)默认是 nf_conntrack_max / 4,若该值过小会导致哈希冲突升高、查找变慢,可手动设为质数,如 net.netfilter.nf_conntrack_buckets = 65536
  • 某些云厂商(如 AWS ENA、azure Accelerated Networking)驱动不兼容旧内核的 conntrack 回收逻辑,升级内核或打补丁比调参更治本
text=ZqhQzanResources