一、概述
网络虚拟化是云计算的最重要部分,本文详细讲述 Linux 抽象出来的各种网络设备的原理、用法、数据流向。您通过此文,能够知道如何使用 Linux 的基础网络设备进行配置以达到特定的目的,分析出 Linux 可能的网络故障原因。 二、linux抽象网络设备简介
和磁盘设备类似,Linux用户使用网络功能,不能通过直接操作硬件完成,而需要直接或间接的操作一个Linux为用户抽象出来的设备即通用的Linux网络设备; 三、相关网络设备工作原理
Bridge:
Bridge(网桥)是Linux上用来做TCP/IP二层协议交换的设备,与物理交换机功能相似。Bridge设备实例可以和Linux上其他网络设备实例连接即attach一个从设备,类似于在物理交换机上和用户终端之间连接一个网线。当数据到达时,Bridge会根据报文中的MAC信息进行广播、转发、丢弃处理。【为什么是MAC信息?因为是二层协议交换设备】
VLAN设备工作过程
如图所示,Linux 里 802.1.q VLAN 设备是以母子关系成对出现的,母设备相当于现实世界中的交换机 TRUNK 口,用于连接上级网络,子设备相当于普通接口用于连接下级网络。当数据在母子设备间传递时,内核将会根据 802.1.q VLAN Tag 进行对应操作。母子设备之间是一对多的关系,一个母设备可以有多个子设备,一个子设备只有一个母设备。当一个子设备有一包数据需要发送时,数据将被加入 VLAN Tag 然后从母设备发送出去。当母设备收到一包数据时,它将会分析其中的 VLAN Tag,如果有对应的子设备存在,则把数据转发到那个子设备上并根据设置移除 VLAN Tag,否则丢弃该数据。在某些设置下,VLAN Tag 可以不被移除以满足某些监听程序的需要,如 DHCP 服务程序。举例说明如下:eth0 作为母设备创建一个 ID 为 100 的子设备 eth0.100。此时如果有程序要求从 eth0.100 发送一包数据,数据将被打上 VLAN 100 的 Tag 从 eth0 发送出去。如果 eth0 收到一包数据,VLAN Tag 是 100,数据将被转发到 eth0.100 上,并根据设置决定是否移除 VLAN Tag。如果 eth0 收到一包包含 VLAN Tag 101 的数据,其将被丢弃。上述过程隐含以下事实:对于寄主 Linux 系统来说,母设备只能用来收数据,子设备只能用来发送数据。和 Bridge 一样,母子设备的数据也是有方向的,子设备收到的数据不会进入母设备,同样母设备上请求发送的数据不会被转到子设备上。可以把 VLAN 母子设备作为一个整体想象为现实世界中的 802.1.q 交换机,下级接口通过子设备连接到寄主 Linux 系统网络里,上级接口同过主设备连接到上级网络,当母设备是物理网卡时上级网络是外界真实网络,当母设备是另外一个 Linux 虚拟网络设备时上级网络仍然是寄主 Linux 系统网络。
需要注意的是母子 VLAN 设备拥有相同的 MAC 地址,可以把它当成现实世界中 802.1.q 交换机的 MAC,因此多个 VLAN 设备会共享一个 MAC。当一个母设备拥有多个 VLAN 子设备时,子设备之间是隔离的,不存在 Bridge 那样的交换转发关系,原因如下:802.1.q VLAN 协议的主要目的是从逻辑上隔离子网。现实世界中的 802.1.q 交换机存在多个 VLAN,每个 VLAN 拥有多个端口,同一 VLAN 端口之间可以交换转发,不同 VLAN 端口之间隔离,所以其包含两层功能:交换与隔离。Linux VLAN device 实现的是隔离功能,没有交换功能。一个 VLAN 母设备不可能拥有两个相同 ID 的 VLAN 子设备,因此也就不可能出现数据交换情况。如果想让一个 VLAN 里接多个设备,就需要交换功能。在 Linux 里 Bridge 专门实现交换功能,因此将 VLAN 子设备 attach 到一个 Bridge 上就能完成后续的交换功能。总结起来,Bridge 加 VLAN device 能在功能层面完整模拟现实世界里的 802.1.q 交换机。
Linux 支持 VLAN 硬件加速,在安装有特定硬件情况下,图中所述内核处理过程可以被放到物理设备上完成。 TAP 设备与 VETH 设备
TUN/TAP 设备是一种让用户态程序向内核协议栈注入数据的设备,一个工作在三层,一个工作在二层,使用较多的是 TAP 设备。VETH 设备出现较早,它的作用是反转通讯数据的方向,需要发送的数据会被转换成需要收到的数据重新送入内核网络层进行处理,从而间接的完成数据的注入。
TAP设备和VETH设备工作过程
如图所示,当一个 TAP 设备被创建时,在 Linux 设备文件目录下将会生成一个对应 char 设备,用户程序可以像打开普通文件一样打开这个文件进行读写。当执行 write()操作时,数据进入 TAP 设备,此时对于 Linux 网络层来说,相当于 TAP 设备收到了一包数据,请求内核接受它,如同普通的物理网卡从外界收到一包数据一样,不同的是其实数据来自 Linux 上的一个用户程序。Linux 收到此数据后将根据网络配置进行后续处理,从而完成了用户程序向 Linux 内核网络层注入数据的功能。当用户程序执行 read()请求时,相当于向内核查询 TAP 设备上是否有需要被发送出去的数据,有的话取出到用户程序里,完成 TAP 设备的发送数据功能。针对 TAP 设备的一个形象的比喻是:使用 TAP 设备的应用程序相当于另外一台计算机,TAP 设备是本机的一个网卡,他们之间相互连接。应用程序通过 read()/write()操作,和本机网络核心进行通讯。
VETH 设备总是成对出现,送到一端请求发送的数据总是从另一端以请求接受的形式出现。该设备不能被用户程序直接操作,但使用起来比较简单。创建并配置正确后,向其一端输入数据,VETH 会改变数据的方向并将其送入内核网络核心,完成数据的注入。在另一端能读到此数据。 网络设置举例说明
为了更好的说明 Linux 网络设备的用法,下面将用一系列的例子,说明在一个复杂的 Linux 网络元素组合出的虚拟网络里,数据的流向。网络设置简介如下:一个中心 Bridge:bridge0 下 attach 了 4 个网络设备,包括 2 个 VETH 设备,1 个 TAP 设备 tap0,1 个物理网卡 eth0。在 VETH 的另外一端又创建了 VLAN 子设备。Linux 上共存在 2 个 VLAN 网络,既 vlan100 与 vlan200。物理网卡和外部网络相连,并且在它之下创建了一个 VLAN ID 为 200 的 VLAN 子设备。