容器網路(八)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
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
當前網路結構如圖所示: