
老早以前我就想写一篇这样的文章因为每次向人推荐 OpenStack 入门方案最后都会被复杂安装劝退。直到我折腾出一套组合才觉得这事终于能坐下来好好聊聊了。这套组合就是 DevStack Multipass用 Multipass 快速拉起来一台 Ubuntu 虚拟机再在虚拟机里跑 DevStack 的 stack.sh 脚本把 OpenStack 的核心服务一次性部署好。整个流程下来不用准备几台物理机不用折腾复杂的自动化运维工具一个普通的笔记本就能跑起来。为什么要写这个主题因为很多人搞 OpenStack 学习第一步就卡在“装不上”。官方生产部署一般推荐 kolla-ansible 或者 TripleO但这些东西为了生产环境考虑了太多因素参数多、依赖重、对机器要求高用来学习完全是杀鸡用牛刀。DevStack 是 OpenStack 社区官方维护的开发测试脚本它的定位就是在单一节点上快速拉起一个可用的 OpenStack 环境非常适合学习、试验和 CI 验证。而 Multipass 负责提供一个干净、可销毁的宿主机环境让整个流程可复现。这篇文章适合三类人一是刚开始学 OpenStack、想先跑起来看看它长什么样的开发者二是需要在本地方便地做二次开发测试的工程人员三是准备给学生或同事做培训、希望有一套“照着敲就能成功”的教学环境的人。我会从装 Multipass 开始一步步走到创建第一台云主机并把我踩过的坑和一些排查思路都整理出来。1. 项目概述与方案选型1.1 为什么本地学习 OpenStack 首选 DevStackDevStack 本质是一组 Bash 脚本核心文件是 stack.sh。运行它时脚本会去拉取 OpenStack 各个服务项目的代码然后自动完成依赖安装、数据库初始化、Keystone 服务注册、Nova/Neutron/Glance 等服务的配置和启动。整个过程像是一个“自动化安装向导”把生产环境需要手工做的步骤全部封装起来了。这里要敲个重点DevStack 不是生产环境方案这一点从名字就看得出来“Dev”是 Development。它默认会开很多调试开关日志也打得非常详细所有服务都跑在同一个节点上网络、存储、认证全部是简化模式。但恰恰是这种“简化”让它成为理解 OpenStack 组件协作关系的最好教材。通过它跑起来的 OpenStack服务清单、配置文件、数据库都可以清晰地查到想深入看哪个组件都可以直接去看代码。相比那些容器化部署DevStack 让你能直接看到每个服务的真实进程这对学习非常友好。另外DevStack 还带了一堆方便调试的功能比如./unstack.sh可以快速停掉所有服务./clean.sh可以清空安装数据改完代码后重新跑一遍 stack.sh 就能让环境回到最新状态。做开发测试时这种“随时推倒重来”的能力非常宝贵。实际工程项目里我也用 DevStack 做 CI 环境的临时节点跑完就销毁成本极低。1.2 为什么用 Multipass 而不是传统虚拟机有人会问为什么不直接在电脑上装一台 VirtualBox 虚拟机再用它来跑 DevStack其实完全可以我以前也这么干过但体验差不少。Multipass 是 Canonical 官方出的轻量级虚拟机管理工具它直接调用宿主机底层的虚拟化能力比如 macOS 的 HyperKit、Windows 的 Hyper-V以及 Linux 的 KVM命令式管理虚拟机比手动点 VirtualBox 的图形界面利索得多。Multipass 最大的好处有两个启动快、占用低。它使用的是精简过的 Ubuntu Cloud 镜像通常十几秒就能把一台配置好的 Ubuntu 虚拟机拉起来而且支持在命令行直接指定 CPU、内存、磁盘大小对硬件资源的使用非常可控。配合multipass launch一条命令就能创建出一台干净的 Ubuntu 环境。对比更重的 VagrantMultipass 的命令集更简单和系统集成更自然。尤其当你想给多个同学或同事出一份统一的实验环境时只要把几条multipass命令和一份local.conf发出去大家克隆下来就能跑不会出现“我这边三步五步好了你那边莫名其妙起不来”的尴尬。可复现性是我在标题里特意强调“可复现指南”的原因。1.3 这套组合的完整工作链路用一张图来理解整个安装链路脑补文字版宿主机你的笔记本/台式机通过 Multipass 启动一台 Ubuntu VM在 VM 内部下载 DevStack 代码并配置 local.conf执行 stack.sh 后VM 就变成一个 all-in-one 的 OpenStack 节点里面同时跑着 Keystone、Glance、Nova、Neutron、Horizon 等核心服务宿主机通过浏览器访问 VM 的 IP 加/dashboard路径打开 Horizon 控制台也可以通过 SSH 进入 VM 使用命令行工具。这个链路里的每一步都可以抽出来单独复现。Multipass 的 VM 规格、local.conf 的配置、后续安装命令都是声明式的。也就是说只要你在同一套硬件环境和网络条件下按这同一份指南操作大概率能拿到相同的结果。这也是我想强调“可复现”的价值——不是玄学而是可以照着抄的作业。2. 环境准备从安装 Multipass 到初始化虚拟机2.1 Windows/macOS/Linux 安装 Multipass 的几种方式Multipass 的安装并没有太多坑但不同平台还是有点区别。Windows 上安装 Multipass 之前要先确认系统已经开启了 Hyper-V 或 WSL2 底层。安装包可以从官网下载也可以用winget install Canonical.Multipass来装。装好以后打开 PowerShell 或者 CMD输入multipass version能看到版本号就算成功。macOS 上最简单的方式是brew install --cask multipass或者直接从官网下载 pkg 安装包。如果机器比较老可能要注意 Multipass 对虚拟化框架的要求不过 M 系列芯片和 Intel 芯片都能跑只是底层驱动不同。Linux 上推荐用 snapsudo snap install multipass它会自动处理依赖。安装完以后不管哪个平台都可以先跑multipass list看看当前有哪些虚拟机刚装好时应该是空的。如果你在 Windows 上碰见“不支持的虚拟化”报错多半是 Hyper-V 没开或者和别的虚拟化软件冲突需要在“启用或关闭 Windows 功能”里把 Hyper-V 勾选上然后重启。这块我会在后面的坑位里细说。2.2 创建一台足够跑 OpenStack 的 Ubuntu 虚拟机DevStack 是个资源大户虽然 OpenStack 各个服务都压缩在一台机器上但它内部还是有消息队列、数据库、镜像服务、网络代理等一堆进程。所以给虚拟机的配置不要太抠我的建议是最低给 4 核 CPU、8GB 内存、50GB 磁盘。如果你的宿主机内存只有 16GB给虚拟机 8GB 后还剩 8GB 给本机基本够用如果只有 8GB 内存建议把 swap 加上再试否则很容易中途 OOM。创建虚拟机只需要一条命令multipass launch -n devstack -c 4 -m 8G -d 50G 22.04这里-n是虚拟机名字-c指定 CPU 核数-m指定内存-d指定磁盘大小最后的22.04是 Ubuntu 版本代号。我推荐用 22.04 LTS后续的 OpenStack 版本兼容性比较好。命令执行后Multipass 会自动下载对应镜像并启动第一次会慢一些之后再用同样镜像就是秒级启动。创建完成后先用multipass list查看 VM 状态和 IP 地址再用multipass shell devstack进入虚拟机。这里提醒一下VM 的默认用户名就是ubuntu密码不是重点因为 Multipass 会配置好 SSH 密钥所以你也可以直接用multipass exec devstack -- bash -c uname -a这种宿主机直调方式在 VM 里执行命令。2.3 进入 VM 后的基础环境整理进入虚拟机后第一件事是更新软件包索引和升级已有软件sudo apt update sudo apt upgrade -y这一步最好做完因为 DevStack 在安装时会安装很多依赖如果基础系统本身不干净很容易出现装到一半因为某个旧包报错。接下来要确认几个基础工具是否就位sudo apt install -y git python3 python3-pip另外如果你的网络环境访问 GitHub 和 PyPI 比较慢可以在 VM 里配置好国内的 pip 镜像源和 git 镜像再往下走。这里不展开太多但是我可以给一个 pip 加速的简单做法创建或修改~/.pip/pip.conf写入[global]和指向你习惯的镜像源的index-url。这样后面stack.sh下载 Python 依赖会快很多省得反复超时。DevStack 建议用一个非 root 且有 sudo 权限的用户来安装。Multipass 默认的ubuntu用户正好满足要求。注意不要在 root 下直接跑 stack.sh脚本里会有检查建议用普通用户跑。接下来我们就以ubuntu用户身份把 DevStack 目录 clone 到主目录下。3. DevStack 核心配置与安装过程3.1 拉取 DevStack 代码并选择 OpenStack 版本先回到ubuntu用户主目录执行git clone https://opendev.org/openstack/devstack cd devstack这里拉的是默认分支通常是 master。对于学习环境我更推荐签出到稳定的发布分支比如stable/2024.1或stable/2023.2。稳定分支和默认分支的区别在于前者经过了发布测试组件之间的版本匹配更可靠踩到兼容性坑的概率低很多。签出分支的命令git checkout stable/2024.1如果你想安装特定组件的最新代码也可以不签出分支直接在 master 上跑但那样就要接受“不确定性”。我在实际使用中发现跟着稳定的 OpenStack 版本走是最省心的因为社区文档、各组件依赖关系都围绕着发布版本做过验证。另外devstack目录里除了 stack.sh还有samples/local.conf示例文件我们可以拿它作为配置模板。3.2 local.conf 里的密码、IP 与服务裁剪local.conf 是 DevStack 的灵魂它决定了这个 OpenStack 环境长什么样。在 devstack 目录下新建一个文件名字就叫local.conf。我的最小配置是这样[[local|localrc]] ADMIN_PASSWORDadmin123 DATABASE_PASSWORD$ADMIN_PASSWORD RABBIT_PASSWORD$ADMIN_PASSWORD SERVICE_PASSWORD$ADMIN_PASSWORD HOST_IP192.168.64.10这里我把所有密码都指向ADMIN_PASSWORD方便记忆。密码不要包含$、#、这类会被 shell 解释的字符否则脚本会凌乱。HOST_IP就是虚拟机的 IP可以通过multipass info devstack查到最好手动写死避免 DevStack 自动检测的时候选错网卡。默认配置会启用很多服务包括 Cinder、Swift、Tempest 等。对于只想体验核心 OpenStack 功能的人来说这些服务不仅拖慢安装还占用大量内存和磁盘。所以我习惯把它们关掉[[local|localrc]] ... disable_service tempest disable_service cinder c-sch c-api c-vol disable_service swift这样保留 Keystone、Glance、Nova、Placement、Neutron、Horizon足够用来学习和创建云主机了。如果后续想单独开启哪个服务比如想试用对象存储 Swift直接把disable_service swift这行删掉然后重新跑./stack.sh就行。DevStack 这种“按需裁剪服务”的能力是我一直推荐它做学习环境的重要原因。改配置就像搭积木每次重装都能按需组装。3.3 执行 stack.sh 并实时监控日志配置写好后直接运行./stack.sh如果一切顺利脚本会经过依赖安装、源码拉取、数据库初始化、服务注册等阶段整个过程大概 15 到 30 分钟具体时间取决于你的网络速度和宿主机性能。第一次跑的时候建议另开一个终端用下面的命令实时看日志tail -f /home/ubuntu/devstack/logs/stack.sh.log或者直接观察当前终端输出。DevStack 的日志很啰嗦但也很诚实哪一步失败会直接报红色错误信息。安装成功的标志是最后一段提示通常会告诉你This is your host IP address和Horizon is now available at http://IP/dashboard。就算看到这个提示也别急着关终端先在 VM 里等几秒让服务完成健康检查。我之前就有过刚显示成功就去做其他操作结果 Nova 服务还没来得及注册完的情况。多等十秒后面的操作会更顺。4. 安装后的功能验证与第一台云主机4.1 用 openstack CLI 确认核心服务全部在线安装完成后进入 devstack 目录先加载环境变量cd ~/devstack source openrc admin adminopenrc脚本会设置好OS_*系列环境变量让openstack命令知道该往哪个数据中心、哪个租户发请求。执行完以后先查一下认证服务openstack service list正常情况下能看到 keystone、nova、neutron、glance、placement 等服务的条目每一条对应一个服务类型。再顺手查一下组件状态openstack endpoint list openstack compute service list openstack network agent list openstack image list前两个确认认证端点和 Nova 服务状态网络代理列表能让你看到 DHCP、L3、metadata 等 agent 是否都处于 up 状态。如果某个 agent 是 down 的创建出来的云主机大概率没有网络所以这一步最好仔细看。日志在/home/ubuntu/devstack/logs下具体到n-*和q-*这些服务都有单独日志文件。4.2 通过浏览器访问 Horizon 仪表板命令行验证通过后可以再看看 Web 界面。在宿主机浏览器里访问http://虚拟机IP/dashboard会出现一个登录页输入admin和 local.conf 里设置的ADMIN_PASSWORD就能登录。Horizon 是 OpenStack 的官方 Web 面板项目、镜像、网络、实例这些资源都能在界面里看到。第一次登录可能会遇到页面样式加载不全的情况大多数时候是静态文件缓存的问题刷新几遍或者换个无痕窗口就好了。还有个小提醒因为 DevStack 默认是 HTTP浏览器可能提示不安全这是正常的直接继续访问就好。登录后可以先去“项目 → 计算 → 实例”页面看一眼前提环境再继续下一步命令行操作。4.3 从创建网络到拉起第一台实例的完整操作现在开始干正事创建第一台云主机。我们需要分四步创建网络、创建路由、准备镜像和密钥、创建实例。这一步是比较经典的用户链走通了你对 OpenStack 的“租户网络”模型就有体感了。先建一个隔离的专用网络命令如下openstack network create demo-net openstack subnet create --subnet-range 192.168.100.0/24 --network demo-net --dns-nameserver 8.8.8.8 demo-subnet openstack router create demo-router openstack router add subnet demo-router demo-subnet这里我建了一个 24 位掩码的子网用的网段跟 DevStack 默认的public网段不冲突。路由的作用是让这个子网里的实例能和外部通信后面我们还要给路由绑定外部网关。接着准备镜像和密钥。Cirros 是一个专门用来做云主机测试的最小 Linux 镜像只有几十 MB非常适合首次练习openstack image create --disk-format qcow2 --container-format bare --public cirros \ --file /path/to/cirros-0.6.2-x86_64-disk.img如果没有现成镜像文件可以先用wget下载到 VM 里路径替换一下即可。密钥方式我习惯用openstack keypair create mykey mykey.pem然后chmod 600 mykey.pem。这样后面 SSH 登录才能用上。最后创建实例openstack server create --flavor m1.tiny --image cirros --network demo-net \ --key-name mykey demo-instancem1.tiny是 DevStack 默认自带的“微型”规格内存只有 512MB跑 Cirros 完全够用。创建后可以openstack server list查看状态从BUILD变成ACTIVE就表示成功。为了能够从外部访问这台实例还需要给它绑定一个浮动 IP并放行安全组规则openstack floating ip create public openstack server add floating ip demo-instance 浮动IP openstack security group rule create --protocol icmp --ingress default openstack security group rule create --protocol tcp --dst-port 22 --ingress default之后就可以用ping 浮动IP测试连通性了。如果 ping 不通优先检查路由外网网关和安全组规则。5. 常见问题与避坑速查表5.1 内存不足导致的安装中断这是我在本地和远程服务器上跑 DevStack 时遇到最多的失败原因。VM 内存给得太小或者宿主机内存不够stack.sh经常会在编译或者服务启动阶段被系统 OOM Killer 杀掉表现就是日志里直接出现Killed字样后面没有任何明确报错。排查思路很简单先在 VM 里执行dmesg | tail看有没有 out of memory 的记录如果有官方建议是加大内存我实践经验是 8GB 起步才舒服。如果宿主机物理内存确实紧张退而求其次的办法是增加 swap。在 Multipass 创建的 VM 里加 swap 有点绕可以进入 VM 后用 fallocate 创建一块 swap 文件然后挂载启用。另外也可以按上文那样裁剪服务把 Cinder、Swift、Tempest 都禁掉能省下不少常驻内存。5.2 下载超时和依赖拉取失败DevStack 安装过程会从 Git 仓库拉取 OpenStack 各组件的源码也会用 pip 安装大量 Python 依赖。这两个环节最容易因为网络问题导致失败尤其在某些网络环境下默认源可能会很慢。如果你碰到git clone卡住或者pip install超时多半是源访问慢不是脚本问题。应对办法有两个方向。一是配置国内镜像源。git 方面可以用git config --global url.镜像地址.insteadOf https://opendev.org/openstack这样的重写规则pip 方面就是前面提过的pip.conf。DevStack 里很多GIT_BASE变量也可以自定义具体可以看官方文档。二是善用 DevStack 的断点续跑能力——如果安装在中途失败修复网络后直接重新跑./stack.sh它不会重复执行已经完成的步骤会接着往下走。我经常“多跑几次就过去了”。5.3 版本兼容性带来的各种怪问题DevStack 对 Ubuntu 版本、Python 版本和 OpenStack 版本之间的组合是有讲究的。比如 Ubuntu 24.04 用的 Python 3.12如果你硬要跑老的 stable/2023.1 分支可能会碰到 Python 包不兼容的问题。反过来用 Ubuntu 20.04 跑最新的 master 也可能因为 Python 版本太老而报错。所以我的建议是尽量使用官方持续集成中常见的组合例如 Ubuntu 22.04 stable/2024.1这套我用下来很稳。如果你在不太新也不太旧的版本组合上遇到了莫名的 RuntimeError不要急着改代码先在本地看看 DevStack 仓库里有没有相应的 issue 或 patch。很多时候某个版本刚发布社区会有一批兼容性修复只要切换到最新的稳定补丁分支就能解决。另外./clean.sh之后重跑 stack.sh 也是一个万能的“重置键”很多半新不旧的状态都可以通过它恢复。5.4 如何干净地卸载与重建环境本地学习最不缺的就是折腾环境搞坏了怎么办不用慌。在 DevStack 里可以执行./unstack.sh停掉所有服务再执行./clean.sh清理掉安装的数据和编译产物如果还想更彻底直接销毁整个 Multipass 虚拟机就行multipass delete devstack multipass purge之后再创建一台全新的 VM整个过程不过几分钟。这种“大不了重来”的底气正是 Multipass 带来的最大优势。补充一个细节Multipass 的delete只是把 VM 标记为删除需要再执行purge才会真正清掉磁盘上的数据。如果你只是暂时不用可以先multipass stop devstack保留环境下次multipass start devstack继续用。这个习惯能帮你省下很多重复安装的时间。5.5 故障速查表含经验值除了上面的逐条分析我习惯把踩过的坑整理成一张表贴在笔记里遇到问题先对号入座。故障现象可能原因处理办法安装中断日志出现 Killed内存不足触发 OOM增加 VM 内存或关闭 Cinder/Swift/Tempest 服务git clone 阶段卡住网络访问慢配置 git 镜像或本地源重跑 stack.sh 续跑pip install 超时PyPI 速度慢配置 pip 镜像源使用 pip.conf创建实例一直 BUILDNova/Neutron 服务状态异常查看 compute service list 和对应服务日志Horizon 样式加载不全静态文件缓存强制刷新或换无痕窗口端口无法访问安全组未放行添加 ICMP/TCP 安全组规则这张表我后来在团队内部分享时也经常用配合日志定位基本能解决九成以上的安装问题。6. 我实践后的经验与后续玩法6.1 几个让我省时间的操作习惯实践几次之后我摸索出几个提高效率的小习惯。第一每次创建 VM 后我会把 DevStack 的local.conf放到宿主机的一个目录里管理起来然后用multipass mount挂载进 VM。这样重装 VM 时不用重新手写配置直接复制过来就行版本管理也方便。第二不要一直盯着安装日志发呆。stack.sh跑的时候我会同时打开一个终端用top看 VM 的 CPU 和内存变化另一个终端随时准备tail日志。一旦发现内存快满了趁早决定要不要停掉重来不要等 OOM。第三网络相关的参数比如HOST_IP、子网网段首次写好之后不要随意改动否则很容易出现“服务都起来了但网络不通”的玄学问题。6.2 在 DevStack 基础上还能做哪些试验环境跑通之后玩法就多了。你可以试试用 Heat 编排一组多层应用体验一下基础设施即代码也可以把 Cinder 重新启用来练习块存储挂载还可以接入 Octavia 体验负载均衡服务。这些在本地 DevStack 上都能跑只是资源要再宽裕点。如果想把环境分享给团队成员可以写一个简单的启动脚本把multipass launch、git clone、local.conf生成、./stack.sh封装成一条命令大家克隆脚本后一键执行。我在内部培训里就干过这件事效果很好极大降低了新人上手 OpenStack 的门槛。最后再分享一个真实感受别怕环境搞坏本地环境的优势就是可以随意破坏和重建折腾得越多理解得越深。