tun/tap 与 bridge+vnet 与 macvtap 有什么区别?(用于虚拟化 KVM)

tun/tap 与 bridge+vnet 与 macvtap 有什么区别?(用于虚拟化 KVM)

我刚刚发现了很多不同的 KVM 网络实现方法。但我不知道哪种方法才是正确的。我发现 openstack 使用 macvtap 来实现 neutron 网络。而且看起来不错。

但是它们之间有什么区别以及为什么要使用每种方式呢?

方法 1 [ OLD? TUN/TAP ]

http://www.shakthimaan.com/installs/debian-tun-tap-setup.html

/--------\   /----\   /----\   /----\   /--------\
|Internet|---|eth0|---|br0 |---|tap0|---|Guest NIC
\--------/   \----/   \----/   \----/   \--------/

已经弃用了,对吧?

方法 2 [ Bridge+Vnet ] <- 这就是 virt-manager 所做的

http://www.linux-kvm.com/content/using-bridged-networking-virt-manager

基本上,你创建一个桥接接口,里面有你的物理接口,

auto br0
#iface br0 inet dhcp
iface br0 inet static
address 172.16.0.100
network 172.16.0.0
netmask 255.255.0.0
broadcast 172.16.255.255
gateway 172.16.0.1
   bridge_ports eth2
   bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

当您从 virt-manager 启动虚拟机时,会创建一个 vnet 接口并将其添加到网桥。至少到目前为止我知道是这样。不需要 tun/tap 接口。

它在很长一段时间内都运行得很好,但现在我发现了一些问题。

https://bugs.launchpad.net/ubuntu/+source/core-network/+bug/1255516

为什么没有 TAP 接口就可以向桥接器添加新的 vnet 接口?

方式 3 [ MACVTAP ]

最后是macvtap接口。

http://virt.kernelnewbies.org/MacVTap

它复制了 TUN/TAP 软件接口,但做得更好。不知道是什么方式,但似乎更好。

macvtap 相对于第二种方式有什么优势?

有什么更好的?

对此有什么帮助吗?

答案1

这些方法的作用从根本上是不同的。要理解原因,您需要了解网络的分层模型。就我们的目的而言,第 1、2 和 3 层很重要:

  • 第 1 层是物理层 - 它指定了可以使用哪些电缆、哪些电压/电流模式代表该电缆上的 1 和 0、电缆两端的设备如何协商它们以什么比特率运行等等。
  • 第 2 层是链路层 - 它指定电缆两端的事物以何种语言进行通信。此层的以太网设备具有帧和 MAC 地址等内容。
  • 第 3 层是网络层 - 它指定设备如何使用到另一台设备的直接第 2 层链路到达它们在第 2 层无法直接到达的第三个设备。此层的设备具有 IP 地址和路由表。

MACVLAN/MACVTAP

MACVLAN 创建一个虚拟的第 2 层或链路层设备,它具有自己的 MAC 地址,并与现有设备共享第 1 层或物理层。最明显可理解的情况是,您将以太网设备插入网络,并基于该以太网设备创建 MACVLAN 设备;现在您有两个具有不同 MAC 地址的以太网“设备”,但它们都在同一条电缆上传输帧。我将在下文中讨论 MACVTAP。

MACVLAN 接口能够以多种不同的方式与现有的以太网接口进行交互,特别是当一个帧出现在其中一个接口上,而该帧的地址是另一个接口的地址时:

  • 私人的模式,该帧被丢弃;两个接口无法相互通信,只能与外部设备通信。
  • 韦帕模式中,帧像任何其他帧一样通过物理层发送。如果您将设备插入到交换机中,该交换机足够聪明,能够发现该帧需要沿其到达的同一端口发送回去,那么它将被发送它的同一物理层接收,然后第 2 层将使用 MAC 将其发送到目标网络接口。
  • 模式,当一个帧出现在一个设备上时,会检查它是否是发往另一个设备的,如果是,则将它发送到另一个设备而不经过第 1 层。
  • 还有一些比较不为人知的模式。

请注意,MACVLAN 接口有一个重要限制:它们无法进行地址学习。因此,您无法将 MACVLAN 接口桥接到第二个物理设备,并期望能够通过第一个物理设备访问第二个物理设备。这适用于原始以太网接口,但不适用于连接到它的 MACVLAN 接口。

调谐/分接

TAP 接口也是一个新的虚拟第 2 层设备,但没有附加第 1 层。相反,程序可以获取表示物理层的文件描述符。然后它可以将原始以太网帧数据写入该文件描述符,内核会将其视为在实际物理接口上收到的任何其他以太网数据包。

