13-网络虚拟化与Flat网络

2019-12-30 18:39:28 浏览数 (1)

1.网络虚拟化

引入

上一篇讲提到的其中一个问题

为什么可以不需要实际的交换机路由器,也能弄出网络来?

是因为OpenStack中采用了网络虚拟化技术

先来说说为什么需要网络虚拟化技术,不要会怎么样?

没有网络虚拟化出现的问题

(1) MAC和ARP表项不足

代码语言:txt复制
假设一个互联网云计算中心的服务器有5000台,按照1:20的比例进行虚拟化,则有10万个虚拟机。

通常每个虚拟机会配置两个业务网口,这样这个云计算中心就有20万个虚拟网口,对应的就是需要20万个MAC地址和IP地址。云计算要求资源灵活调度,业务资源任意迁移。也就是说任意一个虚拟机可以在整个云计算网络中任意迁移。这就要求全网在一个统一的二层网络中。

全网任意交换机都有可能学习到全网所有的MAC表项。与此对应的则是,目前业界主流的接入交换机的MAC表项只有32K,基本无法满足互联网云计算的需求。

另外,网关需要记录全网所有主机、所有网口的ARP信息。这就需要网关设备的有效ARP表项超过20万。大部分的网关设备芯片都不具备这种能力。

(2)4K VLAN Trunk

传统的大二层网络支持任意VLAN的虚拟机迁移到网络的任意位置,一般有两种方式。

方式一
代码语言:txt复制
虚拟机迁移后,通过自动化网络管理平台动态的在虚拟机对应的所有端口上下发VLAN配置;
代码语言:txt复制
同时,还需要动态删除迁移前虚拟机对应所有端口上的VLAN配置。这种方式的缺点是实现非常复杂,同时自动化管理平台对多厂商设备还面临兼容性的问	题,所以很难实现。
方式二
代码语言:txt复制
在云计算网络上静态配置VLAN,在所有端口上配置VLAN trunk all。这种方式的优点是非常简单,是目前主流的应用方式。
代码语言:txt复制
但这也带来了巨大的问题:任一VLAN内如果出现广播风暴,则全网所有VLAN内的虚拟机都会受到风暴影响,出现业务中断。

(3)VLAN上限问题

云计算网络中有可能出现多租户需求。如果租户及业务的数量规模超出VLAN的上限(4K),则无法支撑客户的需求。

(4)虚拟机迁移网络依赖问题

VM迁移需要在同一个二层域内,基于IP子网的区域划分限制了二层网络连通性的规模。

原文描述

OpenStack中的网络虚拟化

在OpenStack 是通过 Neutron 组件在物理网络环境之上提供满足多项目要求的虚拟网络和服务。

Neutron 提供的网络虚拟化能力包括:

(1)接收客户的操作请求

代码语言:txt复制
在上一篇中,我们创建一个网络时,我们发过去的请求,是由Neutron-Server的API进行接受处理的

(2)租户(项目)隔离性

代码语言:txt复制
在创建时,还可以选择一个对应项目,使它们同名不同项目间的网络互相不冲突

2.环境准备

添加用户

  • 创建一个ctf1用户属于ctf项目
代码语言:txt复制
[root@controller /(keystone_admin)]# openstack user create ctf1 --project ctf --password  123456 --email ctf1@vip.com
 --------------------- ---------------------------------- 
| Field               | Value                            |
 --------------------- ---------------------------------- 
| default_project_id  | 2c9ab6ba08b94b0cab0cb4407a073bee |
| domain_id           | default                          |
| email               | ctf1@vip.com                     |
| enabled             | True                             |
| id                  | a24342d7e2834d6ea54426690226c7de |
| name                | ctf1                             |
| options             | {}                               |
| password_expires_at | None                             |
 --------------------- ---------------------------------- 
  • 添加一个角色
代码语言:txt复制
[root@controller /(keystone_admin)]#  openstack role add --project ctf --user ctf1 _member_

创建云主机规格

