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