想学 OpenStack,最劝退的不是概念有多绕,而是第一步“搞几台物理服务器”就直接把大多数人挡在门外。我当初踩了一圈坑,最后固定下来的方案是 DevStack + Multipass:用 Multipass 在笔记本上快速拉一个轻量虚机,再在虚机里跑 DevStack 部署脚本,全程下来基本就是喝杯咖啡的等待时间。这篇文章就把整个流程拆开揉碎,从环境检查到虚机创建,从 local.conf 逐行解读到安装失败后的排查,完整走一遍“本地可复现”的路径。适合两类人:一是想快速把 OpenStack 跑起来看看长什么样的新手,二是需要在本地搭一套开发测试环境、随时推倒重来的工程师。
1. 为什么是 DevStack + Multipass,而不是其他组合
1.1 DevStack 的定位:大约等于“OpenStack 的快速原型工具”
先说清楚一个容易误解的点:DevStack 不是 OpenStack 的简化版,也不是生产环境部署工具。它本质是一组 shell 脚本,会自动把 OpenStack 的核心服务从源码拉下来,然后按依赖关系依次安装、配置、启动。这套脚本覆盖了 Keystone(身份认证)、Nova(计算)、Neutron(网络)、Glance(镜像)、Cinder(块存储)以及 Horizon(仪表盘)这些核心组件,安装完就是一个能跑通完整业务链路的单节点 OpenStack。
它的价值在于“可复现”。你不需要手动装数据库、消息队列、各服务的 Python 依赖,也不用自己写配置文件,DevStack 会自动生成一套默认配置并把所有服务串起来。也因此它只适合开发测试和学习,不适合生产。生产环境的 OpenStack 部署是另一套完全不同的玩法,涉及容器化、高可用、多节点网络规划,复杂度完全不在一个量级上。
1.2 Multipass 解决了什么问题
Multipass 是 Canonical 出品的轻量级虚机管理工具,底层走的还是 KVM/QEMU 或者 Hyper-V 那套虚拟化,但它把创建和管理虚机的操作封装成了极简的命令行。和 VirtualBox 或 VMware 相比,它最大的优势是:一条命令就能启动一个带官方 Ubuntu 镜像的虚机,并且支持 --cpus、--mem、--disk 直接指定资源,还内置了 cloud-init 集成,可以注入 SSH key、自定义初始脚本。
从复现实验的角度看,Multipass 还有一个很实用的特性:文件系统挂载。你可以把宿主机的一个目录直接挂载到虚机里,这样 DevStack 的 local.conf 配置文件在宿主机上编辑,在虚机里立即生效,不用来回拷贝。
1.3 几种常见方案的横向对比
我自己最初也试过几种方案,各自体验差异很大,直接做了一张对比表供参考:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 物理服务器 + DevStack | 环境最真实,性能不受虚拟化损耗 | 门槛高,大多数人不具备多台物理机条件 | 有现成服务器、想贴近真实部署 |
| VirtualBox / VMware 虚机 + DevStack | 通用性强,跨平台 | 创建和配置虚机需要手动点界面,网络模式偶尔有坑 | 在没有 Multipass 或者公司强制指定虚拟化平台时 |
| Multipass + DevStack | 命令行秒建虚机,支持挂载目录,干净易销毁重建 | 只提供 Ubuntu 镜像,可定制性低于完整虚拟化平台 | 本地开发、学习、快速验证的最优解 |
| 容器化(Kolla-Ansible 等) | 部署方式贴近生产,组件容器化管理 | 对机器性能要求更高,概念更复杂,不适合刚入手 | 有一定 OpenStack 基础后进阶用 |
如果你只想把 OpenStack 跑起来、看界面、试创建实例,Multipass 组合是效率最高的路径。等你能熟练解释清楚 DevStack 部署完之后每个服务在干什么,再去看 Kolla-Ansible 或者 TripleO 都不迟。
2. 环境准备里最容易翻车的三个细节
2.1 先确认虚拟化支持,不然 Multipass 会慢到你怀疑人生
Multipass 虽然封装得很好,但它在底层一定要调用虚拟化能力。如果你是在笔记本上跑,先确认 CPU 虚拟化已经被正确穿透:
- Linux 下用
ls /dev/kvm,如果存在这个设备文件,说明 KVM 可用。 - macOS 上查看“系统报告 -> 硬件 -> 虚拟机”,确认
Virt特性。 - Windows 上检查任务管理器里的“虚拟化”是否显示“已启用”,同时要确认 Hyper-V 平台功能有没有和 Multipass 的驱动冲突。Windows 上常见的情况是:装了 Docker Desktop(用了 WSL2)之后再装 Multipass,需要让 Multipass 走 Hyper-V 后端,否则性能极差。
这一项如果没查,最常见的现象是虚机能启动,但极慢,安装 DevStack 时某个服务编译到一半直接卡死。因为 Multipass 在没有 KVM 加速时会回退到纯软件模拟,那个性能跑 OpenStack 基本是不可用的。
2.2 内存和磁盘规划要按“两次安装”的余量来算
DevStack 这个脚本会拉取大量源码并做 pip 安装,还涉及编译部分 Python 扩展。官方文档写的建议是最低 8GB 内存、40GB 磁盘。以我的实际体验来看,8GB 内存属于“能跑但很勉强”的状态,安装过程中 Nova 的编译阶段可能会出现内存不足风险;16GB 内存是比较舒服的配置,跑起来之后还能同时开几个实例做验证。
磁盘方面,我给的建议是至少 50GB,其中虚机占掉 40GB 左右。为什么故意留一点余量?因为 DevStack 拉下来的源码、pip 缓存、日志文件都很占空间,如果你还想在 Glance 里上传几个测试镜像、创建几台实例,磁盘会迅速增长。而且一旦部署到一半磁盘满了,清理起来特别麻烦,因为很多服务的数据目录散落在 /opt/stack 下面。
2.3 网络模式:默认 NAT 最稳,别上来就折腾桥接
Multipass 默认使用的是 NAT 网络,也就是虚机和宿主机共用一个出口 IP,外部网络通过宿主机转发访问虚机。这个模式对于 DevStack 来说完全够用,因为你要做的验证工作基本都是“登录虚机看服务”以及“通过浏览器访问 Horizon”,而 Horizon 访问可以通过 Multipass 的 IP 直接完成,不需要端口转发。
有些人一开始觉得应该让虚机用桥接模式获得一个和宿主机同网段的 IP,这样“看起来比较像真环境”。但桥接模式在 macOS 上经常需要额外配置,Windows 上还涉及网卡绑定问题,折腾的成本远大于收益。用 NAT 模式配合 Multipass 的multipass list查看虚机 IP,然后直接在浏览器里访问http://<虚机IP>/dashboard就行了。真正的多节点网络配置是后面学习 Neutron 时的事,不是第一轮安装该考虑的问题。
3. Multipass 建虚机的完整步骤:从安装到进入 shell
3.1 安装 Multipass:三条命令解决
Multipass 支持三大平台:
- macOS:
brew install --cask multipass,或者直接从官网下载 pkg 安装包。 - Ubuntu:
sudo snap install multipass。 - Windows:下载安装包,或通过 winget:
winget install Canonical.Multipass。
安装完先跑multipass version验证一下。如果你是 Windows 用户,安装过程中如果提示需要启用 Hyper-V,按照指引重启即可。
3.2 launch 参数详解:为什么要锁定 22.04 而不是最新版
创建虚机的命令我推荐这样写:
multipass launch --name devstack-node --cpus 4 --mem 8G --disk 50G --release 22.04各参数含义如下:
--name devstack-node:虚机名称,后面所有操作都基于这个名字。--cpus 4:分配 4 个 vCPU。如果宿主机只有 4 核物理核,建议降到 2,否则会抢光宿主机资源。--mem 8G:按前面说的,至少 8GB,如果机器内存大于 16GB,可以给到 12G。--disk 50G:磁盘空间,预留足够余量。--release 22.04:指定 Ubuntu 22.04 LTS。为什么不直接用默认的 24.04?因为 OpenStack 社区对特定发行版的适配有一个时间差,DevStack 在 22.04 上的兼容性最成熟,Python 版本也正好是 OpenStack 各服务依赖较多的 Python 3.10。24.04 的 Python 版本更新,某些旧版本的依赖包在 pip 安装时可能会出现编译错误,踩过的人都知道那有多烦。
执行完这条命令,Multipass 会自动下载镜像并启动虚机。这一步的耗时取决于网络环境,通常几分钟。镜像下载完成后,用multipass list确认状态,输出类似:
Name State IPv4 Image devstack-node Running 192.168.64.15 Ubuntu 22.04 LTS3.3 进入虚机并做基础检查
multipass shell devstack-node这一步会直接进入到虚机的 shell,之后的所有操作都在虚机内部完成。进来之后先做两件小事:
一是更新软件源并安装基础工具:
sudo apt update && sudo apt upgrade -y sudo apt install -y git net-tools curl二是确认网络能正常访问外网,因为 DevStack 需要从 GitHub / OpenDev 等仓库拉源码:
curl -sI https://opendev.org | head -n 1如果这一步返回了 HTTP 状态码,说明网络没有问题。如果超时,大概率是 DNS 配置问题,检查一下/etc/resolv.conf,或者把nameserver改成公共 DNS 再试。网络问题一定在安装之前解决,否则后面 DevStack 脚本拉源码阶段会无限重试。
4. 安装 DevStack 的完整链路:local.conf 是灵魂
4.1 为什么必须要建一个非 root 用户
DevStack 官方文档从一开始就强调:不要用 root 跑安装脚本。原因有两个层面:一是 OpenStack 的各个服务在启动时不应该以 root 身份运行,这是安全基线;二是 DevStack 脚本内部会在你的用户目录下创建/opt/stack这样的数据目录,并给目录设置特定的属主和权限,如果直接用 root,很多权限检查会直接跳过,反而掩盖了问题。
所以先创建用户:
sudo useradd -s /bin/bash -d /opt/stack -m stack echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack sudo su - stack第一行创建了一个家目录为/opt/stack的普通用户 stack;第二行给这个用户配置了免密 sudo,这是为了让 DevStack 脚本里大量sudo操作不被打断;第三行切换到该用户,之后的操作全部在这个身份下进行。
4.2 拉取 DevStack 源码
git clone https://opendev.org/openstack/devstack cd devstack如果访问 OpenDev 不稳定,可以换成 GitHub 上的镜像仓库https://github.com/openstack/devstack.git。二者代码是同步的,选一个能连上的就行。clone 完成后,在 devstack 目录下创建 local.conf,这是整个安装流程的控制中心。
4.3 local.conf 逐行解读:每个密码和 IP 的作用
DevStack 的 local.conf 格式是 INI 风格,核心段是[[local|localrc]]。下面是我实际使用的配置,逐行加注释:
[[local|localrc]] ADMIN_PASSWORD=admin DATABASE_PASSWORD=dbpass RABBIT_PASSWORD=rabbitpass SERVICE_PASSWORD=servicepass HOST_IP=192.168.64.15ADMIN_PASSWORD:管理员的登录密码,对应 Horizon 页面和openstack命令行的 admin 用户。这个要记住,后面都要用。DATABASE_PASSWORD:OpenStack 各服务连接数据库(默认是 MariaDB)时使用的密码。DevStack 会给每个服务创建独立的数据库账号,但统一使用这个密码。RABBIT_PASSWORD:RabbitMQ 的密码。RabbitMQ 是各个服务之间通信的消息队列,Nova 和 Neutron 的调度、状态同步都依赖它。SERVICE_PASSWORD:服务账号的密码。OpenStack 中每个服务(Nova、Neutron 等)在 Keystone 里都有一个服务账号,这个密码就是统一服务账号密码。HOST_IP:虚机的 IP 地址。为什么要手动指定?因为 DevStack 在某些网络环境下无法自动探测到正确的本机 IP,如果探测到了 127.0.0.1 或者多个网卡时产生了歧义,后续 Keystone 生成的 endpoint 地址会指向错误 IP。手动指定是最稳的。
还有一个可选参数我建议加上:
ENABLED_SERVICES+=,tempestTempest 是 OpenStack 的集成测试套件,装上之后可以跑官方测试用例验证部署是否正常。不过它额外占用时间和磁盘,第一轮安装可以先不加,等确认核心服务跑通了再考虑。
4.4 执行 ./stack.sh:等待过程中发生了什么
配置完成后,直接执行:
./stack.sh接下来就是一段漫长的等待,视网络和机器性能通常在 20~40 分钟。这个脚本做的事情大致分三个阶段:
第一阶段是安装系统级的依赖包,包括 Python、数据库、消息队列、网络组件等。这个阶段主要耗时在apt install和pip install上。如果网络状况一般,可以考虑把 pip 源和 apt 源换成国内镜像,方法是在 local.conf 里追加:
PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple第二阶段是拉取 OpenStack 各组件的源代码并逐个安装配置。DevStack 会创建一个/opt/stack目录,把所有源码 clone 到那里。你会在屏幕上看到大量Cloning into ...的日志,以及每个服务依次显示Starting ...的字样。
第三阶段是启动服务和创建默认资源。脚本最后会创建默认的 flat 网络、默认的安全组,并打印出准确的访问地址和账号信息。当屏幕出现类似This is your host IP address的提示时,说明安装完成了。
5. 安装失败不用慌:常见的坑与排查链路
第一次跑 DevStack,很少有人能一把过。我自己就翻车过三四回,而且翻车的原因五花八门。这里总结几个高概率的问题和完整的排查思路。
5.1 失败位置一:git clone 阶段卡住或超时
日志里出现大量Could not resolve host或者Connection timed out,基本都是网络问题。排查链路如下:
- 确认虚机能访问外网,
curl -sI https://opendev.org。 - 如果是 DNS 问题,修改
/etc/resolv.conf,加nameserver 8.8.8.8。 - 如果虚机网络正常但 git 仓库连接不稳定,可以考虑在 local.conf 里同时配置 GitHub 镜像仓库地址,DevStack 支持通过
GIT_BASE指定基础仓库地址。
这个问题应该在安装前解决,所以在跑 stack.sh 之前先把网络检查做扎实,比安装过程中再排查高效得多。
5.2 失败位置二:pip 编译某个包时 OOM 或被 kill
日志里出现Killed这个单词,或者有一个任务显示signal: SIGKILL,十有八九是内存不够。OpenStack 的某些 Python 依赖(比如cryptography、lxml)在源码安装时会编译 C 扩展,编译过程内存占用很高。如果虚机内存只有 4GB,这一步大概率过不去。
处理方法有两个层面:
一是给虚机分配更多内存,这个需要在 Multipass 创建阶段就决定好,事后改比较麻烦,所以创建虚机时一定不要手软,至少 8GB;
二是给 pip 增加编译时的临时目录限制,在 local.conf 里加:
PIP_USE_DOWNLOAD_CACHE=0这个参数的意义是让 pip 在安装大量包时不用本地缓存,减少 I/O 和磁盘占用,但它的主要作用是降低部分环境下的安装失败概率。如果内存确实不够,最稳妥的办法还是销毁虚机重新创建,用更大的内存配置。不要试图在一台 4GB 虚机上通过各种小技巧硬撑,DevStack 跑起来之后的日常运行也需要内存,勉强通过安装阶段不代表后面能用。
5.3 失败位置三:某一步报错,但不知道卡在哪
DevStack 有一个非常友好的特性:它每一步都有日志输出,并且会把详细的日志写在/opt/stack/logs目录下。如果你发现屏幕上某个服务启动失败,先去这个目录里找对应的日志文件。
最典型的排查路径是:
ls /opt/stack/logs/ tail -n 100 /opt/stack/logs/n-api.log比如 Nova 的 API 服务日志里如果出现503 Service Unavailable,多半是因为 Keystone 还没就绪或者服务账号密码配置不一致。这时候去查 Keystone 的日志,确认 token 机制是否正常。日志文件是唯一能准确反映真实状态的信息源,不要在终端一堆输出里瞎猜。
5.4 失败之后的正确姿势:re-run 还是 clean 重来
这是新手最容易纠结的问题。
./stack.sh并不是一次性脚本,它内部对每个步骤有状态标记。如果安装中途失败,你修复了问题之后再次执行./stack.sh,它会跳过已经完成的步骤,从失败的位置继续。这是 DevStack 设计上非常体贴的一点,也意味着大部分失败场景不需要销毁重来。
但如果错误是深层级的,比如本地 Python 环境被弄坏了,或者某一步改写了系统级配置导致后续步骤无法进行,那继续./stack.sh可能只是在同一个地方反复报错。这时候的清理命令是:
./clean.sh它会停止所有 OpenStack 服务并清掉大部分数据。注意,clean.sh 并不保证让你的环境恢复到安装前的状态,如果 clean 之后重新安装仍然失败,那就直接销毁虚机重建最快:
multipass delete devstack-node && multipass purge然后再重新执行第 3 章的建虚机命令。这其实就是 Multipass 方案最大的优势,推倒重来的成本极低,不会有“装坏了机器”的心理负担。
6. 安装完成后的第一轮验证:确认所有服务真的活着
6.1 命令行层级的验证
安装完成后,screen 会话中会挂着所有服务的进程,但为了确认它们从系统层面真的注册成功了,还是要进入命令行验证。
先加载 admin 环境变量:
source openrc admin admin这个脚本会设置OS_AUTH_URL、OS_USERNAME等环境变量,让openstack命令行工具知道你连接的 Keystone 地址和身份。
然后执行:
openstack service list会看到类似下面的输出:
+----------------------------------+----------+---------------+ | ID | Name | Type | +----------------------------------+----------+---------------+ | ... | glance | image | | ... | keystone | identity | | ... | neutron | network | | ... | nova | compute | +----------------------------------+----------+---------------+看到这些服务类型全部处在正常状态,说明 Keystone 的注册信息没有问题了。接着验证 Nova 和 Neutron 是否就绪:
openstack compute service list openstack network agent list第一条命令对应的输出里,每个服务应该都是enabled和up状态;第二条命令里的 agent 状态也应该是:-)表示存活。
6.2 浏览器访问 Horizon 面板
Horizon 默认运行在虚机的 80 端口,路径是/dashboard。在宿主机浏览器直接访问:
http://<虚机IP>/dashboard但前提是 Multipass 的 NAT 网络模式下宿主机能直接访问虚机的这个 IP,默认是可以的。在这个页面用admin和你在 local.conf 里设置的ADMIN_PASSWORD登录。
登录后会看到一个横向的导航栏,包含“项目”、“管理员”、“身份”等菜单。在这个界面,你不需要急着点一堆按钮,先点“管理员 -> 系统 -> 服务”看一眼,确认所有 service 都在启用状态。这一步的意义是验证 Horizon 到 Keystone 和各个服务的 API 连通性,如果某一行显示异常,说明后端对应的服务有问题,需要回日志里查。
6.3 创建第一台测试实例的完整链路
建议完整走一遍创建实例的流程,因为这是对整条链路的最终检阅。步骤分五步:
第一步,上传镜像到 Glance:
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img openstack image create "Ubuntu 22.04" \ --file jammy-server-cloudimg-amd64.img \ --disk-format qcow2 --container-format bare \ --public第二步,创建 flavor:
openstack flavor create --vcpus 1 --ram 512 --disk 2 m1.tiny第三步,创建网络。这一步很关键,DevStack 默认会创建一个名为 private 的私有网络,但如果你之前手动修改过网络配置,可能有差异。先查一下:
openstack network list如果有private网络,直接复用它;如果没有,则:
openstack network create private openstack subnet create --network private --subnet-range 192.168.200.0/24 private-subnet第四步,创建一个安全组并放行 ICMP 和 SSH。步骤是为了你后面能 ping 通实例、用 SSH 登录:
openstack security group create basic openstack security group rule create --proto icmp basic openstack security group rule create --proto tcp --dst-port 22 basic第五步,创建实例并绑定浮动 IP:
openstack server create --flavor m1.tiny --image "Ubuntu 22.04" --network private --security-group basic test-instance openstack floating ip create public openstack server add floating ip test-instance <floatIP>从接下来这一连串命令能跑通且实例状态变成ACTIVE,就意味着从镜像服务、网络服务、计算服务到认证服务,整条链路的 L2、L3 转发与调度功能都工作了。我建议你走到这一步再算真正“装完了”,因为有很多案例是服务列表看起来全绿,但实际创建实例时网络组件的流表规则没下发成功,导致实例无法拿到 IP。
7. 高频问题速查:报错信息到解决动作的一张表
| 现象 | 可能原因 | 排查/解决动作 |
|---|---|---|
apt update超时或找不到源 | 虚机 DNS 配置不正确 | 检查 /etc/resolv.conf,添加nameserver 8.8.8.8后重试 |
clone 源码时Could not resolve host | DNS 或网络受限 | 确保虚机外网连通后再重跑 stack.sh,或换 GIT_BASE 镜像仓库 |
安装过程中Killed | 虚机内存不足 | 查看 /opt/stack/logs 下对应日志,如确认 OOM 则销毁重建更大内存虚机 |
openstack service list缺少某个服务 | 安装中断或失败 | 重跑 ./stack.sh,让它从失败点继续;如反复失败则 clean.sh 后重装 |
| Horizon 无法打开 | 网络或服务未启动 | 先curl -I http://<虚机IP>/dashboard,再确认 horizon 服务日志 |
openstack server create后实例一直 ERROR | 镜像格式不对或资源不足 | 查看 nova 的 conductor 日志,确认镜像是否损坏,检查 vCPU 和内存剩余 |
| 无法 ping 通 / SSH 登录实例 | 安全组规则缺失 | 检查安全组规则,放行 ICMP 和 22 端口 |
multipass launch慢 | 镜像下载慢 | 查看 Multipass 镜像源配置,确认是否能切换平台镜像加速 |
| 安装错版本(如 24.04 下编译失败) | 发行版适配问题 | 彻底销毁虚机,用--release 22.04重新创建 |
8. 最后再说几点使用中的体会
我的建议是:别急着在生产环境折腾 OpenStack,先在本地用 DevStack 把“部署、验证、排错”这套循环跑顺。这样你后续再接触生产级方案时,起码对整体架构和各个服务之间有真实的感知。而且 Multipass 这个底层工具的熟悉度本身也很有价值,它不只是用来跑 OpenStack,日常做任何 Ubuntu 测试环境都可以用它快速拉起一个干净环境。
如果你第一次跑 DevStack 失败了,不用觉得是自己操作不对。这个项目本身就是给开发者快速迭代用的,日志和工作流的设计都默认了你会有多次折腾的过程。学会看/opt/stack/logs里的日志、学会理解local.conf每个参数的作用,比单纯跑通一次脚本价值高得多。等你能不看教程独立完成一次从建机到创建实例的全流程,这套环境就真正变成你自己的工具箱了。