OpenStack-Ansible (OSA) 是另一个 OpenStack 部署工具,但它的定位和设计哲学与 DevStack 截然不同。如果说 DevStack 是开发者的"瑞士军刀",那么 OpenStack-Ansible 就是运维工程师的"重型施工机械"。
理解 OSA 的关键在于理解 Ansible 和 生产级部署 这两个核心概念。
1. 核心理念与设计哲学
与 DevStack 相比,OSA 的设计目标完全不同:
-
为生产而生 (Production-Ready First) :OSA 的首要目标是部署一个可用于生产环境的 OpenStack 集群。这意味着它天生就考虑了高可用性 (HA)、安全性、可伸缩性和可升级性。
-
声明式与幂等性 (Declarative & Idempotent):你不用告诉 OSA 如何 去做,而是告诉它你想要什么样的最终状态(例如,"我需要3个控制节点,Keystone 服务必须运行")。OSA 会利用 Ansible 的能力来达到这个状态。反复运行同一个部署命令不会破坏环境,只会确保环境符合你的声明。
-
配置即代码 (Configuration as Code) :所有的环境定义、主机清单、服务参数都通过 YAML 文件进行管理。这使得整个云平台的架构可以被版本控制、审查和轻松复制。
-
容器化控制平面 (Containerized Control Plane) :这是 OSA 的一个标志性特点。所有的 OpenStack API 和后端服务(如 Keystone, Nova-API, Galera数据库, RabbitMQ)都运行在 LXC 容器中。这带来了巨大的好处:
-
隔离性:服务之间互不干扰,宿主机环境保持干净。
-
可升级性:升级一个服务通常意味着销毁旧容器,用新版本的代码和依赖启动一个新容器,大大降低了升级的风险和复杂性。
-
-
高度结构化和角色化 (Structured and Role-Based) :它遵循 Ansible 的最佳实践,将所有逻辑封装在可重用的角色 (Roles) 中。每个 OpenStack 服务(如 Keystone)都是一个独立的 Ansible Role。
2. 关键文件和目录结构解析
OSA 的目录结构是典型的 Ansible 项目结构,理解它至关重要。
Generated code
.
├── ansible.cfg # Ansible 的核心配置文件,定义了角色路径、默认行为等
│
├── playbooks/ # 部署的入口!用户主要执行这里的 playbook
│ ├── setup-hosts.yml # 1. 准备所有目标主机 (基础设置)
│ ├── setup-infrastructure.yml # 2. 部署基础架构服务 (DB, MQ, Memcached)
│ ├── setup-openstack.yml # 3. 部署 OpenStack 服务
│ ├── run-upgrade.yml # 用于执行版本升级
│ └── ...
│
├── inventory/ # 定义你的集群环境 (主机、分组、变量)
│ ├── dynamic_inventory.py # 一个动态生成 Ansible inventory 的脚本
│ └── templates/ # inventory 的模板
│
├── etc/openstack_deploy/ # 用户的配置目录 (全局覆盖)
│ ├── openstack_user_config.yml # 定义你的主机清单和分组 (最重要的文件之一)
│ ├── user_variables.yml # 定义你想要覆盖的全局变量 (另一个最重要的文件)
│ └── conf.d/ # 按服务存放变量覆盖
│
├── roles/ # 核心逻辑!每个角色对应一个部署单元
│ ├── os_keystone/ # Keystone 服务的 Ansible Role
│ │ ├── tasks/main.yml # 这个 Role 的主任务列表
│ │ ├── handlers/main.yml # 触发器,如"当配置文件改变时重启服务"
│ │ ├── templates/ # 服务的配置文件模板 (如 keystone.conf.j2)
│ │ ├── defaults/main.yml # 这个 Role 的默认变量
│ │ └── ...
│ ├── os_nova/ # Nova 服务的 Ansible Role
│ ├── galera_server/ # Galera (MariaDB) 数据库的 Role
│ └── ... # 每个基础服务和 OpenStack 服务都有一个 Role
│
└── releasenotes/ # 版本发布说明
content_copydownload
Use code with caution.
小结:
-
执行入口: playbooks/*.yml
-
用户配置: /etc/openstack_deploy/ 下的 YAML 文件(这是你工作的地方)
-
部署蓝图 (主机清单): /etc/openstack_deploy/openstack_user_config.yml
-
部署参数 (变量): /etc/openstack_deploy/user_variables.yml
-
核心实现: roles/ 目录下的每个子目录
3. 部署流程详解("三步走"的史诗)
OSA 的部署过程通常分为清晰的三大步,对应三个核心的 Playbook。
阶段 0: 准备工作 (你的工作)
在运行任何命令之前,你必须配置两个核心文件:
-
/etc/openstack_deploy/openstack_user_config.yml:
-
在这里,你定义你的物理或虚拟主机。
-
你将这些主机分配到不同的组里,比如 controller_hosts, compute_hosts, storage_hosts。
-
你为每个主机指定 IP 地址,特别是用于管理网络 (container_address) 和隧道网络 (tunnel_address) 的 IP。
-
-
/etc/openstack_deploy/user_variables.yml:
-
在这里,你可以覆盖几乎所有 OpenStack-Ansible 的默认设置。
-
例如,设置外部网络的 CIDR、选择 Neutron 的网络后端 (VLAN or VXLAN)、设置 Keystone 的默认域、调整 Nova 的超分比等等。
-
阶段 1: ansible-playbook playbooks/setup-hosts.yml
这是引导阶段,它在所有目标主机上运行,目标是让这些主机"准备好"承载 OpenStack。
-
创建 sshd 配置,确保 Ansible 可以无密码登录。
-
安装基础软件包,如 python, ntp, lvm2 等。
-
进行一些系统安全加固 (Security Hardening)。
-
配置网络:创建 Linux Bridge(如 br-mgmt, br-vlan),为后续的容器和 Neutron 网络做准备。
-
安装 LXC 和其他容器化所需的工具。
阶段 2: ansible-playbook playbooks/setup-infrastructure.yml
这是构建基础架构层。OpenStack 服务依赖一些核心的后端服务,这个 playbook 负责部署它们。
-
数据库 (Galera Cluster): 在 infra_hosts (通常是控制器节点) 上,部署一个高可用的 MariaDB Galera 集群。每个 MariaDB 实例都运行在一个独立的 LXC 容器中。
-
消息队列 (RabbitMQ): 同样在 infra_hosts 上,部署一个高可用的 RabbitMQ 集群,用于 OpenStack 服务间的通信。每个 RabbitMQ 实例也运行在自己的 LXC 容器里。
-
缓存 (Memcached): 部署 Memcached 服务,供 Keystone 等服务用作令牌缓存。
阶段 3: ansible-playbook playbooks/setup-openstack.yml
这是部署 OpenStack 服务本身的阶段。Ansible 会根据你的配置,按依赖顺序逐个部署 OpenStack 服务。
让我们以部署 Keystone 为例,看看内部发生了什么:
-
setup-openstack.yml playbook 会调用 os_keystone 这个 role。
-
Ansible 会在 identity_hosts (在 openstack_user_config.yml 中定义的,通常是控制器) 上执行 os_keystone role 中的任务。
-
os_keystone role (roles/os_keystone/tasks/main.yml) 的主要任务包括:
-
创建容器: 在目标主机上创建一个名为 keystone_container 的 LXC 容器。
-
安装依赖: 在容器内部,使用 apt 或 yum 安装 Keystone 软件包及其 Python 依赖。
-
生成配置: 使用 templates/keystone.conf.j2 模板和所有相关的变量(来自默认值和你 user_variables.yml 的覆盖),生成 keystone.conf 文件,并把它放到容器的 /etc/keystone/ 目录下。
-
数据库设置: 在 Galera 数据库中为 Keystone 创建数据库和用户。
-
数据库同步: 在容器内执行 keystone-manage db_sync 命令。
-
服务管理: 确保容器内的 keystone-api 服务已启动并设置为开机自启。
-
引导 Keystone: 创建默认的域、项目、用户、角色,并为其他 OpenStack 服务注册 endpoints。
-
所有其他 OpenStack 服务(Nova, Neutron, Cinder 等)都遵循这个类似模式,在各自的容器中被部署和配置。
4. 配置系统:YAML 的层次与覆盖
理解 OSA 的变量覆盖逻辑是定制化的关键。Ansible 变量的优先级从低到高是:
-
Role Defaults: roles/<role_name>/defaults/main.yml - 这是最低优先级的默认值。
-
OSA Global Defaults: playbooks/defaults/main.yml 和 inventory/group_vars - OSA 提供的全局默认值。
-
User Global Overrides : /etc/openstack_deploy/user_variables.yml - 这是你最应该使用的文件,它的优先级很高,可以覆盖上面所有的默认值。
-
User Group/Host Overrides: 你可以在 /etc/openstack_deploy/group_vars/ 目录下为特定主机组定义变量。
-
命令行变量: 使用 -e "variable=value" 传入的变量,优先级最高。
这种分层结构让你既能享受 OSA 提供的"最佳实践"默认值,又能灵活地进行局部或全局的精细化调整。
如何阅读和调试 OSA 源码
-
从 Playbook 开始: 打开 playbooks/setup-openstack.yml,看它 import 或 include 了哪些 playbook,以及它针对哪些主机组 (hosts: ...) 运行,调用了哪些角色 (roles: ...)。
-
深入 Role 的 tasks/main.yml: 这是 Role 的执行逻辑核心。阅读它,了解这个 Role 一步步做了什么。你会看到大量使用 lxc_container, template, service, command 等 Ansible 模块。
-
检查 templates 目录: 想知道 nova.conf 是怎么生成的?去 roles/os_nova/templates/nova.conf.j2 文件里看。所有 {{ variable_name }} 都是将被替换的变量。
-
追溯变量来源: 想知道 {{ keystone_db_password }} 这个变量的值从哪来?
-
首先 grep -r "keystone_db_password" 整个项目。
-
通常会在 roles/os_keystone/defaults/main.yml 或 vars/main.yml 中找到它的定义。
-
然后检查你自己的 user_variables.yml 是否覆盖了它。
-
-
使用 Ansible 工具:
-
--check (Check Mode): 运行 ansible-playbook ... --check。这会进行"干运行"(dry run),不会实际改变任何东西,但会报告哪些任务会做出更改。这是最安全的调试方式。
-
--diff: 配合 --check 使用,可以显示文件内容的具体变化。
-
-v, -vv, -vvv (Verbosity): 增加详细输出,让你看到每个任务的输入、输出和执行状态。-vvv 是你的终极调试利器。
-
总结:DevStack vs. OpenStack-Ansible
|-----------|----------------------------------|----------------------------|
| 特性 | DevStack | OpenStack-Ansible |
| 核心目标 | 快速搭建 开发/测试 环境 | 部署 生产级、高可用 的云平台 |
| 架构 | 单节点,All-in-one,服务直接跑在宿主机 | 多节点,分布式,服务运行在 LXC 容器 中 |
| 配置方式 | Shell 脚本 (local.conf) | 结构化 YAML 文件 (*.yml) |
| 源代码来源 | 直接从 Git master/branch 克隆 | 可使用发行版软件包或从 Git 克隆 |
| 幂等性 | 基本具备,但主要是脚本层面的检查 | 由 Ansible 核心保证,非常健壮 |
| 升级 | 不支持。通常是 unstack.sh && stack.sh | 核心特性,支持滚动升级和主要版本升级 |
| 目标用户 | OpenStack 开发者、贡献者 | 云运维工程师、系统架构师 |
| 复杂性 | 较低,易于上手 | 较高,需要理解 Ansible 和分布式系统概念 |
OpenStack-Ansible 是一个强大、成熟且经过实战检验的项目。通过将部署逻辑封装在 Ansible Roles 中,并利用容器化技术,它提供了一个既有标准范式(Opinionated)又高度可配置(Configurable)的生产级 OpenStack 部署方案。