Linux提供丰富的网络命名空间的隔离内容,网络命名空间为空间内所有的进程提供了全套的网络设施(独立的设备界面,路由表,ARP表,IP地址表,iptables规则等),Linux网络虚拟化技术是openstack网络,docker容器网络以及k8s网络等虚拟网络的基础。
这里主要介绍Linux常用到的虚拟网络接口类型,关于其他内容可以查看之前的<
网卡:tunp/tap 与veth
tun/tap 与veth是当前主流的虚拟网卡方案
tun/tap 是操作系统内核中的虚拟网络设备,为用户层程序提供数据的接收与传输。物理网络接口如veth0或ens160 ,接口两端分别是内核协议栈和外面的物理网络。
而对于TUN/TAP 虚拟接口 比如 tun0,接口一端是连接用户层程序,另外一端则是根据配置的方式不同而不一样,可以跟物理网卡一样直接连接内核协议栈,也可以连接网桥(bridge)。Linux通过内核模块TUN提供tun/tap功能,该模块提供了一个设备接口/dev/net/tun 供用户层程序读写,用户层程序通过/dev/net/tun 读写主机内核协议栈的数据。
tun和tap是两种类型的虚拟设备,其一大区别是:
tun是一个点对点的三层设备(网络层设备),从tun设备读取数据,你将能够拿到三层包tap是一个二层设备(以太网设备),从tap网卡获取数据,你将能拿到二层包
tap/tun 和网络协议栈的数据传输

图中tun0就是虚拟出来的虚拟网卡,跟物理网卡eth0的区别就是eth0 连接着物理网络,而tun0连接着应用。这样协议栈发给tun0发的数据包就可以被应用读取到(图中线3),并且可以对数据包进行一些自定义的修改,然后再通过物理网卡发送出去(图中线4,5,6),这就是现在大多数代理服务的实现原理。
我们可以大致的看下数据包的传输流程:
假设eth0的ip为 10.1.1.11 tun0的ip:192.165.1.12
1.服务A构建数据包,目标ip为192.165.1.12,通过socket A将数据包发送到协议栈。2.linux网络协议栈根据数据包的目标ip,进行路由匹配,发现要从tun0发送出去3.tun0发现自己的另一端被服务B打开,所以把数据包发送给服务B4.服务B收到数据后,对原数据包进行自定义的处理,然后构建一个新的数据包,原ip是eth0的ip,目标ip是10.1.1.0/24的网关 10.1.1.1,重新封装数据包,然后重新发给网络协议栈5.网络协议栈根据本地的路由匹配,将数据包通过eth0网卡发送出去
TUN/TAP 应用最多的场景是 VPN 代理:
clash : 一个支持各种规则的隧道,也支持 TUN 模式tun2socks : 一个全局透明代理,和 VPN 的工作模式一样,它通过创建虚拟网卡+修改路由表,在第三层网络层代理系统流量。
veth(Virtual Ethernet)
veth实际上不是一个网络设备而是一对设备,要使用veth,必须在两个独立的网络名称空间中才有意义,因为veth pair是一端连接着协议栈,另一端彼此相连接,在 veth 设备的其中一端输入数据,这些数据就会从设备的另外一端原样不变地流出。

