当你想了解OpenStack的Neutron网络,打开下面这张图的时候,心里一定是崩溃的,看起来这些模块连在一起很复杂,但其实和你家里的网络很像,看不出来?看我来慢慢解析。

其实这个网络的样子更像是我上大学的时候的寝室里面的网络。

作为一个已到中年的80后,在两千年初上大学的时候,当时家用路由器的价格还很高,所以我们寝室买不起家用路由器,只好买一个hub,将整个寝室的四台电脑连接起来,整个寝室只有一个对外网口,于是寝室长的电脑需要买两张网卡(当时买另外一张网卡是需要整个寝室分摊钱的),一张连接外网网口,一张连接Hub,其实是充当路由器的作用,其他的室友的网线都插到Hub上,任何一个人要上外网,必须把寝室长的电脑打开才可以。

整个寝室的网络拓扑结构如下:

如果是现在家里有路由器的,拓扑架构如下:

家里的路由器一般都会有DHCP功能,家里的设备只要连接到路由器,就会自动被分配一个IP地址,家里的路由器会有一个内网IP地址192.168.1.1,

家里的电脑的网关一般就设置为这个地址,当家里的电脑上网的时候,也是通过路由器,从公网口出去到互联网上访问。

接下来,我们将整个寝室放在一台物理机里面,虚拟机是你的电脑,路由器和DHCP Server相当于家用路由器或者寝室长的电脑,外网网口访问互联网,所有的电脑都通过内网网口连接到一个Hub上,名为br-int,虚拟机要想访问互联网,需要通过Hub br-int连到路由器上,然后通过路由器将请求转发到公网。

接下来的事情就惨了,你和你的寝室长闹矛盾了,你们要分开宿舍住,分成两个宿舍,对应上面的图,路由器和VM分在两台物理机上,这下把一个完整的br-int一刀两断,一半放在寝室长宿舍,一半放在你的宿舍。

可是只有你的寝室长有公网口可以上网,于是你偷偷的在两个宿舍中间打了一个隧道,用网线通过隧道将两个宿舍的两个br-int连接起来,让你的电脑和你寝室长的电脑感觉上,还是连到同一个br-int上,其实中间通过你的隧道中的网线做了转发。

为什么要多一个br-tun这个虚拟交换机呢?主要通过br-int这一层将虚拟机之间的互联和主机之间的互联分成两层来设计,tun的意思就是tunnel,就是隧道,隧道可以各种挖法,GRE,VXLAN都可以。

如果两个寝室之间的互联是通过VLAN,则结构如下:

这两个加起来,是不是最上面的那张图了。

接下来我们详细解读各个部分:

一、tap/tun设备

将guest system的网络和host system的网络连在一起

Tun/tap驱动程序中包含两个部分,一部分是字符设备驱动,还有一部分是网卡驱动部分

二、Openvswitch的基本概念

br-int & br-tun由Openvswitch实现

Openvswitch是一个virutal switch, 支持Open Flow协议,当然也有一些硬件Switch也支持Open Flow协议,他们都可以被统一的Controller管理,从而实现物理机和虚拟机的网络联通。

Openvswitch创建出来的虚拟交换机会保存很多Flow Table包含许多entry,每个entry是对packet进行处理的规则

Match Field涵盖TCP/IP协议各层:

  • Layer 1 – Tunnel ID, In Port, QoS priority, skb mark

  • Layer 2 – MAC address, VLAN ID, Ethernet type

  • Layer 3 – IPv4/IPv6 fields, ARP

  • Layer 4 – TCP/UDP, ICMP, ND

Action也主要包含下面的操作:

  • Output to port (port range, flood, mirror)

  • Discard, Resubmit to table x

  • Packet Mangling (Push/Pop VLAN header, TOS, ...)

  • Send to controller, Learn

这些Flow Table可以通过OpenFlow协议进行增删查改。

这些FlowTable里面的规则执行顺序安装Table的优先级来,高优先级的先执行,低优先级的后执行,执行过程中可任意修改网络包的内容,修改完毕后,可以扔给另一个Table,也可以直接output从一个虚拟口将包发出来。

三、解析br-int

br-int主要使用openvswitch中port的vlan功能

