Docker Macvlan


參考博客:https://blog.csdn.net/daye5465/article/details/77412619

一、Macvlan

  交換機的vlan是根據端口來划分的,如果一個PC接入vlan10的端口它就在vlan10中,否則就在其他vlan中。而 MAC VLAN 則可以有效解決這個問題,它根據 終端設備的 MAC 地址來划分 VLAN。這樣,即使用戶改變了接入端口,也仍然處在原 VLAN 中。

  macvlan 允許你在主機的一個網絡接口上配置多個虛擬的網絡接口,這些網絡 interface 有自己獨立的 mac 地址,也可以配置上 ip 地址進行通信。macvlan 下的虛擬機或者容器網絡和主機在同一個網段中,共享同一個廣播域。macvlan 和 bridge 比較相似,但因為它省去了 bridge 的存在,所以配置和調試起來比較簡單,而且效率也相對高。除此之外,macvlan 自身也完美支持 VLAN。

       同一Vlan間數據傳輸是通過二層互訪,即mac地址實現的,不需要使用路由。不同vlan的用戶單播默認不能直接通信,如果想要通信,還需要三層設備做路由,Macvlan也是如此。用Macvlan技術虛擬出來的虛擬網卡,在邏輯上和物理網卡是對等的。物理網卡也就相當於一個交換機,記錄着對應的虛擬網卡和MAC地址,當物理網卡收到數據包后,會根據目的mac地址判斷這個包屬於哪一個虛擬網卡。

 

  1.1 條件

  1. Macvlan是Linux內核支持的網絡接口。要求的Linux內部版本是v3.9–3.19和4.0+。
  2. 大多數雲服務商限制了macvlan。確保自身的網絡設備可以使用
  3. 只適合在linux服務器上運行。Mac和windows版本的Docker並不支持,在Windows Server中Docker EE也不支持
  4. 請將網卡名稱 eth0 改成自己的網卡名稱

  1.2 工作原理

  1. 通過為物理網卡創建Macvlan子接口,允許一塊物理網卡擁有多個獨立的MAC地址和IP地址。虛擬出來的子接口將直接暴露在底層物理網絡中。從外界看來,就像是把網線分成多股,分別接到了不同的主機上一樣。
  2. 物理網卡收到包后,會根據收到包的目的MAC地址判斷這個包需要交給哪個虛擬網卡。

  1.3 工作模式

  • VEPA(Virtual Ethernet Port Aggregator)mode:需要主接口連接的交換機支持 VEPA/802.1Qbg 特性。所有發送出去的報文都會經過交換機,交換機作為再發送到對應的目標地址(即使目標地址就是主機上的其他 macvlan 接口),也就是 hairpin mode 模式,這個模式用在交互機上需要做過濾、統計等功能的場景。
  • Brideg mode: 常用  通過虛擬的交換機將主接口的所有 macvlan 接口連接在一起,這樣的話,不同 macvlan 接口之間能夠直接通信,不需要將報文發送到主機之外。這個模式下,主機外是看不到主機上 macvlan interface 之間通信的報文的
  • Private mode: 過濾掉所有來自其他 macvlan 接口的報文,因此不同 macvlan 接口之間無法互相通信
  • Passthru mode:

二、配置Docker Macvlan

  2.1 系統環境

    hostname hostip kernel
docker2 172.16.200.218 4.15.7-1.el7.elrepo.x86_64
docker3 172.16.200.223 4.15.7-1.el7.elrepo.x86_64

   2.2 Bridge Macvlan

  1. 兩台機器都做同樣的操作

docker network create -d macvlan \
> --subnet=172.16.30.1/24 \
> --gateway=172.16.30.1 \
> -o parent=eno16777736 \
> my-macvlan-net

# -d macvlan : 創建macvlan網絡
# subnet : 子網
# gateway: 網關
# -o parent=eno16777736 :橋接到網卡(名稱為自己機器的網卡名稱)
# my-macvlan-net :新建的macvlan 網絡的名稱

  

  查看:

  

  

  2. 創建容器測試聯通 

       單機使用macvlan創建容器測試聯通

