Docker網絡基本原理

Docker網絡基本原理介紹

直觀上看,要實現網絡通信,機器需要至少一個網絡接口(物理接口或虛擬接口)與外界相通,並可以收發數據包;此外,如果不同子網之間要進行通信,需要額外的路由機制。

Docker中的網絡接口默認都是虛擬的接口。虛擬接口的最大優勢就是轉發效率極高。這是因爲Linux通過在內核中進行數據複製來實現虛擬接口之間的數據轉發,即發送接口的發送緩存中的數據包將被直接複製到接收接口的接收緩存中,而無需通過外部物理網絡設備進行交換。對於本地系統和容器內系統來看,虛擬接口跟一個正常的以太網卡相比並無區別,只是它速度要快得多。

Docker容器網絡就很好地利用了Linux虛擬網絡技術,在本地主機和容器內分別創建一個虛擬接口,並讓它們彼此連通(這樣的一對接口叫做veth pair)。

一般情況下,Docker創建一個容器的時候,會具體執行如下操作:

1.創建一對虛擬接口,分別放到本地主機和新容器的命名空間中;

2.本地主機一端的虛擬接口連接到默認的docker0網橋或指定網橋上,並具有一個以veth開頭的唯一名字,如veth1234;

3.容器一端的虛擬接口將放到新創建的容器中,並修改名字作爲eth0。這個接口只在容器的命名空間可見;

4.從網橋可用地址段中獲取一個空閒地址分配給容器的eth0(例如172.17.0.2/16),並配置默認路由網關爲docker0網卡的內部接口docker0的IP地址(例如172.17.42.1/16)。

完成這些之後,容器就可以使用它所能看到的eth0虛擬網卡來連接其他容器和訪問外部網絡。用戶也可以通過docker network命令來手動管理網絡。

Docker網絡默認模式

按docker官方的說法,docker容器的網絡有五種模式:

1)bridge模式,--net=bridge(默認)
這是dokcer網絡的默認設置,爲容器創建獨立的網絡命名空間,容器具有獨立的網卡等所有單獨的網絡棧,是最常用的使用方式。
在docker run啓動容器的時候,如果不加--net參數,就默認採用這種網絡模式。安裝完docker,系統會自動添加一個供docker使用的網橋docker0,我們創建一個新的容器時,
容器通過DHCP獲取一個與docker0同網段的IP地址,並默認連接到docker0網橋,以此實現容器與宿主機的網絡互通。
 
2)host模式,--net=host
這個模式下創建出來的容器,直接使用容器宿主機的網絡命名空間。
將不擁有自己獨立的Network Namespace,即沒有獨立的網絡環境。它使用宿主機的ip和端口。
 
3)none模式,--net=none
爲容器創建獨立網絡命名空間,但不爲它做任何網絡配置,容器中只有lo,用戶可以在此基礎上,對容器網絡做任意定製。
這個模式下,dokcer不爲容器進行任何網絡配置。需要我們自己爲容器添加網卡,配置IP。
因此,若想使用pipework配置docker容器的ip地址,必須要在none模式下才可以。
 
4)其他容器模式(即container模式),--net=container:NAME_or_ID
與host模式類似,只是容器將與指定的容器共享網絡命名空間。
這個模式就是指定一個已有的容器,共享該容器的IP和端口。除了網絡方面兩個容器共享,其他的如文件系統,進程等還是隔離開的。
 
5)用戶自定義:docker 1.9版本以後新增的特性,允許容器使用第三方的網絡實現或者創建單獨的bridge網絡,提供網絡隔離能力。

bridge模式

bridge模式是docker默認的,也是開發者最常使用的網絡模式。在這種模式下,docker爲容器創建獨立的網絡棧,保證容器內的進程使用獨立的網絡環境,
實現容器之間、容器與宿主機之間的網絡棧隔離。同時,通過宿主機上的docker0網橋,容器可以與宿主機乃至外界進行網絡通信。
其網絡模型可以參考下圖:

從上面的網絡模型可以看出,容器從原理上是可以與宿主機乃至外界的其他機器通信的。同一宿主機上,容器之間都是連接掉docker0這個網橋上的,它可以作爲虛擬交換機使容器可以相互通信。
然而,由於宿主機的IP地址與容器veth pair的 IP地址均不在同一個網段,故僅僅依靠veth pair和namespace的技術,還不足以使宿主機以外的網絡主動發現容器的存在。爲了使外界可以方位容器中的進程,docker採用了端口綁定的方式,也就是通過iptables的NAT,將宿主機上的端口
端口流量轉發到容器內的端口上。

舉一個簡單的例子,使用下面的命令創建容器,並將宿主機的3306端口綁定到容器的3306端口:
docker run -tid --name db -p 3306:3306 MySQL
 
在宿主機上,可以通過iptables -t nat -L -n,查到一條DNAT規則:
 
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306
 
上面的172.17.0.5即爲bridge模式下,創建的容器IP。
 
很明顯,bridge模式的容器與外界通信時,必定會佔用宿主機上的端口,從而與宿主機競爭端口資源,對宿主機端口的管理會是一個比較大的問題。同時,由於容器與外界通信是基於三層上iptables NAT,性能和效率上的損耗是可以預見的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章