本篇將講述Docker網絡的一些概念,以便您在設計和部署應用程序時充分利用到這些功能。前端
首先,Docker的網絡子系統是可插拔驅動式的,默認狀況下存在或支持多種網絡接口,如bridge、host、overlay、macvlan以及none類型的網絡接口。web
接下來,咱們先來探討下bridge(橋接)網絡模式docker
bridge是docker默認的網絡模式,若是不指定類型,則這是您正在建立的網絡類型,bridge模式會爲每個容器分配一個Network Namespace、IP等,並將容器的網絡鏈接到一個網橋(docker0)上。數據庫
特色:同一個宿主機上全部容器默認會在同一個網段(默認網段:172.17.0.0/16)下,且相互之間能夠通訊以及訪問外部網絡(前提是宿主機能夠訪問外部網絡)。後端
網橋就是在多個網段之間轉發流量的鏈路層設備。網橋能夠是運行在主機內核中的軟件或者硬件設備。緩存
Docker使用的是軟件網橋,容許鏈接在同一網橋的容器間進行通訊,同時提供與未鏈接到網橋網絡的容器進行隔離。Docker網橋會自動設置相關規則(用iptables),不一樣網橋上的容器不能直接相互通訊。安全
網橋適用於在同一個Docker守護程下的容器。對於在不一樣Docker守護進程下運行的容器之間的通訊,能夠在宿主機上添加路由,也可使用overlay網絡。網絡
當啓動Docker daemon時,會自動建立默認的網橋網絡(docker0)而且還會啓動iptables來設置您的訪問規則。您能夠建立用戶自定義的網橋網絡,用戶自定義的網橋網絡優於默認的網橋(docker0),特色以下:架構
一、用戶自定義的網橋在容器化應用程序之間提供了更好的隔離性和互操做性。ide
鏈接在同一網橋下的容器同屬一個網絡,所以全部端口能夠互訪,但對外部網絡是不公開的,這使得容器化應用程序能夠輕鬆地相互通訊,同時提升了安全性。
想象一下,一個帶有web前端和後端,另外還有數據庫的應用架構(用戶<-->web入口<-->後端應用<-->數據庫)。外部網絡只須要訪問web前端(如80端口),但只有後端應用須要訪問數據庫。若使用用戶自定義的網橋,只須要對外開放web端口,數據庫不須要對外開聽任何端口,先後端均可以經過用戶自定義的網橋來訪問數據庫。
二、用戶自定義的網橋提供了容器之間的自動DNS解析。
在默認網橋上建立的容器,相互訪問時只能經過IP地址,除非您使用--link選項,但--link是須要在容器的兩個方向上建立,對於須要通訊的兩個以上的容器,這會變得複雜。而在用戶自定義的網橋網絡上,容器間能夠經過名稱或別名相互解析。
回想一下,在使用物理主機或者VM主機時,咱們應用程序的配置文件中通常用hosts中的主機名稱或者IP,而如今在容器中,使用自定義網絡,咱們只要改寫成容器名就行了,不須要太關注主機名稱或者IP,是否是很開森。
三、使用用戶自定義網橋的容器,支持隨時斷開或鏈接到不一樣的(用戶自定義)網絡。
在容器的生命週期中,您能夠動態切換容器間的網絡鏈接,好比,您建立了自定義my-net01和my-net02橋接網絡,這兩個網絡中的容器能夠互相動態切換的。若是您是經過默認網橋建立的容器,也能夠切換到自定義網橋中,而沒必要刪除容器重建。
注:這裏在實際驗證過程當中,貌似與官方文檔描述有出入。
四、每一個用戶自定義的網絡都是建立了一個可配置的網橋。
若是全部容器都使用默認網橋網絡,雖然說能夠修改配置,但全部容器都使用相同的設置,例如MTU和iptables規則。此外,配置默認網橋網絡須要重啓Docker進程。
如果使用docker network create建立和配置用戶自定義的網橋網絡。若是不一樣的應用程序組有不一樣的網絡需求,則能夠在建立每一個用戶定義的網橋時分別對其進行配置。
五、使用默認網橋的容器之間可共享環境變量。
起初,在兩個容器之間共享環境變量的惟一方法是使用--link。這種類型的變量共享在用戶自定義的網絡中是不可能的。然而,如今卻有更好的方法來共享環境變量。
(1)、多個容器可使用Docker的卷(Volume)來裝載包含共享信息的文件或目錄。
(2)、多個容器可使用docker compose來一塊兒啓動,compose文件中能夠定義共享變量。
(3)、可使用swarm服務來代替獨立的容器,並共享密鑰和配置。
管理自定義網橋網絡
一、使用docker network ls 查看默認支持網絡
# docker network ls
NETWORK ID NAME DRIVER SCOPE
e22a6ab223fe bridge bridge local
15b417347346 host host local
5926c0bd11d0 none null local
二、使用docker network create 建立自定義網橋網絡
# 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來建立,由於默認就是bridge模式,固然,您也能夠指定自定義網橋的子網、IP範圍、網關和其餘項,例如:
# 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
刪除自定義網橋網絡
# 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的網絡列出並刪除
同一個自定義網橋中的容器經過容器名互相訪問
一、建立自定義網絡my-web-net01
# docker network create my-web-net01
二、建立容器t0一、t02並使用my-web-net01網絡
# docker run -idt --network=my-web-net01 --name t01 busybox /bin/sh
# docker run -idt --network=my-web-net01 --name t02 busybox /bin/sh
三、使用ping命令分別從t0一、t02使用容器名進行互ping,驗證網絡的互通性
# docker exec -it t01 ping t02
# docker exec -it t01 ping t02
結論:同一自定義網絡中的容器能夠經過容器名互相訪問
在默認網橋中的容器不能經過容器名互相訪問
一、在默認網橋中建立t0三、t04容器
# docker run -idt --name=t03 busybox /bin/sh
# docker run -idt --name=t04 busybox /bin/sh
二、使用ping命令分別從t0三、t04使用容器名進行互ping,驗證網絡的互通性
# docker exec -it t03 ping t04
ping: bad address 't04'
# docker exec -it t04 ping t03
ping: bad address 't03'
三、使用ping命令分別從t0三、t04使用ip地址互ping,驗證網絡的互通性
# 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
結論:在默認網橋中的容器不能經過容器名互相訪問,但能夠經過ip互訪。
自定義網橋中的容器,能夠動態切換容器間的網絡鏈接
一、建立自定義網橋my-web-net02
# docker network create my-web-net02
二、將在my-web-net01網橋中的容器t02同時加到my-web-net02網絡中,而後查看t02的網絡,如圖1.1所示,發現t02多了一個eth1網卡。
# docker network connect my-web-net02 t02
圖1.1
三、將t02移出my-web-net01網絡,而後,咱們再次查看t02的網絡鏈接,如圖1.2所示,發現只有eth1網卡了
# docker network disconnect my-web-net01 t02
四、再次驗證t02是否還能與t01互通,如圖1.3所示。
圖1.3
結論:默認已經不能互通,即便用ip也不能,由於t01屬於my-web-net01,t02屬於my-web-net02。
五、將t02加回到my-web-net01網絡,驗證互通性,如圖1.4所示。
# docker network connect my-web-net01 t02
圖1.4
結論:t01與t02能夠互通。
將默認網橋中的容器,加入到自定義網橋,驗證互通性
一、將t03加入到自定義網橋my-web-net01中,並驗證t03與t01和t04的互通性,如圖1.5所示。
圖1.5
二、將容器從某網絡中移除再從新加入網卡名會發生變化,如圖1.6所示。
圖1.6
總結
不論是自定義網橋仍是默認網橋中的容器,均支持動態切換容器間的網絡鏈接,另外,容器在作網絡切換時網卡名稱會發生變化(重啓容器後名稱會恢復),這對於須要綁定網卡名稱的應用會存在問題,好比阿里的tair緩存。