【Docker】vxlan的原理与实验

news2024/11/18 9:49:01

VXLAN(Virtual eXtensible Local Area Network,虚拟可扩展局域网),是一种虚拟化隧道通信技术。它是一种Overlay(覆盖网络)技术,通过三层的网络来搭建虚拟的二层网络。

VXLAN介绍

VXLAN是在底层物理网络(underlay)之上使用隧道技术,借助UDP层构建的Overlay的逻辑网络,使逻辑网络与物理网络解耦,实现灵活的组网需求。它对原有的网络架构几乎没有影响,不需要对原网络做任何改动,即可架设一层新的网络。也正是因为这个特性,很多容器的网络才会选择VXLAN作为通信网络。

VXLAN不仅支持一对一,也支持一对多,一个VXLAN设备能通过像网桥一样的学习方式学习到其他对端的IP地址,还可以直接配置静态转发表。

VXLAN基本概念

  • VNI(VXLAN Network Identifier,VXLAN网络标识符):VXLAN通过VXLAN ID来标识,其长度为24比特。一般每个VNI对应一个租户,也就是说使用VXLAN理论上可以支撑千万级别的租户。

  • VTEP(VXLAN Tunnel End Point,VXLAN隧道端点):VXLAN网络的边缘设备,用来进行VXLAN报文的处理(封包和解包)。VXLAN的相关处理都在VTEP上进行,例如识别以太网数据帧所属的VXLAN、基于VXLAN对数据帧进行二层转发、封装/解封装报文等。VTEP可以是一台独立的物理设备,也可以是虚拟机所在服务器的虚拟交换机。

  • VXLAN Tunnel:两个VTEP之间点到点的逻辑隧道。VTEP为数据帧封装VXLAN头、UDP头、IP头后,通过VXLAN隧道将封装后的报文转发给远端VTEP,远端VTEP对其进行解封装。隧道是一个逻辑上的概念,在VXLAN模型中并没有具体的物理实体向对应。隧道可以看做是一种虚拟通道,VXLAN通信双方认为自己是在直接通信,并不知道底层网络的存在。从整体来说,每个VXLAN网络像是为通信的虚拟机搭建了一个单独的通信通道,也就是隧道。

    上图所示为VXLAN的工作模型,它创建在原来的IP网络(三层)上,只要是三层可达(能够通过IP相互通信)的网络就能部署 VXLAN。在VXLAN网络的每个端点都有一个VTEP设备,负责VXLAN协议报文的解包和封包,也就是在虚拟报文上封装VTEP通信的报文头部。

物理网络上可以创建多个VXLAN网络,可以将这些VXLAN网络看成一个隧道,不同节点上的虚拟机/容器能够通过隧道直连。通过VNI标识不同的VXLAN网络,使得不同的VXLAN可以相互隔离。

VXLAN的报文格式


VXLAN Header:在原始二层帧的前面增加8字节的VXLAN的头部,其中最主要的是VNID,占用3个字节(即24bit),类似VLAN ID,可以具有2^24个网段。

UDP Header:在VXLAN和原始二层帧的前面使用8字节UDP头部进行封装(MAC IN UDP),目的端口号缺省使用4789,源端口按流随机分配(通过MAC,IP,四层端口号进行hash操作),这样可以更好的做ECMP。

在上面添加的二层封装之后,再添加底层网络的IP头部(20 字节)和MAC头部(14 字节),这里的IP和MAC是宿主机的IP地址和 MAC地址。

VXLAN通讯过程

总的来说,VXLAN报文的转发过程就是:原始报文经过VTEP,被VTEP添加上VXLAN头部以及外层的UDP头部,再发送出去,对端 VTEP接收到VXLAN报文后拆除外层UDP头部,并根据VXLAN头部的VNI把原始报文发送到目的服务器。但这里有一个问题,第一次通信前双方如何知道所有的通信信息?这些信息包括:

  • 哪些VTEP需要加到一个相同的VNI组?
  • 发送方虚拟机怎么知道对方的MAC地址?
  • VTEP怎么知道目的虚拟机在哪一台宿主机上?

这三个问题可以归结为同一个问题:VXLAN网络怎么感知彼此的存在并选择正确的路径传输报文?

第一个问题简单,VTEP通常由网络管理员来配置。要回答后面两个问题,还得回到VXLAN协议的报文上,看看一个完整的VXLAN报文需要哪些信息:

  • 内层报文:通信双方的IP地址已经明确,只需要VXLAN填充对方的MAC地址,因此需要一个机制来实现ARP功能。
  • VXLAN头部:只需要知道VNI。一般直接配置在VTEP上,要么提前规划,要么根据内层报文自动生成。
  • UDP头部:需要知道源端口和目的端口,源端口由系统自动生成,目的端口默认是4789。
  • IP头部:需要知道对端VTEP的IP地址,这个是最关键的部分。

