nf_conntrack: table full, dropping packet.告警

背景

今晚数据库服务器收到到告警3306端口不通,登上服务器查看mysql进程正常,通过客户端也能正常连接,但是keepalived 一直检测说3306端口不通

检测日志/var/log/messages发现一直在打印”nf_conntrack: table full, dropping packet.”
通过网络查找资料,找到问题所在,

问题分析:

究其原因:nf_conntrack是一个内核模块,用于跟踪一个连接状态。连接跟踪状态可以供其他模块使用,例如state等,可通过以下查看

nf_conntrack模块会使用一个哈希表记录 tcp 通讯协议的 established connection记录,
当有大量的网站访问时,若iptables记录连接跟踪状态,就可能导出现“nf_conntrack:table full”,从而导致一系列问题。

处理办法:

关闭防火墙。 简单粗暴,直接有效

chkconfig iptables off
chkconfig ip6tables off
service iptables stop
service ip6tables stop

切记:在防火墙关闭状态下,不要通过iptables指令(比如 iptables -nL)来查看当前状态!因为这样会导致防火墙被启动,而且规则为空。虽然不会有任何拦截效果,但所有连接状态都会被记录,浪费资源且影响性能并可能导致防火墙主动丢包!

加大防火墙跟踪表的大小,优化对应的系统参数

1、状态跟踪表的最大行数的设定

理论最大值 CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (ARCH / 32)
以64G的64位操作系统为例,CONNTRACK_MAX = 64*1024*1024*1024/16384/2 = 2097152
即时生效请执行: sysctl -w net.netfilter.nf_conntrack_max=2097152
永久生效修改:/etc/sysctl.conf

2、设置跟踪连接保存5小时。

net.netfilter.nf_conntrack_tcp_timeout_established = 300

3、设置其哈希表大小

哈希表大小通常为总表的1/8,最大为1/2。CONNTRACK_BUCKETS = CONNTRACK_MAX / 8
同样64G的64位操作系统,哈希最佳范围是 262144 ~ 1048576 。
运行状态中通过 sysctl net.netfilter.nf_conntrack_buckets 进行查看,通过文件 /sys/module/nf_conntrack/parameters/hashsize 进行设置
或者新建 /etc/modprobe.d/iptables.conf ,重新加载模块才生效:
options nf_conntrack hashsize=262144

扩展

还有些相关的系统参数sysctl -a | grep nf_conntrack可以调优(/etc/sysctl.conf ):

net.netfilter.nf_conntrack_max = 1048576
net.netfilter.ip_conntrack_tcp_timeout_established = 3600
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120