最近看到一个case,是运行了高负载docker应用的主机上,nf_conntrack报告table full。其实这是一个老问题了,原因是docker在处理容器网络的时候,默认会用nat的方式,也就是容器里面看到的地址空间是一个私有地址,需要操作系统iptables/nftables来转换。而这个转化,就需要nf_conntrack来追踪和支持。
也没什么太好的解决办法,要么就用host network,绕过nat,要么就用no tracking的方式,让iptables别记录nf_conntrack。总之没有什么特别好的办法。
openshift是一个容器平台,那么openshift上是怎么处理的呢?我们实际来看看。
# 可以看到,openshift上,对应vxlan的通讯,不进行nf_conntrack的追踪,也就是说,对于vxlan的通讯,不会被记录在nf_conntrack中。
iptables -L -v -n -t raw
# Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
# pkts bytes target prot opt in out source destination
# 88M 39G OPENSHIFT-NOTRACK all -- * * 0.0.0.0/0 0.0.0.0/0 /* disable conntrack for vxlan */
# Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
# pkts bytes target prot opt in out source destination
# 87M 54G OPENSHIFT-NOTRACK all -- * * 0.0.0.0/0 0.0.0.0/0 /* disable conntrack for vxlan */
# Chain OPENSHIFT-NOTRACK (2 references)
# pkts bytes target prot opt in out source destination
# 0 0 CT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:4789 NOTRACK
# 统计总的连接跟踪数
conntrack -L -o extended | wc -l
# conntrack v1.4.4 (conntrack-tools): 760 flow entries have been shown.
# 760
# 统计 TCP 协议各个状态的连接跟踪数
conntrack -L -o extended | awk '/^.*tcp.*$/ {sum[$6]++} END {for(i in sum) print i, sum[i]}'
# conntrack v1.4.4 (conntrack-tools): 774 flow entries have been shown.
# LAST_ACK 1
# CLOSE 78
# ESTABLISHED 428
# SYN_SENT 1
# TIME_WAIT 214
# 统计各个源 IP 的连接跟踪数
conntrack -L -o extended | awk '{print $7}' | cut -d "=" -f 2 | sort | uniq -c | sort -nr | head -n 10
# conntrack v1.4.4 (conntrack-tools): 805 flow entries have been shown.
# 226 10.128.0.1
# 225 192.168.7.73
# 74 192.168.7.71
# 68 10.128.0.36
# 61 172.30.0.10
# 38 127.0.0.1
# 13 10.128.0.16
# 10 10.128.0.34
# 7 10.128.0.39
# 5 10.128.0.9
# 如果没有conntrack的话,可以用下面的命令来查看
awk -F'=' '{c[$2]++} END {for ( i in c) print i,c[i]}' /proc/net/nf_conntrack | sort -g -k 3
# ...ignored...
# 10.128.0.16 dst 13
# 10.128.0.37 dst 14
# 10.128.0.43 dst 27
# 127.0.0.1 dst 38
# 192.168.7.71 dst 62
# 10.128.0.36 dst 67
# 0000:0000:0000:0000:0000:0000:0000:0001 dst 208
# 192.168.7.73 dst 220
# 10.128.0.1 dst 230
# 如果链接数量太大的话,用下面的命令先把链接信息导出来,然后在别的机器上排序
awk -F'=' '{print $2}' /proc/net/nf_conntrack > list
awk '{c[$1]++} END {for ( i in c) print i,c[i]}' list | sort -g -k 2
-
https://blog.cloudflare.com/conntrack-turns-a-blind-eye-to-dropped-syns/
-
https://blog.cloudflare.com/conntrack-tales-one-thousand-and-one-flows/
-
https://blog.longwin.com.tw/2018/07/linux-nf-conntrack-table-full-drop-packet-2018/
-
https://www.reddit.com/r/docker/comments/iq04tw/nated_containers_conntrack_table_full_inside/
-
https://forum.proxmox.com/threads/how-to-disable-nf_conntrack-completely.17957/
-
https://blog.csdn.net/chunnidong6528/article/details/100975427
-
https://www.redhat.com/en/blog/mitigate-tcp-syn-flood-attacks-red-hat-enterprise-linux-7-beta