实际上,VTEP也会有自己的转发表,转发表通过泛洪和学习机制来维护,对于目标MAC地址在转发表中不存在的未知单播,广播流量,都会被泛洪给除源VTEP外所有的VTEP,目标VTEP响应数据包后,源VTEP会从数据包中学习到MAC,VNI和VTEP的映射关系,并添加到转发表中,后续当再有数据包转发到这个MAC地址时,VTEP会从转发表中直接获取到目标VTEP地址,从而发送单播数据到目标VTEP。

点对点的VXLAN通信

点对点的VXLAN通信,在这个实验中使用两台虚拟机构成一个VXLAN网络,每台机器的网卡作为vtep,通过设置的ip互相通信。

主机规划:

  • node1:172.20.160.13/20
  • node2:172.20.161.221/20

实验结构图如下图所示。

对于,两台主机的网卡之间的通信,如果不使用vxlan,就需要设置路由表,此时两个网卡的ip不能是同一个网段。接下来,进行点对点的vxlan的通信。

在node1上创建一个名字为vxlan-ethd,类型为vxlan的网卡,后面是vxlan-ethd网卡需要的参数:

  • id 1:指定VNI的值,这个值可以在1到2^24之间
  • dstport:vtep通信的端口
  • remote 172.20.161.221:对方vtep的地址,类似于点对点协议
  • local 172.20.160.13:当前节点vtep要使用的IP地址
$ sudo ip link add vxlan-ethd type vxlan id 1 dstport 4789 remote 172.20.161.221 local 172.20.160.13

启动vxlan-ethd网卡并为其分配IP;

$ sudo ip link set vxlan-ethd up
$ sudo ip addr add 10.0.1.1/24 dev vxlan-ethd

在node2上也进行同样的操作:

$ sudo ip link add vxlan-ethd type vxlan id 1 dstport 4789 remote 172.20.160.13 local 172.20.161.221
$ sudo ip link set vxlan-ethd up
$ sudo ip addr add 10.0.1.2/24 dev vxlan-ethd

接下来,这两个位于不同虚拟机上的网卡就可以通过vxlan隧道进行通信了,在node1中尝试访问node2的10.0.1.2

$ ping -I 10.0.1.1 10.0.1.2 -c 3
PING 10.0.1.2 (10.0.1.2) from 10.0.1.1 : 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.899 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.934 ms
64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=1.53 ms

--- 10.0.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2022ms
rtt min/avg/max/mdev = 0.899/1.124/1.539/0.293 ms

跨主机的容器通信

上面最简单的点对点VXLAN实验只是个简单的演示,没有太多实际工程意义,本节用容器通信来演示一个更加完整的场景。

场景描述:在node1和node2上各部署一个docker容器,默认情况下,一个容器宿主机上的容器能够直接用私网IP地址通信,因为它们利用一个网桥接在一起。而不同宿主机上的容器无法直接用私网IP地址通信。使用自建的vxlan网络接口,来打通不同宿主机上容器,让它们可以直接利用内网IP通信。

准备容器

在node1上创建app1容器,指定IP为172.18.0.2:

$ sudo docker network create --subnet 172.18.0.0/16 my-network
04a3be456f01099cb18818fa50804cc69a359ee77ba8d8d3e3bb12cf06e52434

$ sudo docker container run -d --rm --name app1 --network my-network --ip 172.18.0.2 busybox ping 8.8.8.8
c7fbfe06fb871d88d3fc9224636c25da78d61cf8aaa98b87df65403e771437be

在node2上创建app2容器,指定IP为172.18.0.3:

$ sudo docker network create --subnet 172.18.0.0/16 my-network
09fb688212d956ebbb5e775f8d8847d9cf2705c7ed96127dc411648383ba839f

$ sudo docker container run -d --rm --name app2 --network my-network --ip 172.18.0.3 busybox ping 8.8.8.8
745c98439680ecc9ef97b02aabda3dcc8fb19bd76f73b2e79d9134f858b17fbd

在node1中的容器app1上访问node2中的容器app2,和预期一致,是无法ping通的:

$ sudo docker container exec -it app1 ping -c 3 172.18.0.3
PING 172.18.0.3 (172.18.0.3): 56 data bytes

--- 172.18.0.3 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss

创建VXLAN接口接入docker网桥

在两个容器宿主机上各创建一个VXLAN接口,并且将VXLAN接口接入docker网桥的端口上,如下图:

有了VXLAN接口的连接后,从node1上容器app1发出的包到达docker网桥后,可以从网桥的VXLAN接口出去,从而报文在VETP(VXLAN接口)处被封装成VXLAN报文,再从物理网络上到达对端VETP所在的主机node2。对端VTEP能正确解包VXLAN报文的话,随后即可将报文通过node2上的docker网桥送到上层的docker容器app2中。

在node1上配置如下:

$ sudo ip link add vxlan_docker type vxlan id 200 remote 172.20.161.221 dstport 4789 dev eth0

$ sudo ip link set vxlan_docker up

$ sudo brctl addif br-04a3be456f01 vxlan_docker

在node2上配置如下:

$ sudo ip link add vxlan_docker type vxlan id 200 remote 172.20.160.13 dstport 4789 dev eth0

$ sudo ip link set vxlan_docker up

$ sudo brctl addif br-09fb688212d9 vxlan_docker

此时再在node1中的容器app1上访问node2中的容器app2,结果如下,ping可以通。

$ sudo docker container exec -it app1 ping -c 3 172.18.0.3
PING 172.18.0.3 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=1.841 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.562 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=1.615 ms

--- 172.18.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.562/1.339/1.841 ms

FDB表

FDB(Forwarding Database entry,即转发表)是Linux网桥维护的一个二层转发表,用于保存远端虚拟机/容器的MAC地址,远端VTEP IP,以及VNI的映射关系,可以通过bridge fdb命令来对FDB表进行操作:

$ sudo bridge fdb
02:42:ac:12:00:03 dev vxlan_docker master br-e4fbde69f952
ca:d7:ea:37:0a:b2 dev vxlan_docker vlan 1 master br-e4fbde69f952 permanent
ca:d7:ea:37:0a:b2 dev vxlan_docker master br-e4fbde69f952 permanent
00:00:00:00:00:00 dev vxlan_docker dst 172.20.161.221 via eth0 self permanent
02:42:ac:12:00:03 dev vxlan_docker dst 172.20.161.221 self
33:33:00:00:00:01 dev br-e4fbde69f952 self permanent
01:00:5e:00:00:01 dev br-e4fbde69f952 self permanent
02:42:f7:03:fb:17 dev br-e4fbde69f952 vlan 1 master br-e4fbde69f952 permanent
02:42:f7:03:fb:17 dev br-e4fbde69f952 master br-e4fbde69f952 permanent

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1298688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STL(七)(map篇)

### 这里重点学习map ### 在实际做题过程中,multimap几乎用不到### unordered_map拥有极好的平均时间复杂度和极差的最坏时间复杂度,所以他的时间复杂度是不稳定的,unordered_map一般用不到,要做一个了解 1.map map是一种关联容器,用于存储一组键值对(key-value pairs),其中每…

在OpenCV基于深度学习的超分辨率模型实践

1. 引言 OpenCV是一个开源的计算机视觉库,拥有大量优秀的算法。基于最新的合并,OpenCV包含一个易于使用的接口,主要用于实现基于深度学习方法的超分辨率(SR)。该接口包含预先训练的模型,这些模型可以非常容…

vue3路由跳转页面到顶部,Stable Diffusion使用ControlNet

打开新页面时,页面自动回到顶部 在router.js页面添加 router.beforeEach((to, from, next) > {// 在每次导航之前滚动到页面顶部window.scrollTo({top: 0,behavior: smooth // 可选的,使滚动平滑进行});next(); }); Controlnet ControlNet 是用来…

企业计算机服务器中了eking勒索病毒怎么办,eking勒索病毒解密数据恢复

随着计算机网络技术的不断发展与应用,企业的生产运营效率得到了极大提升,但网络安全威胁一直存在,网络威胁的技术也在不断更新,给企业的数据安全带来了严重威胁。在本月,云天数据恢复中心陆续接到很多企业的求助&#…

Windows安装kafka

压缩包下载地址:https://www.apache.org/dyn/closer.cgi?path/kafka/3.6.1/kafka_2.13-3.6.1.tgz 启动kafka步骤 zookeeper-server-start.bat rem 闭命令提示符窗口的命令回显,这样在运行脚本时不会显示脚本的具体命令内容 echo offrem 命令行启动未…

html实现动漫视频网站模板源码

文章目录 1.视频设计来源1.1 主界面1.2 动漫、电视剧、电影视频界面1.3 播放视频界面1.4 娱乐前线新闻界面1.5 关于我们界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/detail…

【小米电脑管家】安装使用教程--非小米电脑

安装说明功能体验下载资源 Xiaomi HyperOS发布后,小米妙享电脑端独立版本也走向终点,最新的【小米电脑管家】将会内置妙享实现万物互联。那么本篇文章将分享非小米电脑用户如何绕过设备识别验证安装使用【小米电脑管家】实现万物互联 安装说明 1.解压文…

构建外卖系统:使用Django框架

在当今数字化的时代,外卖系统的搭建不再是什么复杂的任务。通过使用Django框架,我们可以迅速建立一个强大、灵活且易于扩展的外卖系统。本文将演示如何使用Django构建一个简单的外卖系统,并包含一些基本的技术代码。 步骤一:安装…

SQL语句---删除索引

介绍 使用sql语句删除索引。由于索引会占用一定的磁盘空间,因此,为了避免影响数据库性能,应该及时删除不再使用的索引。 命令 drop index 索引名 on 表名;例子 删除a表中的singleidx索引: drop index singleidx on a;下面是执…

Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)

目录 一、前言 二、Bean配置信息重用 1.简介 : 2.实例 : 三、关于Bean的创建顺序 1.简介 : 2.实例 : 四、关于Bean的单例和多例 1.简介 : 2.实例 : 五、关于Bean的生命周期 1.简介 : 2.实例 : 六、Bean配置后置处理器 1.简介 : 2.实例 : 七、通过.properties文…

NestJS的微服务实现

1.1 基本概念 微服务基本概念:微服务就是将一个项目拆分成多个服务。举个简单的例子:将网站的登录功能可以拆分出来做成一个服务。 微服务分为提供者和消费者,如上“登录服务”就是一个服务提供者,“网站服务器”就是一个服务消…

Hive SQL间隔连续问题

问题引入 下面是某游戏公司记录的用户每日登录数据, 计算每个用户最大的连续登录天数,定义连续登录时可以间隔一天。举例:如果一个用户在 1,3,5,6,9 登录了游戏,则视为连续 6 天登录。 id dt1001 2021-12-121002 2021-12-12…

Zabbix监控腾讯云VPC

一、简介 私有网络(Virtual Private Cloud,VPC)是腾讯云上一块由用户自定义的逻辑隔离网络空间,为云服务器、云数据库等资源提供安全可控的网络环境。通过构建逻辑隔离的、用户自定义配置的网络空间,用户能够提升其云…

无参RCE [GXYCTF2019]禁止套娃1

打开题目 毫无思绪,先用御剑扫描一下 只能扫出index.php 我们尝试能不能用php伪协议读取flag php://filter/readconvert.base64-encode/resourceindex.php php://filter/readconvert.base64-encode/resourceflag.php 但是页面都回显了429 怀疑是不是源码泄露 用…

CTF网络安全大赛是干什么的?发展史、赛制、赛程介绍,参赛需要学什么?

CTF(Capture The Flag)是一种网络安全竞赛,它模拟了各种信息安全场景,旨在提升参与者的网络安全技能。CTF 赛事通常包含多种类型的挑战,如密码学、逆向工程、网络攻防、Web 安全、二进制利用等。 发展史 CTF 的概念…

「Python编程基础」第7章:字符串操作

文章目录 一、回顾二、新手容易踩坑的引号三、转义字符四、多行字符串写法五、注释六、字符串索引和切片七、字符串的in 和 not in八、字符串拼接九、转换大小写十、合并字符串join()十一、分割字符串split()十二、字符串替换 replace()十三、字符串内容判断方法十四、字符串内…

Nginx的性能优化、安全以及防盗链配置

目录 一、nginx的日志分割 二、nginx性能优化之启用epoll模型 三、nginx性能优化之设置worker进程数并与cpu进行绑核 四、nginx性能优化之调整worker的最大打开文件数和最大处理连接请求数量 五、nginx性能优化之启用gzip压缩,提高传输,减少带宽 六…

通俗易懂,什么是.NET Core以及.NET Core能做什么

我们都知道.NET Core是一个可以用来构建现代、可伸缩和高性能的跨平台软件应用程序的通用开发框架。可用于为Windows、Linux和MacOS构建软件应用程序。与其他软件框架不同,.NET Core是最通用的框架,可用于构建各种软件,包括Web应用程序、移动…

HLS实现图像膨胀和腐蚀运算--xf_dilation和xf_erosion

一、图像膨胀和图像腐蚀概念 我们先定义,需要处理的图片为二值化图像A。图片的背景色为黑色,即像素值为0。图片的目标色为白色,即像素值为1。 再定义一个结构元S,结构元范围内所有的像素为白色,像素值为1。 1、图像的…

《三十》模块化打包构建工具 Rollup

19的2小时06分钟 Rollup 是一个 JavaScript 的模块化打包工具,可以帮助编译微小的代码到庞大的复杂的代码中(例如一个库或者一个应用程序)。 Rollup 和 Webpack 的区别: Rollup 也是一个模块化的打包工具,但是它主要…