代码语言:txt复制
[root@controller /(keystone_admin)]# openstack flavor create  --vcpus 1 --ram 218 --disk 5 web.ciross

上传镜像

  • 先上传到/opt目录下
代码语言:txt复制
[root@controller opt(keystone_admin)]# ls -lh
总用量 13M
-rw-r--r--  1 root root 13M 12月 18 20:17 cirros-0.3.4-x86_64-disk.img
drwxr-xr-x. 2 root root   6 6月  18 2018 rh
  • 再上传到openstack中
代码语言:txt复制
[root@controller opt(keystone_admin)]# openstack image create ciross --public --disk-format qcow2 --file /opt/cirros-0.3.4-x86_64-disk.img 

创建主机聚合

  • 创建名称叫cputer的主机聚合,区域叫cpu
代码语言:txt复制
[root@controller /(keystone_admin)]# openstack aggregate create cputer --zone cpu
  • 添加计算机点主机到聚合中
代码语言:txt复制
[root@controller /(keystone_admin)]#openstack aggregate add host cputer computer 

3.Flat网络

需求:现在要在CTF项目中创建2个云主机一个在控制节点,一个在计算节点,网络类型为Flat网络,测试连通性

控制节点

先删除之前创建的ctf_net网络,配置flat网络

1.编辑neutron配置文件

代码语言:txt复制
[root@controller /]# vim /etc/neutron/plugins/ml2/ml2_conf.ini 
[ml2]
#网络驱动类型
type_drivers=flat,vlan,vxlan,gre,local

#这里写租户网络类型,可以写多种
tenant_network_types=flat

#neutron采用的虚拟交换机
mechanism_drivers=openvswitch

#上面写了flat,这里就要写flat对应的配置
[ml2_type_flat]

#flat物理网络类型,在创建的时候必须指定对应的这个名称
flat_networks=external

2.配置第二块网卡

代码语言:txt复制
[root@controller network-scripts]# pwd
/etc/sysconfig/network-scripts
[root@controller network-scripts]# cat ifcfg-ens38
TYPE="Ethernet"
BOOTPROTO="none"
NAME="ens38"
DEVICE="ens38"
ONBOOT="yes"
[root@controller network-scripts]# ifup ens38

3.添加新OVS网桥

  • 添加一个新的ovs网桥,并把第二块网卡桥接到上面去
代码语言:txt复制
[root@controller network-scripts]# ovs-vsctl add-br br-ens38
[root@controller network-scripts]# ovs-vsctl add-port br-ens38 ens38
  • 编辑OVS代理文件
代码语言:txt复制
[ovs]
tenant_network_type=flat
bridge_mappings=external:br-ens38
integration_bridge=br-int
tunnel_bridge=br-tun
local_ip=192.168.150.10
  • 重启服务
代码语言:txt复制
#生效的是ml2_conf.ini配置文件
[root@controller /]# systemctl restart neutron-server
#生效的是openvswitch_agent.ini配置文件
[root@controller /]# systemctl restart neutron-openvswitch-agent

4.创建Flat网络

注意:这个是以admi身份创建的flat类型网络

创建flat网络创建flat网络

上面中的物理网络也就是刚刚写在ml2_conf.ini配置文件中的这一条

代码语言:txt复制
#flat物理网络类型
flat_networks=external

这个代表什么意思?

这种网络称为Provider Network 是由 OpenStack 管理员创建的,直接对应于真实物理机中的已有物理网络的一个网段。

为什么要这个东西?

如果云主机要访问其他计算节点的主机,数据包就必须通过自身的物理网卡走出去,所以它的作用是当云主机要访问外部网络时,走哪个物理网卡

Provider Network有三个属性

  • provider:physical_network (物理网络的逻辑名称,比如刚刚那个external)
  • provider:network_type (网络类型,有vxlan, gre, vlan, flat, local,geneve)
  • provider:segmentation_id (网段ID,比如VLAN号,GRE网络的 Tunnel ID,VXLAN 网络的 VNI)

