两个容器网络互通
2018-01-05
问题
在Centos 7宿主机上安装的Docker 17.12.0-ce,启动了Gitlab和Read The Docs两个容器,两个容器通过端口映射后宿主机都可以正常访问。Read The Docs容器中Ping
Gitlab网络正常,但是用wget访问Gitlab报no route to host
错误。多方查找解法方案如下:
解决方案
快速解决
以管理员身份运行以下命令就可以快速解决问题,想了解详细信息请看下节:
nmcli connection modify docker0 connection.zone trusted
systemctl stop NetworkManager.service
firewall-cmd --permanent --zone=trusted --change-interface=docker0
systemctl start NetworkManager.service
nmcli connection modify docker0 connection.zone trusted
systemctl restart docker.service
详细说明
The explained version and how to check everything worked
The current workaround that seems to work ends up creating a trusted.xml
file AND a ifcfg-docker0
file. The trusted.xml
file would set the zone after a reboot (read and used by firewalld) and the ifcfg-docker0
would set the zone after reload or restart of services and interface or connections restarted (read and used mainly by NetworkManager).
To achieve that:
- After having the new interface (e.g. after installing Docker) and having FirewallD enabled and started, set the zone of the interface with NetworkManager’s
nmcli
:nmcli connection modify docker0 connection.zone trusted
…that would set the zone in NetworkManager and FirewallD for the current session and will create the
ifcfg-docker0
file for services, network or interfaces’ restarts and reloads. - Check that the file was created with:
cat /etc/sysconfig/network-scripts/ifcfg-docker0
…it should output something like:
DEVICE=docker0 STP=no BRIDGING_OPTS=ageing_time=299 TYPE=Bridge BOOTPROTO=none IPADDR=172.17.0.1 PREFIX=16 DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INIT=no NAME=docker0 UUID=5ccc8292-95a2-40d5-9ed6-ab6202fa629e ONBOOT=no ZONE=trusted
…specifically, it should have a:
ZONE=trusted
- Now we need FirewallD to generate that
trusted.xml
file so that it uses it while booting, but for FirewallD to write that file it must think that NetworkManager is not active, so stop NetworkManager:systemctl stop NetworkManager.service
- Now set the zone with FirewallD’s
firewall-cmd
:firewall-cmd --permanent --zone=trusted --change-interface=docker0
- As NetworkManager is stopped, it won’t modify (or even try to create) an
ifcfg-docker0
file, if NetworkManager was running it would try to create that same file and wouldn’t work after reboot. But this time, as Networkmanager is stopped, it will create a file in the other place for configurations, we can see it with:cat /etc/firewalld/zones/trusted.xml
…outputs:
<?xml version="1.0" encoding="utf-8"?>
<zone target="ACCEPT">
<short>Trusted</short>
<description>All network connections are accepted.</description>
<interface name="docker0"/>
</zone>
…we can see that the docker0
interface was added to this trusted
zone by the:
<interface name="docker0"/>
- And now we can start NetworkManager again:
systemctl start NetworkManager.service
- It is possible that you need to set the zone with NetworkManager again as
firewalld
might have “forgotten” the zone settings, it won’t do any harm:nmcli connection modify docker0 connection.zone trusted
- We can check that FirewallD thinks that the
docker0
is in thetrusted
zone. Check the zone of the docker0 interface as seen by FirewallD:firewall-cmd --get-zone-of-interface=docker0
…outputs:
trusted
- And NetworkManager also thinks that it is in the
trusted
zone. Check the zone of the docker0 interface as seen by NetworkManager:nmcli connection show docker0 | grep zone
…outputs something like:
connection.zone: trusted
-
We can restart the system and check that the zone will persist, for both FirewallD and NetworkManager.
-
If you already checked that it worked and don’t want to restart the system, you still will have to restart the Docker service for it to re-create it’s
ipatables
rules:
systemctl restart docker.service
- If you need to change more things with FirewallD and NetworkManager, or if something doesn’t seem to be working, please read that issue in FirewallD, as here I’m not showing a lot of the details: t-woerner/firewalld#195