一、neutron 介绍:
Neutron 概述
传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备;而云环境下的网络已经变得非常复杂,特别是在多租户场景里,用户随时都可能需要创建、修改和删除网络,网络的连通性和隔离不已经太可能通过手工配置来保证了。
如何快速响应业务的需求对网络管理提出了更高的要求。传统的网络管理方式已经很难胜任这项工作,而“
软件定义网络(software-defined networking, SDN)”所具有的灵活性和自动化优势使其成为云时代网络管理的主流。
Neutron 的设计目标是实现“网络即服务(Networking as a Service)”。为了达到这一目标,在设计上遵循了基于 SDN 实现网络虚拟化的原则,在实现上充分利用了 Linux 系统上的各种网络相关的技术。
SDN 模式服务— NeutronSDN( 软件定义网络 ), 通过使用它,网络管理员和云计算操作员可以
通过程序来动态定义虚拟网络设备。Openstack 网络中的
SDN 组件就是 Quantum.但因为版权问题而改名为Neutron 。
Neutron网络基本概念
(1)neutwork
network 是一个隔离的二层广播域。
Neutron 支持多种类型的 network,包括 local, flat, VLAN, VxLAN 和 GRE。
local
local 网络与其他网络和节点隔离。local 网络中的 instance
只能与位于同一节点上同一网络的 instance 通信,local 网络主要用于单机测试。
flat
flat 网络是无 vlan tagging 的网络。flat 网络中的 instance 能与位于同一网络的 instance 通信,并且可以跨多个节点。
vlan
vlan 网络是具有 802.1q tagging 的网络。
vlan 是一个二层的广播域,同一 vlan 中的 instance 可以通信,
不同 vlan 只能通过 router 通信。
vlan 网络可跨节点,是应用最广泛的网络类型。
vxlan
vxlan 是基于隧道技术的 overlay 网络。
vxlan 网络通过唯一的 segmentation ID(也叫 VNI)与其他 vxlan 网络区分。
vxlan 中数据包会通过 VNI 封装成 UDP 包进行传输。因为二层的包通过封装在三层传输,能够克服 vlan 和物理网络基础设施的限制。
gre
gre 是与 vxlan 类似的一种 overlay 网络。主要区别在于使用 IP 包而非 UDP 进行封装。
不同 network 之间在二层上是隔离的。
以 vlan 网络为例,network A 和 network B 会分配不同的 VLAN ID,这样就保证了 network A 中的广播包不会跑到 network B 中。当然,这里的隔离是指二层上的隔离,
借助路由器不同 network 是可能在三层上通信的。
network 必须属于某个 Project( Tenant 租户),Project 中可以创建多个 network。
network 与 Project 之间是 1对多 关系。
(2)subnet
subnet 是一个 IPv4 或者 IPv6 地址段。
instance 的 IP 从 subnet 中分配。
每个 subnet 需要定义 IP 地址的范围和掩码。
network 与 subnet 是 1对多 关系。一个 subnet 只能属于某个 network;一个 network 可以有多个 subnet,
这些 subnet 可以是不同的 IP 段,但不能重叠。下面的配置是有效的:
network A subnet A-a: 10.10.1.0/24 {"start": "10.10.1.1", "end": "10.10.1.50"}
subnet A-b: 10.10.2.0/24 {"start": "10.10.2.1", "end": "10.10.2.50"}
但下面的配置则无效,因为 subnet 有重叠
network A subnet A-a: 10.10.1.0/24 {"start": "10.10.1.1", "end": "10.10.1.50"}
subnet A-b: 10.10.1.0/24 {"start": "10.10.1.51", "end": "10.10.1.100"}
这里不是判断 IP 是否有重叠,而是 subnet 的 CIDR 重叠(都是 10.10.1.0/24)。但是,
如果 subnet 在不同的 network 中,CIDR 和 IP 都是可以重叠的,比如
network A subnet A-a: 10.10.1.0/24 {"start": "10.10.1.1", "end": "10.10.1.50"}
network B subnet B-a: 10.10.1.0/24 {"start": "10.10.1.1", "end": "10.10.1.50"}
这里大家不免会疑惑: 如果上面的IP地址是可以重叠的,那么就可能存在具有相同 IP 的两个 instance,这样会不会冲突? 简单的回答是:不会!
具体原因: 因为
Neutron 的 router 是通过 Linux network namespace 实现的。network namespace 是一种网络的隔离机制。通过它,每个 router 有自己独立的路由表。上面的配置有两种结果:
1. 如果两个 subnet 是通过同一个 router 路由,根据 router 的配置,只有指定的一个 subnet 可被路由。
2. 如果上面的两个 subnet 是通过不同 router 路由,因为 router 的路由表是独立的,所以两个 subnet 都可以被路由。
(3)
port
port 可以看做虚拟交换机上的一个端口。
port 上定义了 MAC 地址和 IP 地址,当 instance 的虚拟网卡 VIF(Virtual Interface) 绑定到 port 时,port 会将 MAC 和 IP 分配给 VIF。
subnet 与 port 是 1对多 关系。一个 port 必须属于某个 subnet;一个 subnet 可以有多个 port。
小结
下面总结了 Project,Network,Subnet,Port 和 VIF 之间关系。
Project 1 : m Network 1 : m Subnet 1 : m Port 1 : 1 VIF m : 1 Instance
Neutron 功能
Neutron 为整个 OpenStack 环境提供网络支持,包括
二层交换,三层路由,负载均衡,防火墙和 VPN 等。
Neutron 提供了一个灵活的框架,通过配置,无论是开源还是商业软件都可以被用来实现这些功能。
二层交换 Switching
Nova 的 Instance 是通过虚拟交换机连接到虚拟二层网络的。Neutron 支持多种虚拟交换机,包括 Linux 原生的 Linux Bridge 和 Open vSwitch。 Open vSwitch(OVS)是一个开源的虚拟交换机,它支持标准的管理接口和协议。
利用 Linux Bridge 和 OVS,Neutron 除了可以创建传统的 VLAN 网络,还
可以创建基于隧道技术的 Overlay 网络,比如 VxLAN 和 GRE(
Linux Bridge 目前只支持 VxLAN)
三层路由 Routing
Instance 可以配置不同网段的 IP,Neutron 的 router(虚拟路由器)实现 instance 跨网段通信。
router 通过 IP forwarding,iptables 等技术来实现路由和 NAT。
负载均衡 Load Balancing
Openstack 在 Grizzly 版本第一次引入了
Load-Balancing-as-a-Service(LBaaS),
提供了将负载分发到多个 instance 的能力。LBaaS 支持多种负载均衡产品和方案,
不同的实现以 Plugin 的形式集成到 Neutron,目前默认的 Plugin 是 HAProxy。
Neutron 通过下面两种方式来保障 instance 和网络的安全性。
Security Group
通过
iptables 限制进出 instance 的网络包。
Firewall-as-a-Service
FWaaS,
限制进出虚拟路由器的网络包,也是通过 iptables 实现。
Neutron 优点:
Openstack 中的
SDN 组件架构也属于可插拔类型。通过
各种插件可以管控不同种类的交换机、路由器、防火墙、负载均衡器并实现 firewall as a service 等许多功能。通过软件来定义的网络,可以对整个云计算设施进行更为精细的掌控。
Neutron 部署方案
方案1:
控制节点 + 计算节点:
控制节点:部署的服务包括:
neutron server, core plugin 的 agent 和 service plugin 的 agent。
计算节点:部署
core plugin 的agent,负责提供二层网络功能。
这里有几点需要说明:
1. core plugin 和 service plugin 已经集成到 neutron server,不需要运行独立的 plugin 服务。
2. 控制节点和计算节点
都需要部署 core plugin 的 agent,因为通过该 agent 控制节点与计算节点才能建立二层连接。
3. 可以部署多个控制节点和计算节点。
方案2:
控制节点 + 网络节点 + 计算节点
在这个部署方案中,OpenStack 由控制节点,网络节点和计算节点组成。
控制节点:部署 neutron server 服务。
网络节点:部署的服务包括:core plugin 的 agent 和 service plugin 的 agent。
计算节点:
部署 core plugin 的agent,负责提供二层网络功能。
这个方案的
要点是将所有的 agent 从控制节点分离出来,部署到独立的网络节点上。
-
控制节点只负责通过 neutron server 响应 API 请求。
-
由
独立的网络节点实现数据的交换,路由以及 load balance等高级网络服务。
-
可以通过
增加网络节点承担更大的负载。
-
可以部署多个控制节点、网络节点和计算节点。
该方案特别适合规模较大的 OpenStack 环境。
配置多个网卡区分不同类型的网络数据
OpenStack 至少包含下面几类网络流量
Management
API
VM
External
Management 网络
用于节点之间
message queue 内部通信以及访问 database 服务,所有的节点都需要连接到 management 网络。
API 网络
OpenStack
各组件通过该网络向用户暴露 API 服务。Keystone, Nova, Neutron, Glance, Cinder, Horizon 的 endpoints 均配置在 API 网络上。通常
,管理员也通过 API 网络 SSH 管理各个节点。
VM 网络(租户网络)
VM 网络也叫 tenant 网络,
用于 instance 之间通信。
VM 网络可以选择的类型包括 local, flat, vlan, vxlan 和 gre。
VM 网络
由 Neutron 配置和管理。
External 网络
External 网络指的是 VM 网络之外的网络,该网络不由 Neutron 管理。 Neutron 可以将 router attach 到 External 网络,为 instance
提供访问外部网络的能力。 External 网络可能是企业的 intranet,也可能是 internet。
这几类网络只是逻辑上的划分,物理实现上有非常大的自由度。
我们
可以为每种网络分配单独的网卡;也可以多种网络共同使用一个网卡;为提高带宽和硬件冗余,可以使用
bonding 技术将多个物理网卡绑定成一个逻辑的网卡
我们的实验环境采用下面的网卡分配方式:
1. 控制节点 3 网卡(eth0, eth1, eth2),计算节点 2 网卡(eth0, eth1)。
2. 合并 Management 和 API 网络,使用 eth0
3. VM 网络使用 eht1。
4. 控制节点的 eth2 与 External 网络连接
物理拓扑:
分割线上方的网络由网络管理员(就是我们啦)配置。 主要涉及
Management, API 和 external 网络。 配置的内容包括节点上的物理网卡,物理交换机和外部路由器,防火墙以及物理连线等
分割线下方是
VM 网络,由 Neutron 管理。 我们只需要通过 Web GUI 或者 CLI 操作,Neutron 会负责实现。
二、neutron 架构
Nuetron 架构
与 OpenStack 的其他服务的设计思路一样,
Neutron 也是采用分布式架构,由
多个组件(子服务)共同对外提供网络服务。
Neutron Server
对外提供 OpenStack 网络 API,
接收请求,并调用 Plugin 处理请求。
Plugin
处理 Neutron Server 发来的请求,维护 OpenStack 逻辑网络状态, 并
调用 Agent 处理请求。
Agent
处理 Plugin 的请求,负责在 network provider 上真正实现各种网络功能。
network provider
提供网络服务的虚拟或物理网络设备,例如 Linux Bridge,Open vSwitch 或者其他支持 Neutron 的物理交换机。
Queue
Neutron Server,Plugin 和 Agent 之间
通过 Messaging Queue 通信和调用。
Database
存放 OpenStack 的网络状态信息,包括 Network, Subnet, Port, Router 等。
-
-
支持分布式部署,获得足够的扩展性。
通常鱼和熊掌不能兼得,虽然获得了这些优势,但这样使得 Neutron 更加复杂,更不容易理解。 后面我们会详细讨论 Neutron 的各个组件,但在这之前,非常有必要先通过一个例子了解这些组件各自的职责以及是如何协同工作。
以创建一个 VLAN100 的 network 为例,
假设 network provider 是 linux bridge, 流程如下:
*****
-
Neutron Server 接收到创建 network 的请求,通过 Message Queue(RabbitMQ)通知已注册的 Linux Bridge Plugin。
-
Plugin 将要创建的 network 的信息(例如名称、VLAN ID等)保存到数据库中,并通过 Message Queue 通知运行在各节点上的 Agent。
-
Agent 收到消息后会在节点上的物理网卡(比如 eth2)上创建 VLAN 设备(比如 eth2.100),并创建 bridge (比如 brqXXX) 桥接 VLAN 设备。
-
plugin 解决的是 What 的问题,即网络要配置成什么样子?而至于如何配置 How 的工作则交由 agent 完成。
-
plugin,agent 和 network provider 是配套使用的,比如上例中 network provider 是 linux bridge,那么就得使用 linux bridge 的 plungin 和 agent;如果 network provider 换成了 OVS 或者物理交换机,plugin 和 agent 也得替换。
-
plugin 的一个主要的职责是在数据库中维护 Neutron 网络的状态信息,这就造成一个问题:所有 network provider 的 plugin 都要编写一套非常类似的数据库访问代码。为了解决这个问题,Neutron 在 Havana 版本实现了一个 ML2(Modular Layer 2)plugin,对 plgin 的功能进行抽象和封装。有了 ML2 plugin,各种 network provider 无需开发自己的 plugin,只需要针对 ML2 开发相应的 driver 就可以了,工作量和难度都大大减少。ML2 会在后面详细讨论。
-
plugin 按照功能分为两类: core plugin 和 service plugin。core plugin 维护 Neutron 的 netowrk, subnet 和 port 相关资源的信息,与 core plugin 对应的 agent 包括 linux bridge, OVS 等; service plugin 提供 routing, firewall, load balance 等服务,也有相应的 agent。后面也会分别详细讨论。
三、neutron server 组件详解:
Neutron server 分层模型
上图是 Neutron Server 的分层结构,至上而下依次为:
Core API:对外提供管理 network, subnet 和 port 的 RESTful API。
Extension API:对外提供管理 router, load balance, firewall 等资源 的 RESTful API。
Commnon Service:认证和校验 API 请求。
Neutron Core:Neutron server 的核心处理程序,通过调用相应的 Plugin 处理请求。
Core Plugin API:定义了 Core Plgin 的抽象功能集合,Neutron Core 通过该 API 调用相应的 Core Plgin。
Extension Plugin API:定义了 Service Plgin 的抽象功能集合,Neutron Core 通过该 API 调用相应的 Service Plgin。
Core Plugin:实现了 Core Plugin API,在数据库中维护 network, subnet 和 port 的状态,并负责调用相应的 agent 在 network provider 上执行相关操作,比如创建 network。
Service Plugin:实现了 Extension Plugin API,在数据库中维护 router, load balance, security group 等资源的状态,并负责调用相应的 agent 在 network provider 上执行相关操作,比如创建 router。
归纳起来,Neutron Server 包括两部分:
1. 提供 API 服务。
2. 运行 Plugin。
即 Neutron Server = API + Plugins
明白了 Neutron Server 的分层模型,我们就更容易理解 Neutron 是如何支持多种 network provider。
四、ML2 Core Plugin 详解:
Neutron 是如何支持多种 network provider?
上节提到 Core Plugin,其功能是维护数据库中 network, subnet 和 port 的状态,并负责调用相应的 agent 在 network provider 上执行相关操作,比如创建 network。
openstack中有两大常见 Core Plugin: linux bridge plugin 和 open vswitch plugin。
Neutron 可以通过开发不同的 plugin 和 agent 支持不同的网络技术。这是一种相当开放的架构。不过随着支持的 network provider 数量的增加,开发人员发现了两个突出的问题:
1. 只能在 OpenStack 中使用一种 core plugin,多种 network provider 无法共存。 只使用一个 core plugin 本身没有问题。但问题在于传统的 core plugin 与 core plugin agent 是一一对应的。也就是说,如果选择了 linux bridge plugin,那么 linux bridge agent 将是唯一选择,就必须在 OpenStack 的所有节点上使用 linux bridge 作为虚拟交换机(即 network provider)。
同样的,如果选择 open vswitch plugin, 所有节点上只能使用 open vswitch,而不能使用其他的 network provider。
2. 不同 plugin 之间存在大量重复代码,开发新的 plugin 工作量大。
所有传统的 core plugin 都需要编写大量重复和类似的数据库访问的代码,大大增加了 plugin 开发和维护的工作量。
ML2 能解决传统 core plugin 的问题
Moduler Layer 2(ML2):是 Neutron 在 Havana 版本实现的一个新的 core plugin,用于替代原有的 linux bridge plugin 和 open vswitch plugin。 作为新一代的 core plugin,提供了一个框架,允许在 OpenStack 网络中同时使用多种 Layer 2 网络技术,不同的节点可以使用不同的网络实现机制。
如上图所示,采用 ML2 plugin 后,可以在不同节点上分别部署 linux bridge agent, open vswitch agent, hyper-v agent 或其他第三方 agent。
ML2 不但支持异构部署方案,同时能够与现有的 agent 无缝集成:以前用的 agent 不需要变,只需要将 Neutron server 上的传统 core plugin 替换为 ML2。
有了 ML2,要支持新的 network provider 就变得简单多了:无需从头开发 core plugin,只需要开发相应的 mechanism driver,大大减少了要编写和维护的代码。
ML2 Core Plugin 详解:
ML2 对二层网络进行抽象和建模,引入了 type driver 和 mechansim driver。这两类 driver 解耦了 Neutron 所支持的网络类型(type)与访问这些网络类型的机制(mechanism),其结果就是使得 ML2 具有非常好的弹性,易于扩展,能够灵活支持多种 type 和 mechanism。
(1) Type Driver
Neutron 支持的每一种网络类型都有一个对应的 ML2 type driver。
type driver 负责维护网络类型的状态,执行验证,创建网络等。 ML2 支持的网络类型包括 local, flat, vlan, vxlan 和 gre。 我们将在后面章节详细讨论每种 type。
(2) Mechansim Driver
Neutron 支持的每一种网络机制都有一个对应的 ML2 mechansim driver。
mechanism driver 负责获取由 type driver 维护的网络状态,并确保在相应的网络设备(物理或虚拟)上正确实现这些状态。
type 和 mechanisim 都太抽象,现在我们举一个具体的例子: type driver 为 vlan,mechansim driver 为 linux bridge,我们要完成的操作是创建 network vlan100,那么:
-
vlan type driver 会确保将 vlan100 的信息保存到 Neutron 数据库中,包括 network 的名称,vlan ID 等。
-
linux bridge mechanism driver 会确保各节点上的 linux brige agent 在物理网卡上创建 ID 为 100 的 vlan 设备 和 brige 设备,并将两者进行桥接。
mechanism driver 有三种类型:
Agent-based
包括 linux bridge, open vswitch 等。
Controller-based
包括 OpenDaylight, VMWare NSX 等。
基于物理交换机
包括 Cisco Nexus, Arista, Mellanox 等。 比如前面那个例子如果换成 Cisco 的 mechanism driver,则会在 Cisco 物理交换机的指定 trunk 端口上添加 vlan100。
本教程讨论的 mechanism driver 将涉及 linux bridge, open vswitch 和 L2 population。
linux bridge 和 open vswitch 的 ML2 mechanism driver 作用是配置各节点上的虚拟交换机。linux bridge driver 支持的 type 包括 local, flat, vlan, and vxlan。open vswitch driver 除这 4 种 type 还支持 gre。
L2 population driver 作用是优化和限制 overlay 网络中的广播流量。 vxlan 和 gre 都属于 overlay 网络。
ML2 core plugin 已经成为 OpenStack Neutron 的首选 plugin,本教程后面会讨论如何在实验环境中配置 ML2 的各种 type 和 mechansim。
五、Service Plugin / Agent 详解:
Core Plugin/Agent 负责管理核心实体:net, subnet 和 port。而对于更高级的网络服务,则由 Service Plugin/Agent 管理。
Service Plugin 及其 Agent 提供更丰富的扩展功能,包括路由,load balance,firewall等,如图所示:
DHCP
dhcp agent 通过 dnsmasq 为 instance 提供 dhcp 服务。
Routing
l3 agent 可以为 project(租户)创建 router,提供 Neutron subnet 之间的路由服务。路由功能默认通过 IPtables 实现。
Firewall
l3 agent 可以在 router 上配置防火墙策略,提供网络安全防护。另一个与安全相关的功能是 Security Group,也是通过 IPtables 实现。 Firewall 与 Security Group 的区别在于:
-
Firewall 安全策略位于 router,保护的是某个 project 的所有 network。
-
Security Group 安全策略位于 instance,保护的是单个 instance。
Firewall 与 Security Group 后面会详细分析。
Load Balance
Neutron 默认通过 HAProxy 为 project 中的多个 instance 提供 load balance 服务。
后面的章节会结合 linux bridge 和 open vswitch 详细讨论每一种 service。
五、 Neutron 架构框架总结:
前面我们详细讨论了 Neutron 架构,包括 Neutron Server,Core 和 Service Agent。现在用两张图做个总结。
第一张:
与 OpenStack 其他服务一样,Neutron 采用的是分布式架构,包括 Neutorn Server、各种 plugin/agent、database 和 message queue。
1. Neutron server 接收 api 请求。
2. plugin/agent 实现请求。
3. database 保存 neutron 网络状态。
4. message queue 实现组件之间通信。
metadata-agent 之前没有讲到,这里做个补充:
instance 在启动时需要访问 nova-metadata-api 服务获取 metadata 和 userdata,这些 data 是该 instance 的定制化信息,比如 hostname, ip, public key 等。
但 instance 启动时并没有 ip,那如何通过网络访问到 nova-metadata-api 服务呢?
答案就是 neutron-metadata-agent 该 agent 让 instance 能够通过 dhcp-agent 或者 l3-agent 与 nova-metadata-api 通信
如果我们将 Neutron 架构展开,则会得到下面第二张图:
- Neutron 通过 plugin 和 agent 提供的网络服务。
- plugin 位于 Neutron server,包括 core plugin 和 service plugin。
- agent 位于各个节点,负责实现网络服务。
- core plugin 提供 L2 功能,ML2 是推荐的 plugin。
- 使用最广泛的 L2 agent 是 linux bridage 和 open vswitch。
- service plugin 和 agent 提供扩展功能,包括 dhcp, routing, load balance, firewall, vpn 等。
至此,Neutron 架构已经讨论完,希望大家已经理解。
neutron— 网络实践
一、虚拟机获取 ip:
用 namspace 隔离 DHCP 服务
Neutron 通过 dnsmasq 提供 DHCP 服务,而 dnsmasq 通过 Linux Network Namespace 独立的为每个 network 服务隔离
在二层网络上,VLAN 可以将一个物理交换机分割成几个独立的虚拟交换机。类似地,在三层网络上,Linux network namespace 可以将一个物理三层网络分割成几个独立的虚拟三层网络。
每个 namespace 都有自己独立的网络栈,包括 route table,firewall rule,network interface device 等。
Neutron 通过 namespace 为每个 network 提供独立的 DHCP 和路由服务,从而允许租户创建重叠的网络。如果没有 namespace,网络就不能重叠,这样就失去了很多灵活性。
每个 dnsmasq 进程都位于独立的 namespace, 命名为 qdhcp-<network id>,例如 flat_net:
ip netns list 命令列出所有的 namespace
ip netns exec <network namespace name> <command> 管理 namespace
root namespace:
其实,宿主机本身也有一个 namespace,叫 root namespace,拥有所有物理和虚拟 interface device。物理 interface 只能位于 root namespace。
新创建的 namespace 默认只有一个 loopback device。管理员可以将虚拟 interface,例如 bridge,tap 等设备添加到某个 namespace。
对于 flat_net 的 DHCP 设备 tap19a0ed3d-fe,需要将其放到 namespace qdhcp-7bf09be4-8653-4869-84f0-33494f238627 中,但这样会带来一个问题:tap19a0ed3d-fe 将无法直接与 root namespace 中的 bridge 设备 brqf153b42f-c3 连接。
Neutron 使用 veth pair 解决了这个问题。
veth pair 是一种成对出现的特殊网络设备,它们象一根虚拟的网线,可用于连接两个 namespace。向 veth pair 一端输入数据,在另一端就能读到此数据。
tap19a0ed3d-fe 与 ns-19a0ed3d-fe 就是一对 veth pair,它们将 qdhcp-f153b42f-c3a1-4b6c-8865-c09b5b2aa274 连接到 brqf153b42f-c3。
如下图所示:
可以通过 ip netns exec qdhcp-7bf09be4-8653-4869-84f0-33494f238627 ip a命令查看ns-ba07bb93配置:
获取 dhcp IP 过程分析
在创建 instance 时,Neutron 会为其分配一个 port,里面包含了 MAC 和 IP 地址信息。这些信息会同步更新到 dnsmasq 的 host 文件。如下图所示:
同时 nova-compute 会设置虚机 VIF 的 MAC 地址。
一切准备就绪,instance 获取 IP 的过程如下:
1. vm 开机启动,发出 DHCPDISCOVER 广播,该广播消息在整个 net 中都可以被收到。
2. 广播到达 veth tap19a0ed3d-fe,然后传送给 veth pair 的另一端 ns-19a0ed3d-fe。dnsmasq 在它上面监听,dnsmasq 检查其 host 文件,发现有对应项,于是dnsmasq 以 DHCPOFFER 消息将 IP(192.168.254.18)、子网掩码(255.255.255.0)、地址租用期限等信息发送给 vm。
3. vm 发送 DHCPREQUEST 消息确认接受此 DHCPOFFER。
4. dnsmasq 发送确认消息 DHCPACK,整个过程结束。
二、VXLAN简介:
overlay network概念:
overlay network 是指建立在其他网络上的网络。overlay network 中的节点可以看作通过虚拟(或逻辑)链路连接起来的。overlay network 在底层可能由若干物理链路组成,但对于节点,不需要关心这些底层实现。
例如 P2P 网络就是 overlay network,隧道也是。vxlan 和 gre 都是基于隧道技术实现的,它们也都是 overlay network。
目前 linux bridge 只支持 vxlan,不支持 gre;
open vswitch 两者都支持。vxlan 与 gre 实现非常类似,而且 vxlan 用得较多,所以本教程只介绍 vxlan。
VXLAN简介:
VXLAN 为 Virtual eXtensible Local Area Network。正如名字所描述的,VXLAN 提供与 VLAN 相同的以太网二层服务,但拥有更强的扩展性和灵活性。与 VLAN 相比,
VXLAN 有下面几个优势:
1. 支持更多的二层网段。
VLAN 使用 12-bit 标记 VLAN ID,最多支持 4094 个 VLAN,这对大型云部署会成为瓶颈。VXLAN 的 ID (VNI 或者 VNID)则用 24-bit 标记,支持 16777216 个二层网段。
2. 能更好地利用已有的网络路径。
VLAN 使用 Spanning Tree Protocol 避免环路,这会导致有一半的网络路径被 block 掉。VXLAN 的数据包是封装到 UDP 通过三层传输和转发的,可以使用所有的路径。
3. 避免物理交换机 MAC 表耗尽。
由于采用隧道机制,TOR (Top on Rack) 交换机无需在 MAC 表中记录虚拟机的信息。
VXLAN 封装和包格式:
VXLAN 是将二层建立在三层上的网络。通过将二层数据封装到 UDP 的方式来扩展数据中心的二层网段数量。
VXLAN 是一种在现有物理网络设施中支持大规模多租户网络环境的解决方案。VXLAN 的传输协议是 IP + UDP。
VXLAN 定义了一个 MAC-in-UDP 的封装格式。在原始的 Layer 2 网络包前加上 VXLAN header,然后放到 UDP 和 IP 包中。通过 MAC-in-UDP 封装,VXLAN 能够在 Layer 3 网络上建立起了一条 Layer 2 的隧道。
VXLAN 包的格式如下:
如上图所示,VXLAN 引入了 8-byte VXLAN header,其中 VNI 占 24-bit。VXLAN 和原始的 L2 frame 被封装到 UDP 包中。这 24-bit 的 VNI 用于标示不同的二层网段,能够支持 16777216 个 LAN。
VXLAN Tunnel Endpoint
VXLAN 使用 VXLAN tunnel endpoint (VTEP) 设备处理 VXLAN 的封装和解封。每个 VTEP 有一个 IP interface,配置了一个 IP 地址。VTEP 使用该 IP 封装 Layer 2 frame,并通过该 IP interface 传输和接收封装后的 VXLAN 数据包。
下面是 VTEP 的示意图:
VXLAN 独立于底层的网络拓扑;反过来,两个 VTEP 之间的底层 IP 网络也独立于 VXLAN。VXLAN 数据包是根据外层的 IP header 路由的,该 header 将两端的 VTEP IP 作为源和目标 IP。
VXLAN 封装和转发包的过程,以及 Linux 对 VXLAN 的原生支持
VXLAN 包转发流程
VXLAN 在 VTEP 间建立隧道,通过 Layer 3 网络传输封装后的 Layer 2 数据。下面例子演示了数据如何在 VXLAN 上传输:
图中 Host-A 和 Host-B 位于 VNI 10 的 VXLAN,通过 VTEP-1 和 VTEP-2 之间建立的 VXLAN 隧道通信。数据传输过程如下:
1. Host-A 向 Host-B 发送数据时,Host-B 的 MAC 和 IP 作为数据包的目标 MAC 和 IP,Host-A 的 MAC 作为数据包的源 MAC 和 IP,然后通过 VTEP-1 将数据发送出去。
2. VTEP-1 从自己维护的映射表中找到 MAC-B 对应的 VTEP-2,然后执行 VXLAN 封装,加上 VXLAN 头,UDP 头,以及外层 IP 和 MAC 头。此时的外层 IP 头,目标地址为 VTEP-2 的 IP,源地址为 VTEP-1 的 IP。同时由于下一跳是 Router-1,所以外层 MAC 头中目标地址为 Router-1 的 MAC。
3. 数据包从 VTEP-1 发送出后,外部网络的路由器会依据外层 IP 头进行路由,最后到达与 VTEP-2 连接的路由器 Router-2。
4. Router-2 将数据包发送给 VTEP-2。VTEP-2 负责解封数据包,依次去掉外层 MAC 头,外层 IP 头,UDP 头 和 VXLAN 头。VTEP-2 依据目标 MAC 地址将数据包发送给 Host-B。
上面的流程我们看到 VTEP 是 VXLAN 的最核心组件,负责数据的封装和解封。隧道也是建立在 VTEP 之间的,VTEP 负责数据的传送。
VTEP 是如何提前获知 IP -- MAC -- VTEP 相关信息的呢?
答案是:
1. Neutron 知道每一个 port 的状态和信息; port 保存了 IP,MAC 相关数据。
2. instance 启动时,其 port 状态变化过程为:down -> build -> active。
3. 每当 port 状态发生变化时,Neutron 都会通过 RPC 消息通知各节点上的 Neutron agent,使得 VTEP 能够更新 VM 和 port 的相关信息。
VTEP 可以根据这些信息判断出其他 Host 上都有哪些 VM,以及它们的 MAC 地址,这样就能直接与之通信,从而避免了不必要的隧道连接和广播。
Linux 对 VXLAN 的支持
VTEP 可以由专有硬件来实现,也可以使用纯软件实现。目前比较成熟的 VTEP 软件实现包括:
1. 带 VXLAN 内核模块的 Linux
2. Open vSwitch
我们先来看 Linux 如何支持 VXLAN
实现方式:
1. Linux vxlan 创建一个 UDP Socket,默认在 8472 端口监听。
2. Linux vxlan 在 UDP socket 上接收到 vxlan 包后,解包,然后根据其中的 vxlan ID 将它转给某个 vxlan interface,然后再通过它所连接的 linux bridge 转给虚机。
3. Linux vxlan 在收到虚机发来的数据包后,将其封装为多播 UDP 包,从网卡发出。
ML2 mechanism driver: Linux Bridge 和 Open vSwitch
网卡分配示例:
- 控制节点三个网卡(eth0, eth1, eth2),计算节点两网卡(eth0, eth1)。
- 合并 Management 和 API 网络,使用 eth0,IP 段为 192.168.104.0/24。
- VM 网络使用 eht1。
- 控制节点的 eth2 与 External 网络连接,IP 段为 10.10.10.0/24。
Linux Bridge :
Open vSwitch:
Open vSwitch 中的网络设备:
br-ex:连接外部(external)网络的网桥。
br-int:集成(integration)网桥,所有 instance 的虚拟网卡和其他虚拟网络设备都将连接到该网桥。
br-tun:隧道(tunnel)网桥,基于隧道技术的 VxLAN 和 GRE 网络将使用该网桥进行通信。
tap interface:命名为 tapXXXX。
linux bridge:命名为 qbrXXXX。
veth pair:命名为 qvbXXXX, qvoXXXX
OVS integration bridge:命名为 br-int。
OVS patch ports:命名为 int-br-ethX 和 phy-br-ethX(X 为 interface 的序号)。
OVS provider bridge:命名为 br-ethX(X 为 interface 的序号)。
物理 interface:命名为 ethX(X 为 interface 的序号)。
OVS tunnel bridge:命名为 br-tun。
三、三层网络介绍:
虚拟机访问外网
(1)虚拟机中访问一个外网地址192.168.253.3,并用 traceroute 命令跟踪路由查看:
(2)根据网络拓扑,由于虚机访问外网要经过本网段的网关192.168.101.1,然后经过路由的外网接口转发出去,到达192.168.253.3
查看路由命名空间:
ip netns list
(3)查看路由命名空间的网络配置,查到路由连接外网的端口和ip:
ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 ip a
路由上的外网端口正好接到外网网桥br-ex上:ovs-vsctl show 查看
(4)查看路由iptables NAT 转发规则,记录对私网做的SNAT
ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 iptables -t nat -L
ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 iptables -t nat -S
规则解释: -A neutron-l3-agent-snat -o qg-8df29d32-d6 -j SNAT --to-source 192.168.253.65 记录了流入接口qg-8df29d32-d6 的数据包做SNAT(基于源地址转发),将源地址修改为192.168.253.65
(5)验证:
在虚机 ping 192.168.253.3 时, 可以通过 tcpdump 分别观察 router 两个 interface 的 icmp 数据包来验证 SNAT 的行为:
在路由qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1,可查到私有网络的网关接口qr-7b56f58b-b5,并在路由中抓取网关接口的icmp包:
ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 tcpdump -i qr-7b56f58b-b5 -n icmp
在路由中,抓取路由的外网接口qg-8df29d32-d6的icmp包:
ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 tcpdump -i qg-8df29d32-d6 -n icmp
外网访问虚机——floating ip原理
SNAT 让 instance 能够直接访问外网,但外网还不能直接访问 instance。因为 instance 没有外网 IP。这里 “直接访问 instance” 是指通信连接由外网发起,例如从外网 SSH 实例。
(1)首先将实例绑定浮动 ip192.168.253.66, floating IP 是配置在 router 的外网 interface 上的,再查看 router 的 interface 配置:
(2)在实例中ping 192.168.253.3 外网地址,在路由的qr-7b56f58b-b5 接口上,实例访问外网ip,外网ip将数据包转发回实例ip;但在路由的qg-8df29d32-d6 接口上,始终是通过 floating IP 192.168.253.66 与外网通信。
(3) 原因是在路由中iptables做了DNA T(基于目的地址转发),查看 router 的 NAT 规则:
当 router 接收到从外网发来的包,如果目的地址是 floating IP 192.168.254.66,将目的地址修改为实例的 IP 192.168.101.3。这样外网的包就能送达到实例;
当实例发送数据到外网,源地址 192.168.101.3 将被修改为 floating IP 192.168.253.66;
四:neutron配置文件:
neutron.conf
[DEFAULT]
state_path = /var/lib/neutron
auth_strategy = keystone
core_plugin = ml2
service_plugins = router
dhcp_agent_notification = true
allow_overlapping_ips = True
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true
transport_url =
rabbit://openstack:admin@controller
[agent]
[cors]
[cors.subdomain]
[database]
connection = mysql+
pymysql://neutron:NEUTRON_DBPASS@controller/neutron
[keystone_authtoken]
memcached_servers = controller:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = neutron
[matchmaker_redis]
[nova]
region_name = RegionOne
auth_type = password
project_domain_name = default
project_name = service
user_domain_name = default
username = nova
password = nova
[oslo_concurrency]
lock_path = $state_path/lock
[oslo_messaging_amqp]
[oslo_messaging_kafka]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_messaging_zmq]
[oslo_middleware]
[oslo_policy]
[qos]
[quotas]
[ssl]
ml2_conf.ini
[DEFAULT]
[ml2]
type_drivers = flat,vxlan
tenant_network_types = vxlan
mechanism_drivers = openvswitch,l2population
extension_drivers = port_security
[ml2_type_flat]
[ml2_type_geneve]
[ml2_type_gre]
[ml2_type_vlan]
[ml2_type_vxlan]
vni_ranges = 1:1000
[securitygroup]
enable_ipset = true
openvswitch_agent.ini
[DEFAULT]
[agent]
tunnel_types = vxlan
l2_population = True
[ovs]
tunnel_bridge = br-tun
local_ip = 192.168.254.63
bridge_mappings =
[securitygroup]
firewall_driver = iptables_hybrid
enable_security_group = true
[xenapi]
l3_agent.ini
[DEFAULT]
interface_driver = openvswitch
external_network_bridge = br-ex
[agent]
[ovs]
metadata_agent.ini
[DEFAULT]
nova_metadata_ip = controller
metadata_proxy_shared_secret = METADATA_SECRET
[agent]
[cache]
dhcp_agent.ini
[DEFAULT]
interface_driver = openvswitch
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = true
[agent]
[ovs]
注意:配置完配置文件后,提前准备ovs外网用的网桥,之后同步数据库,启动服务:
(控制)yum install openstack-neutron openstack-neutron-ml2 openvswitch openstack-neutron-openvswitch ebtables -y
systemctl enable neutron-server.service neutron-dhcp-agent.service openvswitch neutron-openvswitch-agent neutron-metadata-agent.service
systemctl start neutron-server.service neutron-dhcp-agent.service openvswitch neutron-openvswitch-agent neutron-metadata-agent.service
ovs-vsctl add-br br-ex
ovs-vsctl add-port br-ex eth2
systemctl enable neutron-l3-agent.service
systemctl start neutron-l3-agent.service
(计算)yum install openvswitch openstack-neutron-openvswitch ebtables ipset
systemctl enable openvswitch neutron-openvswitch-agent
systemctl start openvswitch neutron-openvswitch-agent
systemctl stop openvswitch neutron-openvswitch-agent
五、部署neutron服务
点进networkservice——installation and configure controller
1)创建neutron数据库
2) 增加用户neutron并授权以及设置密码
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' \ IDENTIFIED BY 'NEUTRON_DBPASS';
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' \ IDENTIFIED BY 'NEUTRON_DBPASS';
3)声明变量创建neutron用户,设置密码为neutron
openstack user create --domain default --password=neutron neutron
4)给neutron用户增加管理员权限
openstack role add --project service --user neutron admin
5)创建一个服务叫neutron
openstack service create --name neutron \
--description "OpenStack Networking" network
6)创建基于neutron服务的三个服务端点
openstack endpoint create --region RegionOne \
network public http://controller:9696
点进 Networking Option 2: Self-service networks(自定义网络)
1)安装neutron相关的组件
yum install openstack-neutron openstack-neutron-ml2 openvswitch openstack-neutron-openvswitch ebtables -y
2)编辑配置文件,安装上面所给模板复制即可
除了openvswitch_agent.ini文件中的loca_ip改为第二个网卡的ip,其他无需更改。
/etc/neutron/neutron.conf
/etc/neutron/plugins/ml2/ml2_conf
/etc/neutron/plugins/ml2/openvswitch_agent.ini
/etc/neutron/l3_agent.ini
/etc/neutron/dhcp_agent.ini
点进Return to Networking controller node configuration.
配置 /etc/neutron/metadata_agent.ini
和/etc/nova/nova.conf
将以下注释取消
neutron]
# ...
url = http://controller:9696 auth_url = http://controller:35357 auth_type = password project_domain_name = default user_domain_name = default region_name = RegionOne project_name = service username = neutron password = NEUTRON_PASS service_metadata_proxy = true metadata_proxy_shared_secret = METADATA_SECRET
8) 创建软连接
ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
9)同步数据库
su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf \ --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
10)重启openstck-nova-api服务
systemctl restart openstack-nova-api.service
11)重启neutron相关服务
systemctl enable neutron-server.service neutron-dhcp-agent.service openvswitch neutron-openvswitch-agent neutron-metadata-agent.service
systemctl start neutron-server.service neutron-dhcp-agent.service openvswitch neutron-openvswitch-agent neutron-metadata-agent.service
ovs-vsctl add-br br-ex
ovs-vsctl add-port br-ex ens38(第二个网卡)
systemctl enable neutron-l3-agent.service
systemctl start neutron-l3-agent.service
openstack network agent list
如果都是up状态即为成功。
[root@controller ml2]# openstack network agent list
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+ | ID | Agent Type | Host | Availability Zone | Alive | State | Binary | +--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+ | 4d19afb8-0bd3-48c0-8e13-cd23e4e1af80 | DHCP agent | controller | nova | True | UP | neutron-dhcp-agent | | 70950269-2093-48f9-8413-d0fb7f0fe891 | Open vSwitch agent | controller | None | True | UP | neutron-openvswitch-agent | | 75c928bb-c9a3-4b84-ad7a-6ec00ff2fd68 | L3 agent | controller | nova | True | UP | neutron-l3-agent | | 79e52de1-c161-4746-96a9-c42865f734fe | Metadata agent | controller | None | True | UP | neutron-metadata-agent | | ef9dfc97-c28b-4604-bfed-66821b6824ff | Open vSwitch agent | compute | None | True | UP | neutron-openvswitch-agent | +--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
compute端
点进Install and configure compute node
1)安装所需组建
yum install openvswitch openstack-neutron-openvswitch ebtables ipset
2)编辑配置文件
/etc/neutron/neutron.conf
点进Networking Option 2: Self-service networks
vim /etc/neutron/plugins/ml2/openswitch_agent.ini
将local_ip改为第二个网卡的ip
vim /etc/nova/nova.conf
取消以下注释
[neutron]
# ... url = http://controller:9696 auth_url = http://controller:35357 auth_type = password project_domain_name = default user_domain_name = default region_name = RegionOne project_name = service username = neutron password = NEUTRON_PASS
3) 重启相关服务
systemctl restart openstack-nova-compute.service systemctl enable openvswitch neutron-openvswitch-agent
4)查看安装情况neutron service
host有compute显示并且up状态就算成功。
[root@controller ml2]# openstack network agent list
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+ | ID | Agent Type | Host | Availability Zone | Alive | State | Binary | +--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+ | 4d19afb8-0bd3-48c0-8e13-cd23e4e1af80 | DHCP agent | controller | nova | True | UP | neutron-dhcp-agent | | 70950269-2093-48f9-8413-d0fb7f0fe891 | Open vSwitch agent | controller | None | True | UP | neutron-openvswitch-agent | | 75c928bb-c9a3-4b84-ad7a-6ec00ff2fd68 | L3 agent | controller | nova | True | UP | neutron-l3-agent | | 79e52de1-c161-4746-96a9-c42865f734fe | Metadata agent | controller | None | True | UP | neutron-metadata-agent | | ef9dfc97-c28b-4604-bfed-66821b6824ff | Open vSwitch agent | compute | None | True | UP | neutron-openvswitch-agent | +--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
报错:
很多时候电脑重新启动后,compute节点的neutron服务会down掉或者alive状态栏显示false,这大多因为controller节点的rabbitmq服务无法正常运行,尽管服务状态时启动的。
造成这一报错的主要原因就是防火墙iptables规则。
我们在controller节点上设置如下规则:
iptables -I INPUT -p tcp --dport 5672 -j ACCEPT
给端口号是5672的设置为白名单。