上一节咱们建立了 macvlan 并部署了容器,本节详细分析 macvlan 底层网络结构。docker
macvlan 不依赖 Linux bridge,brctl show
能够确认没有建立新的 bridge。网络
查看一下容器 bbox1 的网络设备:spa
除了 lo,容器只有一个 eth0,请注意 eth0 后面的 @if4
,这代表该 interface 有一个对应的 interface,其全局的编号为 4
。根据 macvlan 的原理,咱们有理由猜想这个 interface 就是主机的 enp0s9,确认以下:code
可见,容器的 eth0 就是 enp0s9 经过 macvlan 虚拟出来的 interface。容器的 interface 直接与主机的网卡链接,这种方案使得容器无需经过 NAT 和端口映射就能与外网直接通讯(只要有网关),在网络上与其余独立主机没有区别。当前网络结构如图所示:ip
macvlan 会独占主机的网卡,也就是说一个网卡只能建立一个 macvlan 网络,不然会报错:部署
但主机的网卡数量是有限的,如何支持更多的 macvlan 网络呢?get
好在 macvlan 不只能够链接到 interface(如 enp0s9),也能够链接到 sub-interface(如 enp0s9.xxx)。虚拟机
VLAN 是现代网络经常使用的网络虚拟化技术,它能够将物理的二层网络划分红多达 4094 个逻辑网络,这些逻辑网络在二层上是隔离的,每一个逻辑网络(即 VLAN)由 VLAN ID 区分,VLAN ID 的取值为 1-4094。it
Linux 的网卡也能支持 VLAN(apt-get install vlan
),同一个 interface 能够收发多个 VLAN 的数据包,不过前提是要建立 VLAN 的 sub-interface。容器
好比但愿 enp0s9 同时支持 VLAN10 和 VLAN20,则需建立 sub-interface enp0s9.10 和 enp0s9.20。
在交换机上,若是某个 port 只能收发单个 VLAN 的数据,该 port 为 Access 模式,若是支持多 VLAN,则为 Trunk 模式,因此接下来实验的前提是:
enp0s9 要接在交换机的 trunk 口上。不过咱们用的是 VirtualBox 虚拟机,则不须要额外配置了。
若是你们想了解更多 Linux VLAN 实践,可参看 CloudMan 《天天5分钟玩转 OpenStack》中的相关章节。
下面演示如何在 enp0s9.10 和 enp0s9.20 上建立 macvlan 网络。
首先编辑 host1 和 host2 的 /etc/network/interfaces,配置 sub-
auto enp0s9
iface enp0s9 inet manual
auto enp0s9.10
iface enp0s9.10 inet manual
vlan-raw-device enp0s9
auto enp0s9.20
iface enp0s9.20 inet manual
vlan-raw-device enp0s9
而后启用 sub-interface:
ifup enp0s9.10
ifup enp0s9.20
建立 macvlan 网络:
docker network create -d macvlan --subnet=172.16.10.0/24 --gateway=172.16.10.1 -o parent=enp0s9.10 mac_net10
docker network create -d macvlan --subnet=172.16.20.0/24 --gateway=172.16.20.1 -o parent=enp0s9.20 mac_net20
在 host1 中运行容器:
docker run -itd --name bbox1 --ip=172.16.10.10 --network mac_net10 busybox
docker run -itd --name bbox2 --ip=172.16.20.10 --network mac_net20 busybox
在 host2 中运行容器:
docker run -itd --name bbox3 --ip=172.16.10.11 --network mac_net10 busybox
docker run -itd --name bbox4 --ip=172.16.20.11 --network mac_net20 busybox
当前网络结构如图所示:
这四个容器之间的连通性如何?下一节咱们将详细讨论 macvlan 网络的连通和隔离特性。