Jusene's Blog

记一次压测服务器丢包故障排错 nf_conntrack

字数统计: 531阅读时长: 2 min
2020/10/29 Share

背景

测试部门压测,线上服务都是采用kubernetes服务部署,汇报压测数据上不去,开始尝试调整pod数量来解决,而结果并没有改变,开始排查服务器,服务器压力都不大,开始排查日志,dmesg,其中一条error引起了注意。

1
kernel: nf_conntrack: table full, dropping packet.

拒绝服务了 …

nf_conntrack是什么

nf_conntrack是内核netfilter模块用于跟踪链接状态,结合kubernetes的网络应用场景,kubernetes的kube-proxy的ipvs模式,ipvs只是采用了更快的反向代理模式(hash查找),比iptables规则的线性查找更加快速,但是容器与外界的通信必少不了iptables的nat功能参与。

nf_conntrack用hash表记录已建立的连接,如果连接进来比释放的快,把hash表塞满,新连接的数据包会被丢掉,此时netfilter变成了一个黑洞,导致拒绝服务,这发生在3层(网络层),应用程序毫无办法。

centos7默认加载该模块,ubuntu默认不加载,而我们用的是centos7

相关内容

超时的相关参数:

1
sysctl -a | grep conntrack | grep timeout
2
net.netfilter.nf_conntrack_generic_timeout = 600
3
net.netfilter.nf_conntrack_icmp_timeout = 30
4
net.netfilter.nf_conntrack_tcp_timeout_close = 10
5
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3600
6
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
7
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
8
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
9
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
10
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
11
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
12
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
13
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
14
net.netfilter.nf_conntrack_udp_timeout = 30
15
net.netfilter.nf_conntrack_udp_timeout_stream = 180

超时时间 = 连接在哈希表里保留的时间

当前跟踪的连接数:

1
sysctl net.netfilter.nf_conntrack_count
2
net.netfilter.nf_conntrack_count = 1166

查看每个连接的详情:

1
cat /proc/net/nf_conntrack

哈希表大小

1
sysctl net.netfilter.nf_conntrack_buckets
2
net.netfilter.nf_conntrack_buckets = 32768

最大跟踪连接数,默认 nf_conntrack_buckets * 4

1
sysctl net.netfilter.nf_conntrack_max
2
net.netfilter.nf_conntrack_max = 131072
3
4
sysctl net.nf_conntrack_max
5
net.nf_conntrack_max = 131072

tunning 优化

知道问题,无非两种解决方案:

  • 加大buckets和conntrack的数量
  • 优化超时事件,加速移除bucket

通常推荐bucket至少 262144,max至少 1048576,不够再继续加

通常挥手状态不重要:

  • net.netfilter.nf_conntrack_tcp_timeout_fin_wait # 默认 120 秒
  • net.netfilter.nf_conntrack_tcp_timeout_time_wait # 默认 120 秒
  • net.netfilter.nf_conntrack_tcp_timeout_close_wait # 默认 60 秒
  • net.netfilter.nf_conntrack_tcp_timeout_established # 默认 432000 秒(5天)

这里我挑大了bucket和max的值进行解决

CATALOG
  1. 1. 背景
  2. 2. nf_conntrack是什么
    1. 2.1. 相关内容
  3. 3. tunning 优化