veth比起tap/tun 具有更好的性能,因为两个容器之间使用veth通信不需要多次经过网络协议栈。veth以模拟网卡直连的方式很好解决了两个容器之间的通信问题,但是对于多个容器之间的通行依旧使用veth pair的话会变得比较复杂,这个时候就需要虚拟交换机来解决多容器之间的通信问题。
交换机:Linux Bridge
Linux Bridge 是工作在链路层的网络交换机,由 Linux 内核模块 brige 提供,它负责在所有连接到它的接口之间转发链路层数据包,由brctl命令创建与管理。Linux Bridge 创建以后,便能够接入任何位于二层的网络设备,无论是真实的物理设备(譬如 eth0)抑或是虚拟的设备(譬如 veth 或者 tap)都能与 Linux Bridge 配合工作。
当有二层数据包(以太帧)从网卡进入 Linux Bridge,它将根据数据包的类型和目标 MAC 地址,按如下规则转发处理:
如果数据包是广播帧,转发给所有接入网桥的设备。
如果数据包是单播帧:
且 MAC 地址在地址转发表中不存在,则洪泛(Flooding)给所有接入网桥的设备,并将响应设备的接口与 MAC 地址学习(MAC Learning)到自己的 MAC 地址转发表中。
且 MAC 地址在地址转发表中已存在,则直接转发到地址表中指定的设备。
如果数据包是此前转发过的,又重新发回到此 Bridge,说明冗余链路产生了环路。由于以太帧不像 IP 报文那样有 TTL 来约束,因此一旦出现环路,如果没有额外措施来处理的话就会永不停歇地转发下去。对于这种数据包就需要交换机实现生成树协议(Spanning Tree Protocol,STP)来交换拓扑信息,生成唯一拓扑链路以切断环路。
bridge的应用
虚拟机场景(桥接模式)
以KVM的qemu-kvm为例,在虚拟机的网桥模式下,qemu-kvm会为虚拟机创建一个tun/tap的虚拟网卡,连接到br0网桥。在虚拟机的内部,网络接口eth0是qemu-kvm软件模拟的,实际上的虚拟机内网络数据的收发都会被qemu-kvm转换成对/dev/net/tun 的读写。

vm发送数据到其他宿主机的流程
虚拟机发出去的数据包先到达 qemu-kvm 程序数据被用户层程序 qemu-kvm 写入到 /dev/net/tun,到达 tap 设备tap 设备把数据传送到 br0 网桥br0 把数据交给 eth0 发送出去整个流程跑完,数据包都不需要经过宿主机的协议栈,效率高。
容器通信场景(容器网络,NAT 模式)
docker/podman 提供的 bridge 网络模式,就是使用 veth+bridge+iptalbes 实现的
容器运行在自己单独的netwaork namespace 里面,也有自己单独的协议栈。容器网络的结构跟上面虚拟机差不多,不过使用了NAT网络,把虚拟路由器改成veth,这样就导致docker0过来的数据,都要经过宿主机的协议栈,然后才到eth0接口。

vlan
vlan 即虚拟局域网,是一个链路层的广播域隔离技术,可以用于切分局域网,解决广播泛滥和安全性问题。被隔离的广播域之间需要上升到第三层才能完成通讯。其基本原理是在二层协议里插入额外的VLAN协议数据(称为 802.1.q VLAN Tag),同时保持和传统二层设备的兼容性。Linux里的VLAN设备是对 802.1.q 协议的一种内部软件实现,模拟现实世界中的 802.1.q 交换机

