centos7 docker 容器訪問宿主機的 ip 配置問題

場景描述

centos7 運行 docker 容器應用時,須要鏈接宿主機的 mysql3306 端口,發現鏈接不上,docker 容器沒法訪問宿主機的 mysql 數據庫。可是,在容器內訪問外部網絡是能夠 ping 通的。mysql

緣由分析

centos7 上部署 docker 容器,其網絡模式採用的是 bridge 模式。
啓動 docker 時,docker 進程會建立一個名爲 docker0 的虛擬網橋,用於宿主機與容器之間的通訊。當啓動一個 docker 容器時,docker 容器將會附加到虛擬網橋上,容器內的報文經過 docker0 向外轉發。sql

若是 docker 容器訪問宿主機,那麼 docker0 網橋將報文直接轉發到本機,報文的源地址是 docker0 網段的地址。而若是 docker 容器訪問宿主機之外的機器,dockerSNAT 網橋會將報文的源地址轉換爲宿主機的地址,經過宿主機的網卡向外發送。docker

所以,當 docker 容器訪問宿主機時,若是宿主機服務端口會被防火牆攔截,那麼就沒法連通宿主機,出現 No route to host 的錯誤。數據庫

而訪問宿主機所在局域網內的其餘機器,因爲報文的源地址是宿主機 ip,所以,不會被目的機器防火牆攔截,因此能夠訪問。centos

解決問題

首先設置了 mysql 的配置文件,保證 mysql 能夠被任何 ip 訪問:安全

[mysqld]
bind-address = 0.0.0.0

修改完配置文件重啓生效。
但爲了安全考慮,防火牆的 3306 端口仍然是不開放外網訪問的。 bash

容器訪問宿主機的地址使用 eth0 的地址,即宿主機內網 ip 地址。
運行 ipconfig 命令,查看網絡的虛擬網橋相關信息。 網絡

注意:宿主機會把容器 ip 地址段當成外網 ip。(當前說明是 centos7 環境)測試

編輯防火牆文件 /etc/firewalld/zones/public.xml,添加下面 docker0 地址段到配置:centos7

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

重啓防火牆,docker 容器便可正常訪問宿主機端口。

service firewalld restart

🎨 若是有用到 docker-compose 命令,則會自動建立一個名爲 br-"docker network id" 的虛擬網橋。
🎨 此時一樣須要將虛擬網橋地址段配置到防火牆白名單,才能正常訪問,添加配置:

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

image

測試端口

在容器中測試宿主機端口是否能夠鏈接,可使用 wget 內網ip:端口 命令。

$ wget 172.17.25.162:3306  
wget: can not connect to remote host (172.17.25.162): Host is unreachable  #不能夠鏈接

$ wget 172.17.25.162:3306
wget: bad header line: 5.7.29-log  #能夠鏈接
相關文章
相關標籤/搜索