kubernetes节点报nf_conntrack: table full, dropping packet的故障处理

问题现象

系统连接数高的时候,机子出现掉包,查看日志发现报错,nf_conntrack: table full, dropping packet。查看日志的方式如下

[root@master01 ~]# dmesg | grep nf_conntrack | more

[24849375.519322] nf_conntrack: table full, dropping packet
[24849375.519400] nf_conntrack: table full, dropping packet
[24849375.519763] nf_conntrack: table full, dropping packet
[24849375.519805] nf_conntrack: table full, dropping packet
[24849375.519872] nf_conntrack: table full, dropping packet
[24849375.519908] nf_conntrack: table full, dropping packet
[24849375.519988] nf_conntrack: table full, dropping packet
[24849375.520154] nf_conntrack: table full, dropping packet
[24849384.045235] nf_conntrack: table full, dropping packet
[24849384.052088] nf_conntrack: table full, dropping packet
[24849384.052121] nf_conntrack: table full, dropping packet
[24849384.053123] nf_conntrack: table full, dropping packet
[24849384.053180] nf_conntrack: table full, dropping packet
[24849384.053217] nf_conntrack: table full, dropping packet
[24849384.053416] nf_conntrack: table full, dropping packet

 nf_conntrack模块在kernel 2.6.15(2006-01-03发布) 被引入,支持ipv4和ipv6,取代只支持ipv4的ip_connktrack,用于跟踪连接的状态,供其他模块使用。在高并发场景下如果连接进来比释放的快,把哈希表塞满了,新连接的数据包会被丢掉,此时netfilter变成了一个黑洞,导致拒绝服务。 这发生在3层(网络层),应用程序毫无办法。

连接跟踪表溢出
连接跟踪表nf_conntrack,Linux为每个经过内核网络栈的数据包,生成一个新的连接记录项,当服务器处理的连接过多时,连接跟踪表被打满,服务器会丢弃新建连接的数据包。

1.通过dmesg可以确认是否有该情况发生

dmesg | grep nf_conntrack

dmesg | grep nf_conntrack

dmesg -T | grep nf_conntrack #可以显示时间

如果输出值中有“nf_conntrack: table full, dropping packet”,说明服务器nf_conntrack表已经被打满。

2.通过/proc文件系统查看nf_conntrack表实时状态

cat /proc/net/nf_conntrack |more

[root@master01 ~]# cat /proc/net/nf_conntrack |more
ipv4     2 tcp      6 82 TIME_WAIT src=100.117.193.145 dst=172.16.0.87 sport=32898 dport=31180 src=192.168.36.230 dst=172.16.0.87 sport=80 dport=
14417 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 53 TIME_WAIT src=100.117.193.208 dst=172.16.0.87 sport=37910 dport=31180 src=192.168.37.93 dst=172.16.0.87 sport=80 dport=3
2007 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 38 TIME_WAIT src=100.117.193.146 dst=172.16.0.87 sport=22432 dport=31180 src=192.168.36.230 dst=172.16.0.87 sport=80 dport=
48598 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 6 TIME_WAIT src=100.117.193.180 dst=172.16.0.87 sport=13256 dport=31180 src=192.168.36.230 dst=172.16.0.87 sport=80 dport=1
3256 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 3212 CLOSE_WAIT src=113.73.228.130 dst=172.16.0.87 sport=51596 dport=30890 src=192.168.39.231 dst=172.16.0.87 sport=80 dpor
t=51596 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 118 TIME_WAIT src=100.117.193.181 dst=172.16.0.87 sport=9810 dport=31180 src=192.168.36.230 dst=172.16.0.87 sport=80 dport=
26458 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 63 TIME_WAIT src=100.117.193.189 dst=172.16.0.87 sport=42000 dport=31180 src=192.168.37.93 dst=172.16.0.87 sport=80 dport=2
4601 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 31 TIME_WAIT src=100.117.193.215 dst=172.16.0.87 sport=26302 dport=31180 src=192.168.36.228 dst=172.16.0.87 sport=80 dport=
26302 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 2176 CLOSE_WAIT src=222.222.99.103 dst=172.16.0.87 sport=49375 dport=30890 src=192.168.34.202 dst=172.16.0.87 sport=80 dpor
t=49375 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 111 TIME_WAIT src=100.117.193.152 dst=172.16.0.87 sport=4624 dport=31180 src=192.168.37.94 dst=172.16.0.87 sport=80 dport=6
3170 [ASSURED] mark=0 zone=0 use=2

3.查看nf_conntrack表最大连接数

cat /proc/sys/net/netfilter/nf_conntrack_max

