1. 问题描述
如图,我的两个docker服务service1和service2位于同一台服务器上,当service1调用service2时,报错:
Failed to establish a new connection: [Errno 113] No route to host'
2. 原因分析
- 我是在centos服务器上创建的docker容器,其网络模式采用的是bridger模式。
- 启动docker时,docker进程会创建一个名为docker0的虚拟网桥,用于宿主机与容器之间的通信。当启动一个docker容器时,docker容器将会附加到虚拟网桥上,容器内的报文通过docker0向外转发。
- 如果docker容器访问宿主机,那么docker0网桥将报文直接转发到本机,报文的源地址是docker0网段的地址。
- 而如果docker容器访问宿主机以外的机器,docker的SNAT网桥会将报文的源地址转换为宿主机的地址,通过宿主机的网卡向外发送。
- 因此,当docker容器访问宿主机时,宿主机服务端口会被防火墙拦截,从而无法连通宿主机,出现No route to host的错误。
- 而访问宿主机所在局域网内的其他机器,由于报文的源地址是宿主机ip,因此不会被目的机器防火墙拦截,所以可以访问。
3. 解决办法
解决办法有两种:
- 在防火墙上开放指定端口(推荐),本文中的示例端口号为8033
firewall-cmd --zone=public --add-port=8033/tcp --permanent
firewall-cmd --reload
- 关闭防火墙
systemctl stop firewalld
4. 总结
- 我在服务器A上部署的服务调用其他服务器上的服务,比如服务器B的service3服务,是没有问题的,报文的源地址会转换为宿主机的地址;
- 但是如果我访问宿主机的服务,即服务器A上其他容器的服务,报文的源地址是docker0网段的地址,宿主机服务端口会被防火墙拦截,从而出现No route to host的错误,需要在防火墙上开放指定端口来解决。