解決 docker 容器沒法經過 IP 訪問宿主機問題

問題起源

在使用 docker 的過程當中我不幸須要在 docker 容器中訪問宿主機的 80 端口, 而這個 80 端口是另一個容器 8080 端口映射出去的. 當我在容器裏經過 docker 的網橋 172.17.0.1 訪問宿主機時, 竟然發現:docker

curl: (7) Failed to connect to 172.17.0.1 port 80: No route to host

查找問題緣由

能夠肯定的是容器與宿主機是有網絡鏈接的, 由於能夠在容器內部經過 172.17.0.1 Ping 通宿主機:bash

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.curl

解釋

正如 Docker Community Forms 所言, 這是一個已知的 Bug, 宿主機的 80 端口容許其它計算機訪問, 可是不容許來自本機的 Docker 容器訪問. 必須經過設置 firewalld 規則容許本機的 Docker 容器訪問.
gypark 指出能夠經過在 /etc/firewalld/zones/public.xml 中添加防火牆規則避免這個問題:ui

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

注意這裏的 172.17.0.0/16 能夠匹配 172.17.xx.xx IP 段的全部 IP.
以後重啓下防火牆:url

systemctl restart firewalld

以後就能夠在 docker 容器內部訪問宿主機 80 端口.rest

其它問題

實際上當我又用 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 修復了.code

相關文章
相關標籤/搜索