這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
【編者的話】本文主要介紹了Docker網路的基礎。緊接著討論了網路設定工具pipework的使用,以及跨主機通訊的幾種方法。最後介紹了Docker的網路新項目Libnetwork。
網路基礎
Docker現有的網路模型主要是通過使用Network namespace、Linux Bridge、Iptables、veth pair等技術實現的。
- Network namespace:Network namespace主要提供了關於網路資源的隔離,包括網路裝置、IPv4和IPv6協議棧、IP路由表、防火牆、/proc/net目錄、/sys/class/net目錄、連接埠(socket)等。
- Linux Bridge:功能相當於物理交換器,為連在其上的裝置(容器)轉寄資料幀。如docker0橋接器。
- Iptables:主要為容器提供NAT以及容器網路安全。
- veth pair:兩個虛擬網卡組成的資料通道。在Docker中,用於串連Docker容器和Linux Bridge。一端在容器中作為eth0網卡,另一端在Linux Bridge中作為橋接器的一個連接埠。
容器的網路模式
- host模式: 容器和宿主機共用Network namespace。
- container模式: 容器和另外一個容器共用Network namespace。 kubernetes中的pod就是多個容器共用一個Network namespace。
- none模式: 容器有獨立的Network namespace,但並沒有對其進行任何網路設定,如分配veth pair 和橋接器串連,配置IP等。
- bridge模式: Bridge模式是Docker的預設模式,下面這張圖即為Bridge模式下Docker容器的網路連接圖。
容器eth0網卡從docker0橋接器所在的IP網段中選取一個未使用的IP,容器的IP在容器重啟的時候會改變。docker0的IP為所有容器的預設閘道。容器與外界通訊為NAT。
Link 操作
link 操作可以在兩個容器間建立一條資料通道,使得接收容器可以看到源容器的指定資訊。通過設定接收容器的環境變數和/etc/hosts檔案來得到源容器的環境配置資訊以及具體的IP地址,一個非常簡單的服務發現機制。由於link功能有限,個人覺得用處不是太大。
Docker自身的網路功能比較簡單,不能滿足很多複雜的應用情境。因此,有很多開源項目用來改善Docker的網路功能,如pipework、weave、flannel、socketplane等。
網路設定工具pipework
pipeork是一個簡單易用的Docker容器網路設定工具。由200多行shell指令碼實現。通過使用ip、brctl、ovs-vsctl等命令來為Docker容器配置自訂的橋接器、網卡、路由等。有如下功能:
- 支援使用自訂的 Libux Bridge、veth pair為容器提供通訊。
- 支援使用macvlan裝置將容器串連到本網。
- 支援DHCP擷取容器的IP。
- 支援Open vSwitch。
- 支援VLAN劃分。
我之前寫過一篇介紹pipework的文章,裡面通過3個例子介紹了pipwork的使用 (將Docker容器配置到本網環境中、單主機Docker容器VLAN劃分、多主機Docker容器的VLAN劃分), 有興趣的朋友可以去看下,在這裡 http://www.sel.zju.edu.cn/?p=444 (實驗室部落格,裡面有很多Docker相關的文章) 或 http://www.infoq.com/cn/articl ... ctice
Docker容器跨主機通訊
在目前Docker預設的網路環境下,單台主機上的Docker容器可以通過docker0橋接器直接通訊,而不同主機上的Docker容器之間只能通過在主機上做連接埠映射進行通訊。這種連接埠映射方式對很多叢集應用來說極不方便。如果能讓Docker容器之間直接使用自己的IP地址進行通訊,會解決很多問題。目前使Docker容器跨主機通訊主要有一下幾種方法:
- 橋接方法: 通過將不同Docker主機上的docker0橋接器橋接在同一個二層網路中(使用主機的網卡橋接),使得Docker容器可以跨主機通訊。 如:
- 直接路由: 通過在Docker主機上添加靜態路由實現跨宿主機通訊。如:
- 隧道方法:使用GRE、 VxLan隧道實現跨主機通訊。
前兩種方法要求主機在同一個子網中,不常使用。所以我主要介紹隧道的方法。
Overlay隧道模型
Overlay網路其實就是隧道技術,即將一種網路通訊協定封裝在另一種協議中傳輸的技術。隧道被廣泛用於串連那些因使用其他網路而被隔離的主機和網路,結果產生的網路就是所謂的Overlay網路。因為它有效地覆蓋在基礎網路之上,這個模型就可以很好地解決跨網路使Docker容器實現二層或三層通訊的需求。如同一公司不同辦公地點間內網串連的VPN技術,就是將三層IP資料包封裝在隧道協議中進行傳輸。
使用gre隧道串連的多主機容器間通訊,如所示。(OVS + gre)
類Neutron的多租戶的GRE網路
隧道方案的另一個好處就是可以解決VLAN ID 不足的問題。不同的租戶使用不同的 GRE ID在隧道中傳輸。這樣的方案類似於OpenStack的neutron網路。如下:
Libnetwork 前瞻
Libnetwork是Docker官方近一個月來推出的新項目,由這個issue而來。旨在將Docker的網路功能從Docker核心代碼中分離出去,形成一個單獨的庫。 Libnetwork通過外掛程式的形式為Docker提供網路功能。 使得使用者可以根據自己的需求實現自己的Driver來提供不同的網路功能。 目前主要由socketplane的那幫人在開發。
官方目前計劃實現以下Driver:
- Bridge : 這個Driver就是Docker現有網路Bridge模式的實現。 (基本完成,主要從之前的Docker網路代碼中遷移過來)
- Null : Driver的空實現,類似於Docker 容器的None模式。
- Overlay : 隧道模式實現多主機通訊的方案。 (還只是個計劃,具體實現細節還沒定)
Libnetwork所要實現的網路模型基本是這樣的: 使用者可以建立一個或多個網路(一個網路就是一個橋接器或者一個VLAN ),一個容器可以加入一個或多個網路。 同一個網路中容器可以通訊,不同網路中的容器隔離。
1.7 版本的Docker將會把Libnetwork整合進來(目前已經整合進去了),但功能並沒有太大變化,因為目前僅完成了Bridge Driver。 之後會繼續完善。
Docker網路的發展以後就都在這個項目上了,目前這個項目才剛剛開始,還有很多東西沒有確定。大家有興趣可以多多關注一下。
Q&A
問題: GRE隧道多主機通訊的那張圖中,con2擷取的IP為172.17.1.1還是172.17.2.1
答:host1和host2的所有容器在同一個子網中,IP網段為172.17.0.0/16。為了避免IP地址衝突,我使用--fixed-ip參數將host1上容器的IP地址限制在172.17.1.1/24中,將host2上容器地址限制在172.17.2.1/24中。
問題:pipework安裝,br是自動建立的,把物理網卡ip設定到br0上,我不就連不上宿主機了?
答:將物理網卡設定到橋接器上,你首先需要將物理網卡的IP設定到br0上,其次要修改原生路由表,將原本通過物理網卡的路由也設定為br0。
問題: socketplane用的是vxlan,libnetwork要使用gre嗎?
答: vxlan和gre原理差不多的,我文章中只是使用gre做隧道的實驗,並不代表Libnetwork將來使用什麼。
問題:socketplane網路和kubernetes網路有什麼區別和聯絡?
答:socketplane就是將容器直接連在了ovs上,並打上了vlan tag,一個vlan就是一個網路,基本就是這樣。kubernetes的ovs網路可以用下面這張圖來說明:
一台minion上的容器在一個子網中。我知道就這些,具體的還有待深入研究。
問題:Docker官方會不會做容器固定IP?
答: 請參考這個PR: https://github.com/docker/libnetwork/pull/201
===========================
以上內容根據2015年5月26日晚群分享內容整理。
分享人馮明振,Docker network contributor,浙大SEL實驗室碩士研究生,熟悉OpenStack和Docker。DockOne每周都會組織定向的技術分享,歡迎感興趣的同學加我(liyingjiesx)參與。