# docker 2

docker run -it --net my-macvlan-net --ip=172.16.30.9 busybox

docker run -it --net my-macvlan-net --ip=172.16.30.10 busybox

# 測試聯通
/ # ping 172.16.30.10
PING 172.16.30.10 (172.16.30.10): 56 data bytes
64 bytes from 172.16.30.10: seq=0 ttl=64 time=0.168 ms
64 bytes from 172.16.30.10: seq=1 ttl=64 time=0.048 ms
64 bytes from 172.16.30.10: seq=2 ttl=64 time=0.057 ms


# 聯通沒有問題

  

  3. macvlan網絡

  

  ① 查看C1和C2的網絡設備

  

  除了lo,兩個容器中都有一個eth0,並且后面都有@if2。這表明該 interface 有一個對應的 interface,其全局的編號為 4。Macvlan就是在物理網卡上虛擬出來新的虛擬網卡,所以有理由認為這個interface就是eno16777736(我本機網卡名稱)

  ② 確認網卡

  

  可見eth0 就是 eno16777736 通過macvlan虛擬出來的interface。

  ③ 數據傳輸

  連接在虛擬網卡上的C1和C2同屬於一個vlan(macvlan技術),它們之間傳輸數據不需要經過網關(路由),是通過二層轉發,此時的物理網卡就相當於交換機。

  事實上,網關容器也ping不同(不用經過網關)。

  

  

  4. 雙機macvlan聯通

  在docker3這台機器上已經創建macvlan的網絡 

# docker 3

[root@docker3 ~]# docker run -it --net my-macvlan-net --ip=172.16.30.11 busybox

/ # ping 172.16.30.10
PING 172.16.30.10 (172.16.30.10): 56 data bytes
64 bytes from 172.16.30.10: seq=0 ttl=64 time=0.552 ms
c64 bytes from 172.16.30.10: seq=1 ttl=64 time=0.169 ms
64 bytes from 172.16.30.10: seq=2 ttl=64 time=0.189 ms

  

  3個容器間都可以相互ping同,和上面講的差不多,物理網卡相當於交換機,都是vlan間數據傳輸,只是外部多加了一個交換機。這和交換機的vlan有點類似:

   

  但交換機做的vlan,交換機和交換機之間接口要做trunk,才允許vlan數據包通過。而Macvlan是根據MAC地址來划分vlan的,並不需要設置trunk。

 

  注:容器並不能ping同網關、物理網卡地址和外網地址,這是macvlan自身安全性和隔離性的體現,並不是docker容器的原因。

三、用子接口實現多macvlan網絡

  Macvlan 會獨占主機的網卡,也就是說網卡只能創建一個macvlan網絡:

[root@docker3 ~]# docker network create -d macvlan --subnet=172.16.90.0/24 --gateway=172.16.90.1 -o parent=eno16777736 my-macvlan-net2
Error response from daemon: network dm-d6a68779842b is already using parent interface eno16777736


# 再在同一個網卡上創建macvlan網絡,就報錯了

  主機的網卡數量有限,但是macvlan不僅可以連接到interface,也可以連接到sub-interface(如:eno16777736.xxx)

  一個網絡接口可以創建的子接口數量為4094

      先刪除原本的macvlan網絡

docker network rm my_macvlan_net

  

  1. 創建子接口 

[root@docker3 ~]# ip link add link eno16777736 name eno16777736.100 type vlan id 100

[root@docker3 ~]# ip link add link eno16777736 name eno16777736.101 type vlan id 101
[root@docker3 ~]# ifconfig

  

  如果這兩個子接口沒有起來,重啟一下服務器

 

  2. 根據子接口創建macvlan網絡 

[root@docker3 ~]# docker network create -d macvlan \
> --subnet=172.16.100.0/24 \
> --gateway=172.16.100.1 \
> -o parent=eno16777736.100 \
> macvlan_net100

# parent 選擇剛創建的子接口

 

  3. 根據新的macvlan網絡創建容器  

[root@docker3 ~]# docker run -it --net macvlan_net100 --name box1 --ip=172.16.100.11 busybox

