openstack neutron网络插件学习(二)【linux-bridge实现】
2.5.5 DHCP服务Neutron 提供 DHCP 服务的组件是 DHCP agent。DHCP agent 在网络节点运行上,默认通过 dnsmasq 实现 DHCP 功能。DHCP agent 的配置文件位于 /etc/neutron/dhcp_agent.ini。(正常来说一般不需要什么特殊配置)dhcp_driver:使用 dnsmasq 实现 DHCP。interface_drive
目录
至此linux-bridge部分实现neutron网络暂告一段落,后续具体细节部分再针对性的讲解!
2.5.5 DHCP服务
Neutron 提供 DHCP 服务的组件是 DHCP agent。DHCP agent 在网络节点运行上,默认通过 dnsmasq 实现 DHCP 功能。
DHCP agent 的配置文件位于 /etc/neutron/dhcp_agent.ini。(正常来说一般不需要什么特殊配置)
- dhcp_driver:使用 dnsmasq 实现 DHCP。
- interface_driver:使用 linux bridge 连接 DHCP namespace interface。
dnsmasq 是一个提供 DHCP 和 DNS 服务的开源软件。一般一个dnsmasp进程对应一个network,可以为该network内开启了dhcp服务的所有subnet提供服务。DHCP agent 会为每个 network 创建一个目录 /opt/stack/data/neutron/dhcp/,用于存放该 network 的 dnsmasq 配置文件。
dnsmasq 重要的启动参数:(1)--dhcp-hostsfile:存放 DHCP host 信息的文件,dnsmasq 从该文件获取 host 的 IP 与 MAC 的对应关系。 /opt/stack/data/neutron/dhcp/xxx(对应某个netwrok)/host下记录着DHCP、所有VM的Interface信息;(2)--interface:指定提供 DHCP 服务的 interface。dnsmasq 会在该 interface 上监听 instance 的 DHCP 请求;
2.5.6 Linux Network NameSpace
每个 namespace 都有自己独立的网络栈,包括 route table,firewall rule,network interface device 等。Neutron 通过 namespace 为每个 network 提供独立的 DHCP 和路由服务,从而允许租户创建重叠的网络。如果没有 namespace,网络就不能重叠,这样就失去了很多灵活性。
每个 dnsmasq 进程都位于独立的 namespace, 命名为 qdhcp-<network id>(每个dnsmasq进程又对应一个network)。ip netns list 命令可以列出所有的namespace。主机本身也有一个 namespace,叫 root namespace,拥有所有物理和虚拟 interface device。物理 interface 只能位于 root namespace。
veth pair:解决了dhcp的interface(tap设备)无法直接与 root namespace 中的 bridge 设备连接。dhcp的ns设备与tap设备被称为一对veth pair,用来将dhcp的namespace连接到root namespace 中的 bridge 设备,可以通过 ip netns exec <network namespace name> <command>管理 namespace。连接关系如下图所示:
一台VM实例创建并启动dhcp获取到ip的过程如下:
- 在dashboard上创建VM时,neutron会给VM分配一个port,该port包含ip/mac信息,这些信息会自动同步到dnsmasq的host文件,同时compute节点会给创建的VM分配该port对应的mac地址;
- VM开机启动,发出 DHCP DISCOVER 广播,该广播消息在整个对应的network中(subnet的tap设备)都可以被收到;
- dhcp广播报文到达DHCP的tap设备,然后传送给veth pair另一端ns设备。dnsmasq在ns设备上面进行侦听,dnsmasq收到其dhcp discover于是对比自己的host文件发现有对应项(应该是通过mac对比),从而将对应的ip地址、掩码、地址租期信息返回给VM;
- VM发送 DHCPREQUEST 消息确认接受此 DHCPOFFER;
- dnsmasq 发送确认消息 DHCPACK,整个过程结束;
2.5.7 VLAN网络
vlan网络是待tag的网络类型,在实际应用中有较多使用。由于vlan数量有限制(4096),因此不能无限创建vlan。VM通过tap设备连接到对应的网桥上,网桥另一端连接网卡的子接口,数据流量到网卡子接口会被打上vlan tag并传送给网卡主接口,从而实现宿主机上vlan的网络隔离。(一个宿主机网卡可以有多个网卡子接口)
执行vi /etc/neutron/plugins/ml2/ml2_conf.ini配置文件,在ML2中将网络类型修改为vlan,定义标签default,指定普通用户创建网络的vlan范围(admin用户可以使用任意自己指定的vlan),并将标签与物理网卡对应起来。修改如下:(配置完成后重启neutron服务生效)
[ml2]
type_drivers = vlan
tenant_network_types = vlan
......
[ml2_type_vlan]
network_vlan_ranges = default:1:4094
例如:创建2个vlan网络,同一个vlan内的vm可以相互通信,不同vlan内的vm是不能互相通信,若要使跨vlan通信就必须进行三层互通,这就涉及到Routing功能。对于相同网络vlan网络其在控制节点和计算节点的网桥名称都是一样的,可以从下图看出:
2.5.8 Routing
Neutron 的路由服务是由 l3 agent 提供的。 除此之外,l3_agent 通过 iptables 提供 firewall 和 floating ip 服务。
配置文件为 /etc/neutron/l3_agent.ini,如果 mechanism driver 是 linux bridge,则需要将interface_driver改为BridgeInterfaceDriver;若mechanism driver是OVS,则需要将interface_driver改为OVSInterfaceDriver。l3_agent运行在控制节点或者网络节点上。
当创建完成一个vrouter后,底层网桥会给vrouter的接口分配一个tap设备,TAP设备上不配置ip地址,l3 agent 会为每个 router 创建了一个 namespace(router 对应的 namespace 命名为 qrouter-<router id>。),通过 veth pair 与 TAP 相连,然后将 Gateway IP 配置在位于 namespace 里面的 veth interface 上,从而实现三层网络通信。网络架构如下图所示。
- 可以通过ip netns 查看 namespace;
- ip netns exec <namespace name> ip a查看namespace的veth interface地址配置;
讲到这里,需要思考一个问题?为什么vrouter不直接在tap设备上配置网关地址,而是要在namespace的veth接口上配置?-----答案是:在vrouter多做一层namespace可以起到各个租户之间的网络重叠的作用(每个namespace单独一张路由表),而直接在tap设备上配置IP相当于在root的namespace上添加subnet网段的路由(宿主机操作系统上加路由,查的是宿主机的全局路由表),这样的路由时没办法工作的。这个功能在某些特定场合下很重要。
既然已经通过vrouter实现了跨vlan网络的vm通信,那么如果实现vlan网络与外部网络通信呢?这里的外部网络是指的租户网络以外的网络。租户网络是由 Neutron 创建和维护的网络。外部网络不由 Neutron 创建,是已经存在的物理网络,一般都是flat型或者vlan型。
/etc/neutron/plugins/ml2/ml2_conf.ini 配置如下:
若是flat类型网络,需要如下配置:
若是vlan类型网络,则进行如下配置:
在dashboard页面上创建完外部网络并关联vrouter后,会对应创建外部网络的网桥和tap设备,同时也会在vrouter对应的namespace中创建对应于tap设备的veth设备。vrouter 的每个 interface 在 namespace 中都有对应的 veth。如果 veth 用于连接租户网络,命名格式为 qr-xxx,比如 qr-d568ba1a-74 和 qr-e17162c5-00。如果 veth 用于连接外部网络,命名格式为 qg-xxx,比如 qg-b8b32a88-03。整体网络架构如下:
当数据包从 router 连接外网的接口 qg-xxx发出的时候,会做一次 Source NAT,即将包的源地址修改为 router 的外网接口地址,这样就能够保证目的端能够将应答的包发回给 router,然后再转发回源端 instance。可以通过iptables命令查看SNAT的相关规则:
ip netns exec 对应router的namespace iptables -t nat -S
SNAT主要是作为内部VM访问外部网络使用,单外部网络无法直接访问内部VM,此时就需要浮动ip来进行DNAT的转换。
浮动ip必须要知道的几件事:
- floating IP 提供静态 NAT 功能,建立外网 IP 与 instance 租户网络 IP 的一对一映射;
- floating IP 是配置在 router 提供网关的外网 interface 上的,而非 instance 中;
- router 会根据通信的方向修改数据包的源或者目的地址(这句话意思是对于内访外,则修改数据包源地址为float ip;对于外访内,则修改数据包的目的ip为真实VM的ip);
2.5.9 VXLAN网络
前期讲了flat 网络、vlan网络、local网络,还剩下VXLAN网络和GRE网络,这两种都是Overlay网络。overlay network 是指建立在其他网络上的网络。overlay network 中的节点可以看作通过虚拟(或逻辑)链路连接起来的,不需要关心底层的物理链路。vxlan网络相对于vlan有很强的灵活性和扩展性,主要提现在以下几个方面:
- 支持更多的二层网段。vlan的使用12 bit标记vlan ID,最多支持4094个VLAN;Vxlan则用24bit标记vlan ID,最多能支持到 16777216二层网段;
- 能更好的利用现有网络途径。vlan网络通过STP进行防环,一半路径被block;VXLAN则直接用MAC in UDP进行封装,利用三层网络进行转发;
- 避免物理交换机 MAC 表耗尽。由于采用隧道机制,TOR (Top on Rack) 交换机无需在 MAC 表中记录虚拟机的信息。(现在交换机的MAC规格都很大,不是啥问题)
vxlan报文封装格式如下:
VXLAN Tunnel Endpoint(VTEP)
VXLAN 使用 VXLAN tunnel endpoint (VTEP) 设备处理 VXLAN 的封装和解封。每个 VTEP 有一个 IP interface,配置了一个 IP 地址。VTEP 使用该 IP 封装 Layer 2 frame,并通过该 IP interface 传输和接收封装后的 VXLAN 数据包。VTEP既可以是软件设备(OpenvSwitch)也可以是硬件交换机,VTEP之间建立VXLAN隧道。VXLAN 独立于底层的网络拓扑;反过来,两个 VTEP 之间的底层 IP 网络也独立于 VXLAN。可以用一张图描述数据包在vxlan网络中的传输过程(具体细节就不再阐述,很简单,可以在单独去研究一下vxlan网络架构):
目前比较成熟的 VTEP 软件实现包括:1. 带 VXLAN 内核模块的 Linux;2. Open vSwitch。第一种方式如下,第二种方式待后续讲解openvSwitch时详细说明。
- 1. Linux vxlan 创建一个 UDP Socket,默认在 8472 端口监听。
- 2. Linux vxlan 在 UDP socket 上接收到 vxlan 包后,解包,然后根据其中的 vxlan ID 将它转给某个 vxlan interface,然后再通过它所连接的 linux bridge 转给虚机。
- 3. Linux vxlan 在收到虚机发来的数据包后,将其封装为多播 UDP 包(同一个vxlan的都会收到),从网卡发出
vxlan网络的配置
需要在 /etc/neutron/plugins/ml2/ml2_conf.ini 设置 vxlan network 相关参数:
[ml2]
type_drivers = vlan,vxlan
tenant_network_types = vxlan
mechanism_drivers = linuxbridge,l2population
extension_drivers = port_security
[ml2_type_vxlan]
vni_ranges = 1:10000
还需要在ml2_conf.ini中设置vtep:
控制节点/网络节点:
计算节点上同样设置,local_ip即为VTEP的ip地址。注意:作为准备工作,这两个 VTEP IP 需要提前配置到节点的 eth1 上,Neutron 并不会帮我们分配这个 IP。并且,值得注意的是,vxlan网络配置中不会特意配置vxlan标签与网卡的对应关系,它是通过VTEP IP来找到要从哪块网卡出去的。
此时通过 brctl show可以知道底层网络的架构,相比于vlan网络而言,没有eth1.100这种子接口的概念,而是直接用vxlan interface来表示(linuxbridge、vxlan-100、eth1网卡可以对应起来,还会针对这个子网创建了一个DHCP的tap设备,也是连接该linuxbridge),可以ip -d link show dev vxlan-100(创建的vxlan网络名)查看vxlan interface的详细配置。架构如下图:
同一个vxlan内,同一个节点上,VM之前通过linuxbridge就可以直接通信,若是跨节点间,则是通过宿主机间vxlan隧道到达另一主机。
以上vxlan网络只是针对同一个二层网络内进行通信,对于跨vxlan以及vxlan网络到外部网络的通信也是需要依靠vrouter与浮动ip来实现,原理和vlan网络是类似的,此处不再继续阐述。
2.5.10 L2 Population
vxlan组网得环境就是一个大二层网络,如果避免在这种大二层网络中的广播报文占用带宽,就需要L2 Population来解决这个问题。L2 Population 是用来提高 VXLAN 网络 Scalability (可以理解为高效运转)。
如下图,VM A要想去访问其他HOST上的同vxlan的节点时会发送arp广播报文,这样整个网络环境里会存在大量的arp广播报文,从而占用网络带宽。此时L2 Population的出现解决了这个问题。
L2 Population可以让HOST开启一个ARP Proxcy的功能,本地的arp广播报文则由本地HOST主机直接响应其arp请求,并使得VTEP能够预先获知 VXLAN 网络的相关信息:(1)VM的IP/MAC信息;(2)VM--VTEP的对应关系。如下图:
那么此时另一个问题又来了,VTEP 是如何提前获知 IP -- MAC -- VTEP 相关信息的呢?答案如下:
- Neutron 知道每一个 port 的状态和信息; port 保存了 IP,MAC 相关数据。
- instance 启动时,其 port 状态变化过程为:down -> build -> active。
- 每当 port 状态发生变化时,Neutron 都会通过 RPC 消息通知各节点上的 Neutron agent,使得 VTEP 能够更新 VM 和 port 的相关信息。
从而每个VTEP都知道了其他(VTEP)HOST上都有哪些VM,这样就大大减少了网络中arp广播报文的带宽占用。
L2 Population的配置参见vxlan中的相关部分。需要在 /etc/neutron/plugins/ml2/ml2_conf.ini 设置 mechanism_drivers = linuxbridge,l2population,l2_population = Ture;
可以通过bridge fdb show dev vxlan-100(vxlan名称)查看节点上的 forwarding database(保存的其他VTEP的地址以及其他VM的MAC);
2.5.11 Security Group
Neutron 为 instance 提供了两种管理网络安全的方法:安全组(Security Group)和虚拟防火墙。安全组的原理是通过 iptables 对 instance 所在计算节点的网络流量进行过滤。虚拟防火墙则由 Neutron Firewall as a Service(FWaaS)高级服务提供。其底层也是使用 iptables,在 Neutron Router 上对网络包进行过滤。
“default” 安全组有四条规则,其作用是:允许所有外出(Egress)的流量,但禁止所有进入(Ingress)的流量。创建VM时如果没有选择其他安全组,则默认强制使用default安全组。安全组功能可理解就是白名单的服务。具体可以在节点上iptables-save 命令查看相关规则,iptables 的规则是应用在 Neutron port 上的,也就是VM的虚拟网卡TAP设备上。
总结下来,安全组特性如下:
- 通过宿主机上 iptables 规则控制进出 instance 的流量。
- 安全组作用在 instance 的 port 上。
- 安全组的规则都是 allow,不能定义 deny 的规则。
- instance 可应用多个安全组叠加使用这些安全组中的规则。
2.5.12 Neutron FWaaS
Firewall as a Service(FWaaS)是 Neutron 的一个高级服务。用户可以用它来创建和管理防火墙,在 subnet 边界上对 layer 3 和 layer 4 的流量进行过滤。FWaaS 有三个重要概念:Firewall、Policy 和 Rule。
- Firewall:租户能够创建和管理的逻辑防火墙资源。Firewall 必须关联某个 Policy,因此必须先创建 Policy。
- Firewall Policy:Policy 是 Rule 的集合,Firewall 会按顺序应用 Policy 中的每一条 Rule。
- Firewall Rule:Rule 是访问控制规则,由源与目的子网 IP、源与目的端口、协议、allow 或 deny 动作组成。
防火墙与安全组的区别。可以理解为防火墙的最小作用单元是subnet级别的防护,而安全组则是针对instance的防护。 /etc/neutron/fwaas_driver.ini 文件中设置 FWaaS 使用的 driver:(新版防火墙没有这个driver配置)
还需要在 /etc/neutron/neutron.conf 中启用 FWaaS plugin:
具体可以通过 ip netns <namespace名称> iptables-save查看对应router的防火墙规则状态。最后,FWaaS 用于加强 Neutron 网络的安全性,与安全组可以配合使用,防火墙与安全组的异同点总结如下:
相同点:
- 1. 底层都是通过 iptables 实现。
不同点:
- 1. FWaaS 的 iptables 规则应用在 router 上,保护整个租户网络;安全组则应用在虚拟网卡上,保护单个 instance。
- 2. FWaaS 可以定义 allow 或者 deny 规则;安全组只能定义 allow 规则。
2.5.13 Neutorn LBaaS
LBaaS 有三个主要的概念: Pool Member,Pool 和 Virtual IP。
- Pool Member:Pool Member 是 layer 4 的实体,拥有 IP 地址并通过监听端口对外提供服务。
- Pool:Pool 由一组 Pool Member 组成。
- Virtual IP:Virtual IP 也称作 VIP,是定义在 load balancer 上的 IP 地址
OpenStack Neutron 目前默认通过 HAProxy 软件来实现 LBaaS。 HAProxy 是一个流行的开源 load balancer。 Neutron 也支持其他一些第三方 load balancer。实现方式如下图所示:
配置LB:(最新版本的配置可能与下面有差异,按官网最新版本安装步骤来)
/etc/neutron/services/loadbalancer/haproxy/lbaas_agent.ini。定义 interface_driver:
interface_driver 的作用是设置 load balancer 的网络接口驱动,可以有两个选项:
Linux Bridge
interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver
Open vSwitch
interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver
/etc/neutron/neutron.conf 中设置启用 LBaaS plugin:
在 /etc/neutron/neutron_lbaas.conf 中设置 service provider:
除了默认的 HAProxy,Neutron 也支持第三方 provider,比如 radware,VMWareEdge 等等。
LB的几种负载分担算法:
- ROUND_ROUBIN:如果采用 round robin 算法,load balancer 按固定的顺序从 pool 中选择 member 相应 client 的连接请求。这种方法的不足是缺乏机制检查 member 是否负载过重。有可能出现某些 member 由于处理能力弱而不得不继续处理新连接的情况。
- LEAST_CONNECTIONS:如果采用 least connections 算法,load balancer 会挑选当前连接数最少的 pool member。这是一种动态的算法,需要实时监控每个 member 的连接数量和状态。
- SOURCE_IP:如果采用 source IP 算法,具有相同 sourSession Persistencece IP 的连接会被分发到同一个 pool member。source IP 算法对于像购物车这种需要保存状态的应用特别有用;
Session Persistence(会话保持):
- SOURCE_IP:这种方式与前面 load balance 的 SOURCE_IP 效果一样。初始连接建立后,后续来自相同 source IP 的 client 请求会发送给同一个 member;
- HTTP_COOKIE:当 client 第一次连接到 VIP 时,HAProxy 从 pool 中挑选出一个 member。当此 member 响应请求时,HAProxy 会在应答报文中注入命名为 “SRV” 的 cookie,这个 cookie 包含了该 member 的唯一标识。client 的后续请求都会包含这个 “SRV” cookie。HAProxy 会分析 cookie 的内容,并将请求转发给同一个 member。HTTP_COOKIE 优于 SOURCE_IP,因为它不依赖 client 的 IP。
- APP_COOKIE:app cookie 依赖于服务器端应用定义的 cookie。比如 app 可以通过在 session 中创建 cookie 来区分不同的 client。HAProxy 会查看报文中的 app cookie,确保将包含 app cookie 的请求发送到同一个 member。
Key Pairs
对于一些登陆密码随机的image,可以使用key pairs的功能来进行免密登陆。 通过ssh-keygen -t rsa -f xx.key生成 Key Pair,会生成两个文件一个是xx.key。另一个是xx.key.pub。其中 cloud.key.pub 是公钥,需要添加到 instance 的 ~/.ssh/authorized_keys 文件中。 cloud.key 是私钥,用于访问 instance。将公钥cloud.key.pub的内容复制到openstack导入界面中即可,完成导入。然后就可以通过ssh -i指定私钥进行登陆VM了。
健康检查
需要注意,在LB中配置健康检查的目的是周期性探测WEB Server的活动状态,防止server挂了业务流还持续往故障机器发送;
Neutron中LB的底层实现原理
对于每创建一个pool地址池,Neutron 都会创建新的 namespace qlbaas-xxx,该 namespace 对应我们创建的 pool “web servers”。其命名格式为 qlbaas-< pool ID>。对于每一个 pool,Neutron 都会启动一个 haproxy 进程提供 load balancering 功能。也就是说:一个pool地址池-----namespace-----一个haprocxy进程。haproxy 配置文件保存在 /opt/stack/data/neutron/lbaas/< pool ID>/conf 中。
总结一下:(1)LBaaS 为租户提供了横向扩展应用的能力,租户之间是隔离的。(2)租户可以将外部请求 balancing 到多个 instance 上,并通过 monitor 实现应用的高可用。
至此linux-bridge部分实现neutron网络暂告一段落,后续具体细节部分再针对性的讲解!
更多推荐
所有评论(0)