[root@master01 ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
262144

查看nf_conntrack表当前连接数

cat /proc/sys/net/netfilter/nf_conntrack_count

[root@master01 ~]# cat /proc/sys/net/netfilter/nf_conntrack_count
164607

查看nf_conntrack_buckets哈希表最大大小

cat /proc/sys/net/netfilter/nf_conntrack_buckets

[root@master01 ~]# cat /proc/sys/net/netfilter/nf_conntrack_buckets
65536

查看netfilter相关的内核参数

sysctl -a | grep conntrack

[root@master01 ~]# sysctl -a | grep conntrack
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.cni0.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.docker0.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
net.netfilter.nf_conntrack_acct = 0
net.netfilter.nf_conntrack_buckets = 65536
net.netfilter.nf_conntrack_checksum = 1
net.netfilter.nf_conntrack_count = 174611
net.netfilter.nf_conntrack_dccp_loose = 1
net.netfilter.nf_conntrack_dccp_timeout_closereq = 64
net.netfilter.nf_conntrack_dccp_timeout_closing = 64
net.netfilter.nf_conntrack_dccp_timeout_open = 43200
net.netfilter.nf_conntrack_dccp_timeout_partopen = 480
net.netfilter.nf_conntrack_dccp_timeout_request = 240
net.netfilter.nf_conntrack_dccp_timeout_respond = 480
net.netfilter.nf_conntrack_dccp_timeout_timewait = 240
net.netfilter.nf_conntrack_events = 1
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_expect_max = 1024
net.netfilter.nf_conntrack_generic_timeout = 600
net.netfilter.nf_conntrack_helper = 1
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_log_invalid = 0
net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_sctp_timeout_closed = 10
net.netfilter.nf_conntrack_sctp_timeout_cookie_echoed = 3
net.netfilter.nf_conntrack_sctp_timeout_cookie_wait = 3
net.netfilter.nf_conntrack_sctp_timeout_established = 432000
net.netfilter.nf_conntrack_sctp_timeout_heartbeat_acked = 210
net.netfilter.nf_conntrack_sctp_timeout_heartbeat_sent = 30
net.netfilter.nf_conntrack_sctp_timeout_shutdown_ack_sent = 3
net.netfilter.nf_conntrack_sctp_timeout_shutdown_recd = 0
net.netfilter.nf_conntrack_sctp_timeout_shutdown_sent = 0
net.netfilter.nf_conntrack_tcp_be_liberal = 0
net.netfilter.nf_conntrack_tcp_loose = 1
net.netfilter.nf_conntrack_tcp_max_retrans = 3
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 3600
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_timestamp = 0
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180
net.nf_conntrack_max = 262144

如果确认服务器因连接跟踪表溢出而开始丢包,首先需要判断是否正遭受DDOS攻击,如果是正常的业务流量造成,可以考虑调整nf_conntrack的参数
nf_conntrack_max决定连接跟踪表的大小,默认值是65536,可以根据系统内存大小计算一个合理值:CONNTRACK_MAX = RAMSIZE(in bytes)/16384/(ARCH/32),如32G内存可以设置1048576;
一个连接占用312字节内存,65536大约25M内存占用,存储在内核空间,这部分内存不能swap,当CONNTRACK_MAX为 1048576,HASHSIZE buckets为 262144 时,最多占390MB内存开销,对现在的vps服务器来说毫无压力,你用512M的vps跑业务当我没说。
nf_conntrack_buckets决定存储conntrack条目的哈希表大小,默认值是nf_conntrack_max的1/4,延续这种计算方式:BUCKETS = CONNTRACK_MAX/4,如32G内存可以设置262144;
net.netfilter.nf_conntrack_tcp_timeout_established # 决定ESTABLISHED状态连接的超时时间,默认值是5天,可以缩短到1小时,即3600,这个值基本上没什么效果,还是加上吧。
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 秒,CLOSE_WAIT是被动方收到FIN发ACK,然后会转到LAST_ACK发FIN,除非程序写得有问题,正常来说这状态持续时间很短。
net.netfilter.nf_conntrack_generic_timeout # 默认 600 秒(10分钟)通用超时设置,作用于4层(传输层)未知或不支持的协议
net.netfilter.nf_conntrack_tcp_timeout_max_retrans # 默认 300 秒
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged # 默认 300 秒
推荐bucket至少 262144,max至少 1048576,不够再继续加,或者缩短超时时间可以让netfilter更快地把跟踪的记录从哈希表里移除。
哈希表使用情况:

grep conntrack /proc/slabinfo

前面三个数字代表
当前活动对象数、当前使用对象总数、每个对象的内存占用大小(字节)

sysctl -w net.netfilter.nf_conntrack_max=1048576

echo 262144 > /sys/module/nf_conntrack/parameters/hashsize

sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600

通过sysctl -w和echo的命令,是临时生效的,重启会复原也可以编辑文件添加:

vim /etc/sysctl.conf

net.netfilter.nf_conntrack_max = 1048576

net.netfilter.nf_conntrack_tcp_timeout_established = 3600

修改后,执行sysctl -p 生效
和buckets表开机自动修改

echo "echo 262144 > /sys/module/nf_conntrack/parameters/hashsize" >> /etc/rc.d/rc.local

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忍冬行者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值