为何创建Docker网络会随机中断Jenkins服务器与Docker服务器的连接?
这是个挺典型的Docker网络与外部访问冲突的问题,结合你描述的症状——只有Jenkins服务器被断连、手动清理容器网络就恢复、随机触发——我梳理了几个最可能的原因,以及对应的调试和解决步骤:
可能的核心原因
1. Docker默认子网与Jenkins服务器子网重叠
Docker默认的bridge网络(通常是172.17.0.0/16或192.168.0.0/20这类私有网段)如果和Jenkins服务器所在的子网刚好重叠,当Docker创建网络和容器时,会自动在服务器上添加路由规则,把原本要发往Jenkins的流量误导向Docker内部网络。而你的个人电脑子网不在这个冲突范围内,所以完全不受影响。这种冲突不会每次都触发,只有当容器分配的IP刚好命中Jenkins相关的路由条目时才会爆发,所以看起来是随机的。
2. Docker自动生成的iptables规则干扰了SSH访问
Docker会自动管理服务器的iptables规则来处理容器的网络转发,偶尔在创建/销毁容器网络时,会意外生成拒绝Jenkins服务器IP访问的规则,或者覆盖了原本允许SSH(22端口)访问的规则。由于你的个人电脑IP不在这些错误规则的拦截范围内,所以还能正常连接。
3. Conntrack连接跟踪表溢出
Red Hat 7上的conntrack模块负责跟踪网络连接状态,如果容器创建的连接过多,加上Jenkins保持的SSH长连接,可能会把conntrack表撑满,导致新的连接(包括Jenkins的重试连接)无法建立。而你的个人电脑连接属于新发起的短连接,可能刚好避开了表满的瞬间,或者conntrack的清理机制对长连接更不友好,优先丢弃了Jenkins的连接。
分步调试与解决
1. 排查子网冲突
首先在Docker服务器上执行:
docker network inspect bridge
查看默认bridge网络的Subnet字段,比如"Subnet": "172.17.0.0/16"。然后确认Jenkins服务器的IP所在的子网,看是否有重叠。
如果确实重叠,修改Docker默认子网:
- 编辑
/etc/docker/daemon.json(没有就新建),添加自定义子网:{ "bip": "192.168.200.1/24" } - 重启Docker服务:
systemctl restart docker
之后再运行Jenkins任务,观察是否还会出现断连问题。
2. 对比iptables规则变化
在问题出现的瞬间,立刻在Docker服务器上导出当前iptables规则:
iptables-save > /tmp/iptables-broken.txt
手动清理容器和网络后,再导出正常状态的规则:
iptables-save > /tmp/iptables-normal.txt
用diff命令对比两个文件:
diff /tmp/iptables-broken.txt /tmp/iptables-normal.txt
重点关注INPUT、FORWARD链中针对Jenkins服务器IP的规则,看是否有新增的拒绝条目,或者允许SSH的规则被删除/修改。
你也可以实时监控iptables规则变化,触发Jenkins任务时执行:
watch -n 1 iptables -L -n
观察规则在容器创建前后的变化,定位异常规则。
3. 检查Conntrack状态
问题出现时,执行以下命令查看当前连接数和最大限制:
# 当前连接数 conntrack -L | wc -l # 最大限制 sysctl net.netfilter.nf_conntrack_max
如果当前连接数接近最大值,说明是conntrack溢出。可以临时调大限制:
sysctl -w net.netfilter.nf_conntrack_max=131072
要永久生效,把配置写入/etc/sysctl.conf:
echo "net.netfilter.nf_conntrack_max=131072" >> /etc/sysctl.conf sysctl -p
同时检查长连接超时参数:
sysctl net.netfilter.nf_conntrack_tcp_timeout_established
如果默认的432000秒(5天)被改短了,建议改回默认值,避免Jenkins的SSH长连接被提前清理。
4. 监控SSH连接状态
当Jenkins任务停滞时,在Jenkins服务器上执行:
netstat -anp | grep <Docker服务器IP>
查看连接状态(比如SYN_SENT表示正在尝试连接但没响应,FIN_WAIT2表示连接被异常断开)。同时在Docker服务器上执行:
ss -anp | grep <Jenkins服务器IP>
对比两端的连接状态,确认是哪一端主动断开了连接。
临时缓解方案
在Jenkins的SSH执行步骤中,不管任务成功还是失败,都添加清理命令:
docker-compose down -v
确保每次任务结束后,容器、网络和卷都被彻底移除,避免残留的网络规则影响后续连接。另外,不要使用Docker默认的bridge网络,手动创建自定义网络并在docker-compose.yml中指定:
docker network create --subnet 192.168.201.0/24 my-project-net
在docker-compose.yml中添加:
networks: default: external: name: my-project-net
内容的提问来源于stack exchange,提问作者vctls

