欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

详解如何解决docker容器无法通过IP访问宿主机问题

程序员文章站 2022-04-25 17:15:22
问题起源 在使用 docker 的过程中我不幸需要在 docker 容器中访问宿主机的 80 端口, 而这个 80 端口是另外一个容器 8080 端口映射出去的. 当...

问题起源

在使用 docker 的过程中我不幸需要在 docker 容器中访问宿主机的 80 端口, 而这个 80 端口是另外一个容器 8080 端口映射出去的. 当我在容器里通过 docker 的网桥 172.17.0.1 访问宿主机时, 居然发现:

curl: (7) failed to connect to 172.17.0.1 port 80: no route to host

查找问题原因

可以确定的是容器与宿主机是有网络连接的, 因为可以在容器内部通过 172.17.0.1 ping 通宿主机:

root@930d07576eef:/# ping 172.17.0.1
ping 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.130 ms

也可以在容器内部访问其它内网和外网.

iptables 显示也允许 docker 容器访问:

# iptables --list | grep docker
docker-isolation all -- anywhere       anywhere      
docker   all -- anywhere       anywhere      
chain docker (1 references)
chain docker-isolation (1 references)

之后在查找一些资料后发现这个问题:no route to host network request from container to host-ip:port published from other container.

解释

正如 docker community forms 所言, 这是一个已知的 bug, 宿主机的 80 端口允许其它计算机访问, 但是不允许来自本机的 docker 容器访问. 必须通过设置 firewalld 规则允许本机的 docker 容器访问.

gypark 指出可以通过在 /etc/firewalld/zones/public.xml 中添加防火墙规则避免这个问题:

<rule family="ipv4">
  <source address="172.17.0.0/16" />
  <accept />
</rule>

注意这里的 172.17.0.0/16 可以匹配 172.17.xx.xx ip 段的所有 ip.

之后重启下防火墙:

systemctl restart firewalld

之后就可以在 docker 容器内部访问宿主机 80 端口.

其它问题

实际上当我又用 vmware 新开了一台虚拟机希望能重现这个问题的时候, 发现在新的虚拟机上居然没有类似的问题. 也就是说容器可以直接通过172.17.0.1访问宿主机 80 端口, 查看防火墙配置也没看到有172.17.xx.xx的白名单.
猜测是由于在新的虚拟机安装的 docker 是 docker version 1.12.5, build 047e51b/1.12.5, 也就是 red hat 从 docker 开源版本迁出开发的版本, 而之前的是 docker version 17.06.2-ce, build cec0b72 属于 docker-ce, 可能是 docker 版本有差异, red hat 顺便把那个 known bug 修复了.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。