容器外网通信中止由nf_conntrack表满导致,需三步处理:秒级恢复(清理INVALID/UNREPLIED连接并临时扩容)、精准定位(查容器IP及UDP/DNS占比)、长效加固(NOTRACK绕过、缩短超时、禁用ALG)。
容器向外通信中止,且日志里反复出现 nf_conntrack: table full, dropping packet,说明内核连接跟踪表已耗尽,新出向连接(如 dns 查询、http 请求)的 syn 包被静默丢弃——不是容器或应用挂了,是 conntrack 资源卡死。解决要分三步走:立刻恢复通信、查清谁在撑爆表、长期避免复发。
秒级恢复容器外网通信
别等重启或重载 Docker,先让流量通起来:
- 清理无效连接条目(不中断已有业务):
sudo conntrack -D --state INVALID,UNREPLIED
这能快速释放数百至上万条“僵尸”连接,尤其对 DNS 短连接风暴或探测包残留很有效。 - 临时扩大上限(按宿主机内存估算):
例如 16GB 内存机器,执行:sudo sysctl -w net.netfilter.nf_conntrack_max=262144sudo sysctl -w net.netfilter.nf_conntrack_buckets=65536 - 确认生效:
conntrack -C查当前用量,cat /proc/sys/net/netfilter/nf_conntrack_max看是否已更新。
定位容器侧真实压占源
表满很少是单纯并发高,多是容器行为异常或配置失当:
- 查哪些容器 IP 占连接最多:
conntrack -L | awk '{print $7}' | cut -d= -f2 | sort | uniq -c | sort -nr | head -5
结果里的 IP 若对应某容器的 veth 或 bridge 地址,就锁定问题容器。 - 看协议分布(常见罪魁是 UDP/DNS):
conntrack -L | awk '{print $3}' | sort | uniq -c | sort -nr
若 udp 占比超 70%,大概率是容器内未设 DNS 超时或频繁轮询解析。 - 检查容器是否开启大量短连接又不复用(如 Python requests 不带 session、Node.js 未配 keepalive);也可进容器跑
ss -tan | wc -l对比宿主机 conntrack 数,判断是否真由该容器引发。
针对性加固容器网络环境
永久解决不能只调大数值,得从架构和配置上减负:
- 给容器通信绕过 conntrack(最有效):
在宿主机加 raw 规则,跳过本机发出的出向流量:sudo iptables -t raw -A OUTPUT -m conntrack ! --ctstate RELATED,ESTABLISHED -j NOTRACK
这条规则让新连接不进跟踪表,但保留已建立连接状态,不影响 NAT 和健康检查。 - 缩短 TCP 超时(尤其 time_wait):
在/etc/sysctl.conf加:net.netfilter.nf_conntrack_tcp_timeout_time_wait = 60net.netfilter.nf_conntrack_tcp_timeout_established = 3600 - Docker 场景额外注意:
禁用无用 ALG(如echo 'install nf_conntrack_ftp /bin/true' >> /etc/modprobe.d/blacklist.conf);
确保/etc/docker/daemon.json中没开"iptables": true(Docker 20.10+ 默认 false,开了会强制插入 conntrack 规则)。
容器外网中断背后往往是连接跟踪资源枯竭,而不是网络不通。重点不在扩容,而在识别并阻断无效连接生成路径。调参 + NOTRACK + ALG 清理,三者配合才能真正稳住。

















