1. 程式人生 > 實用技巧 >容器網路(八)macvlan 網路結構分析【51】

容器網路(八)macvlan 網路結構分析【51】

(九)macvlan 網路結構分析

上一節我們建立了 macvlan 並部署了容器,本節詳細分析 macvlan 底層網路結構。

(1)macvlan 網路結構分析

macvlan 不依賴 Linux bridge,brctl show 可以確認沒有建立新的 bridge。

root@host2:~# brctl show
bridge name	bridge id		STP enabled	interfaces
br-283474cba87c		8000.024237a184c6	no		
br-ba21840c1713		8000.0242f55e6a61	no		
docker0		8000.0242a529e093	no	

檢視一下容器 bbox11 的網路裝置:

root@host2:~# docker exec bbox11 ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
8: eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:10:56:0c brd ff:ff:ff:ff:ff:ff

​ 除了 lo,容器只有一個 eth0,請注意 eth0 後面的@if4

,這表明該 interface 有一個對應的 interface,其全域性的編號為3。根據 macvlan 的原理,我們有理由猜測這個 interface 就是主機的 ens38,確認如下:

root@host2:~# ip link show ens38
3: ens38: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:58:95:95 brd ff:ff:ff:ff:ff:ff
root@host2:~# 

​ 可見,容器的 eth0 就是 ens33 通過 macvlan 虛擬出來的 interface。容器的 interface 直接與主機的網絡卡連線,這種方案使得容器無需通過 NAT 和埠對映就能與外網直接通訊(只要有閘道器),在網路上與其他獨立主機沒有區別。當前網路結構如圖所示:

(2)用 sub-interface 實現多 macvlan 網路

macvlan 會獨佔主機的網絡卡,也就是說一個網絡卡只能建立一個 macvlan 網路,否則會報錯:

root@host2:~# docker network create -d macvlan  -o parent=ens38 mac_net2
Error response from daemon: network dm-e46963ceafd9 is already using parent interface ens38
root@host2:~# 

但主機的網絡卡數量是有限的,如何支援更多的 macvlan 網路呢?

好在 macvlan 不僅可以連線到 interface(如 ens38),也可以連線到 sub-interface(如 ens38.xxx)。

VLAN 是現代網路常用的網路虛擬化技術,它可以將物理的二層網路劃分成多達 4094 個邏輯網路,這些邏輯網路在二層上是隔離的,每個邏輯網路(即 VLAN)由 VLAN ID 區分,VLAN ID 的取值為 1-4094。

Linux 的網絡卡也能支援 VLAN(apt-get install vlan),同一個 interface 可以收發多個 VLAN 的資料包,不過前提是要建立 VLAN 的 sub-interface。比如希望 ens38同時支援 VLAN10 和 VLAN20,則需建立 sub-interface ens38.10 和 ens38.20。

在交換機上,如果某個 port 只能收發單個 VLAN 的資料,該 port 為 Access 模式,如果支援多 VLAN,則為 Trunk 模式,所以接下來實驗的前提是:ens38 要接在交換機的 trunk 口上。不過我們用的是 VirtualBox 虛擬機器,則不需要額外配置了。

下面演示如何在 ens38.10 和 ens38.20 上建立 macvlan 網路。 首先編輯 host1 和 host2 的 /etc/network/interfaces,配置 sub-

root@host1:~# cat /etc/netplan/00-installer-config.yaml 
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens33:
      addresses:
      - 10.0.0.21/24
      gateway4: 10.0.0.254
      nameservers:
        addresses:
        - 223.5.5.5
     auto ens38:
       iface ens38 inet manual:
         auto ens38.10:
           iface ens38.10 inet manual:
             vlan-raw-device ens38:
         auto enp0s9.20:
           iface ens38.20 inet manual:
             vlan-raw-device ens38:
  version: 2
root@host1:~#

然後啟用 sub-interface:

ifconfig ens38 up
ifconfig ens38 up

另外方法:

 使用 vconfig 命令在 eth0 配置兩個 VLAN
vconfig add ens38 100
vconfig add ens38 200
# 設定 VLAN 的 REORDER_HDR 引數,預設就行了
vconfig set_flag ens38.100 1 1
vconfig set_flag ens38.200 1 1
# 啟用介面
ifconfig ens38.100 up
ifconfig ens38.200 up
分別在 host1 和 host2 上基於兩個 VLAN 子介面建立 2 個 macvlan 網路,mac10 和 mac20。
docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens38.100 mac10
docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=ens38.200 mac20
3 分別在 host1 和 host2 上執行容器,並指定不同的 macvlan 網路。
# host1
docker run -itd --name d1 --ip=172.16.10.10 --network mac10 busybox
docker run -itd --name d2 --ip=172.16.20.10 --network mac20 busybox

# host2 
docker run -itd --name d3 --ip=172.16.10.11 --network mac10 busybox
docker run -itd --name d4 --ip=172.16.20.11 --network mac20 busybox


建立 macvlan 網路:

docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=ens38.10 mac_net10
docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=ens38.20 mac_net20

在 host1 中執行容器:

docker run -itd --name bbox01 --ip=172.16.10.10 --network mac_net10 busybox
docker run -itd --name bbox02 --ip=172.16.20.10 --network mac_net20 busybox

在 host2 中執行容器:

docker run -itd --name bbox03 --ip=172.16.10.11 --network mac_net10 busybox
docker run -itd --name bbox04 --ip=172.16.20.11 --network mac_net20 busybox

當前網路結構如圖所示: