过程记录
某次部署完服务,我当时调试的时候好好的,后面用户反应服务挂了。我上去看发现是所有的中间件和服务之间都无法相互访问(服务都部署在docker里了)。仔细检查发现是网络不通,关掉防火墙以后服务就通了。即使我在firewalld中放行了对应的端口也没用。
各种搜索+问AI以后,提示有可能跟docker的bridge网络和iptables有关,于是确认了一下现状,内核好像没有加载一个叫做br_netfilter的模块,内核参数net.bridge.bridge-nf-call-iptables也没有开启,把这两个问题解决以后,网络就通了。
ini
# 操作系统信息
NAME="Kylin Linux Advanced Server"
VERSION="V10 (Halberd)"
ID="kylin"
VERSION_ID="V10"
PRETTY_NAME="Kylin Linux Advanced Server V10 (Halberd)"
ANSI_COLOR="0;31"
# 硬件信息
Linux localhost.localdomain 4.19.90-89.26.v2401.ky10.x86_64 #1 SMP Tue Sep 23 16:08:37 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
现状确认
perl
# 确认br_netfilter模块是否已经开启
lsmod | grep br_netfilter
# 没有任何输出= =!
# 确认bridge网络是否开启啦iptables
sysctl -p
# 没有net.bridge.bridge-nf-call-iptables = 1 这行信息的输出
解决步骤
bash
# 1. 确保firewalld放行public区域的3306
firewall-cmd --permanent --zone=public --add-port=3306/tcp
firewall-cmd --reload
# 2. 修复Docker与firewalld冲突(关键步骤!)
echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf
sysctl -p
# 解决报错:sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: 没有那个文件或目录
# 临时加载模块
modprobe br_netfilter
# 永久生效(重启后不丢失)
echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf
# 添加必需的 sysctl 参数
cat > /etc/sysctl.d/99-docker-bridge.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1
EOF
# 重新加载所有参数
sysctl -p /etc/sysctl.d/99-docker-bridge.conf
# 验证iptables是否正常开启
sysctl net.bridge.bridge-nf-call-iptables
# 应返回:net.bridge.bridge-nf-call-iptables = 1
# 重启docker服务
systemctl restart docker
# 最后重新telnet服务就通了
总结
这次的问题主要是br_netfilter这玩意没有开,导致Docker bridge 网络运行在防火墙之外(所以我在防火墙的配置完全影响不到docker的服务,网络该断的还是断了)。Docker和Linux的网络通信过程有点复杂,以后有时间有兴趣再研究吧~
PS:某麒麟系统跟Docker的坑已经踩了不少了,之前还有升级完内核导致服务全部都起不来的,一直无法解决,只得切换到podman才没问题。以后如果再弄信创的项目,还是优先尝试用一下podman吧