docker的網(wǎng)絡(luò)模式,了解docker的網(wǎng)絡(luò)模式對docker通信尤為重要。
(一)網(wǎng)絡(luò)模式介紹
查看顯示的三種網(wǎng)絡(luò)模式厨钻,其實還有一種是容器模式饮潦。一共4種
docker network ls
bridge模式:使用–net =bridge指定燃异,默認(rèn)設(shè)置;
host模式:使用–net =host指定继蜡;
none模式:使用–net =none指定回俐;
container模式:使用–net =container:NAMEorID指定。
(二)bridge模式(docker默認(rèn)的網(wǎng)絡(luò)模式)
①介紹
在默認(rèn)情況下稀并,docker 會在 host 機(jī)器上新創(chuàng)建一個 docker0 的 bridge:可以把它想象成一個虛擬的交換機(jī)仅颇,所有的容器都是連到這臺交換機(jī)上面的。docker 會從私有網(wǎng)絡(luò)中選擇一段地址來管理容器碘举,比如 172.17.0.1/16忘瓦,這個地址根據(jù)你之前的網(wǎng)絡(luò)情況而有所不同。
sudo yum install net-toolsifconfig -a
②數(shù)據(jù)流程
容器內(nèi)部發(fā)送一條報文引颈,查看路由規(guī)則耕皮,默認(rèn)轉(zhuǎn)發(fā)到 172.17.0.1(如果是同一個網(wǎng)段境蜕,會直接把源地址標(biāo)記為 172.17.0.2 進(jìn)行發(fā)送)
通過 eth0 發(fā)送的報文,會在 vethXXX 被接收凌停,因為它直接連在 docker0 上粱年,所以默認(rèn)路由到 docker0
這個時候報文已經(jīng)來到了主機(jī)上,查詢主機(jī)的路由表苦锨,發(fā)現(xiàn)報文應(yīng)該通過 eth0 從默認(rèn)網(wǎng)關(guān)發(fā)送出去逼泣,那么報文就被轉(zhuǎn)發(fā)給 eth0(就是前面提到的要打開 linux 系統(tǒng)的自動轉(zhuǎn)發(fā)配置)
匹配機(jī)器上的 iptables,發(fā)現(xiàn)有一條 -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE舟舒,也就是 SNAT 規(guī)則拉庶,那么 linux 內(nèi)核會修改 ip 源地址為 eth0 的地址,維護(hù)一條 NAT 規(guī)則記錄秃励,然后把報文轉(zhuǎn)發(fā)出去氏仗。(也就是說對于外部來說,報文是從主機(jī) eth0 發(fā)送出去的夺鲜,無法感知容器的存在)
③流程演示方便理解
啟動兩個容器
docker run --name a1 -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done"docker run --name a2 -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done"
容器互相通信
docker exec -it a1 /bin/sh ifconfig#查看到a1的ip是172.17.0.2exitdocker exec -it a2 /bin/sh ifconfig#查看到a2的ip是172.17.0.3#在a2容器內(nèi)可以ping通172.17.0.2ping 172.17.0.2#在a1容器內(nèi)嘗試ping下a2的ip 172.17.0.3#在a1容器內(nèi)可以ping通172.17.0.2ping 172.17.0.3
記錄ip太麻煩了皆尔,可以通過link的方式直接讓容器包含起來
這樣只是單向的,還需要刪除a1币励,重新創(chuàng)建才能添加link a2慷蠕,
docker run --name a2 --link a1 -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done"docker exec -it a2 /bin/shping a1
④自定義網(wǎng)絡(luò)
但是建議大家不要使用link的方式,如果容器千千萬都link食呻,人就受不了了流炕。還是自定網(wǎng)絡(luò)比較靠譜。下面說說自定義網(wǎng)絡(luò)
docker network create -d bridge net-test
測試網(wǎng)絡(luò)通信仅胞,創(chuàng)建容器每辟,進(jìn)行通信
不需要ip的方式兩個容器都是通的。自定義網(wǎng)絡(luò)牛Xclass
docker run --name test3 --network net-test -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done"docker run --name test4 --network net-test -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done"docker exec -it test3 /bin/shping test4exitdocker exec -it test4 /bin/shping test3exit
自定義網(wǎng)絡(luò)的IP段看下干旧。172.18網(wǎng)段渠欺。
docker network inspect net-test
container 里面包括test3 和test4
(三)host模式(共享主機(jī)的網(wǎng)絡(luò)模式)
docker 不會為容器創(chuàng)建單獨的網(wǎng)絡(luò) namespace,而是共享主機(jī)的 network namespace椎眯,也就是說:容器可以直接訪問主機(jī)上所有的網(wǎng)絡(luò)信息挠将。在實際微服務(wù)的環(huán)境中不建議使用這種。
#network 更換成host docker run --name test5_host --network host -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done"? docker exec -it test5_host? /bin/shifconfig
跟宿主機(jī)是一樣的
直接使用 Docker host 的網(wǎng)絡(luò)最大的好處就是性能盅视,如果容器對網(wǎng)絡(luò)傳輸效率有較高要求捐名,則可以選擇 host 網(wǎng)絡(luò)。當(dāng)然不便之處就是犧牲一些靈活性闹击,比如要考慮端口沖突問題镶蹋,Docker host 上已經(jīng)使用的端口就不能再用了。Docker host 的另一個用途是讓容器可以直接配置 host 網(wǎng)路。比如某些跨 host 的網(wǎng)絡(luò)解決方案贺归,其本身也是以容器方式運行的淆两,這些方案需要對網(wǎng)絡(luò)進(jìn)行配置,比如管理 iptables拂酣。容器中秋冰,對這些設(shè)備有全部的訪問權(quán)限。因此docker提示我們婶熬,這種方式是不安全的剑勾。如果在隔離良好的環(huán)境中(比如租戶的虛擬機(jī)中)使用這種方式,問題不大赵颅。
(四)none模式(空網(wǎng)絡(luò)模式)
這種none的也就自己通過exec的方式訪問虽另。
docker run --name test7_none --network none -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done"? docker exec -it test7_none /bin/shifconfig
其實還真有應(yīng)用場景。封閉意味著隔離饺谬,一些對安全性要求高并且不需要聯(lián)網(wǎng)的應(yīng)用可以使用 none 網(wǎng)絡(luò)捂刺。比如某個容器的唯一用途是生成密碼,就可以放到 none 網(wǎng)絡(luò)中避免密碼被竊取募寨。
(四)container 模式(容器之前的共享模式族展,學(xué)習(xí)k8s這個很重要)
一個容器直接使用另外一個已經(jīng)存在容器的網(wǎng)絡(luò)配置:ip 信息和網(wǎng)絡(luò)端口等所有網(wǎng)絡(luò)相關(guān)的信息都是共享的。需要注意的是:這兩個容器的計算和存儲資源還是隔離的拔鹰。
# test7_container 依賴a1的網(wǎng)絡(luò)模式 docker run --name test7_container --network container:a1 -d busybox /bin/sh -c "while true;do echo hello docker;sleep 10;done" # 分別進(jìn)入test7_container 和a1查看ifconfig 發(fā)現(xiàn)兩個是一樣的docker exec -it test7_container /bin/shifconfigexitdocker exec -it a1 /bin/shifconfigexit
kubernetes 的 pod 就是用這個實現(xiàn)的仪缸,同一個 pod 中的容器共享一個 network namespace。