Docker之單機網路二
Docker網路初探
- 後臺方式啟動一個最新版本的centos映象;
dockerrun-d-it--namecentosworktestcentos:latest
- 進入容器內部,檢視容器的網路資訊,我們可以看到一個eth0的網絡卡資訊,該網絡卡上掛載的一個Veth-Pair,通過Veth-Pair與內部的網橋通訊;
#檢視容器資訊
dockerps
#進入容器內部
dockerexec-itad9342449b86/bin/bash
#檢視網路資訊(yuminstallnet-tools)
ifconfig
- 使用route -n檢視容器內部的路由表資訊,可以證實eth0是這個容器預設的通訊的裝置;
- 接下來我們退出容器,看下宿主機的網路情況,我們可以看到宿主機網路上掛載了一個Veth-Pair,猜測是掛載到docker0上的,這裡我們推斷docker0可能是一個bridge;
- 驗證docker0是否是bridge,我們可以通過brctl show(yum install -y bridge-utils)命令來檢視,通過檢視我們發現docker0果然是一個bridge;
- 通過上面的實驗我們可以猜測docker的網路模型結構應該是類似於網路篇上的結構,如下圖:
- 為了驗證結論的正確性,我們再次啟動一個centosworktest02的容器,檢查docker0是否掛載了新的Veth-Pair;
#後臺方式啟動一個名字為centosworktest02的centos映象
dockerrun-d-it--namecentosworktest02centos:latest
#檢視docker0是否掛掛載資訊的Veth-Pair
brctlshow
#檢視網路情況
ifconfig
- 通過驗證我們發現我們猜測基本正確,接下來我們驗證一下容器之間網路的連通性,我們從centosworktest02 ping(yum install -y iputils) centosworktest,發現容器間的網路也是通的;
經過一系列驗證,我們發現整體的猜測是正確的docker預設的在宿主機內部的網路模型就是通過bridge和Veth-Pair進行通訊的。
Docker網路模型
實現原理
Docker使用Linux橋接,在宿主機虛擬一個Docker容器網橋(docker0),Docker啟動一個容器時會根據Docker網橋的網段分配給容器一個IP地址,同時Docker網橋是每個容器的預設閘道器。因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的IP直接通訊。
Docker網橋是宿主機虛擬出來的,並不是真實存在的網路裝置,外部網路是無法定址到的,這也意味著外部網路無法通過直接容器IP訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過對映容器埠到宿主主機埠,即docker run建立容器時候通過 -p 或 -P 引數來啟用,訪問容器的時候就通過[宿主機IP]:[容器埠]訪問容器。
網路模型
bridge
bridge模式是Docker的預設網路模式,也就是我們在網路初探上探索的模式,這裡對其容器與宿主機的通訊進行一個總結,當Docker程序啟動時,會在主機上建立一個名為docker0的虛擬網橋,在此宿主機上啟動的Docker容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。
容器啟動的時候會從docker0子網中分配一個IP給容器使用,並設定docker0的IP地址為容器的預設閘道器。在主機上建立一對虛擬網絡卡veth pair裝置,Docker將veth pair裝置的一端放在新建立的容器中,並命名為eth0的網絡卡,另一端放在主機中,以vethxxx這樣類似的名字命名,並將這個網路裝置加入到docker0網橋中,到這裡我們只是完成了宿主機與容器,同一主機上容器間的通訊,此時容器還不能與外部網路進行通訊。
為了使外界可以訪問容器中的程序,docker採用了埠繫結的方式,也就是通過iptables的NAT,將宿主機上的埠流量轉發到容器內的埠上。當使用使用docker run -p時,就是在iptables做了DNAT規則,實現埠轉發功能。可以使用iptables -t nat -vnL檢視。
bridge模式中的容器與外界通訊時,必定會佔用宿主機上的埠,從而與宿主機競爭埠資源,此外由於容器與外界通訊是基於三層iptables NAT,效能和效率上的損耗肯定是不可避免的。
host
如果啟動容器的時候使用host模式,容器直接與宿主機使用同一網路命令空間,採用此模式的容器,可以直接使用宿主機的IP地址與外面進行通訊,如果宿主機具有公網的IP地址時,那容器也會擁有這個公有的IP地址,與此同時,容器內服務的埠地址也能直接使用宿主機的埠,無需再進行額外的NAT轉換。因此host最大的優勢就是網路效能比較好,但是容器將不再擁有隔離、獨立的網路棧。容器會與宿主機競爭網路棧使用,容器內部將不再擁有所有的埠資源。
none
如果啟動容器的時候使用none模式,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。容器中只有lo迴環地址,沒有其他網絡卡。這種型別的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。
container
如果使用該模式新建立的容器和已經存在的容器會共享一個 Network Namespace,而不是和宿主機共享。新建立的容器不會建立自己的網絡卡,配置自己的 IP,而是和一個指定的容器共享IP、埠範圍等資訊。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過 lo 網絡卡裝置通訊。