TAP 接口的最大特点是物理层处于用户模式;任何具有适当权限的软件都可以以任何方式生成以太网帧,并将它们推送到内核视为真实物理接口的东西中。这使得它们对于 VPN 和隧道等非常有用;您可以在用户空间中编写任何类型的隧道软件,并且无需干预内核空间即可将帧放入网络堆栈,您只需创建一个 TAP 设备并将帧写入其文件描述符即可。

TUN 设备与 TAP 设备类似,只是它们在第 3 层而不是第 2 层运行,并且用户模式软件必须将原始 IP 数据包而不是原始以太网帧写入文件描述符。

回到移动式真空泵设备,这些是 MACVLAN 和 TAP 接口的混合体。与 TAP 接口一样,用户模式程序可以获取文件描述符并将原始以太网帧写入其中。与 MACVLAN 接口一样,这些帧随后通过真实以太网设备的物理层发送。这允许您轻松地将编写为使用 TAP 设备的软件改为使用 MACVLAN 设备。

虚拟网络

这在概念上类似于 TUN/TAP 网络,但具有更发达的控制平面(因此使用它的用户模式软件可以更灵活地配置接口)和更优化的数据平面(因此您可以更有效地通过虚拟网络设备移动数据)。

这些都做类似的事情,但功能略有不同。它们都可用于将虚拟机连接到以太网:

  • 虚拟化产品可以从客户机获取以太网帧并将其写入 TAP 设备的文件描述符中。主机可以为该 TAP 设备分配自己的 IP 地址,也可以将其与以太网接口一起从属于网桥以共享主机的 IP 地址,或者可以配置 iptables 以使用 NAT 转发其上的流量。
  • 虚拟化产品可以从客户机获取以太网帧并将其写入 MACVTAP 设备的文件描述符中;然后这些帧直接在以太网设备的物理层上传输,从而有效地为虚拟机提供“真正的”以太网设备(但请注意,可以为其他类型的网络接口(如网桥)创建 MACVLAN / MACVTAP 设备)。
  • 虚拟化产品可以将客户机中的 virtio 驱动程序连接到主机中的 virtio 驱动程序,以实现非常高效的网络连接。

答案2

这真的取决于你到底想实现什么

  • 水龙头/调音台

不管是虚拟机还是物理机。TUN 为您带来隧道网络,TAP 为您带来设备。简而言之,您通过隧道网络连接到另一个网络。

例如,配置 OpenVPN 网络时,客户端会为您提供 10.8.0.6。VPN 服务器 10.8.0.1 会将您的请求路由到后面的另一个网络(例如 192.168.xx)。使用 TAP 时,您会直接从目标网络(192.168.10.x/24)收到 IP(192.168.10.10/24)。很简单。

“Linux Bridge”将 VNET(来自 VM)桥接到物理以太网。如果您想要 VM(基于 KVM),则必须在主机上的 VNET 和以太网之间建立桥接

答案3

我想说这取决于你的使用情况。

自动添加/删除虚拟主机?

尝试一下 macvtap。应该也比 macvlan(这大致就像在物理设备中添加另一个 MAC,到达那里的信息由网络堆栈处理)或额外的桥接器性能更好,因为 macvtap 以某种方式绕过网络堆栈并直接导出 tap 字符设备。但不要因此而责怪我。除了两者(macvlan/macvtap)共享相同的可用模式(VEPA/hairpin、桥接、私有)之外,只有当您的交换机支持反射中继模式时,hairpinning 才有效。(到达端口 x 的物理交换机的数据包必须被允许再次从同一端口 x 离开交换机。)

因为使用网桥时 eth0(或您使用的任何一个)处于混杂模式,所以 macvXXX 模式被认为具有更高的吞吐量。

这些模式还定义了隔离的“数量”(虚拟主机能否看到彼此的流量?HV 又如何呢?)。我还不知道其内部是如何运作的。

veth(虚拟以太网对)在隔离方面有些类似,您定义两个虚拟接口,一个连接到网桥,另一个连接到您的虚拟机。隔离是通过将 vm 接口放入其自己的命名空间来实现的,因此设备在某种程度上是隔离的。所有流量都汇集在网桥上,但一个虚拟主机无法看到另一个虚拟主机的 vNIC。

如果您使用网桥,则需要进行额外的配置,并且当网桥关闭时,您的所有连接也会关闭。当网桥恢复时,您可能必须将所有虚拟接口重新连接到网桥(或者只需重新启动整个 hv...)。

底线:如果您不经常更改拓扑,只需使用桥接,因为您可以在网上找到最多的信息,这比阅读内核代码要好。哎呀,即使您运行的是最新版,iproute2-doc 包本身也缺少 iproute2 实际拥有的大部分信息。尝试man ip-tcp_metrics从可用的手册页或 ip-crefs.ps 中查找相关信息...

相关内容