Port的一个重要的方面就是VLAN Configuration,有两种模式:

模式一:trunk port

  • 这个port不配置tag,配置trunks

  • 如果trunks为空,则所有的VLAN都trunk,也就意味着对于所有的VLAN的包,本身带什么VLAN ID,就是携带者什么VLAN ID,如果没有设置VLAN,就属于VLAN 0,全部允许通过。

  • 如果trunks不为空,则仅仅带着这些VLAN ID的包通过。

模式二:access port

  • 这个port配置tag,从这个port进来的包会被打上这个tag

  • 如果从其他的trunk port中进来的本身就带有VLAN ID的包,如果VLAN ID等于tag,则会从这个port发出

  • 从其他的access port上来的包,如果tag相同,也会被forward到这个port

  • 从access port发出的包不带VLAN ID

  • 如果一个本身带VLAN ID的包到达access port,即便VLAN ID等于tag,也会被抛弃。

例如要创建如下的虚拟网络和虚拟交换机

执行以下的命令

ovs-vsctl add-br ubuntu_br

ip link add first_br type veth peer name first_if

ip link add second_br type veth peer name second_if

ip link add third_br type veth peer name third_if

ovs-vsctl add-port ubuntu_br first_br

ovs-vsctl add-port ubuntu_br second_br

ovs-vsctl add-port ubuntu_br third_br

ovs-vsctl set Port vnet0 tag=101

ovs-vsctl set Port vnet1 tag=102

ovs-vsctl set Port vnet2 tag=103

ovs-vsctl set Port first_br tag=103

ovs-vsctl clear Port second_br tag

ovs-vsctl set Port third_br trunks=101,102

需要监听ARP,所以禁止MAC地址学习

ovs-vsctl set bridge ubuntu_br flood-vlans=101,102,103

实验结果如下:

从192.168.100.102来ping 192.168.100.103,应该first_if和second_if能够收到包

从192.168.100.100在ping 192.168.100.105, 则second_if和third_if可以收到包

从192.168.100.101来ping 192.168.100.104, 则second_if和third_if可以收到包

四、解析br-tun

br-tun主要使用openvswitch的tunnel功能和Flow功能。

Openvswitch支持三类Tunnel:gre,vxlan,ipsec_gre。

命令分别如下:

ovs-vsctl add-br testbr

ovs-vsctl add-port testbr gre0 -- set Interface gre0 type=gre options:local_ip=192.168.100.100 options:remote_ip=192.168.100.101

ovs-vsctl
add-port testbr vxlan0 -- set Interface vxlan0 type=vxlan
options:local_ip=192.168.100.100 options:remote_ip=192.168.100.102

ovs-vsctl
add-port testbr ipsec0 -- set Interface ipsec0 type=ipsec_gre
options:local_ip=192.168.100.101 options:remote_ip=192.168.100.102
options:psk=password

对于Flow Table的管理,由ovs-ofctl来控制

  • add−flow switch flow

  • mod−flows switch flow

  • del−flows switch [flow]

主要控制两类

  • Match Field

  • Actions

对于Match Field,不同网络层的表示方式不同,如下:

Actions有以下几类:

  • output:port 和 output:NXM_NX_REG0[16..31]

  • enqueue:port:queue

  • mod_vlan_vid:vlan_vid

  • strip_vlan

  • mod_dl_src:mac 和 mod_dl_dst:mac

  • mod_nw_src:ip 和 mod_nw_dst:ip

  • mod_tp_src:port 和 mod_tp_dst:port

  • set_tunnel:id

  • resubmit([port],[table])

  • move:src[start..end]−>dst[start..end]

  • load:value−>dst[start..end]

  • learn(argument[,argument]...)

我们模拟创建一个如下的网络拓扑结构,模拟OpenStack里面的行为

Flow Table的设计如下:

下面详细描述FlowTable的添加过程,OpenStack也是这样一个个规则添加进去的。

(1) 删除所有的Flow

ovs-ofctl del-flows br-tun

(2) Table 0

从port 1进来的,由table 1处理

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 in_port=1 actions=resubmit(,1)"

从port 2/3进来的,由Table 3处理

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 in_port=2 actions=resubmit(,3)"

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 in_port=3 actions=resubmit(,3)"

