1. 多区域部署到底在解决什么问题
第一次接触多区域这个概念,是在一个跨机房容灾的项目里。当时业务侧提的需求很直接:单机房挂掉之后,核心业务要在可接受的时间内恢复,而且日常状态下两个机房的资源都要能用起来,不能白白闲置。单区域部署的 OpenStack 集群做不到这一点,因为控制平面是单点的,数据库、消息队列、API 服务全在一个逻辑区域内,一旦这个区域出问题,整个云平台就瘫了。
多区域部署的核心思路,是把控制平面拆成两层:一层是全局层,负责跨区域共享的资源,比如 Keystone 认证、Glance 镜像、部分公共数据库;另一层是区域层,每个区域有自己的 Nova、Neutron、Cinder、Placement 等计算和存储服务。这样设计的好处是,区域之间相对独立,一个区域的故障不会直接拖垮另一个区域,同时用户又只需要一套认证凭据就能访问所有区域的资源。
用 kolla-ansible 来做这件事,是因为它本身就把 OpenStack 各个组件容器化了,部署和升级的粒度很清晰。多区域场景下,kolla-ansible 提供了--limit和 inventory 分组的能力,可以针对不同区域分别执行部署命令,不需要手工去改一堆配置文件。这一点在实际运维中非常关键,因为多区域环境最怕的就是配置漂移,手工改的东西越多,后面排查问题越痛苦。
适合读这篇内容的人,我大致分三类:第一类是有单区域 kolla-ansible 部署经验,现在要扩展到多区域的运维;第二类是在做私有云规划,需要评估多区域方案可行性的架构人员;第三类是已经上了多区域但遇到各种诡异问题,想找排查思路的同行。如果你连单区域都没部署过,建议先把单区域的流程跑通,再来看多区域,否则很多概念会混淆。
2. 整体架构设计与关键选型考量
2.1 全局层与区域层的职责划分
多区域架构里,最容易踩坑的地方就是职责划分不清。我见过有人把 Keystone 在每个区域都部署一套,结果用户账号同步成了大问题。正确的做法是,Keystone 只在全局层部署一套,所有区域共用。Glance 也是类似,镜像只需要在全局层存一份,各区域通过配置指向全局 Glance 的 endpoint 即可。但 Nova、Neutron、Cinder 这些必须每个区域独立部署,因为它们直接管理本区域的物理资源。
数据库层面,全局层需要一套独立的 MariaDB 或 MySQL,存放 Keystone、Glance 以及各区域的 service catalog 信息。每个区域自己也需要一套数据库,存放本区域的 Nova、Neutron、Cinder 数据。消息队列同理,全局层一套 RabbitMQ,区域层各自一套。这里有个细节,区域层的 Nova 需要和全局层的 Keystone 通信做认证,所以网络连通性必须提前规划好,不能等到部署的时候才发现防火墙没放行。
2.2 为什么选择 kolla-ansible 而不是手工部署
手工部署多区域 OpenStack 不是不行,但工作量会随着区域数量线性增长。每加一个区域,就要重复一遍配置、安装、调试的流程,而且很容易出现某个区域的配置和别的区域不一致。kolla-ansible 的优势在于,它把配置模板化了,inventory 文件里通过分组来区分不同区域,执行的时候用--limit指定目标区域,就能保证每个区域的部署流程完全一致。
另一个考虑是升级。多区域环境下,升级必须一个区域一个区域地滚动进行,不能同时全升。kolla-ansible 支持按分组执行kolla-ansible upgrade,配合--limit可以精确控制升级范围。手工部署的话,你得自己写脚本去控制这个顺序,还要处理升级过程中的依赖关系,复杂度高很多。
2.3 网络规划的前置条件
多区域部署对网络的要求比单区域高得多。首先,全局层和区域层之间需要一条稳定的管理网络,延迟不能太高,否则 Keystone 认证会超时。其次,区域之间的租户网络是否要打通,取决于业务需求。如果业务需要跨区域的虚拟机互相通信,那就需要做 VXLAN 或 VLAN 的跨区域打通,这个在 Neutron 层面配置起来比较麻烦,建议在规划阶段就明确。
我个人的经验是,管理网络和业务网络一定要分开。管理网络走独立的物理链路或者 VLAN,专门用于 OpenStack 组件之间的通信。业务网络走另一套,给虚拟机用。混在一起的话,一旦业务流量跑满,管理网络也会受影响,导致 API 响应变慢甚至超时。
3. 部署前的环境准备与 inventory 设计
3.1 基础环境检查清单
在动手之前,先把下面这些检查项过一遍,能省掉后面很多返工的时间。
| 检查项 | 要求 | 备注 |
|---|---|---|
| 操作系统 | CentOS 7.9 或 Ubuntu 20.04/22.04 | 所有节点版本必须一致 |
| Docker | 版本不低于 20.10 | kolla-ansible 对 Docker 版本有要求 |
| Python | 3.8 及以上 | 控制节点需要 |
| 时间同步 | 所有节点 NTP 对齐 | 偏差超过 1 秒会导致认证失败 |
| 主机名解析 | /etc/hosts 或 DNS 可解析 | 所有节点互相能解析 |
| 防火墙 | 按需放行端口 | 管理网络建议先全通,后期再收紧 |
| 磁盘 | 系统盘和数据盘分离 | 数据盘做 LVM 或直接挂载 |
时间同步这一项特别容易被忽略。我有一次部署完,Keystone 认证一直报 token 无效,查了半天才发现是某个区域的计算节点时间慢了 3 秒。OpenStack 对时间敏感度很高,NTP 一定要配好,并且定期检查。
3.2 inventory 文件的分组设计
kolla-ansible 的 inventory 文件是多区域部署的核心。下面是一个简化后的结构示例,实际使用时要根据你的节点数量和角色分配来调整。
[control:children] global-control region1-control region2-control [global-control] global-node1 ansible_host=10.0.0.1 [region1-control] region1-node1 ansible_host=10.0.1.1 [region2-control] region2-node1 ansible_host=10.0.2.1 [network:children] region1-network region2-network [region1-network] region1-node1 [region2-network] region2-node1 [compute:children] region1-compute region2-compute [region1-compute] region1-compute1 ansible_host=10.0.1.11 [region2-compute] region2-compute1 ansible_host=10.0.2.11 [monitoring:children] global-control [storage:children] region1-storage region2-storage这个结构的关键点在于,全局层和区域层用不同的分组名区分开。执行部署命令时,通过--limit指定分组,就能精确控制操作范围。比如部署全局层用--limit global-control,部署区域一用--limit region1-control:region1-network:region1-compute。
3.3 全局配置文件的分区域覆盖
kolla-ansible 的配置文件放在/etc/kolla/globals.yml和/etc/kolla/下的各个组件配置目录里。多区域场景下,不同区域可能需要不同的配置,比如区域一的 Neutron 用的隧道网段和区域二不一样。这时候可以用globals.yml里的条件判断,或者更简单的做法是,为每个区域准备一份独立的配置目录,部署时通过--configdir指定。
我一般会这样组织目录结构:
/etc/kolla/ ├── global/ │ ├── globals.yml │ └── passwords.yml ├── region1/ │ ├── globals.yml │ └── passwords.yml └── region2/ ├── globals.yml └── passwords.yml全局层的配置放在global/下,区域层的配置各自独立。部署全局层时用--configdir /etc/kolla/global,部署区域一时用--configdir /etc/kolla/region1。这样配置隔离得很干净,不会互相干扰。
4. 全局层部署实操与关键参数
4.1 全局层需要部署哪些服务
全局层不是把所有服务都装一遍,而是只装跨区域共享的那些。具体来说,Keystone、Glance、MariaDB、RabbitMQ、Memcached 是必须的。Horizon 可以放在全局层,也可以每个区域各放一个,看你的访问需求。如果希望用户从一个入口访问所有区域,Horizon 放全局层更合适。
在globals.yml里,需要明确指定哪些服务启用、哪些禁用。下面是一个全局层的配置片段:
kolla_base_distro: "centos" kolla_install_type: "source" openstack_release: "zed" network_interface: "eth0" api_interface: "eth0" neutron_external_interface: "eth1" enable_keystone: "yes" enable_glance: "yes" enable_horizon: "yes" enable_nova: "no" enable_neutron: "no" enable_cinder: "no" enable_placement: "no"注意enable_nova、enable_neutron这些在全局层要设为no,因为它们是区域层的服务。如果误开了,部署会报错,因为全局层没有对应的计算节点。
4.2 数据库和消息队列的初始化
全局层的 MariaDB 和 RabbitMQ 需要先初始化,再部署其他服务。kolla-ansible 提供了kolla-ansible -i inventory bootstrap-servers来做基础环境准备,然后kolla-ansible -i inventory deploy --limit global-control来部署全局层服务。
部署完成后,需要手动创建 Keystone 的数据库和用户,以及 Glance 的数据库和用户。这些操作在 kolla-ansible 的 post-deploy 阶段会自动完成,但如果你要自定义一些参数,比如数据库字符集,就需要在部署前修改配置文件。
注意:全局层的数据库不要和区域层共用。我见过有人为了省资源,把区域层的数据库也放在全局层节点上,结果区域一的计算节点访问数据库要跨机房,延迟高得离谱,Nova 调度经常超时。
4.3 Keystone 的 region 配置
Keystone 需要知道有哪些 region 存在,这个信息在globals.yml里通过keystone_regions参数配置。比如:
keystone_regions: - name: "RegionOne" description: "Global Region" - name: "RegionTwo" description: "Edge Region"每个区域在 Keystone 里注册后,service catalog 里会带上 region 信息。用户认证时,如果不指定 region,默认会落到第一个 region。所以建议在客户端配置里明确指定 region,避免请求被路由到错误的区域。
5. 区域层部署与跨区域通信配置
5.1 区域层服务的独立部署
区域层的部署流程和单区域类似,但有几个关键差异。首先,区域层的 Keystone 不需要部署,因为认证走全局层。在globals.yml里要把enable_keystone设为no,同时指定keystone_admin_url和keystone_internal_url指向全局层的 Keystone endpoint。
其次,区域层的 Nova 需要配置nova_region_name,这个值要和 Keystone 里注册的 region 名称一致。Neutron 也需要配置neutron_region_name。这些参数在globals.yml里设置,部署时会自动写入对应的配置文件。
区域层的数据库和消息队列是独立的,所以database_address和rabbitmq_address要指向本区域的节点,不能指向全局层。这一点在配置的时候要特别小心,写错了会导致区域层服务连不上数据库。
5.2 跨区域网络打通的关键配置
如果业务需要跨区域的虚拟机通信,Neutron 层面需要做额外配置。常见做法是使用 VXLAN 隧道,把两个区域的租户网络打通。具体来说,需要在两个区域的 Neutron 里配置相同的 VNI 段,并且确保两边的隧道端点能互相访问。
配置项主要在neutron.conf和ml2_conf.ini里。kolla-ansible 通过globals.yml的neutron_tunnel_network和neutron_vni_ranges来控制。比如:
neutron_tunnel_network: "10.0.100.0/24" neutron_vni_ranges: "1000:2000"两个区域要用不同的隧道网段,但 VNI 范围可以重叠,因为 VNI 是本地有效的。跨区域通信时,Neutron 会根据路由表把流量送到对端的隧道端点。
提示:跨区域网络打通后,一定要测试 MTU。VXLAN 封装会增加 50 字节的开销,如果物理网络 MTU 是 1500,隧道网络的 MTU 要设成 1450,否则大包会被丢弃,表现为虚拟机之间能 ping 通但传文件卡死。
5.3 区域层部署的执行顺序
区域层的部署建议按以下顺序执行:
- 先部署控制节点(control、network),确保 API 服务和网络服务起来。
- 再部署计算节点(compute),让 Nova 注册到本区域的 controller。
- 最后部署存储节点(storage),如果有独立的 Cinder 或 Swift 节点。
每部署完一个区域,用openstack hypervisor list和openstack network agent list检查一下服务是否正常注册。如果某个服务没起来,先排查日志,不要急着部署下一个区域。
6. 常见问题排查与避坑经验
6.1 认证失败与 region 不匹配
这是多区域部署里最常见的问题。表现是用户在某个区域执行命令时报 401 或 403,但换个区域就正常。原因通常是 service catalog 里的 endpoint 没有正确带上 region 信息,或者客户端配置里的 region 名称和 Keystone 里注册的不一致。
排查步骤:
- 用
openstack endpoint list查看所有 endpoint 的 region 字段。 - 检查
/etc/kolla/regionX/globals.yml里的nova_region_name等参数是否和 Keystone 里的 region 名称完全一致,大小写敏感。 - 在客户端用
openstack --os-region-name RegionOne token issue测试指定 region 的认证。
6.2 数据库连接超时
区域层的服务连不上本区域的数据库,或者连上了但响应很慢。先检查database_address配置是否正确,再检查数据库的max_connections是否够用。多区域环境下,每个区域的服务都会连自己的数据库,连接数会比单区域多不少。如果max_connections设得太小,高峰期会出现连接被拒绝的情况。
我一般会把max_connections设成 1000 以上,并且开启连接池。kolla-ansible 默认的配置可能偏保守,需要根据实际节点数量调整。
6.3 消息队列脑裂
RabbitMQ 在多区域环境下容易出现脑裂,尤其是网络抖动的时候。表现是某个区域的服务突然收不到消息,或者消息重复消费。预防措施是配置 RabbitMQ 的集群模式,并且设置合理的cluster_partition_handling策略。kolla-ansible 支持通过globals.yml配置 RabbitMQ 集群,但跨区域的 RabbitMQ 集群不建议做,因为网络延迟会导致集群状态同步困难。每个区域独立一套 RabbitMQ 更稳妥。
6.4 常见问题速查表
| 问题现象 | 可能原因 | 排查方向 |
|---|---|---|
| API 返回 401 | region 名称不匹配 | 检查 globals.yml 和 Keystone |
| 虚拟机无法跨区域通信 | 隧道网络未打通 | 检查 Neutron VXLAN 配置 |
| 数据库连接超时 | 地址错误或连接数满 | 检查 database_address 和 max_connections |
| 消息队列无响应 | 集群脑裂或网络分区 | 检查 RabbitMQ 日志和集群状态 |
| 部署卡在某个任务 | 依赖服务未就绪 | 查看 ansible 日志和容器状态 |
7. 多区域运维的日常操作与扩展思路
7.1 滚动升级的正确姿势
多区域环境下升级 OpenStack,必须一个区域一个区域地来。先升级全局层,再升级区域一,验证没问题后再升级区域二。升级前一定要备份数据库和配置文件,升级过程中密切监控 API 的响应时间。
kolla-ansible 的升级命令是kolla-ansible -i inventory upgrade --limit region1-control:region1-network:region1-compute。升级完成后,用kolla-ansible post-deploy更新一下环境变量。
7.2 新增区域的流程
业务扩张需要加新区域时,流程大致如下:
- 在 Keystone 里注册新 region。
- 准备新区域的节点,配置好网络和时间同步。
- 在 inventory 里添加新区域的分组和节点。
- 复制一份区域配置目录,修改 region 名称和网络参数。
- 执行部署命令,指定新区域的分组。
- 验证新区域的服务注册和资源可用性。
整个过程最耗时的其实是网络规划和节点准备,部署本身用 kolla-ansible 跑一遍就行,通常半小时内能完成。
7.3 监控与告警的跨区域统一
多区域环境下,监控不能各看各的,需要一个统一的视图。我一般会在全局层部署一套 Prometheus 和 Grafana,每个区域的节点上跑 node_exporter 和各个服务的 exporter,数据统一汇总到全局层的 Prometheus。告警规则也集中管理,避免每个区域一套规则导致维护困难。
网络延迟的监控要特别关注,全局层和区域层之间的 RTT 如果超过 50ms,Keystone 认证就会明显变慢。可以在每个区域部署一个 blackbox_exporter,定期探测到全局层的延迟,超过阈值就告警。
7.4 资源配额与调度策略
多区域环境下,Nova 的调度需要考虑区域间的资源分布。默认的调度器可能把虚拟机都调度到资源最多的区域,导致其他区域闲置。可以通过AggregateInstanceExtraSpecsFilter和 host aggregate 来控制,把不同区域的资源划分到不同的 aggregate,然后通过 flavor 的 extra specs 指定虚拟机落到哪个 aggregate。
配额管理也要注意,Keystone 的配额是全局的,但实际资源是分区域的。如果某个区域的资源用完了,用户在其他区域还能创建虚拟机,但配额显示还有剩余,容易造成困惑。建议在运维层面做好资源统计,定期同步各区域的实际使用量。
8. 个人实操体会与后续扩展方向
多区域部署这件事,说难不难,说简单也不简单。难点不在技术本身,而在规划和细节。我踩过最大的坑是网络规划没做好,全局层和区域层之间的管理网络带宽不够,导致 Keystone 认证高峰期超时,用户登录要等十几秒。后来把管理网络从千兆升到万兆,问题才解决。所以如果你正在规划多区域,管理网络的带宽一定要留足余量,别在这上面省钱。
另一个体会是,配置文件的管理比部署本身更重要。多区域环境下,配置项成倍增加,手工维护很容易出错。我后来把所有配置都放到了 Git 仓库里,用 Ansible 的--configdir指定不同区域的配置目录,每次变更都走代码审查,配置漂移的问题就少了很多。
后续如果要扩展,可以考虑的方向有几个:一是把全局层也做成高可用,避免全局层成为新的单点;二是引入多级区域,比如区域下面再分子区域,适合超大规模的场景;三是把部分服务下沉到边缘,减少跨区域的流量。这些方向各有取舍,具体怎么选,还是要看业务的实际需求和资源预算。