对于vlan的几点理解
1.VLAN分离了广播域;
2.单独的一个VLAN模拟了一个常规的交换以太网,因此VLAN将一个物理交换机分割成了一个或多个逻辑交换机;
3.不同VLAN之间通信需要三层参与;
4.当多台交换机级联时,VLAN通过VID来识别,该ID插入到标准的以太帧中,被称作tag;
5.大多数的tag都不是端到端的,一般在上行路上第一个VLAN交换机打tag,下行链路的最后一个VLAN交换机去除tag;
6.只有在一个数据帧不打tag就不能区分属于哪个VLAN时才会打上tag,能去掉时尽早要去掉tag;
7.最终,IEEE 802.1q解决了VLAN的tag问题。除了IEEE 802.1q,其余的都是和实现相关的,虽然Cisco和H3C的实现很类似,Linux可以和它们有大不同。
VXLAN
什么是VXLAN
在介绍vxlan之前,需要介绍两个名词:
underlay网络:即物理网络
overlay网络:指在现有的物理网络之上构建的虚拟网络。其实就是一种隧道技术,将原生态的二层数据帧报文进行封装后通过隧道进行传输
VXLAN就属于overlay网络协议,使用UDP包来封装数据链路层的以太网帧,目前所有overlay的跨主机容器网络方案,基本都是基于vxlan是实现的
VXLAN即虚拟扩展局域网,是大二层网络中广泛使用的网络虚拟化技术。在源网络设备与目的网络设备之间建立一条逻辑VXLAN隧道,采用MAC in UDP(User Datagram Protocol)封装方式,即,将虚拟机发出的原始以太报文完整的封装在UDP报文中,然后在外层使用物理网络的IP报文头和以太报文头封装,这样,封装后的报文就像普通IP报文一样,可以通过路由网络转发,这就像给二层网络的虚拟机插上了路由的翅膀,使虚拟机彻底摆脱了二、三层网络的结构限制。
VXLAN的出现解决了什么问题:
虚拟化(虚拟机和容器)的兴起使得一个数据中心会有成千上万的机器需要通信,而传统的 VLAN 技术只能支持 4096 个网络上限,已经满足不了不断扩展的数据中心规模
越来越多的数据中心(尤其是公有云服务)需要提供多租户的功能,不同用户之间需要独立地分配 ip 和 MAC 地址,如何保证这个功能的扩展性和正确性也是一个待解决的问题
云计算业务对业务灵活性要求很高,虚拟机可能会大规模迁移,并保证网络一直可用,也就是大二层的概念。解决这个问题同时保证二层的广播域不会过分扩大,也是云计算网络的要求
VXLAN的模型
vxlan 这类隧道网络的一个特点是对原有的网络架构影响小,原来的网络不需要做任何改动,在原来网络基础上架设一层新的网络。
vxlan 自然会引入一些新的概念,这部分就讲讲它们。下面这张图 是 vxlan 的工作模型,它创建在原来的 IP 网络(三层)上,只要是三层可达(能够通过 IP 互相通信)的网络就能部署 vxlan。在每个端点上都有一个 vtep 负责 vxlan 协议报文的封包和解包,也就是在虚拟报文上封装 vtep 通信的报文头部。物理网络上可以创建多个 vxlan 网络,这些 vxlan 网络可以认为是一个隧道,不同节点的虚拟机能够通过隧道直连。每个 vxlan 网络由唯一的 VNI 标识,不同的 vxlan 可以不相互影响

VXLAN的特有名词介绍
什么是VXLAN VTEP
VTEP(VXLAN Tunnel Endpoints,VXLAN隧道端点)是VXLAN网络的边缘设备,是VXLAN隧道的起点和终点,源服务器发出的原始数据帧,在VTEP上被封装成VXLAN格式的报文,并在IP网络中传递到另外一个VTEP上,并经过解封转还原出原始的数据帧,最后转发给目的服务器。
什么是VXLAN VNI
VNI(VXLAN Network Identifier,VXLAN 网络标识符),VNI是一种类似于VLAN ID的用户标识,一个VNI代表了一个租户,属于不同VNI的虚拟机之间不能直接进行二层通信。
VNI还可分为二层VNI和三层VNI,它们的作用不同,二层VNI是普通的VNI,用于VXLAN报文同子网的转发;三层VNI和VPN实例进行关联,用于VXLAN报文跨子网的转发。
Tunnel
Tunnel(隧道)是一个逻辑上的概念,在 vxlan 模型中并没有具体的物理实体想对应。隧道可以看做是一种虚拟通道,vxlan 通信双方(图中的虚拟机)认为自己是在直接通信,并不知道底层网络的存在。从整体来说,每个 vxlan 网络像是为通信的虚拟机搭建了一个单独的通信通道,也就是隧道
对于vxlan的详细介绍这里就不再展开,推荐有兴趣的大佬可以看下下面的推荐文章
https://info.support.huawei.com/info-finder/encyclopedia/zh/VXLAN.html
https://blog.invgate.com/vxlan-vs-vlan
https://cizixs.com/2017/09/25/vxlan-protocol-introduction/
https://gobomb.github.io/post/learning-linux-veth-and-bridge/
http://icyfenix.cn/immutable-infrastructure/network/linux-vnet.html#%E8%99%9A%E6%8B%9F%E5%8C%96%E7%BD%91%E7%BB%9C%E8%AE%BE%E5%A4%87