默认丢弃

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=0 actions=drop"

(3) Table 1

对于单播,由table 20处理

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=1 table=1 dl_dst=00:00:00:00:00:00/01:00:00:00:00:00
actions=resubmit(,20)"

对于多播,由table 21处理

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=1 table=1 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00
actions=resubmit(,21)"

(4) Table 2

默认丢弃

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=0 table=2 actions=drop"

(5) Table 3

默认丢弃

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=0 table=3 actions=drop"

Tunnel ID -> VLAN ID

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=1 table=3 tun_id=0x1
actions=mod_vlan_vid:1,resubmit(,10)"

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=1 table=3 tun_id=0x2
actions=mod_vlan_vid:2,resubmit(,10)"

(6) Table 10

MAC地址学习

ovs-ofctl
add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=1 table=10 
actions=learn(table=20,priority=1,hard_timeout=300,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1"

  • Table 10是用来学习MAC地址的,学习的结果放在Table 20里面,Table20被称为MAC learning table

  • NXM_OF_VLAN_TCI这个是VLAN
    Tag,在MAC Learning table中,每一个entry都是仅仅对某一个VLAN来说的,不同VLAN的learning
    table是分开的。在学习的结果的entry中,会标出这个entry是对于哪个VLAN的。

  • NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]这个的意思是当前包里面的MAC
    Source
    Address会被放在学习结果的entry里面的dl_dst里面。这是因为每个switch都是通过Ingress包来学习,某个MAC从某个port进来,switch就应该记住以后发往这个MAC的包要从这个port出去,因而MAC
    source address就被放在了Mac destination address里面,因为这是为发送用的。

  • load:0->NXM_OF_VLAN_TCI[]意思是发送出去的时候,vlan tag设为0,所以结果中有actions=strip_vlan

  • load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[]意思是发出去的时候,设置tunnel id,进来的时候是多少,发送的时候就是多少,所以结果中有set_tunnel:0x3e9

  • output:NXM_OF_IN_PORT[]意思是发送给哪个port,由于是从port2进来的,因而结果中有output:2

(7) Table 20

这个是MAC Address Learning Table,如果不空就按照规则处理

如果为空,就使用默认规则,交给Table 21处理

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=0 table=20 actions=resubmit(,21)"

(8) Table 21

默认丢弃

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=0 table=21 actions=drop"

VLAN ID -> Tunnel ID

ovs-ofctl
add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=1table=21dl_vlan=1
actions=strip_vlan,set_tunnel:0x1,output:2,output:3"

ovs-ofctl
add-flow br-tun "hard_timeout=0 idle_timeout=0
priority=1table=21dl_vlan=2
actions=strip_vlan,set_tunnel:0x2,output:2,output:3"

五、解析Router

使用namespace中的routing table

ip netns exec
qrouter-5a74908c-712c-485c-aa9f-6c1e8b57e3e1 route -n

Kernel IP routing table

Destination     Gateway         Genmask        
Flags Metric Ref    Use Iface

0.0.0.0         16.158.164.1    0.0.0.0         UG   
0      0        0 qg-52de6441-db

10.0.0.0        0.0.0.0         255.255.255.0   U    
0      0        0 qr-e0967604-78

16.158.164.0    0.0.0.0         255.255.252.0   U    
0      0        0 qg-52de6441-db

Floating IP使用namespace中的iptables的nat

ip netns exec
qrouter-5a74908c-712c-485c-aa9f-6c1e8b57e3e1 iptables -t nat -nvL

六、解析br-ex

将namespace中的网络和namespace外的网络连接起来

欢迎关注微信公众号

