docker macvlan實現容器ip和區域網互通
原文:http://qiankunli.github.io/2017/01/13/docker_macvlan.html
簡介
macvlan基礎
如果採用硬體支援的方式來設定vlan,交換機是劃分區域網的關鍵裝置,所以本文說xx vlan,主要是針對交換機說的。
macvlan
常用的 VLAN 劃分方式是通過埠進行劃分,雖然這種劃分 VLAN 的方式設定比較很簡單, 但僅適用於終端裝置物理位置比較固定的組網環境。隨著移動辦公的普及,終端裝置可能不 再通過固定埠接入交換機,這就會增加網路管理的工作量。比如,一個使用者可能本次接入 交換機的埠 1,而下一次接入交換機的埠 2,由於埠 1 和埠 2 屬於不同的 VLAN,若 使用者想要接入原來的 VLAN 中,網管就必須重新對交換機進行配置。顯然,這種劃分方式不 適合那些需要頻繁改變拓撲結構的網路。而 MAC VLAN 則可以有效解決這個問題,它根據 終端裝置的 MAC 地址來劃分 VLAN。這樣,即使使用者改變了接入埠,也仍然處在原 VLAN 中。
mac vlan不是以交換機埠來劃分vlan,因此,一個交換機埠可以接受來自多個mac地址的資料。一個交換機埠要處理多個vlan的資料,則要設定trunk模式。
交換機IP-MAC-PORT
網路中實際傳輸的是“幀”,幀裡面是有目標主機的MAC地址的。在乙太網中,一個主機要和另一個主機進行直接通訊,必須要知道目標主機的MAC地址。但這個目標MAC地址是如何獲得的呢?它就是通過地址解析協議獲得的。所謂“地址解析”就是主機在傳送幀前將目標IP地址轉換成目標MAC地址的過程。ARP協議的基本功能就是通過目標裝置的IP地址,查詢目標裝置的MAC地址,以保證通訊的順利進行。
ARP欺騙,當計算機接收到ARP應答資料包的時候,就會對本地的ARP快取進行更新,將應答中的IP和MAC地址儲存在ARP快取中。但是,ARP協議並不只在傳送ARP請求才接收ARP應答。
在交換機上配置了IMP(ip-mac-port對映)功能以後,交換機會檢查每個資料包的源IP地址和MAC,對於沒有在交換機內記錄的IP和MAC地址的計算機所發出的資料包都會被交換機所阻止。ip-mac-port對映靜態設定比較麻煩,可以開啟交換機上面的DHCP SNOOPING功能, DHCP Snooping可以自動的學習IP和MAC以及埠的配對,並將學習到的對應關係儲存到交換機的本地資料庫中。
預設情況下,交換機上每個埠只允許繫結一個IP-MAC條目,所以在使用docker macvlan時要開啟這樣的限制。
整體思路
以下實現基於docker1.13,物理機使用192.168.0.0/16
網段,容器使用172.31.0.0/16
網段。
- docker host,自定義ipam plugin負責ip地址管理,每個docker host執行一個ipam plugin,並根據ipam plugin建立local scope的macvlan network。
- 建立容器時使用macvlan網路
- 外接交換機負責容器之間、host之間、容器與host之間的連通性。
docker macvlan 用802.1q模式,對於一個交換機埠來說:
- 物理機和容器的資料包屬於不同的vlan,so, 交換機埠設定為trunk;
- 物理機和容器的資料包屬於不同的網段,so,在交換機的三層加一層路由,打通物理機和容器的兩個網段。
macvlan網路
物理機建立vlan的sub interface
使用802.1q vlan時,我們發出去的資料包,要有802.1q中的vlan tag。為了不影響物理網絡卡的正常使用,就是隻有基於sub interface(eth1.10)來發送802.1q package。
-
Load the 802.1q module into the kernel.
sudo modprobe 8021q
-
Create a new interface that is a member of a specific VLAN, VLAN id 10 is used in this example. Keep in mind you can only use physical interfaces as a base, creating VLAN’s on virtual interfaces (i.e. eth0:1) will not work. We use the physical interface eth1 in this example. This command will add an additional interface next to the interfaces which have been configured already, so your existing configuration of eth1 will not be affected.
sudo vconfig add eth1 10
-
Assign an address to the new interface.
sudo ip addr add 10.0.0.1/24 dev eth0.10
-
Starting the new interface.
sudo ip link set up eth0.10
基於sub interface建立docker macvlan 網路
docker network create -d macvlan \
--subnet=172.31.0.0/16 \
--gateway=172.31.0.1 \
-o parent=eth0.10 macvlan10
建立容器,指定使用macvlan網路
docker run --net=macvlan10 -it --name macvlan_test5 --rm alpine /bin/sh