OpenStack 2025.2 (Flamingo) 在 openEuler 25.09 / 主机 open88 的单节点部署:12 章部署文档(含 30+ 条故障速查、单网卡 br0+veth 实例出网方案、重启自愈验证)、一键部署脚本(7 阶段 + 55 项验收)、配置副本、13 个 systemd 单元与 6 个 Apache WSGI vhost。
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 21 天前 | ||
| 2 天前 | ||
| 2 天前 | ||
| 2 天前 | ||
| 2 天前 | ||
| 2 天前 |
OpenStack 2025.2 (Flamingo) 单节点部署 —— open88
在 openEuler 25.09 上以源码方式部署 OpenStack 2025.2 (Flamingo) 单节点环境, 含 keystone / glance / placement / nova / neutron / horizon / cinder 七个服务, 并支持单网卡环境下的实例流量出口(br0 + veth 打通物理局域网)。
本仓库从一台已实际验证通过的机器(
open88)上整理而来:部署文档、 配置副本、systemd 单元、Apache vhost、一键部署脚本与验收脚本。
仓库内容
| 路径 | 说明 |
|---|---|
OpenStack-2025.2-Flamingo-部署文档.md |
主文档:12 章 + 2 附录,约 1550 行 |
OpenStack-Flamingo-运维手册.md |
运维手册:OpenStack 简介 + 七组件运维命令 + 故障解决方法 + 速查附录 |
deploy/README.md |
一键脚本使用说明 |
deploy/install/ |
一键部署脚本(7 阶段 + 主控 + 57 项验收) |
deploy/etc/ |
各服务配置副本(口令为占位符) |
deploy/systemd/ |
14 个自建 systemd 单元 |
deploy/httpd/ |
6 个 Apache mod_wsgi vhost |
deploy/scripts/ |
运维脚本(出口切换 / 看门狗 / 开机自检) |
部署文档结构
1 概述 5 Python 运行环境 9 故障排查记录(30+ 条踩坑)
2 目录规划 6 各服务安装 10 单网卡与实例出网方案
3 基础组件安装 7 systemd 托管 11 日常运维命令
4 下载源码包 8 验证结果 12 使用一键脚本部署
附录 A 资源与凭据速查 附录 B 重装提示
环境
| 项 | 值 |
|---|---|
| 主机 | open88 / 192.168.3.88 |
| 操作系统 | openEuler 25.09(内核 7.2.0) |
| Python | 3.11.13 |
| 数据盘 | /data(NVMe SSD),所有软件与数据落此盘 |
| 网卡 | 单网卡 enp2s0(管理 + 实例出口复用) |
| CPU / 内存 | AMD FX-6100 六核(AMD-V)/ 30 GB |
已部署服务
| 服务 | 版本 | 端口 |
|---|---|---|
| keystone | 28.0.3.dev6 | 5000 |
| glance | 31.1.1.dev18 | 9292 |
| placement | 14.0.1.dev8 | 8778 |
| nova | 32.2.2.dev2 | 8774 / 8775 |
| neutron | 27.0.5.dev8 | 9696 |
| horizon | 25.5.3.dev10 | 80 |
| cinder | 27.0.1.dev25 | 8776 |
一键部署
cd deploy/install
vi answers.conf # 改 MANAGE_IP / MANAGE_GW / MANAGE_IF / 口令
sudo ./install.sh # 全量部署(约 20–40 分钟)
sudo ./90-verify.sh # 验收(57 项)
支持断点续装与干跑:
./install.sh --list # 列出阶段
./install.sh --dry-run # 只打印不执行
sudo ./install.sh 3 # 从中断的阶段继续
详见 deploy/README.md。
验收
90-verify.sh 共 57 项检查,覆盖基础服务(含 conntrack 命令与日志轮转配置)、
服务单元、监听端口、API 响应、服务目录、网络与存储、端到端实例创建。本机实测结果:
=== 验收汇总 ===
通过:57 项
失败:0 项
全部验收通过 ✓
单网卡出口方案
物理交换机 / 局域网 192.168.3.0/24
│
enp2s0(纯 L2 桥端口)
│
┌──────────── br0 (Linux 网桥, NM) ────────────┐
│ 192.168.3.88/24 + 默认路由(管理地址) │
│ veth-br0 ●~~~~● veth-brex │
└────────────────────────┼─────────────────────┘
│
┌──── br-provider (OVS, neutron) ────┐
│ phy-br-provider ↔ br-int │
└───────────────┼─────────────────────┘
│
qrouter(qg/qr) → 实例浮动 IP / SNAT
enp2s0 是唯一网卡,直接挂进 OVS 网桥会让管理 IP 无处安放。
方案是先用 br0 承接管理 IP(网卡降为桥端口),再用一对 veth 把
br0 与 br-provider 在 L2 连通——两类流量各走各的网桥,只在 L2 交汇。
⚠️ 启用出口切换(
WITH_EGRESS_SWITCH=yes)会造成秒级断网, 详见文档第 10 章(含自动回滚看门狗与实战踩坑记录)。
镜像优化:缩小 root 分区 + root 密钥登录
对 glance 中的系统镜像做了两项优化:收缩磁盘与根分区(减小镜像文件与实例
root 盘占用)和放开 root 密钥登录(keypair 直登 root)。以下以
openeuler-24.03-LTS-SP4 镜像(ID e6af4933)为例,已在 open88 实测。
优化结果
| 项目 | 优化前 | 优化后 |
|---|---|---|
| 镜像虚拟大小 | 11 GiB | 4.6 GiB |
| 实例根分区 | 8 G(实际用 2.4G) | 4.1 G(ext4 已收缩) |
| EFI 分区 | 2 G(实际用 80M) | 512 M |
| root 密钥登录 | cloud-init 拦截,只能 cirros/普通用户 | keypair 直登 root |
步骤一:qemu-nbd 挂载镜像
modprobe nbd max_part=8
qemu-nbd --connect=/dev/nbd0 <镜像.qcow2>
partprobe /dev/nbd0 && fdisk -l /dev/nbd0 # 记录原分区布局与 blkid 的 UUID
步骤二:收缩 ext4 根分区并搬迁
e2fsck -f -y /dev/nbd0p2
resize2fs /dev/nbd0p2 4200M # 离线收缩有最小值限制,先 fsck 再缩
用 sfdisk 写入新分区表(EFI 512M + root 按收缩后大小),注意保持
label-id 与原磁盘标识一致、分区序号不变(fstab 按 UUID 挂载不受影响):
sfdisk --force /dev/nbd0 <<'EOF'
label: dos
label-id: 0x031bef61 # ← 改成 blkid / fdisk 读到的原值
start=2048, size=1048576, type=e
start=1052672, size=8603648, type=83
EOF
缩小分区后文件系统数据仍留在旧偏移,需原位搬迁到新分区起点(目标偏移在 源偏移之前,前向 dd 安全):
dd if=/dev/nbd0 of=/dev/nbd0 bs=1M skip=<旧起点扇区/2048> \
seek=<新起点扇区/2048> count=<fs大小扇区/2048> conv=notrunc
e2fsck -f -y /dev/nbd0p2 # 搬迁后必须校验
步骤三:重建 EFI 分区
mkfs.vfat -F 16 -i <原volume-id去横线> /dev/nbd0p1 # 保持 fstab 的 UUID 不变
mount /dev/nbd0p1 /mnt2 && cp -a <EFI备份>/. /mnt2/ && umount /mnt2
步骤四:清零空闲块、收缩虚拟大小并压缩
mount /dev/nbd0p2 /mnt && dd if=/dev/zero of=/mnt/zero bs=4M status=none; \
rm -f /mnt/zero; sync; umount /mnt
qemu-nbd -d /dev/nbd0
qemu-img resize --shrink <镜像> <新总扇区数×512>
qemu-img convert -c -O qcow2 -o compression_type=zstd <镜像> <镜像>.new
步骤五:同步 glance 元数据(无 openstackclient 时直改 DB)
替换 /data/openstack/glance/images/ 下同名文件后,更新 DB 中的
size / virtual_size / checksum(md5, varchar32) / os_hash_algo /
os_hash_value(sha256),再 systemctl restart glance-api。
直接换文件不改 DB 会导致元数据与文件不一致。
步骤六:放开 root 密钥登录
keypair 登录 root 失败的根因是 cloud-init 默认 disable_root: true——
实例首启时它会向 root 的 authorized_keys 注入 command="echo Please login as ..." 拦截命令。在镜像内改两处:
# /etc/cloud/cloud.cfg
disable_root: false
# /etc/ssh/sshd_config(显式允许密钥登录 root,仍禁密码)
PermitRootLogin prohibit-password
⚠️ 只影响新创建的实例;存量实例需手动删掉
/root/.ssh/authorized_keys里的command="..."前缀。
平台适配
本文档与脚本面向 openEuler / RHEL 系。部分内容参考了另外两台机器的实践:
| 主机 | 平台 | 要点 |
|---|---|---|
open88(本仓库) |
openEuler 25.09 | 单网卡 br0 + veth;数据全落 /data |
euler88 |
openEuler 26.09 | eno1 直挂 br-ex2;另有 patches/sudoers 等 |
devstack-1 |
Ubuntu | apt 源;systemd 单元不同 |
已知限制
- 单节点:未验证多计算节点、cell 扩容与 HA
- cinder 用单机 loop 文件做卷组,无副本;未部署 cinder-backup
- 宿主机重启后实例需手动
openstack server start(libvirt 无 autostart) - 一键脚本除验收脚本外,尚未在干净机器上端到端跑过全流程