Vxlan学习笔记---概念与实践

先导---Overlay网络

Overlay网络是一种灵活的叠加虚拟网络。

为什么需要Overlay网络?

image-20210809100319330

  • 移动性 - 跟踪边缘设备连接的主机
  • 伸缩性 - 减少核心网络状态,网络边缘分布式和分区处理
  • 多租户 - 共享网络资源
  • 灵活性/可编程 - 减少维护节点数量

使用Overlay网络可按需在底层承载网络上快速部署虚拟业务网络。

Overlay术语

(本文中大部分都原图在参考资料10中的PPT)

image-20210809100339954

Overlay分类

服务:

  • 二层服务
  • 三层服务

边缘设备:

  • 网络式Overlay
  • 主机式Overlay(如VXLAN)
  • 混合式Overlay(如使用OVS实现的VXLAN)

信令:

  • 数据平面学习
  • 控制平面学习

image-20210809101010806

image-20210809101029321

简介

VXLAN全名为Virtual eXtensible Local Area Network,即虚拟可扩展局域网。它基于UDP,是一种虚拟化隧道通信技术。它是一种建立在三层网络之上的一种Overlay网络。

工作原理

术语

  • VTEP(VXLAN Tunnel Endpoints, VXLAN隧道端点)

    VXLAN网络的边缘设备,用来进行封包和解包。VTEP可以是网络设备或端节点。项目里就使用OVS来作为VTEP。

  • VNI(VXLAN Network Identifier,VXLAN网络标识符)

    是每个VXLAN段的标识,长24位。

  • Tunnel(VXLAN隧道)

    是个逻辑上的概念,像是为通信的双方搭建了一个单独的通信通道。

物理网络上可以创建多个VXLAN网络,通过VNI来标识不通的VXLAN网络,使之可以互相隔离。

报文格式

VXLAN的报文格式如下:

preview

由内到外分别为:

  • VXLAN Header

    在原始的二层帧前,长度为8字节。大部分都是保留位,最重要的是VNI,占24位。

  • UDP Header

    将原始二层帧和VXLAN头用UDP头进行封装,目的端口号(=VXLAN端口)默认使用4789,源端口通过内层数据包的哈希得出,这样更方便在VXLAN的Overlay网络上做负载均衡。

  • IP Header

    源ip为源VTEP的IP地址,目的Ip为目的VTEP的IP地址。

  • MAC Header

    源MAC为源VTEP的MAC地址,目的MAC为到达目的VTEP的路径中下一跳设备的MAC地址。

注意到在原始的二层帧前面又加了50个字节的报头,因此需要设置VM/容器中网卡的mtu为1450。

VXLAN的转发过程

VXLAN的转发过程为:原始报文从源VM出发,经过源VTEP,被VTEP加上VXLAN头部及UDP头部,根据VXLAN头部的VNI将封装后的报文(通过底层物理网络)递送至所有拥有此VNI的VTEP,目的VTEP再递交给对应的VM。

这里的VM泛指虚拟机和docker等虚拟网络设备

这里就产生了一个问题:

  • 源VTEP如何知道该递交给哪个VTEP,即如何获取目的VTEP的ip地址?

其实,VTEP内部会有一张转发表,该表是通过学习机制来维护的。转发表长这样:

VTEP IP VTAP MAC VNI

根据这张表,就可以解决上面的问题,完成VXLAN报文的转发。

下图展示了VTAP发现和学习地址的过程。

image-20210809095022326

下图展示了VXLAN单播数据流的转发过程

image-20210809095223399

跨宿主机docker搭建vxlan过程

linu环境下常用的vxlan实现方式有Linux内核实现和OVS实现,这里使用OVS实现。

  1. 在两端创建容器,取名为test1

    sudo docker run -itd --name test1 --net=none --privileged=true router/quagga
    
  2. 在两端的OVS上添加网桥,取名为test_br

    sudo ovs-vsctl add-br testbr
    
  3. 连接网桥和容器,容器中的网卡取名为tap1,设置mtu=1450

    sudo ovs-docker add-port testbr tap1 test1 --mtu=1450
    
  4. 为网桥添加一个vxlan类型的端口vxlan_port,remote_ip为对端地址(粘贴时注意更换)。vni标识为24位。

    sudo ovs-vsctl add-port testbr vxlan_port \
        -- set Interface vxlan_port \
        type=vxlan options:remote_ip=10.1.1.122 \
        options:key=123456 options:dst_port=8472
    
  5. 为两端的容器配置ip地址,其中一端为10.0.0.1/24,另一端为10.0.0.2/24(这里容器里没有ifconfig这个命令,为方便,使用了nsenter进入容器进行操作)

    sudo nsenter -t $(sudo docker inspect -f {{.State.Pid}} test1) -n ifconfig tap1 10.0.0.1/24
    
  6. ping另一端

    sudo nsenter -t $(sudo docker inspect -f {{.State.Pid}} test1) -n ping 10.0.0.2
    
  7. 实验后清理环境

    sudo docker rm -f test1 && sudo ovs-vsctl del-br testbr
    

VXLAN MTU设置

参考资料

  1. VXLAN简介(英文)
  2. 什么是VXLAN(中文,华为)
  3. Docker+OpenvSwitch搭建vxlan
  4. VXLAN 基础教程:VXLAN 协议原理介绍
  5. rfc7348-VXLAN
  6. VXLAN原理介绍与实例分析
  7. Wireshark解析展示Vxlan协议
  8. VXLAN Series – How VTEP Learns and Creates Forwarding Table – Part 5
  9. Virtual Extensible LAN (VXLAN) Overview
  10. VxLAN技术 探讨和方案选择