故障描述
客户端访问Web时出现超时(time out);服务端的系统日志/var/log/messages打印“kernel: nf_conntrack: table full, dropping packet”。
故障原因
iptables的connection-tracking模块使用一部分系统内存来跟踪表中的连接。系统日志打印的“nf_conntrack: table full, dropping packet”表明连接跟踪表conntrack已满,无法为新连接创建条目并记录跟踪,进而出现“dropping packet”丢包问题。
解决步骤
解决方案是为连接跟踪表增加条目容量。
CentOS 6系列操作系统解决步骤
- 查看连接跟踪表conntrack的容量参数nf_conntrack_max。执行以下命令:
sysctl net.netfilter.nf_conntrack_max
- 检查当前跟踪的连接数参数,如果该值达到nf_conntrack_max值则会出现丢包现象。执行以下命令:
cat /proc/sys/net/netfilter/nf_conntrack_count
- 增加连接跟踪表的容量参数(以内存为64G,net.netfilter.nf_conntrack_max值2097152为例)。
- 执行以下命令,使配置即时生效。
sysctl -w net.netfilter.nf_conntrack_max=2097152
- 执行以下命令,确保系统重启后配置仍生效。
echo "net.netfilter.nf_conntrack_max = 2097152" >> /etc/sysctl.conf
- 如果conntrack表中容量显著增加,则还应增加存储conntrack的哈希表大小以提高效率。CentOS 6及以上版本中,计算公式是hashsize = conntrack_max/4。设置哈希大小,执行以下命令:
echo "options nf_conntrack expect_hashsize=524288 hashsize=524288" >> /etc/modprobe.conf
- 重启iptables,执行以下命令:
service iptables restart
CentOS 7系列操作系统解决步骤
- 在/etc/modprobe.d/firewalld-sysctls.conf中设置conntrack的哈希值,执行以下命令:
echo "options nf_conntrack expect_hashsize=131072 hashsize=131072" >> /etc/modprobe.d/firewalld-sysctls.conf
- 重启firewalld,执行以下命令:
systemctl restart firewalld
- 确认参数修改成功,执行以下命令:
sysctl -a |grep nf_conntrack_max
其他说明
- 本文操作适用于CentOS系统,且系统已开启主机防火墙。其他Linux系统可能存在差异。
- 本文操作涉及修改CentOS系统内核参数。在线修改内核参数可能会使内核不稳定,建议修改后重启系统。请评估风险后再操作。
注意.net.netfilter.nf_conntrack_max并不是越高越好,通常需要根据内存大小进行设置。nf_conntrack_max计算公式(64位)为:CONNTRACK_MAX = RAMSIZE (in bytes)/16384/2。