本篇將講述Docker網(wǎng)絡的一些概念,以便您在設計和部署應用程序時充分利用到這些功能。
從策劃到設計制作,每一步都追求做到細膩,制作可持續(xù)發(fā)展的企業(yè)網(wǎng)站。為客戶提供成都網(wǎng)站設計、網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)頁設計、域名注冊、網(wǎng)頁空間、網(wǎng)絡營銷、VI設計、 網(wǎng)站改版、漏洞修補等服務。為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造優(yōu)易品牌,攜手廣大客戶,共同發(fā)展進步。
首先,Docker的網(wǎng)絡子系統(tǒng)是可插拔驅(qū)動式的,默認情況下存在或支持多種網(wǎng)絡接口,如bridge、host、overlay、macvlan以及none類型的網(wǎng)絡接口。
接下來,我們先來探討下bridge(橋接)網(wǎng)絡模式
bridge是docker默認的網(wǎng)絡模式,如果不指定類型,則這是您正在創(chuàng)建的網(wǎng)絡類型,bridge模式會為每一個容器分配一個Network Namespace、IP等,并將容器的網(wǎng)絡連接到一個網(wǎng)橋(docker0)上。
特點:同一個宿主機上所有容器默認會在同一個網(wǎng)段(默認網(wǎng)段:172.17.0.0/16)下,且相互之間可以通信以及訪問外部網(wǎng)絡(前提是宿主機可以訪問外部網(wǎng)絡)。
網(wǎng)橋就是在多個網(wǎng)段之間轉(zhuǎn)發(fā)流量的鏈路層設備。網(wǎng)橋可以是運行在主機內(nèi)核中的軟件或者硬件設備。
Docker使用的是軟件網(wǎng)橋,允許連接在同一網(wǎng)橋的容器間進行通信,同時提供與未連接到網(wǎng)橋網(wǎng)絡的容器進行隔離。Docker網(wǎng)橋會自動設置相關(guān)規(guī)則(用iptables),不同網(wǎng)橋上的容器不能直接相互通信。
網(wǎng)橋適用于在同一個Docker守護程下的容器。對于在不同Docker守護進程下運行的容器之間的通信,可以在宿主機上添加路由,也可以使用overlay網(wǎng)絡。
當啟動Docker daemon時,會自動創(chuàng)建默認的網(wǎng)橋網(wǎng)絡(docker0)并且還會啟動iptables來設置您的訪問規(guī)則。您可以創(chuàng)建用戶自定義的網(wǎng)橋網(wǎng)絡,用戶自定義的網(wǎng)橋網(wǎng)絡優(yōu)于默認的網(wǎng)橋(docker0),特點如下:
1、用戶自定義的網(wǎng)橋在容器化應用程序之間提供了更好的隔離性和互操作性。
連接在同一網(wǎng)橋下的容器同屬一個網(wǎng)絡,因此所有端口可以互訪,但對外部網(wǎng)絡是不公開的,這使得容器化應用程序可以輕松地相互通信,同時提高了安全性。
想象一下,一個帶有web前端和后端,另外還有數(shù)據(jù)庫的應用架構(gòu)(用戶<-->web入口<-->后端應用<-->數(shù)據(jù)庫)。外部網(wǎng)絡只需要訪問web前端(如80端口),但只有后端應用需要訪問數(shù)據(jù)庫。若使用用戶自定義的網(wǎng)橋,只需要對外開放web端口,數(shù)據(jù)庫不需要對外開放任何端口,前后端都可以通過用戶自定義的網(wǎng)橋來訪問數(shù)據(jù)庫。
2、用戶自定義的網(wǎng)橋提供了容器之間的自動DNS解析。
在默認網(wǎng)橋上創(chuàng)建的容器,相互訪問時只能通過IP地址,除非您使用--link選項,但--link是需要在容器的兩個方向上創(chuàng)建,對于需要通信的兩個以上的容器,這會變得復雜。而在用戶自定義的網(wǎng)橋網(wǎng)絡上,容器間可以通過名稱或別名相互解析。
回想一下,在使用物理主機或者VM主機時,我們應用程序的配置文件中一般用hosts中的主機名稱或者IP,而現(xiàn)在在容器中,使用自定義網(wǎng)絡,我們只要改寫成容器名就好了,不需要太關(guān)注主機名稱或者IP,是不是很開森。
3、使用用戶自定義網(wǎng)橋的容器,支持隨時斷開或連接到不同的(用戶自定義)網(wǎng)絡。
在容器的生命周期中,您可以動態(tài)切換容器間的網(wǎng)絡連接,比如,您創(chuàng)建了自定義my-net01和my-net02橋接網(wǎng)絡,這兩個網(wǎng)絡中的容器可以互相動態(tài)切換的。如果您是通過默認網(wǎng)橋創(chuàng)建的容器,也可以切換到自定義網(wǎng)橋中,而不必刪除容器重建。
注:這里在實際驗證過程中,貌似與官方文檔描述有出入。
4、每個用戶自定義的網(wǎng)絡都是創(chuàng)建了一個可配置的網(wǎng)橋。
如果所有容器都使用默認網(wǎng)橋網(wǎng)絡,雖說可以修改配置,但所有容器都使用相同的設置,例如MTU和iptables規(guī)則。此外,配置默認網(wǎng)橋網(wǎng)絡需要重啟Docker進程。
若是使用docker network create創(chuàng)建和配置用戶自定義的網(wǎng)橋網(wǎng)絡。如果不同的應用程序組有不同的網(wǎng)絡需求,則可以在創(chuàng)建每個用戶定義的網(wǎng)橋時分別對其進行配置。
5、使用默認網(wǎng)橋的容器之間可共享環(huán)境變量。
起初,在兩個容器之間共享環(huán)境變量的唯一方法是使用--link。這種類型的變量共享在用戶自定義的網(wǎng)絡中是不可能的。然而,現(xiàn)在卻有更好的方法來共享環(huán)境變量。
(1)、多個容器可以使用Docker的卷(Volume)來裝載包含共享信息的文件或目錄。
(2)、多個容器可以使用docker compose來一起啟動,compose文件中可以定義共享變量。
(3)、可以使用swarm服務來代替獨立的容器,并共享密鑰和配置。
管理自定義網(wǎng)橋網(wǎng)絡
1、使用docker network ls 查看默認支持網(wǎng)絡
# docker network ls
NETWORK ID NAME DRIVER SCOPE
e22a6ab223fe bridge bridge local
15b417347346 host host local
5926c0bd11d0 none null local
2、使用docker network create 創(chuàng)建自定義網(wǎng)橋網(wǎng)絡
# docker network create my-web-net01
# docker network ls
NETWORK ID NAME DRIVER SCOPE
e22a6ab223fe bridge bridge local
15b417347346 host host local
899362727b48 my-web-net01 bridge local
5926c0bd11d0 none null local
可以看到,我們并沒有指定--driver=bridge來創(chuàng)建,因為默認就是bridge模式,當然,您也可以指定自定義網(wǎng)橋的子網(wǎng)、IP范圍、網(wǎng)關(guān)和其他項,例如:
# docker network create --driver=bridge --subnet=172.23.10.0/24 my-web-net02
或者再細化一點
# docker network create \
--driver=bridge \
--subnet=172.24.0.0/16 \
--ip-range=172.24.10.0/24 \
--gateway=172.24.10.254 \
my-web-net03
刪除自定義網(wǎng)橋網(wǎng)絡
# docker network ls
NETWORK ID NAME DRIVER SCOPE
e22a6ab223fe bridge bridge local
15b417347346 host host local
899362727b48 my-web-net01 bridge local
49352768c5dd my-web-net02 bridge local
7e29b5afd1be my-web-net03 bridge local
5926c0bd11d0 none null local
# docker network rm my-web-net01
或者指量刪除
# docker network rm $(docker network ls -f name=my-web -q) #該命令含義是將名字包含my-web的網(wǎng)絡列出并刪除
同一個自定義網(wǎng)橋中的容器通過容器名互相訪問
1、創(chuàng)建自定義網(wǎng)絡my-web-net01
# docker network create my-web-net01
2、創(chuàng)建容器t01、t02并使用my-web-net01網(wǎng)絡
# docker run -idt --network=my-web-net01 --name t01 busybox /bin/sh
# docker run -idt --network=my-web-net01 --name t02 busybox /bin/sh
3、使用ping命令分別從t01、t02使用容器名進行互ping,驗證網(wǎng)絡的互通性
# docker exec -it t01 ping t02
# docker exec -it t01 ping t02
結(jié)論:同一自定義網(wǎng)絡中的容器可以通過容器名互相訪問
在默認網(wǎng)橋中的容器不能通過容器名互相訪問
1、在默認網(wǎng)橋中創(chuàng)建t03、t04容器
# docker run -idt --name=t03 busybox /bin/sh
# docker run -idt --name=t04 busybox /bin/sh
2、使用ping命令分別從t03、t04使用容器名進行互ping,驗證網(wǎng)絡的互通性
# docker exec -it t03 ping t04
ping: bad address 't04'
# docker exec -it t04 ping t03
ping: bad address 't03'
3、使用ping命令分別從t03、t04使用ip地址互ping,驗證網(wǎng)絡的互通性
# docker exec -it t03 ifconfig
# docker exec -it t04 ifconfig
# docker exec -it t03 ping 172.17.0.6
# docker exec -it t04 ping 172.17.0.4
結(jié)論:在默認網(wǎng)橋中的容器不能通過容器名互相訪問,但可以通過ip互訪。
自定義網(wǎng)橋中的容器,可以動態(tài)切換容器間的網(wǎng)絡連接
1、創(chuàng)建自定義網(wǎng)橋my-web-net02
# docker network create my-web-net02
2、將在my-web-net01網(wǎng)橋中的容器t02同時加到my-web-net02網(wǎng)絡中,然后查看t02的網(wǎng)絡,如圖1.1所示,發(fā)現(xiàn)t02多了一個eth2網(wǎng)卡。
# docker network connect my-web-net02 t02
圖1.1
3、將t02移出my-web-net01網(wǎng)絡,然后,我們再次查看t02的網(wǎng)絡連接,如圖1.2所示,發(fā)現(xiàn)只有eth2網(wǎng)卡了
# docker network disconnect my-web-net01 t02
4、再次驗證t02是否還能與t01互通,如圖1.3所示。
圖1.3
結(jié)論:默認已經(jīng)不能互通,即使用ip也不能,因為t01屬于my-web-net01,t02屬于my-web-net02。
5、將t02加回到my-web-net01網(wǎng)絡,驗證互通性,如圖1.4所示。
# docker network connect my-web-net01 t02
圖1.4
結(jié)論:t01與t02可以互通。
將默認網(wǎng)橋中的容器,加入到自定義網(wǎng)橋,驗證互通性
1、將t03加入到自定義網(wǎng)橋my-web-net01中,并驗證t03與t01和t04的互通性,如圖1.5所示。
圖1.5
2、將容器從某網(wǎng)絡中移除再重新加入網(wǎng)卡名會發(fā)生變化,如圖1.6所示。
圖1.6
總結(jié)
不管是自定義網(wǎng)橋還是默認網(wǎng)橋中的容器,均支持動態(tài)切換容器間的網(wǎng)絡連接,另外,容器在做網(wǎng)絡切換時網(wǎng)卡名稱會發(fā)生變化(重啟容器后名稱會恢復),這對于需要綁定網(wǎng)卡名稱的應用會存在問題,比如阿里的tair緩存。