建议使用命令来创建,WEB界面中创建时遇到到的问题报错信息不是很明显

上面的操作相当于命令

代码语言:txt复制
[root@controller /(keystone_admin)]#  openstack network create ctf_net --project ctf --provider-network-type flat --provider-physical-network external

指定子网

子网在openstack中它是一个ipv4或ipv6的一个地址池,它必须与一个网络相关联,可以给用户分配ip,指定网关、DNS。

创建子网创建子网

分配一个地址池

分配DHCP分配DHCP

现在已经创建成功

image.pngimage.png

创建子网的操作相当于命令

代码语言:txt复制
openstack subnet create ctf_subnet --project ctf --allocation-pool  start=172.16.199.10,end=172.16.199.100  --subnet-range 172.16.199.0/24 --network ctf_net

5.创建一个云主机

  • 复制原来的admin配置文件,修改成ctf1
代码语言:txt复制
[root@controller ~(keystone_netuser1)]# cat keystonerc_ctf1
unset OS_SERVICE_TOKEN
    export OS_USERNAME=ctf1
    export OS_PASSWORD='123456'
    export OS_REGION_NAME=RegionOne
    export OS_AUTH_URL=http://192.168.150.10:5000/v3
    export PS1='[u@h W(keystone_ctf1)]$ '
    
export OS_PROJECT_NAME=ctf
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_IDENTITY_API_VERSION=3
  • 使用ciross镜像所在ctf_net网络(不是子网的id,是网络的id)上创建一个云主机
代码语言:txt复制
[root@controller ~(keystone_ctf1)]# openstack network list
[root@controller ml2(keystone_ctf1)]# openstack network list
 -------------------------------------- --------- -------------------------------------- 
| ID                                   | Name    | Subnets                              |
 -------------------------------------- --------- -------------------------------------- 
| 5892263b-fec8-4be0-ae86-f8e86ee5f311 | ctf_net | 6cb6193a-cb9c-47e3-99e5-d36a2747b0e2 |
 -------------------------------------- --------- -------------------------------------- 


[root@controller ~(keystone_ctf1)]# openstack server create serverA --image ciross --flavor web.ciross --nic net-id=5892263b-fec8-4be0-ae86-f8e86ee5f311 

6.查看网络信息

  • 查看虚拟机的网卡信息
代码语言:txt复制
[root@controller ~]# virsh domiflist instance-00000003 
接口     类型     源        型号      MAC
-------------------------------------------------------
tap9f9c98cb-13 bridge     qbr9f9c98cb-13 virtio      fa:16:3e:66:e4:5b
  • 查看linux网格信息
