記一次Docker網橋模式無法訪問宿主機: 故障排除經歷
- 2019 年 10 月 8 日
- 筆記
背景:
之前做了一個項目,需要在容器內訪問宿主機提供的Redis 服務(這是一個比較常見的應用場景哈), 常規方案:
① 主機網路(docker run –network=host): 完全應用主機網路堆棧,在容器內localhost就是指向宿主機
② 網橋網路(docker run –network=bridge): 這也是docker容器默認的網路通訊模式,容器內localhost 指向的是容器自身,不能使用 localhost 訪問宿主機上localhost:6379承載的Redis服務 。
docker會默認建立docker0 網橋;
網橋有一個網關ip, 有一個子網段; 網橋內容器從子網段中確定容器ip( ip addr eth0), 網橋內容器可通過 service name相互訪問;
網橋內容器通過 docker0 Getway得以訪問外網。
我們不做騷操作,肯定還是沿用常見的②網橋模式:
第一步:自定義網橋並應用該自定義網橋
docker network create --gateway 172.16.1.1 --subnet 172.16.1.0/24 app_bridge
docker run --network=app_bridge --name ......
# 以下截取自docker-compose.yml文件
...... networks: default: name: app_bridge external: true
為啥不利用默認docker0網橋?
本文開頭已講: docker0 是默認網橋,新建的容器默認都會加入這個網橋,所以我們需要建立一個專屬於本程式的網橋app_bridge
第二步:容器內建立 對應於宿主機的別名
為實現在容器內網橋模式訪問宿主機localhost:6379 的服務, 必須搭配docker 提供的 –add-host 選項(對應到docker-compose.yml這個配置是extra_host
)。
docker run 的–add-host 選項能在 容器 /etc/hosts 文件增加行記錄,便於我們使用該名稱訪問其他網路。
docker run -it --add-host dockerhost:172.16.1.1 ubuntu cat /etc/hosts 172.17.0.22 09d03f76bf2c fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback 172.16.1.1 dockerhost
之後在程式的配置文件即可應用 dockerhost:6379 訪問宿主機Redis服務。
—————————————— 稍熟悉docker網路模型的朋友都能理所當然完全上述操作—————————————————–
一個狀況:
我在公司CentOS7機器上使用上述操作, 容器內一直無法連通宿主機(容器間還是能正常訪問)。
簡化問題測試:新建容器,在容器內嘗試ping docker0 網關, 嗶了狗了,4台公司機器都ping不通docker0網關,外網還是正常訪問。
那這個問題就成了: 使用默認的docker0網橋,容器內無法ping通docker0網關,進而無法訪問宿主機。
呀呀呀呀, 八成是公司機器的配置問題,好慌,我是一個linux 小白,我是一個linux 小白,我是一個linux 小白 ~。。~
追問了公司運維,發現:
Chain INPUT (policy DROP)
INPUT鏈的預設策略是 丟棄,就是本機默認不接受任何連接,除非滿足下面的INPUT 鏈策略。
這個策略的初衷是為了 伺服器安全(尼瑪, 導致容器訪問宿主機的基礎能力都沒有了!!!)。
運維方案:
-
service iptables stop 關閉iptables
-
把要使用的網橋網段加入 INPUT鏈
作為一個linux准小白,默默的 使用service iptables stop 關閉了公司設定的iptables.
OK, That‘s All, 以後若有朋友遇到 默認網橋容器內無法ping通網橋,無法訪問宿主機,可參考本文排障。