Openvswitch支持三种隧道的方式:

  • gre
  • vxlan
  • ipsec_gre

我们先来看GRE。

GRE全称Generic Routing Encapsulation,是一种隧道协议,通过将其他协议封装在一个点对点的连接中,实现跨公网的网络互联。

如图所示,在左面数据中心的服务器Host A要访问右面数据中心的Host B。

所以Host A发出的包中源地址是A的地址10.0.1.2,目标地址是B的地址10.0.2.2。

然而两个数据中心是通过公网才能通信,所以要在Router A和Router B之间,通过互相的公网地址(172.19.20.18和172.19.20.21)建立一个GRE隧道。

从Host A发出的包先到达Router A,然后通过GRE隧道进行封装,在原来的包头上加上GRE包头,然后外层的源地址和目标地址变成了隧道两端的公网地址(172.19.20.18和172.19.20.21).。

由于外层地址是公网地址,当然可以通过Internet到达,到达Router B之后,在GRE隧道的另一端,将外层公网地址卸掉,然后将GRE包头卸掉,于是剩下了里面原本的源地址和目标地址,目标地址就是Host B的地址,于是成功到达。

当Host B将返回结果发回给Host A的时候,则走完全相反的路径就可以了。

GRE是点对点的连接,并且一个GRE端点可以有多个隧道,因而需要有一个标志位标识当前包属于哪个隧道,这就是GRE包头中的key。

我们再来看VXLAN。

VXLAN要复杂一些,主要是通过通过对L2包的打包和解包实现不同的L2网络感觉在同一个L2网络里面。

VXLAN有几个概念:

  • 需要支持多播和组播,因为在VXLAN网络里面,需要这两个协议发现目标MAC地址
  • VNI,全称VXLAN Network Identifier,是一个24位的ID,用于标识不同的VXLAN
  • VTEP,全称VXLAN Tunnel End Point,是VXLAN隧道的两端

VXLAN的包头如下:

在最原始的包外面,首先加上的是VXLAN包头,里面主要就是VNI。

在VXLAN包头外面,加了一层UDP包头,目标端口和源端口都是VTEP的端口。

在UDP包头外面,加一层IP包头,目标地址和源地址都是VTEP的地址。

在IP包头的外面,加一层MAC包头,MAC层的目标和源地址,要看两个VTEP是否在同一个网段,如果在同一个网段,MAC直达,如果不是,还需要通过Gateway去转发,目标MAC就变成了Gateway的MAC地址。

如果两个VM,连接到两个VTEP上,希望通过VXLAN相互通信,并且通信的时候,两个VM需要感知他们似乎在同一个VLAN下面。

首先两个VTEP启动的时候,需要加入同一个组播组,通过IGMP协议。

当VM1要发送包给VM2的时候,一开始VM1只知道VM2的IP地址,但是不知道VM2的MAC地址,如果他们在同一个VLAN里面,发现MAC地址这件事情,需要通过ARP协议,以广播的方式在VLAN里面询问,而是这个IP地址的机器VM2,会将MAC地址发送出来,于是VM1才能知道VM2的MAC地址。

既然按上面所述,VM1和VM2需要感觉上,他们是在同一个VLAN里面的,于是VM1就像原来一样发送了ARP请求。

ARP请求到达了VTEP1,VTEP1知道VM1不是在一个VLAN里面,而是在一个VXLAN里面,而且VM2也不归自己管,所以只好将ARP包通过VXLAN包头封装起来,然后通过组播,将ARP请求发送到所有的VTEP。

VTEP2知道VM2归自己管,于是将组播接收下啦,将VXLAN包头卸掉,将里面的ARP包发送给VM2,VM2看到ARP包,以为同一个VLAN里面的虚拟机在询问自己的MAC地址,于是将自己的MAC地址发送出来。

VTEP2将ARP的结果封装VXLAN包头后发送给VTEP1,VTEP1将VXLAN包头卸掉后,将ARP的结果发送给VM1,VM1收到后感觉像从同一个VLAN里面发出来的一样。

在整个过程中,VTEP1和VTEP2都学习到了一条知识,就是VM1的MAC归VTEP1管,VM2的MAC归VTEP2管,以后两个VM通信的时候,不需要再组播问某个VM归谁管了,直接发送就可以了。

当双方知道了MAC地址以后,两个VM之间的交互和GRE就很像了。

内部的IP和MAC地址被封装起来,外面加上VTEP的IP和MAC地址,发送到另一端后,再把外层卸下来,发送给对端的VM。

最后下一节我们来看IPSec隧道。