觉得OpenStack的网络复杂?其实你家里就有同样一个网络的更多相关文章

  1. Linux就这个范儿 第12章 一个网络一个世界

    Linux就这个范儿 第12章 一个网络一个世界 与Linux有缘相识还得从一项开发任务说起.十八年前,我在Nucleus  OS上开发无线网桥AP,需要加入STP生成树协议(SpanningTree ...

  2. jmeter 建立一个网络服务的测试计划

    如何创建一个 测试计划 测试一个网络服务. 你会 创建5个用户发送请求到一页. 同时,你会告诉用户运行测试两次. 的总数 请求用户请求(5)x(1)x(重复2次)= 10 HTTP请求. 来 建立测试 ...

  3. VM网络无法连接--提示ethernet0无法连接到虚拟网络

    打开 “编辑->虚拟网络设置"里面,点“恢复默认” 如果还不行 然后 开网络和共享中心 左击  本地连接(若是无线网络,则点击无线网络连接)----属性----共享---- 在:允许其 ...

  4. c/c++ 网络编程 UDP 用if_nameindex和ioctl取得主机网络信息

    网络编程 UDP 用if_nameindex和ioctl取得主机网络信息 getifaddrs函数取得的东西太多了,如果只想取得网卡名字和网卡编号可以用下面的2个函数. 1,if_nameindex ...

  5. Android: 网络随时需要在3G和Wifi切换,网络程序需要注意

    平时,3G和WIFI 都开着的时候,Android默认使用Wifi,但现实环境中不可能到处都有wifi,所以手机会经常自动切换网络. 有的时候,手机一开始使用wifi上网,当进入待机后10-30分钟, ...

  6. Iperf是一个网络性能测试工具

    http://blog.163.com/hlz_2599/blog/static/142378474201341341339314/ Iperf是一个网络性能测试工具.Iperf可以测试TCP和UDP ...

  7. Java网络编程和NIO详解开篇:Java网络编程基础

    Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...

  8. 在CANopen网络中通过LSS服务设置节点地址和网络波特率

    CANopen专有个子协议用来描述怎样去通过网络设置节点地址和波特率,就是CiA DSP-305,大伙都叫LSS协议,是Layer Setting Services的缩写,不太好翻译,也许可以翻译成底 ...

  9. 使用 Scrapy 构建一个网络爬虫

    来自weixin 记得n年前项目需要一个灵活的爬虫工具,就组织了一个小团队用Java实现了一个爬虫框架,可以根据目标网站的结构.地址和需要的内容,做简单的配置开发,即可实现特定网站的爬虫功能.因为要考 ...

随机推荐

  1. BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]

    3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...

  2. BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster [广义后缀自动机]

    JZPGYZ - Sevenk Love Oimaster     Oimaster and sevenk love each other.       But recently,sevenk hea ...

  3. Ubuntu的Java环境变量

    新架构要上线了,这两天开始准备分析一下了,今天是直接进到JAVA_HOME的lib目录执行的java -cp sa-jdi.jar sun.jvm.hotspot.HSDB,然后报了个错: 这是哪来的 ...

  4. Selenium_WebDriver_控制浏览器

    版权声明:本文为博主原创文章,转载请注明出处.  浏览器环境: ①GoogleChrome:60 ②chromedriver:2.30: 访问 操作 方法 示例 访问页面 void get(java. ...

  5. C#小笔记:单例模式

    双重锁定: public class Singleton { private static Singleton instance; private static readonly object syn ...

  6. linux scp远程拷贝文件及文件夹

    [http://www.jb51.net/LINUXjishu/73131.html] 1.拷贝本机/home/administrator/test整个目录至远程主机192.168.1.100的/ro ...

  7. dedecms data文件夹外迁

    出于网站安全考虑,我们一般要把data文件夹迁移到网站根目录外面. dedecms data文件夹外迁方法: 1. 修改首页文件中配置文件路径 打开/index.php,把代码 if(!file_ex ...

  8. 5. 跟踪标记 (Trace Flag) 834, 845 对内存页行为的影响

    跟踪标记:834 功能: 在64位的windows环境下,为SQL Server开启这个跟踪标记,那么SQL Server 会使用大页(Large pages)为内存缓冲区(buffer pool)分 ...

  9. .addClass(),.removeClass(),.toggleClass()的区别

    .addClass("className")方法是用来给指定元素增加类名,也就是说给指定的元素追加样式: 可以同时添加多个类名,空格符隔开 $("selector&quo ...

  10. Mysql给某一台主机授权访问,修改root密码

    ubuntu上用的是phpstudy,安装好之后,敲mysql,提示没有,需要安装mysql的客户端. 安装好之后直接敲mysql,敲 mysql 再敲use mysql 再敲mysql -uroot ...