Octavia 简介
Octavia is an open source, operator-scale load balancing solution designed to work with OpenStack.
自 Pike 以来 OpenStack 推荐使用 Octavia 代替 neutron-lbaas extension 作为 Load Balancing as a Service 的首选方案,并在 Queens 中将 neutron-lbaas 标记为废弃 —— Neutron-lbaas is now deprecated。
社区推崇 Octavia 的原因有很多,它解决了 neutron-lbaas 遗留的历史包袱,能够对外提供独立而稳定的 API。简单的说,社区认为 neutron-lbaas 使 Neutron 的项目管理变得拖沓,LBaaS 应该作为一个独立项目得到长足的发展,事实也是如此。
《Octavia 分析与实现》系列基于 Rocky,主要记录、分析了 Octavia 作为 OpenStack LBaaS 的抽象设计,开发性设计及架构代码实现,从中感受社区开发者们对 Octavia 的寄予。
本文作为系列的开篇,希望能够从宏观的角度鸟瞰 Octavia 的全貌,由面及点,更利于后续理解 Octavia 的底层实现细节。
基本对象概念
LBaaS:对于 OpenStack 云平台而言,LB(负载均衡)被作为一种服务提供给用户,用户得以按需地获取可配置的业务负载均衡方案,这就是所谓 Load Balancing as a Service。
LoadBalancer:负载均衡服务的根对象,用户对负载均衡的定义、配置和操作都基于此。
VIP:与 LoadBalancer 关联的虚拟 IP 地址,每个 LoadBalancer 最起码有一个 VIP 作为外部对后端业务集群访问的标准入口。
Listener:下属于 LoadBalancer 的监听器,可配置监听外部对 VIP 的访问类型(e.g. 协议、端口)。
Pool:后端的真实业务云主机集群域,一般的,用户会根据云主机的业务类型进行划分。
Member:业务云主机,下属于 Pool,对应传统负载均衡体系中的 Real Server。
Health Monitor:挂靠于 Pool,周期性对 Pool 中的 Member(s) 进行健康检查。
L7 Policy:七层转发策略,描述了数据包转发的动作(e.g. 转发至 Pool,转发至 URL 或拒绝转发)。
L7 Rule:七层转发规则,下属于 L7 Policy,描述了数据包转发的匹配域(e.g. 转发至 Pool 中所有以 webserver 开头的 Members)。
图1. 动静分离负载均衡应用模型图
上图是一个简易的利用负载均衡实现的 Web 动静页面分离模型,辅助理解上述概念及其个体与整体间的关系。
基本使用流程
下面从使用的角度来感性了解 Octavia,首先介绍 Octavia 的网络结构。
图2. Octavia 网络架构图(注:图源来自孔令贤的博客)
标准的 Octavia 网络架构,包含了:
Amphora(e):实体为云主机,作为负载均衡器的载体,也是 Octavia 默认的 Loadbalancer Provider。
lb-mgmt-net:是一个与 OpenStack Management/API Network 打通的网络,admin project 可见,东侧连接 Amphora Instance、西侧连接 Octavia Services。
tenant-net:业务云主机所在的网络。
vip-net:提供 VIP 地址池的网络。
NOTE:其中 vip-net 和 tenant-net 可以是同一个网络,但在生产环境中,我们建议分开。这样更有利于针对性的施加安全策略,划分不同级别的网络安全隔离域。
图3. 初始的 OpenStack 网络拓扑图
在 Dashboard 创建一个 Loadbalancer 的步骤:
- Step 1. 设定 loadbalancer 的 VIP。支持直接指定 VIP,或由 DHCP 分配。
- Step 2. 设定 listener 监听的协议及端口。监听
http://<VIP>:8080/
的外部访问。
- Step 3. 设定 pool 的负载均衡算法。这里选择 RR 轮询分发算法。
- Step 4. 设定 pool 下属的 members。设定 members 需要指定端口和权重,前者组成了接受数据转发的 socket,后者表示分发的优先级。
- Step 5. 设定 health monitor 的健康检查规则。如果 members 出现 PING 不同的情况,则会被标记为故障,不再接受分发。
创建完 lb-1 之后的网络拓扑变更如下图。可以看出,Amphorae 在之中起到了关键作用,使用端口挂载的方式将属于 3 个不同网络中的 VIP、Members 及 Octava Services 串连起来,Amphorae(双耳壶)也因此得名。
图4. 创建 LoadBalancer 之后的 OpenStack 网络架构图
现在,我们不妨粗浅的梳理一下 Octavia Amphora Provider 的设计思路:
- Amphorae 作为负载均衡器软件(HAProxy)和高可用支撑(Keepalived)的运行载体,通过 Agent 与 Octavia Services 通信。
- Octavia Services 接收到用户 Create LoadBalancer 和 VIP 的选项参数后,通知 Agent 动态变更 haproxy、keepalived 的配置文件。
- 将 Members 所处的 Subnet 接入 Amphorae,内含的 haproxy 通过 Member Socket(IP, Port) 分发请求数据包。
图5. 简易的 Octavia 通讯模型
这里再补充一下与 Octavia 相关的 image 和 security group 的内容。Launch Amphora Instance 需要使用特定的镜像,Octavia 提供了专门的镜像制作工具。暂支持 CentOS 和 Ubuntu 两种操作系统,也支持设定 password,不过在生产环境中还是建议使用 keypair 进行登录。至于安全组,从图 5 可以看出 Amphora 的安全组最起码要满足 ingress:UDP/5555 和 egress:TCP/9443 两条规则。
使用 amphora image 的步骤:
- Step 1. 上传 amphora image
$ /opt/rocky/octavia/diskimage-create/diskimage-create.sh -i ubuntu
$ openstack image create amphora-x64-haproxy \
--public \
--container-format=bare \
--disk-format qcow2 \
--file /opt/rocky/octavia/diskimage-create/amphora-x64-haproxy.qcow2 \
--tag amphora
Step 2. 配置使用 amphora image
[controller_worker]
amp_image_owner_id = <amphora-image id>
amp_image_tag = amphora
...
使用 amphora security group 的步骤:
- Step 1. 创建 amphora 使用的安全组
$ openstack security group create amphora-sec-grp --project <admin project id>
$ openstack security group rule create --remote-ip "0.0.0.0/0" --dst-port 9443 --protocol tcp --ingress --ethertype IPv4 --project <admin project id> amphora-sec-grp
$ openstack security group rule create --remote-ip "0.0.0.0/0" --dst-port 5555 --protocol udp --egress --ethertype IPv4 --project <admin project id> amphora-sec-grp
- Step 2. 配置使用 amphora security group
[controller_worker]
amp_secgroup_list = <amphora-sec-grp id>
...
软件架构
图6. Octavia 架构图(注:图源自 Octavia 官方文档)
Octavia 的架构设计依旧是常规的「生产者-消费者」异步通讯模型,API 与 Worker 分离再通过 MessageQueens 进行通信。
- Octavia API:标准 RESTful API,Octavia v2 API(default enabled)是 LBaaS v2 API 的超集,完全向后兼容。所以版本滞后的 OpenStack 平台也可通过 Neutron Octavia Driver 进行集成。
- Octavia Controller Worker:Octavia 的核心,底层采用 Driver & Plugin 的设计来满足 OpenStack 平台所代表的开放性,支撑上层的 3 大功能模块。
- Octavia Worker:负责完成 API 请求,是 Octavia 主干功能的执行者。
- Health Manager:负责保证 LoadBalancer Provider 的高可用
- Housekeeping Manager:名副其实的 Housekeeping(家政),保障 Octavia Services 清洁的运行环境。实现了 SpaceAmphora、DatabaseCleanup 和 CertRotation。
NOTE:需要特别说明的是,架构图中虽然只给出了 Amphora 一种 LB Provider,但 Drivers & Plugin 设计实际上是支持多种 LB Provider 的(e.g. F5)。社区一直有计划将这些已实现的 Drivers 从 openstack/neutron-lbaas repo 迁移到 openstack/octavia repo,只是一直很缺人手。
服务进程清单
Octavia Service Menu 是软件架构的具象表现:
- octavia-api
- octaiva-worker
- octavia-health-manager
- octavia-housekeeping
代码结构
下面列举一些关键的目录:
- amphora:Amphora REST API 和 amphora-agent 的实现
- api:Octavia API 的实现
- certificates:CA 认证的实现,支持 Amphora 与 Octavia Controller Worker 间的安全通信以及 TLS 功能
- compute:实现了 Compute Driver 的抽象和 novaclient 的封装
- network:实现了 Network Driver 的抽象和 neutronclient 的封装
- db:ORM 层的封装实现
- policies:定义了 API 请求的鉴权策略
继续展开 controller 目录:
- healthmanager:Health Manager 的实现
- housekeeping Manager:HouseKeeping Manager 的实现
- queue:内部 RPC 通信实现,应用了 cotyledon 框架和 oslo_messaging 库
api/handlers/queue/producer.py
controller/queue/consumer.py
- worker:Octavia Worker 的实现,应用了 TaskFlow 框架
- flows:任务流的封装,每个功能单元都会被定义为一个 Flow
- tasks:任务的封装,使得任务的逻辑实现得以高度重用
PS:cotyledon 是由社区开发用于替代 oslo.service 的第三方开源库。
Cotyledon provides a framework for defining long-running services. It provides handling of Unix signals, spawning of workers, supervision of children
processes, daemon reloading, sd-notify, rate limiting for worker spawning, and more.
—— 摘自 cotyledon 官方文档
最后简单终结一下 Octavia 的架构设计,作为独立项目,其继承了 OpenStack 一贯优秀的开放性,在 LB Provider、Certificates Driver、Compute Driver 和 Network Driver 这些外部支撑节点都高度抽象出了 Driver 类,使 Vendors 和 Users 得以简便接入现有的基础设施。这无疑是 Octavia 甚至 OpenStack 受到欢迎的原因之一。
下一篇《Octavia Rocky 的实现与分析系列二:创建 LoadBalancer 的流程》即将更新,敬请期待!