[root@docker3 ~]# docker run -it --net macvlan_net100 --name box2 --ip=172.16.100.12 busybox

  4. 測試網絡連通  

[root@docker3 ~]# docker exec box1 ping 172.16.100.12
PING 172.16.100.12 (172.16.100.12): 56 data bytes
64 bytes from 172.16.100.12: seq=0 ttl=64 time=0.157 ms
64 bytes from 172.16.100.12: seq=1 ttl=64 time=0.059 ms
64 bytes from 172.16.100.12: seq=2 ttl=64 time=0.047 ms
64 bytes from 172.16.100.12: seq=3 ttl=64 time=0.048 ms

  表明在同一台機器上,同一個子接口下的vlan中的設備是互通的

   5.測試不同子接口下vlan間的互通

   其實vlan間默認單播不能直接通信,如果想要通信需要三層路由。Macvlan也是如此:

  創建子接口101的容器(先創建macvlan_net101網絡)  

docker run -it --name box3 --net macvlan_net101 --ip 172.16.101.10 busybox

docker run -it --name box4 --net macvlan_net101 --ip 172.16.101.9 busybox

  測試:

[root@docker3 ~]# docker exec box3 ping 172.16.101.9
PING 172.16.101.9 (172.16.101.9): 56 data bytes
64 bytes from 172.16.101.9: seq=0 ttl=64 time=0.223 ms
64 bytes from 172.16.101.9: seq=1 ttl=64 time=0.050 ms
64 bytes from 172.16.101.9: seq=2 ttl=64 time=0.050 ms
64 bytes from 172.16.101.9: seq=3 ttl=64 time=0.052 ms
64 bytes from 172.16.101.9: seq=4 ttl=64 time=0.052 ms
^C
[root@docker3 ~]# docker exec box3 ping 172.16.100.11
^C


# 可以看出同一個vlan中的容器是可以直接通信的

#  不同vlan即不同子接口下的容器不能直接通信

  6.多主機間多子接口通信  

  多機間Macvlan子接口vlan通信和 Macvlan Bridge是一樣的,同一個vlan間的容器是可以互訪的,不同子接口下即不同vlan間默認不能直接通信。

   在docker2上面也創建兩個子接口100和101 ,其實重復docker3的操作

   創建兩個容器,分別屬於vlan100 和 vlan 101

[root@docker2 ~]# docker run -itd --name box21 --net macvlan_net100 --ip 172.16.100.21 busybox
3934bc62132d4cd8dec9a1cfae64f36ac2d056013a53c5d73a3345afaefee482

[root@docker2 ~]# docker run -itd --name box22 --net macvlan_net101 --ip 172.16.101.22 busybox
2e1c223ae54d430d6c6808fd89b5db8488591edf7c799ec6bd57cb40c2fff421

# box21 : vlan100   172.16.100.21

# box22: vlan101   172.16.101.22

  測試雙機間的互聯: 

root@docker2 ~]# docker exec box21 ping 172.16.100.11
PING 172.16.100.11 (172.16.100.11): 56 data bytes
64 bytes from 172.16.100.11: seq=0 ttl=64 time=4.585 ms
64 bytes from 172.16.100.11: seq=1 ttl=64 time=0.198 ms
64 bytes from 172.16.100.11: seq=2 ttl=64 time=0.205 ms
64 bytes from 172.16.100.11: seq=3 ttl=64 time=0.225 ms
^C

[root@docker2 ~]# docker exec box21 ping 172.16.101.22


^C
[root@docker2 ~]# docker exec box22 ping 172.16.101.9
PING 172.16.101.9 (172.16.101.9): 56 data bytes
64 bytes from 172.16.101.9: seq=0 ttl=64 time=4.789 ms
64 bytes from 172.16.101.9: seq=1 ttl=64 time=0.197 ms
64 bytes from 172.16.101.9: seq=2 ttl=64 time=0.182 ms
^C

# 上述顯示 雙機間同vlan 間可以相互通信

#  不同vlan間不能直接通信

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM