【Docker】vxlan的原理与实验

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.mfbz.cn/a/239435.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

常用的测试用例大全

登录、添加、删除、查询模块是我们经常遇到的,这些模块的测试点该如何考虑 1)登录 ① 用户名和密码都符合要求(格式上的要求) ② 用户名和密码都不符合要求(格式上的要求) ③ 用户名符合要求,密码不符合要求(格式上的要求) ④ 密码符合要求&#xf…

使用Java将图片添加到Excel的几种方式

1、超链接 使用POI&#xff0c;依赖如下 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency>Java代码如下,运行该程序它会在桌面创建ImageLinks.xlsx文件。 …

【从零开始学习JVM | 第六篇】快速了解 直接内存

前言&#xff1a; 当谈及Java虚拟机&#xff08;JVM&#xff09;的内存管理时&#xff0c;我们通常会想到堆内存和栈内存。然而&#xff0c;还有一种被称为"直接内存"的特殊内存区域&#xff0c;它在Java应用程序中起着重要的作用。直接内存提供了一种与Java堆内存和…

十几个软件测试实战项目【外卖/医药/银行/电商/金融】

项目一&#xff1a;ShopNC商城 项目概况&#xff1a; ShopNC商城是一个电子商务B2C电商平台系统&#xff0c;功能强大&#xff0c;安全便捷。适合企业及个人快速构建个性化网上商城。 包含PCIOS客户端Adroid客户端微商城&#xff0c;系统PC后台是基于ThinkPHP MVC构架开发的跨…

windows如何解决端口冲突(实用篇)

在项目设计中&#xff0c;环境配置成功点击运行瞬间&#xff0c;一大堆红爆出&#xff0c;8080端口占用&#xff0c;这个是很烦人的。。。 解决方式&#xff1a; 笨方法&#xff1a;一、查看所有端口实用情况&#xff08;挨个扫&#xff09; 按住【WINR】快捷键打开运行输入…

Android View闪烁动画AlphaAnimation,Kotlin

Android View闪烁动画AlphaAnimation&#xff0c;Kotlin private fun flickerAnimation(view: View?) {val animation: Animation AlphaAnimation(1f, 0f) //不透明到透明。animation.duration 500 // 1次过程时长。animation.interpolator LinearInterpolator() // 线性速…

赴美上市传闻再起,SHEIN走到十字路口

作者 | 辰纹 来源 | 洞见新研社 裹挟着“黑五”大胜的余波&#xff0c;跨境电商巨头SHEIN&#xff08;希音&#xff09;将赴美IPO的传闻又在行业中散播开来。 金融投资报称SHEIN此次IPO的估值或达900亿美元&#xff1b;上海证券报表示&#xff0c;SHEIN已对投资人发出了路演…

10天玩转Python第3天:python循环语句和字符串、列表全面详解与代码示例

目录 1 循环1.1 for 循环1.2 break 和 continue 2 容器3 字符串3.1 定义3.2 下标3.3 切片3.4 字符串的查找方法 find3.5 字符串的替换方法 replace3.6 字符串的拆分 split3.7 字符串的链接 join 4 列表4.1 定义4.1 列表支持下标和切片, 长度4.3 查找 - 查找列表中数据下标的方法…

centos7x 安装支持gpu驱动的docker

1、卸载以前版本的驱动 sudo /usr/bin/nvidia-uninstall2、先安装基础项 yum install kernel kernel-devel gcc make -yyum install kernel kernel-devel gcc gcc-c make -y 3、禁用驱动源 nouveau echo "blacklist nouveau " >>/etc/modp…

12.12_黑马数据结构与算法笔记Java

目录 079 优先级队列 无序数组实现 080 优先级队列 有序数组实现 081 优先级队列 堆实现 1 082 优先级队列 堆实现 2 083 优先级队列 堆实现 3 084 优先级队列 e01 合并多个有序链表1 084 优先级队列 e01 合并多个有序链表2 085 阻塞队列 问题提出 086 阻塞队列 单锁实…

Linux:gdb的简单使用

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》 文章目录 前言一、前置理解二、使用总结 前言 gdb是Linux中的调试代码的工具 一、前置理解 我们都知道要调试一份代码&#xff0c;这份代码的发布模式必须是debug。那你知道在li…

【代码随想录】刷题笔记Day34

前言 考过概率论&#xff0c;发过一场烧&#xff0c;兜兜转转又一月&#xff0c;轻舟已撞万重山&#xff0c;赶紧刷题 贪心算法理论基础 贪心的本质&#xff1a;局部最优→全局最优无套路&#xff0c;常识性推导 举反例 455. 分发饼干 - 力扣&#xff08;LeetCode&#xf…

FastAPI之响应模型

前言 响应模型我认为最主要的作用就是在自动化文档的显示时&#xff0c;可以直接给查看文档的小伙伴显示返回的数据格式。对于后端开发的伙伴来说&#xff0c;其编码的实际意义不大&#xff0c;但是为了可以不用再额外的提供文档&#xff0c;我们只需要添加一个 response_mod…

慢SQL诊断

最近经常遇到技术开发跑来问我慢SQL优化相关工作&#xff0c;所以干脆出几篇SQL相关优化技术月报&#xff0c;我这里就以公司mysql一致的5.7版本来说明下。 在企业中慢SQL问题进场会遇到&#xff0c;尤其像我们这种ERP行业。 成熟的公司企业都会有晚上的慢SQL监控和预警机制。…

784. 字母大小写全排列

字母大小写全排列 描述 : 给定一个字符串 s &#xff0c;通过将字符串 s 中的每个字母转变大小写&#xff0c;我们可以获得一个新的字符串。 返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。 回文串 是正着读和反着读都一样的字符串。 题目 : LeetCode 784. 字母…

Linux--操作系统

1. 常见的操作系统 Windowsmac OSLinuxiOSAndroid 2. 操作系统的定义 操作系统直接运行在计算机上的系统软件&#xff0c; 它是控制硬件和支持软件运行的计算机程序。 3. 操作系统的作用 向下控制硬件向上支持软件的运行&#xff0c;具有承上启下的作用。 4.总结 操作系统…

集合03 Collection (List) - Java

List ArrayListArrayList注意事项ArrayList底层操作机制-源码分析&#xff08;重点&#xff09; VectorVector基本介绍 ——Vector和ArrayList比较Vector底层结构和源码分析 LinkedList基本介绍LinkedList的底层结构和操作机制LinkedList的增删改查 ——LinkedList和ArrayList比…

12.字符串拼接【2023.12.4】

1.问题描述 我们在编程过程中经常会遇到把不同字符串拼接在一起的情况&#xff0c;从而更直观地展示给用户我们所要表达的信息。本题将给出两个字符串&#xff0c;请依次将这两个字符串拼接在一起。 2.解决思路 用字符串拼接符 进行连接两个字符串 3.代码实现 str1input(…

我的创作三周年纪念日

今天收到CSDN官方的来信&#xff0c;创作三周纪念日到了。 Dear: Hann Yang &#xff0c;有幸再次遇见你&#xff1a; 还记得 2020 年 12 月 12 日吗&#xff1f; 你撰写了第 1 篇技术博客&#xff1a; 《vba程序用7重循环来计算24》 在这平凡的一天&#xff0c;你赋予了它…

【异常解决】SpringBoot + Maven 在 idea 下启动报错 Unable to start embedded Tomcat(已解决)

Unable to start embedded Tomcat&#xff08;已解决&#xff09; 一、背景介绍二、原因分析2.1 网络上整理2.2 其他原因 三、解决方案 一、背景介绍 spring boot(v2.5.14) maven idea 启动项目 之前项目一直启动的好好的&#xff0c;都能正常运行。重启的时候突然就不能启…
最新文章