提示:本文是我学习neutron的学习笔记,记录自己对neutron实现的一些理解。
NEUTRON网络实现
前言
近期公司组织参加了一个云计算的培训,但培训对neutron说得非常模糊,于是自己在网上查找了不少资料,再结合实操谈一下自己对neutron网络实现的理解。
一、几个基本概念
neutron并不是完全重新开发的东西,它充分利用了LINUX的现有技术,下面就简单说一个neutron涉及到的几个基本概念。
1、TAP设备
TUN/TAP 虚拟网络设备一端连着协议栈,另外一端不是物理网络,而是另外一个处于用户空间的应用程序。表现在虚拟机上,就是一端为VM的网卡,另一端则是宿主机上的TAP设备。
查看Tap设备可以使用以下命令:
ip tuntap
2、veth pair 虚拟网络设备
veth虚拟网络设备的特点是 它会 成对出现,分别连着两个不同的设备。成对的veth发送数据后会直接到另外一个veth 设备上去 ,而且每个veth 都可以设置IP 地址,并且 参与 三层IP网络路由过程。连接docker容器,连接网桥(Bridge)等。查看veth设备也是用ip命令
ip link type veth
3、网桥Linux Bridge
linux内核支持网口的桥接。可以把虚拟的网卡或者物理的网卡桥接到一块,实现二层互通。查看网桥可以使用以下命令:
brctl show
4、OVS 虚拟交换机
OVS上的PORT是连接到OVS自己的网桥上的,而对应的interface则表现为宿主机上的虚拟网卡。
ovs有很多术语,我们选取一些常见的术语做解释。
Bridge
网桥,也就是交换机(不过是虚拟的,即vSwitch),一台主机中可以创建多个网桥。当数据包从网桥的某个端口进来后,网桥会根据一定的规则把该数据包转发到另外的端口,也可以修改或者丢弃报文。
Port
交换机的端口,有以下几种类型:
1、Normal: 将网卡(物理或者虚拟的)添加到bridge时它们会成为Port,类型为Normal。此时物理网卡配置ip已没有意义,它已经“退化成一根网线”只负责数据报文的进出。Normal类型的Port常用于vlan模式下多台物理主机相连的那个口,交换机的一端属于Trunk模式。
2、Internal: 此类型的Port,ovs会自动创建一个虚拟网卡接口(Interface),此端口收到数据都会转发给这块网卡,从网卡发出的数据也会通过Port交给ovs处理。当ovs创建一个新的Bridge时,会自动创建一个与网桥同名的Internal Port,同时也会创建一个与网桥同名的Interface。另外,Internal Port可配置IP地址,然后将其up,即可实现ovs三层网络。
3、Patch: 与veth pair功能类似,常用于连接两个Bridge,注意是连接OVS自己实现的网桥,不是LINUX网桥。如果要连接LINUX网桥要通过veth
4、Tunnel: 实现overlay网络,支持GRE、vxlan、STT、Geneve和IPSec等隧道协议。
Interface
网卡,虚拟的(TUN/TAP)或物理的都可以。
Controller
控制器,ovs可以接收一个或多个OpenFlow控制器的管理,主要功能为下发流表来控制转发规则。
FlowTable
流表,ovs进行数据转发的核心功能,定义了端口之间的转发数据规则。每条流表规则可以分为匹配和动作两部分,“匹配”决定哪些数据将被处理,“动作”则决定了这些数据将被如何处理。
重点要知道PORT和Interface的概念。port是OVS自己的端口,而interface则是跟OVS相连的接口。查看OVS
ovs-vsctl show
一般PORT如果类型为Internal,则会在宿主机内会虚拟出一块对外的网卡。OPENSTACK内一般用于把router(实际上就是一个namespace)连接到OVS上
每个OVS上有多个网桥,在OPENSTACK中 Bridge br-int 一般用于内部子网。不同的子网用不同的tag区分,只有tag一样的port才可以互通。
OPENSTACK里面新建端口实际上就是在OVS里面新建立一个类型为Internal的PORT
5、网络命名空间
命名空间(Linux namespace)是linux内核针对实现容器虚拟化映入的一个特性。我们创建的每个容器都有自己的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样,命名空间保证了容器之间互不影响。
这个图引自https://blog.csdn.net/PPPPPPPKD/article/details/121473312
二、neutron网络实现原理图
这个图引自https://blog.csdn.net/devcloud/article/details/125441786这张图很好的描述了neutron是如何实现子网和路由的。
这张图更具体,如果能看懂这个图,那么neutron就非常简单了。
三、一个具体的例子
下面我们通过一个具体的例子,看看一个VM发送的报文是如何走的。这里VM对应到的TAP设备是tapbd5d379d-ba。
1.首先看看LINUX的网桥
brctl show
bridge name bridge id STP enabled interfaces
qbr7ba323fc-30 8000.f6d0773f31d6 no qvb7ba323fc-30
tap7ba323fc-30
qbr9655beb7-33 8000.266c39eede97 no qvb9655beb7-33
qbra7019107-36 8000.c2c9b6f43621 no qvba7019107-36
qbrb66d6c99-5b 8000.fe4be6ba0aae no qvbb66d6c99-5b
qbrbd5d379d-ba 8000.2a5c35818d40 no qvbbd5d379d-ba
tapbd5d379d-ba
qbrcccbc018-27 8000.5a75b1dc267f no qvbcccbc018-27
tapcccbc018-27
virbr0 8000.5254002b7da4 yes virbr0-nic
可见其是先接入网桥qbrbd5d379d-ba,跟接口qvbbd5d379d-ba桥接,而qvbbd5d379d-ba是一个veth。检查qvbbd5d379d-ba其对端是qvobd5d379d-ba
ip link show type veth
57: qvbbd5d379d-ba@qvobd5d379d-ba: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1450 qdisc noqueue master qbrbd5d379d-ba state UP mode DEFAULT group default qlen 1000
2、再看看OVS
ovs-vsctl show
#网桥br-int
Bridge br-int
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port "qg-0d2745a8-15"
tag: 5
Interface "qg-0d2745a8-15"
type: internal
Port "qvo7ba323fc-30"
tag: 3
Interface "qvo7ba323fc-30"
Port "tapab1402b9-50"
tag: 5
Interface "tapab1402b9-50"
type: internal
Port int-br-ex
Interface int-br-ex
type: patch
options: {peer=phy-br-ex}
Port "tap3e386537-a0"
tag: 3
Interface "tap3e386537-a0"
type: internal
Port "qr-09c72fa9-4d"
tag: 3
Interface "qr-09c72fa9-4d"
type: internal
Port br-int
Interface br-int
type: internal
Port "tap5ebb361a-ea"
tag: 4
Interface "tap5ebb361a-ea"
type: internal
Port "qvob66d6c99-5b"
tag: 2
Interface "qvob66d6c99-5b"
Port "qr-039cf290-a5"
tag: 4
Interface "qr-039cf290-a5"
type: internal
Port "tapadfd5e8e-73"
tag: 1
Interface "tapadfd5e8e-73"
type: internal
Port "qvo9655beb7-33"
tag: 4
Interface "qvo9655beb7-33"
Port "qg-f9f7bcae-26"
tag: 2
Interface "qg-f9f7bcae-26"
type: internal
Port patch-tun
Interface patch-tun
type: patch
options: {peer=patch-int}
Port "qvobd5d379d-ba"
tag: 1
Interface "qvobd5d379d-ba"
Port "tape58019a4-5f"
tag: 2
Interface "tape58019a4-5f"
type: internal
Port "qr-f2bbc89a-d2"
tag: 1
Interface "qr-f2bbc89a-d2"
type: internal
Port "qvoa7019107-36"
tag: 2
Interface "qvoa7019107-36"
Port "qg-3c7ea664-e0"
tag: 5
Interface "qg-3c7ea664-e0"
type: internal
#网桥br-tun
Bridge br-tun
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port patch-int
Interface patch-int
type: patch
options: {peer=patch-tun}
Port br-tun
Interface br-tun
type: internal
#网桥br-ex
Bridge br-ex
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port "enp0s8"
Interface "enp0s8"
Port br-ex
Interface br-ex
type: internal
Port phy-br-ex
Interface phy-br-ex
type: patch
options: {peer=int-br-ex}
40f0215f-2dcd-4af7-903b-d492c4c0e4d1
Manager "ptcp:6640:127.0.0.1"
is_connected: true
Bridge br-tun
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port patch-int
Interface patch-int
type: patch
options: {peer=patch-tun}
Port br-tun
Interface br-tun
type: internal
这个OVS里面有三个网桥,分别是br-int、br-tun和br-ex。注意一般计算节点应该只有br-int和br-tun。我这个是使用all-in-one的openstack里面查看的,所以才会出现三个网桥在同一个ovs里面的情况。br-ex一般是在网络节点。
查到qvobd5d379d-ba是接入到OVS且属于ovs的网桥br-int的tag 1。这也就是说其接入了子网,标识是tag 1
在ovs的tag 1里面有3个接口,另外两个分别是命名空间qrouter-130c2f3c-7cad-49ef-93c6-38a8a698e333和qdhcp-038486b3-9bb6-4740-8863-2de2e10b7527
一个是用于虚拟路由器用来进行路由转发和nat,一个是用于dhcp分配IP。
查看命名空间
ip netns
qrouter-4077c27a-e785-4e19-848a-8421eef617e3f
qdhcp-aff8cdb4-f3d7-4a91-a332-24031a69ddfe
qrouter-130c2f3c-7cad-49ef-93c6-38a8a698e333
qrouter-9b7ac3f4-a51e-462d-9ed0-c1520b1a66eb
qdhcp-65a6c126-7da1-4f8f-b584-b86eb8ac9d5f
qdhcp-5e3282bc-9aa1-43d5-a621-e10b6d684a14
qdhcp-038486b3-9bb6-4740-8863-2de2e10b7527
qdhcp-39a7a6bd-ca34-416f-9599-0ab8de227dc7