背景:
之前做了一個(gè)項(xiàng)目,需要在容器內(nèi)訪問宿主機(jī)提供的Redis 服務(wù)(這是一個(gè)比較常見的應(yīng)用場景哈), 常規(guī)方案:
① 主機(jī)網(wǎng)絡(luò)(docker run --network=host
): 完全應(yīng)用主機(jī)網(wǎng)絡(luò)堆棧,在容器內(nèi)localhost就是指向宿主機(jī)
② 網(wǎng)橋網(wǎng)絡(luò)(docker run --network=bridge
): 這也是docker容器默認(rèn)的網(wǎng)絡(luò)通信模式,容器內(nèi)localhost 指向的是容器自身,不能使用 localhost 訪問宿主機(jī)上localhost:6379承載的Redis服務(wù) 。
docker會(huì)默認(rèn)建立docker0 網(wǎng)橋;
網(wǎng)橋有一個(gè)網(wǎng)關(guān)ip, 有一個(gè)子網(wǎng)段; 網(wǎng)橋內(nèi)容器從子網(wǎng)段中確定容器ip( ip addr eth0), 網(wǎng)橋內(nèi)容器可通過 service name相互訪問;
網(wǎng)橋內(nèi)容器通過 docker0 Getway得以訪問外網(wǎng)。
不做騷操作,沿用常見的②網(wǎng)橋模式:
第一步:自定義網(wǎng)橋并應(yīng)用該自定義網(wǎng)橋
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
為啥不利用默認(rèn)docker0網(wǎng)橋?
本文開頭已講: docker0 是默認(rèn)網(wǎng)橋,新建的容器默認(rèn)都會(huì)加入這個(gè)網(wǎng)橋,所以我們需要建立一個(gè)專屬于本程序的網(wǎng)橋app_bridge
第二步:容器內(nèi)建立 對(duì)應(yīng)于宿主機(jī)的別名
為實(shí)現(xiàn)在容器內(nèi)網(wǎng)橋模式訪問宿主機(jī)localhost:6379 的服務(wù), 必須搭配docker 提供的 --add-host 選項(xiàng)(對(duì)應(yīng)到docker-compose.yml這個(gè)配置是extra_host)。
docker run 的--add-host 選項(xiàng)能在 容器 /etc/hosts 文件增加行記錄,便于我們使用該名稱訪問其他網(wǎng)絡(luò)。
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
之后在程序的配置文件即可應(yīng)用 dockerhost:6379 訪問宿主機(jī)Redis服務(wù)。
------------------------------------------ 稍熟悉docker網(wǎng)絡(luò)模型的朋友應(yīng)該 都能理解并完成上述操作-----------------------------------------------------
一個(gè)狀況:
我在公司CentOS7機(jī)器上使用上述操作, 容器內(nèi)一直無法連通宿主機(jī)(容器間還是能正常訪問)。
簡化問題測試:新建容器,在容器內(nèi)嘗試ping docker0 網(wǎng)關(guān), 嗶了狗了,4臺(tái)公司機(jī)器都ping不通docker0網(wǎng)關(guān),外網(wǎng)還是正常訪問。
那這個(gè)問題就成了: 使用默認(rèn)的docker0網(wǎng)橋,容器內(nèi)無法ping通docker0網(wǎng)關(guān),進(jìn)而無法訪問宿主機(jī)。
呀呀呀呀, 八成是公司機(jī)器的配置問題 ~。。~
追問公司運(yùn)維同學(xué),發(fā)現(xiàn):
Chain INPUT (policy DROP)
以上INPUT鏈的缺省策略是丟棄:從容器內(nèi)訪問宿主機(jī)的INPUT鏈規(guī)則并不匹配其中列出的任意一條,將被丟棄,所以我們從容器ping docker0網(wǎng)關(guān)會(huì)卡住收不到結(jié)果。
除非滿足列出的INPUT鏈規(guī)則,否則缺省的策略就是丟棄。
后面還有轉(zhuǎn)發(fā)和OUTPUT鏈缺省是 接受
這個(gè)策略的初衷是 服務(wù)器安全(尼瑪, 導(dǎo)致容器訪問宿主機(jī)的基礎(chǔ)能力都沒有了?。。。?。
運(yùn)維方案:
① 使用 sudo service iptables stop
關(guān)閉iptables
② 把要使用的網(wǎng)橋網(wǎng)段加入 INPUT鏈
sudo iptables -I INPUT -s 172.17.0.0/16 -j ACCEPT
【接受docker0子網(wǎng)段172.17.0.0/16 INPUT】 加入規(guī)則, 傳送門
OK, That‘s All, 以后若有朋友在公司網(wǎng)絡(luò)遇到 默認(rèn)網(wǎng)橋容器內(nèi)無法ping通網(wǎng)橋網(wǎng)關(guān),進(jìn)而無法訪問宿主機(jī),可參考本文排障。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。