Docker-Compose导致ssh连接断开的问题

一般情况下,使用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
2
sudo 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。

  1. 修改/etc/docker/daemon.json
1
2
3
{
"default-address-pools": [{"base":"10.10.0.0/16","size":24}]
}
  1. 关闭所有docker服务

  2. 删除现有网桥

    1
    sudo docker network prune

  3. 重启docker

    1
    sudo systemctl restart docker

  4. 启动所有docker服务

0%