一般情况下,使用docker-compose不会出现网络问题,但是我遭遇的这个情况比较特殊,故记录之。
我遭遇的情况是:通过172.17.0.0网段的客户端访问具有Internet地址的ssh服务器,此情况使用docker或docker-compose都会导致ssh连接断开。这种情况常见于单位内部使用172.17.0.0网段的私有地址部署局域网,管理员通过ssh管理本单位的Internet服务器的时候。
安装docker导致ssh断开连接
其原因为docker安装完成时,立刻生成docker0网桥。由于ssh服务器是Internet地址,故docker认为默认的网段172.17.0.0/16
不会与宿主机冲突,所以分配给docker0网桥的地址是172.17.0.1
。然而,因为局域网主机全是172.17.0.0/16
,故从该服务器到局域网的所有流量均会被发送到docker0,导致ssh断开连接。
这个问题比较容易定位,解决方案也很直观。打开/lib/systemd/system/docker.service
,在ExecStart=...
这一行末尾添加--bip "172.18.0.1/16"
然后运行下面的命令重启docker即可: 1
2sudo systemctl daemon-reload
sudo systemctl restart docker
使用docker-compose启动容器时导致ssh断开连接
其原因为使用docker-compose启动一组容器会共用一个全新的网桥,docker-compose也认为默认的网段172.17.0.0/16
不会与宿主机冲突,且docker0居然不用,所以不用白不用,所以你懂的,于是ssh挂了!
解决方案:添加一条到局域网的路由,这等于报告docker和docker-compose172.17.0.0/16
这个网段已经有用了,你两悠着点。
首先使用route
命令查看默认网关,一般是与主机IP地址同网段的xxx.xxx.xxx.254这个地址。
然后使用如下命令添加一条路由。
1 | sudo route add -net 172.17.0.0 netmask 255.255.0.0 gw <默认网关> |
现在在使用docker-compose就不会导致ssh断开连接了。
合并两个问题
其实只要我们添加了这一条路由,那么也就不用在/lib/systemd/system/docker.service
,中添加--bip "172.18.0.1/16"
了。
固化配置
若上述测试没有问题了,那么将命令 1
route add -net 172.17.0.0 netmask 255.255.0.0 gw <默认网关>
写入/etc/rc.local
即可永远生效。
未解决的地方
不知为何偶尔使用docker-compose还是会导致断网,此时检查路由表发现上述命令添加的路由表已经丢失。
所以,运行docker-compose之前最好确认路由表中记录是否在,不在的话,手动重新添加一下。
参考连接
docker-compose network creation kicks me out of ssh
最新解决方案
之前的解决方案还是有问题。因为企业大了,网络复杂,整个局域网其实不止用到172.17.*.*
这个网段。所以当服务起来之后,如果占用了172.18.*.*
,而有客户端在这个网段的话,这个客户端将无法访问服务。
所以最终的方案是更换地址池到A类IP。
- 修改
/etc/docker/daemon.json
1 | { |
关闭所有docker服务
删除现有网桥
1
sudo docker network prune
重启docker
1
sudo systemctl restart docker
启动所有docker服务