代码语言:txt复制
[root@controller ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
qbr9f9c98cb-13		8000.aa908a6357a5	no		qvb9f9c98cb-13
							tap9f9c98cb-13

查看网络命名空间

代码语言:txt复制
[root@controller ~]# ip netns show
qdhcp-5892263b-fec8-4be0-ae86-f8e86ee5f311 (id: 0)

查看网络命名空间的网卡信息

代码语言:txt复制
[root@controller ~]# ip netns exec qdhcp-5892263b-fec8-4be0-ae86-f8e86ee5f311 ip add
36: tap91000a6c-33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether fa:16:3e:c6:53:03 brd ff:ff:ff:ff:ff:ff
    inet 172.16.199.10/24 brd 172.16.199.255 scope global tap91000a6c-33
       valid_lft forever preferred_lft forever
    inet6 fe80::f816:3eff:fec6:5303/64 scope link 
       valid_lft forever preferred_lft forever

查看OVS交换机的信息

代码语言:txt复制
[root@controller opt(keystone_admin)]# ovs-vsctl show
   Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        #给子网分配dhcp的设备
        Port "tap91000a6c-33"
            tag: 3
            Interface "tap91000a6c-33"
                type: internal
        #连接到ens38网卡的设备        
        Port "int-br-ens38"
            Interface "int-br-ens38"
                type: patch
                options: {peer="phy-br-ens38"}
                
        #linux虚拟交换机连接自己的设备
        Port "qvo9f9c98cb-13"
            tag: 3
            Interface "qvo9f9c98cb-13"

    Bridge "br-ens38"
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
		#连接br-int的设备
        Port "phy-br-ens38"
            Interface "phy-br-ens38"
                type: patch
                options: {peer="int-br-ens38"}
        Port "ens38"
            Interface "ens38"
    ovs_version: "2.11.0"

主机连接结构图

云主机连接图云主机连接图
tap
代码语言:txt复制
模拟一个二层的网络设备,可以接受和发送二层数据包
代码语言:txt复制
它是ServerA虚拟机连接到linux虚拟网桥间的一个中间设备
qbr
代码语言:txt复制
因为ovs没有数据包过滤的功能所以qbr的存在主要是为了辅助iptables来实现 security group功能,有时候也被称为安全网桥。
qvb
代码语言:txt复制
neutron veth, Linux Bridge-side,它是linux虚拟网桥连接,OVS交换机的一个接口设备
qvo
代码语言:txt复制
neutron veth, OVS-side,专门给inux虚拟网桥连接的一个接口设备
br-int
代码语言:txt复制
它是计算节点中专门用来给虚拟机内部通信的一个交换机
namespace
代码语言:txt复制
linux内核功能中用来实现隔离的一套机制,不同 namespace 中的资源之间彼此不可见。
代码语言:txt复制
上面创建的一个子网就是在一个namespace中,可以用ip netns show 查看到

计算节点

1.添加第二块网卡

  • 不需要设置ip地址,启用它就可以
代码语言:txt复制
[root@computer network-scripts]# cat ifcfg-ens38 
TYPE="Ethernet"
BOOTPROTO="none"
NAME="ens38"
DEVICE="ens38"
ONBOOT="yes"

#启用网卡
[root@computer network-scripts]# ifup ens38

2.添加OVS网桥

  • 添加一个新的ovs网桥,并把第二块网卡桥接到上面去
代码语言:txt复制
[root@computer /]# ovs-vsctl add-br br-ens38
[root@computer /]# ovs-vsctl add-port br-ens38 ens38

3.配置ovs代理文件

  • 配置ovs代理文件添加映射
代码语言:txt复制
[root@computer ml2]# vim /etc/neutron/plugins/ml2/openvswitch_agent.ini
[ovs]
tenant_network_type=flat
bridge_mappings=external:br-ens38

4.重启服务

代码语言:txt复制
[root@computer ml2]# systemctl restart neutron-openvswitch-agent.service 

5.创建云主机

  • 在计算节点上创建云主机
代码语言:txt复制
[root@controller /(keystone_netuser1)]# openstack server create ServerB --image ciross --flavor web.ciross --nic net-id=5892263b-fec8-4be0-ae86-f8e86ee5f311 --availability-zone cpu

连接性测试

如果发现云主机,dhcp获取半天,可以把接口

ServerA

  • 网卡信息
代码语言:txt复制
$ sudo ifconfig eth0 172.16.199.60 netmask 255.255.255.0 up
$ ifconfig 
eth0      Link encap:Ethernet  HWaddr FA:16:3E:66:E4:5B  
          inet addr:172.16.199.60  Bcast:172.16.199.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fe66:e45b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:433 errors:0 dropped:0 overruns:0 frame:0
          TX packets:127 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:56264 (54.9 KiB)  TX bytes:11878 (11.5 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:12 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1020 (1020.0 B)  TX bytes:1020 (1020.0 B)
  • ping->ServerB
代码语言:txt复制
$ ping 172.16.199.70
PING 172.16.199.70 (172.16.199.70): 56 data bytes
64 bytes from 172.16.199.70: seq=0 ttl=64 time=11.517 ms
64 bytes from 172.16.199.70: seq=1 ttl=64 time=1.633 ms
64 bytes from 172.16.199.70: seq=2 ttl=64 time=1.387 ms
 
--- 172.16.199.70 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.387/4.845/11.517 ms

ServerB

  • 网卡信息
代码语言:txt复制
$ sudo ifconfig eth0 172.16.199.70 netmask 255.255.255.0 up
$ ifconfig 
eth0      Link encap:Ethernet  HWaddr FA:16:3E:12:F3:D9  
          inet addr:172.16.199.70  Bcast:172.16.199.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:fe12:f3d9/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:24 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:3368 (3.2 KiB)  TX bytes:1750 (1.7 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:12 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1020 (1020.0 B)  TX bytes:1020 (1020.0 B)
  • ping->ServerA
代码语言:txt复制
$ ping 172.16.199.60
PING 172.16.199.60 (172.16.199.60): 56 data bytes
64 bytes from 172.16.199.60: seq=0 ttl=64 time=12.311 ms
64 bytes from 172.16.199.60: seq=1 ttl=64 time=2.079 ms
64 bytes from 172.16.199.60: seq=2 ttl=64 time=1.782 ms


--- 172.16.199.60 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.782/5.390/12.311 ms

流程分析

首先说说什么是flat网络

  • flat网络叫扁平网络,独占一个物理网卡设备,一般用于网关出口
  • flat网络里的所有主机都在同子网里,相比vlan没有任何的隔离
  • 适用于小范围的网络结构

图示

ServerA要与ServerB能够相互通信,它的数据包就必须要走br-ens38,通过br-ens38到物理网卡ens38,再到对方的ens38物理网卡,逐层传递直到虚拟机。

flat网络flat网络

为了简洁表示,上面省去了tab、qvb与qvo

引出-Neutron的架构

Plugin/Agent架构

Plugin/Agent架构图Plugin/Agent架构图

Neutron-Server提供一个api接口负责接收其他组件发来的请求

Core Plugins主要负责二层交换

Service Plugins主要负责三层路由,二者大部分都是和数据库通讯

Plugins将和数据库通讯以后的数据做一层封装写入到缓存MQ队列

L2 agent负责二层交换的服务

L3 agent负责三层路由的服务

DHCP agent负责自动获取网络地址的服务

ML2

上面的网络是一个二层结构,没有通过路由器,在neutron中是由neutron-plugin里的l2来管理的

ml2插件是通过对接下面的驱动来实现各种网络虚拟化功能的

它的配置文件在/etc/neutron/plugins/ml2/ml2_conf.ini

ml2插件示意图ml2插件示意图

DHCP agent

  • Neutron是用开源软件dnsmasq来给云主机提供DHCP和DNS服务的
  • 每个网络的DHCP运行在一个network namespace中,namespace由qdhcp-<DHCP-UUID>命名
  • 这里它不存在DHCP中继的问题,因为它是每一个子网都有一个对应的DHCP进程

云主机通过DHCP获取地址的过程

云主机请求DHCP流程云主机请求DHCP流程

1.nova-compute向Neutron Server 发送一个请求虚拟机IP地址的请求

2.Neutron Server为虚拟机创建MAC地址和IP地址,将此信息存储到数据库当中

3.Neutron Server同时将这个信息异步发送给DHCP agent

4.DHCP agent收到对应信息以后再发送给dnsmasq,后者将它保存起来

5.nova创建虚拟机以后会初始化MAC地址

6.当虚拟机启动的时候,默认的ip地址是0.0.0.0,会发送一个广播,dnsmasq会监听到虚拟机发送的报文,对应的将对应MAC地址的IP地址返回给虚拟机,这样虚拟机启动完成以后就会有IP地址

原文字描述

L3 agent

  1. L3 agent负责路由、浮动IP分配、地址转换和安全组管理
  2. 通过iptables实现安全组、路由以及地址转换
  3. 每个虚拟路由运行在一个network namespace中,每个namespace 由qroute-<router-UUID>命名

这里提前讲了L3 agent,下节讲vlan网络

0 人点赞