原文连接:Linux 虚拟网卡技术:Macvlanhtml
在 Macvlan 出现以前,咱们只能为一块以太网卡添加多个 IP 地址,却不能添加多个 MAC 地址,由于 MAC 地址正是经过其全球惟一性来标识一块以太网卡的,即使你使用了建立 ethx:y
这样的方式,你会发现全部这些“网卡”的 MAC 地址和 ethx 都是同样的,本质上,它们仍是一块网卡,这将限制你作不少二层的操做。有了 Macvlan
技术,你能够这么作了。linux
Macvlan 容许你在主机的一个网络接口上配置多个虚拟的网络接口,这些网络 interface
有本身独立的 MAC 地址,也能够配置上 IP 地址进行通讯。Macvlan 下的虚拟机或者容器网络和主机在同一个网段中,共享同一个广播域。Macvlan 和 Bridge
比较类似,但由于它省去了 Bridge 的存在,因此配置和调试起来比较简单,并且效率也相对高。除此以外,Macvlan 自身也完美支持 VLAN
。web
同一 VLAN 间数据传输是经过二层互访,即 MAC 地址实现的,不须要使用路由。不一样 VLAN 的用户单播默认不能直接通讯,若是想要通讯,还须要三层设备作路由,Macvlan 也是如此。用 Macvlan 技术虚拟出来的虚拟网卡,在逻辑上和物理网卡是对等的。物理网卡也就至关于一个交换机,记录着对应的虚拟网卡和 MAC 地址,当物理网卡收到数据包后,会根据目的 MAC 地址判断这个包属于哪个虚拟网卡。**这也就意味着,只要是从 Macvlan 子接口发来的数据包(或者是发往 Macvlan 子接口的数据包),物理网卡只接收数据包,不处理数据包,因此这就引出了一个问题:本机 Macvlan 网卡上面的 IP 没法和物理网卡上面的 IP 通讯!**关于这个问题的解决方案咱们下一节再讨论。bash
咱们先来看一下 Macvlan 技术的流程示意图:markdown
简单来讲,Macvlan 虚拟网卡设备是寄生在物理网卡设备上的。发包时调用本身的发包函数,查找到寄生的物理设备,而后经过物理设备发包。收包时,经过注册寄生的物理设备的 rx_handler
回调函数,处理数据包。网络
说到 Macvlan,就不得不提 Bridge
,由于你能够把 Macvlan 当作一个简单的 Bridge。但他们之间仍是有很大的区别的。less
Bridge 实际上就是一种旧式交换机,他们之间并无很大的差异。Bridge 与交换机的区别在与市场,而不在与技术。交换机对网络进行分段的方式与 Bridge 相同,交换机就是一个多端口的网桥。确切地说,高端口密度的 Bridge 就称为局域网交换机。ide
Bridge 有如下特色:函数
Frame
)。Linux Bridge
)。如下是一个在 Linux 主机上,多个 VM 使用 bridge 相互通信的情况:工具
Linux 主机中能够经过命令行工具 brctl
来查看 Bridge 的配置,该工具能够经过安装软件包 bridge-utils
来得到。
$ brctl show
bridge name bridge id STP enabled interfaces
br0 8000.080006ad34d1 no eth0
veth0
br1 8000.080021d2a187 no veth1
veth2
复制代码
Bridge 有可能会遇到二层环路,若有须要,你能够开启 STP 来防止出现环路。
Macvlan 有如下特色:
sub interface
);而实体网卡则称为父接口(parent interface
)。parent interface
能够是一个物理接口(eth0),能够是一个 802.1q 的子接口(eth0.10),也能够是 bonding
接口。sub interface
没法直接与 parent interface
通信 (带有 sub interface 的 VM 或容器没法与 host 直接通信)。sub interface
给 host 用。mac0@eth0
的形式来命名以方便区別。用张图来解释一下设定 Macvlan 后的样子:
Macvlan 共支持四种模式,分别是:
在 VEPA
模式下,全部从 Macvlan 接口发出的流量,无论目的地所有都发送给父接口,即便流量的目的地是共享同一个父接口的其它 Macvlan 接口。在二层网络场景下,因为生成树协议的缘由,两个 Macvlan 接口之间的通信会被阻塞,这时须要上层路由器上为其添加路由(须要外部交换机配置 Hairpin
支持,即须要兼容 802.1Qbg 的交换机支持,其能够把源和目的地址都是本地 Macvlan 接口地址的流量发回给相应的接口)。此模式下从父接口收到的广播包,会泛洪给 VEPA 模式的全部子接口。
如今大多数交换机都不支持 Hairpin
模式,但 Linux 主机中能够经过一种 Harpin
模式的 Bridge 来让 VEPA
模式下的不一样 Macvlan 接口通讯(前文已经提到,Bridge 其实就是一种旧式交换机)。怎么配置呢?很是简单,经过一条命令就能够解决:
$ brctl hairpin br0 eth1 on
复制代码
或者使用 iproute2
来设置:
$ bridge link set dev eth0 hairpin on 复制代码
若是你的内核是你手工编译升级的,那么可能你的用户态程序并不支持新内核对应的全部特性,也就是说你的 brctl
可能版本过老不支持 hairpin 命令,那么能够 sysfs
来搞定:
$ echo 1 >/sys/class/net/br0/brif/eth1/hairpin_mode 复制代码
在 Linux 主机上配置了 Harpin
模式以后,源和目的地址都是本地 Macvlan 接口地址的流量,都会被 br0
(假设你建立的 Bridge 是 br0)发回给相应的接口。
若是想在物理交换机层面对虚拟机或容器之间的访问流量进行优化设定,VEPA 模式将是一种比较好的选择。
VEPA
和Passthru
模式下,两个 Macvlan 接口之间的通讯会通过主接口两次:第一次是发出的时候,第二次是返回的时候。这样会影响物理接口的宽带,也限制了不一样 Macvlan 接口之间通讯的速度。若是多个 Macvlan 接口之间通讯比较频繁,对于性能的影响会比较明显。
此种模式相似 Linux 的 Bridge,拥有相同父接口的两块 Macvlan 虚拟网卡是能够直接通信的,不须要把流量经过父网卡发送到外部网络,广播帧将会被泛洪到链接在"网桥"上的全部其余子接口和物理接口。这比较适用于让共享同一个父接口的 Macvlan 网卡进行直接通信的场景。
这里所谓的 Bridge 指的是在这些网卡之间,数据流能够实现直接转发,不须要外部的协助,这有点相似于 Linux host 内建了一个 Bridge,即用 brctl 命令所作的那一切。但和 Linux bridge 毫不是一回事,它不须要学习 MAC 地址,也不须要 STP
,所以效能比起使用 Linux bridge 好上不少。
Bridge 模式有个缺点:若是父接口 down 掉,全部的 Macvlan 子接口也会所有 down 掉,同时子接口之间也将没法进行通信。
此种模式至关于 VEPA
模式的加强模式,其彻底阻止共享同一父接口的 Macvlan 虚拟网卡之间的通信,即便配置了 Hairpin
让从父接口发出的流量返回到宿主机,相应的通信流量依然被丢弃。具体实现方式是丢弃广播/多播数据,这就意味着以太网地址解析 arp
将不可运行,除非手工探测 MAC 地址,不然通讯将没法在同一宿主机下的多个 Macvlan 网卡间展开。之因此隔离广播流量,是由于以太网是基于广播的,隔离了广播,以太网将失去了依托。
此种模式会直接把父接口和相应的MacVLAN接口捆绑在一块儿,这种模式每一个父接口只能和一个 Macvlan 虚拟网卡接口进行捆绑,而且 Macvlan 虚拟网卡接口继承父接口的 MAC 地址。
此种模式的优势是虚拟机和容器能够更改 MAC 地址和其它一些接口参。
最后咱们再来讨论一下 Macvlan 和 Bridge 的各自使用场景。
使用 Macvlan:
使用 Bridge:
Macvlan 是将 VM 或容器经过二层链接到物理网络的近乎理想的方案,但它也有一些局限性:
Ipvlan
,感兴趣能够本身查阅相关资料。本文主要介绍了 Macvlan 的实现原理,比较了它和 Linux Bridge 模式之间的差别及其使用场景,还详细剖析了 Macvlan 四种模式的工做原理和相关注意项。下一节咱们将经过实际演练来模拟 Macvlan 的四种工做模式。