OpenStack Neutron 之 Load Balance
负载均衡(Load Balance)是 OpenStack Neutron 支持的功能之一。负载均衡能够将网络请求分发到多个实际处理请求的虚机上,这样能有效处理高流量的网络请求,负载均衡在现实中有很多使用场景。本文将基于 Neutron 所提供的负载均衡,介绍其基本概念、实现过程,并验证其功能。
Neutron Load Balance 简介
负载均衡(Load Balance)其实早在 OpenStack 的 Grizzly 版本就集成到 Neutron 中。它作为 OpenStack Neutron 项目的高级服务之一,能够均衡的将所收到的网络流量分配给指定的实例们,并且能够确保工作负载以可预见的方式分配到这些实例中,从而达到更高效的使用系统资源的目的。这里的实例,指的是 OpenStack 管理的虚机。 在 Neutron 项目内部,习惯将负载均衡称为 LBaaS(Load Balance as a Service)。自集成到 Neutron 以来,LBaaS 经历过几次大的变化。截止至本文,OpenStack 社区正在进行 Kilo 版本的开发,这个版本中,对 LBaaS 的变化主要有:
- 代码从 Neutron 中抽离,直接由独立的项目管理
- LBaaS V2 的实现
LbaaS V2 是一次较大的改变,它修改了目前的数据结构,为更复杂的用户场景提供了可能,具体的变化可以参考 OpenStack 社区的文档。由于目前社区提供的版本仍然是 LBaaS V1,并且实现 V2 之后将继续对 V1 兼容,因此,本文之后的内容,如无特殊说明都是基于 V1。
Load Balance 基本概念
要了解 Neutron 的负载均衡,首先需要对其内部的数据类型和基本概念有一定的了解。
图 1. LBaaS V1 逻辑架构
图 1 显示了 LBaaS 的逻辑结构,接下来依次介绍其含义。
VIP
VIP(Virturl IP address)就是负载均衡对外提供服务的地址。VIP 有自己的 IP 地址,而且一般都能通过公网进行访问。在 Neutron 中,VIP 对应着二层虚拟设备 br-int 上的一个 port。当负载均衡 Pool 里面至少有一个 member 时,VIP 才有存在的意义,因为这时至少有一个实际的 OpenStack 实例在处理网络请求。VIP 负责将网络流量分发到各个 member,Neutron LBaaS 中支持以下三种网络流量的分发方式。
- Round robin:平均的将网络流量分发到多个 member。
- Source IP:从某一个特定 IP 发来的网络请求,总是发到特定的 member。
- Least connections:将收到的网络请求,发给当前负载均衡池中连接数最少的 member。如果所有的 member 连接数一样,则遵循 Round robin 的方式。
Neutron 中,VIP 还支持设置最大连接数(connection-limit),这样在网络流量大时,可以保护负载均衡池。最大连接数可以设置成-1,这时不限制连接数。
Pool
Pool 是 LBaaS V1 中的 root resource。所有的其他资源都是基于 pool 来创建的。Neutron LBaaS 默认以 HAProxy 为 Driver 实现。在默认情况下,一个 pool 对应着一个独立的 HAProxy 进程,一个独立的 namespace。目前一个 pool 只能有一个 VIP,在 LBaaS V2 里面,可以允许一个 pool 对应多个 VIP。
Member
Member 对应的是 pool 里面处理网络请求的 OpenStack 实例。在 OpenStack Neutron 中,member 是一个逻辑关系,表示着实例与 pool 的对应关系。这也就是说,一个 OpenStack 实例,可以对应不同的 pool,在 Neutron 的 LBaaS 里面创建多个 member。在创建 member 时所选择的实例,必须与 pool 处于同一个 subnet,否则将不能工作。
Health monitor(健康监控)
Health monitor 只有在关联 pool 时才有意义。它用来监测 pool 里面 member 的状态。它会以轮询的方式,去查询各个 member,如果 member 未作出响应,它会更新 member 的状态至 INACTIVE,这样在 VIP 分发网络请求时,就不会考虑这个 member 了。如果 member 恢复了响应,它会更新 member 的状态至 ACTIVE。这时,member 会重新出现在 VIP 的分发列表中。
与其他的概念不同,Health monitor 在 Neutron 的负载均衡中不是必须的。也就是说,没有 Health monitor,也能组成一个负载均衡池。但是,如果没有 Health monitor,pool 会一直认为所有的 member 都是 ACTIVE 状态,这样所有的 member 会一直出现在 VIP 的分发列表中,哪怕 member 对应的实例不能响应网络请求。这在实际应用中会造成负载均衡的响应异常。
Neutron Load Balance 的实现
Neutron LBaaS 是基于 Neutron 实现的,pythone-neutronclient 中包含了 LBaaS 相关的命令,LBaaS 的数据也是存储在 Neutron 的数据库中。LBaaS 的程序架构也遵循着 Neutron 对 service plugin 的要求。具体如图 2 所示。
图 2. LBaaS 代码结构
从图中可以看出,代码主要由三部分组成:
- Extension:负责处理 REST API 请求,并将 REST API 请求转发到 Plugin。
- Plugin:处理核心逻辑,管理 DB 的读写。
- Agent:处理并响应由 Plugin 发来的请求,管理 Driver。前面说过,OpenStack Neutron 默认采用 HAProxy 作为 driver。
功能验证
经过前面的说明,您对 Neutron 的负载均衡应该有了一定的了解。这一部分主要介绍如何配置、使用 Neutron 的负载均衡。
配置
IBM Cloud Manager with OpenStack 默认会配置好 Neutron 的负载均衡。这里再说明一下相关的配置项,这里的配置都是基于 Neutron LBaaS 的默认 driver - HAProxy 来说明的。 首先需要修改 Neutron 的配置,这样 Neutron 在启动的时候就会加载 LBaaS plugin。
清单 1. 修改 Neutron 配置以加载 LBaaS Plugin
# vi /etc/nova/neutron.conf service_plugins=neutron.services.loadbalancer.plugin .LoadBalancerPlugin service_provider=LOADBALANCER:Haproxy:neutron.services .loadbalancer.drivers.HAProxy.plugin_driver .HaproxyOnHostPluginDriver:default
出于排版的需要,清单 1 中的键值对被分成了几行,在实际的配置文件中,每一组键值对必须存在于同一行中。清单 1 中的 service_plugins 必须是在原有的 service_plugins 上追加,即 neutron.conf 里面只能有一个 service_plugins 键,这个键可以对应多个值,以逗号分隔。清单 2 中的 service_provider 可以单独存在,即 neutron.conf 里面可以有多个 service_provider 存在。接下来需要修改 neutron-lbaas-agent 的配置,使得 neutron-lbaas-agent 能正常启动。
清单 2. 修改 neutron-lbaas-agent 配置
# vi /etc/neutron/lbaas_agent.ini device_driver=neutron.services.loadbalancer.drivers .HAProxy.namespace_driver.HaproxyNSDriver interface_driver=neutron.agent.linux.interface .OVSInterfaceDriver
与清单 1 类似,在实际的配置文件中,每一组键值对必须存在于同一行中。清单 2 中的 device_driver 对应的是实际做负载均衡的设备的 driver。清单 2 中的 interface_driver 是指 Neutron 选用的虚拟网卡管理驱动。IBM Cloud Manager with OpenStack 默认采用 OpenVSwitch,因此这里配置成 OVSInterfaceDriver。 最后重启相应的服务即可。
清单 3. 重启服务以使配置生效
# service neutron-server restart # service neutron-lbaas-agent restart
OpenStack Horizon 带有一个 Neutron LBaaS 的管理界面,这个界面默认是不打开的。需要修改 Horizon 的配置并重启 HTTP server 来打开,具体操作如清单 4 所示。
清单 4. 修改 Horizon 配置并重启服务
# vi /etc/openstack-dashboard/local_settings OPENSTACK_NEUTRON_NETWORK = { ‘enable_lb’: True, } # service httpd restart
创建资源
这一部分介绍如何从零开始,在 Neutron 里面建立一个可用的负载均衡池。如前面介绍的,pool 是 Neutron LBaaS 中的 root resource,因此,首先应该创建一个 pool,再创建 pool 里面的 member 和 VIP,最后创建 Health monitor。本文以命令行形式创建资源。如果按照清单 4 中在 OpenStack Horizon 中打开了 LBaaS 的管理界面,也可以通过 OpenStack Horizon 创建负载均衡资源,过程类似,这里就不再赘述。
清单 5. 创建 LBaaS 资源
# neutron lb-pool-create --lb-method ROUND_ROBIN --name mypool --protocol HTTP --subnet-id SUBNET_UUID --provider PROVIDER_NAME # neutron lb-member-create --address 10.0.0.3 --protocol-port 80 mypool # neutron lb-member-create --address 10.0.0.4 --protocol-port 80 mypool # neutron lb-vip-create --name myvip --protocol-port 80 --protocol HTTP –-subnet-id SUBNET_UUID –-address 10.0.0.10 # neutron lb-Healthmonitor-create --delay 3 --type HTTP --max-retries 3 --timeout 3 # neutron lb-Healthmonitor-associate HEALTHMONITOR_UUID mypool
清单 5 中,首先创建了一个 pool,指定的网络流量分发方式是 Round robin,提供服务的协议是 HTTP,这在前面都有说明。--subnet-id 是希望添加的 member 所在的 subnet 的 id,这在前面也有说明。创建 member 时,指定的--address 是实例对应的 IP 地址。在创建 VIP 时,指定的--address 是一个空闲的 IP,这个参数可以不指定,这里为了后面的结果验证写上一个固定的地址。在创建 member 和 VIP 时,都必须指定 pool,它们只能属于一个 pool。而创建 Health monitor 的时候,不用指定 pool,通过一条额外的指令关联 pool。一个 Health monitor 可以关联多个 pool。创建 Health monitor 时,参数的意义分别是:--delay 轮询的间隔;--type 轮询时查询的方式,支持 HTTP、HTTPS、TCP 和 PING;--max-retries 轮询失败的最大尝试次数;--timeout 每次轮询的超时时间。
验证结果
在验证结果之前,需要在加入到负载均衡池中的 OpenStack 实例上面运行 HTTP server,为了区分,本文中实例里的 HTTP server 返回自己的 IP 地址作为响应内容。运行 HTTP server 的方法因系统和环境而不同,但是比较简单,网上也有说明,这里不再赘述。 按照之前创建的资源,负载均衡池现在对外提供的服务地址是 http://10.0.0.10。在这里,写一个测试脚本 test_lb_vip.sh,见清单 6,用来访问 VIP 的服务地址 10 次。
清单 6:测试负载均衡的脚本
#!/bin/bash for k in $( seq 1 10 ) do curl http://10.0.0.10 done 运行测试脚本,最后输出的结果见清单 7。
清单 7. 测试结果
10.0.0.3 10.0.0.4 10.0.0.3 10.0.0.4 10.0.0.3 10.0.0.4 10.0.0.3 10.0.0.4 10.0.0.3 10.0.0.4
从清单 7 的测试结果看,访问 VIP http://10.0.0.10 的 10 次网络流量,被平均的分配到了负载均衡池的两个 member 中,这符合预期。 在实际的使用场景中,一般是希望提供服务的 VIP 地址是公网地址,而实际处理网络流量的 member 是私网地址。基于之前创建的资源,只需按照清单 8 给 VIP 关联上一个 floatingIP 即可实现。
清单 8. 为 VIP 添加公网 IP
# neutron floatingip-create PUBLIC_NETWORK # neutron floatingip-associate FLOATINGIP_ID VIP_PORT
这样在 Neutron 的路由层(三层),建立了一个由 floating IP 对应的公网 IP 和 VIP 对应的私网 IP 组成的对应关系。所有从公网来的网络流量,经过 Neutron 的路由层,都转到了 VIP 对应的私网 IP,从而达到了 VIP 以公网地址的形式提供服务的目的。将清单 6 中的测试脚本改成对应的 floatingIP 地址,重新运行,将得到与清单 7 一样的结果。
总结
负载均衡在实际中,有很广泛的应用场景。OpenStack Neutron 默认以 HAProxy 为负载均衡的 driver,同时也支持 A10 network、netscaler、radware 等作为 driver。IBM Cloud Manager with OpenStack 从 4.2 版本开始支持负载均衡,并以 HAProxy 作为 driver。结合 IBM 高性能的 Power 机器和 OpenStack 便捷的 IaaS(Infrastructure as a Service)管理功能,可以为用户提供更多的应用场景。
来源: http://www.ibm.com/developerworks/cn/cloud/library/1506_xiaohh_openstacklb/