☰
Ubuntu 18.04 单节点 DevStack 部署 OpenStack 最新版实战指南
2026/10/15 12:57:15 网站建设 项目流程

1. 为什么还要折腾 DevStack 单节点部署

先把话说在前头:如果你只是想快速体验一下 OpenStack 的界面长什么样,那用官方打包好的发行版或者容器化方案会省事得多。但如果你是真的想搞明白 OpenStack 各个组件之间到底怎么串起来的、Keystone 怎么发令牌、Nova 怎么调度虚拟机、Neutron 怎么把网络打通,那 DevStack 依然是目前最直接的一条路。它本质上就是一套 Shell 脚本集合,把 OpenStack 所有核心服务的源码从代码仓库拉下来,在本机直接跑起来,不走打包、不走容器,所有配置文件、日志、进程都摊在你面前,出问题了你能一层层扒开看。

我这次的环境是 Ubuntu 18.04 LTS,这个版本虽然不算新,但胜在稳定,社区里大量文档和踩坑记录都是基于它写的,遇到问题容易搜到答案。目标是在一台机器上把单节点 OpenStack 跑起来,版本走 master 分支,也就是所谓的"最新版本"。这里要提醒一句,DevStack 的 master 分支是跟着 OpenStack 开发节奏走的,今天能跑通不代表下周还能跑通,所以如果你追求可复现,最好在跑通之后把当时拉下来的各个仓库 commit 记录下来。

单节点部署意味着所有角色——控制节点、网络节点、计算节点——全部挤在一台机器上。好处是省资源、结构简单;坏处是资源竞争严重,尤其是内存和 CPU,配置不够的话跑起来会非常卡,甚至服务起不来。所以下面我会先讲清楚硬件和系统层面的准备,再进入具体的安装流程。

这篇文章适合两类人:一类是刚接触 OpenStack、想动手把整套东西跑起来看看的运维或开发;另一类是已经用过 OpenStack 但没自己从源码装过、想搞清楚底层细节的人。我会把每一步为什么这么做讲清楚,包括参数怎么算、坑在哪里,尽量让你照着做能复现出来。

2. 环境准备与系统层面的取舍

2.1 硬件资源的实际需求估算

DevStack 官方文档里给的最低配置看起来不高,但那是"能启动"的底线,不是"能用"的配置。我实测下来,单节点跑全套核心服务,比较舒服的配置是这样的:

资源项最低能跑推荐配置说明
CPU2 核4 核及以上Nova 调度、Neutron 转发都吃 CPU
内存8 GB16 GB内存不足是最常见的失败原因
磁盘40 GB60 GB 以上镜像、实例、日志都占空间
网卡1 张2 张更佳单网卡也能跑,但网络配置受限

为什么内存这么关键?因为 OpenStack 核心组件加起来,光是 Python 进程就有几十个,每个 MySQL 连接、每个 RabbitMQ 队列、每个 API 服务的 WSGI worker 都要占内存。8 GB 是勉强能起来的水平,一旦你创建实例,内存马上吃紧。16 GB 能让你在跑起来之后还有余量做实验。

磁盘方面,除了系统本身,DevStack 会把源码放在/opt/stack,Glance 镜像默认存在/opt/stack/data/glance,Nova 实例存在/opt/stack/data/nova。一个 Cirros 镜像才十几 MB,但你要是传个 Ubuntu 云镜像,动辄几百 MB 到 1 GB,再加上实例的磁盘文件,40 GB 很快就满了。

2.2 系统安装时的分区与网络建议

装 Ubuntu 18.04 的时候,我建议手动分区,给/opt单独留一块大空间,因为 DevStack 的东西基本都堆在/opt/stack。如果你用默认的 LVM 自动分区,根分区可能只有几十 GB,后面容易爆。

网络这块,单网卡也能跑,但你要接受一个现实:DevStack 默认会创建一个 Linux bridge,把物理网卡挂上去,然后给你的机器配一个浮动 IP 段。如果你只有一张网卡,而且是通过 SSH 远程连上去操作的,那在 DevStack 配置网络的过程中,你的 SSH 连接很可能会断掉。所以我的做法是:要么直接在虚拟机控制台里操作,要么配两张网卡,一张管理、一张给 OpenStack 用。

提示:如果你是在云主机或者虚拟化环境里装,务必确认你的环境支持嵌套虚拟化,否则 Nova 起不来 KVM 加速,实例只能用 QEMU 软件模拟,慢到怀疑人生。

2.3 系统更新与基础依赖

装完系统第一件事,更新软件源并升级:

sudo apt update sudo apt upgrade -y

然后装一批基础工具,这些在后面排查问题时会用到:

sudo apt install -y git curl wget vim net-tools bridge-utils \ python3-pip python3-dev build-essential

这里解释一下为什么装这些。git是拉源码用的,DevStack 本身就是从 git 仓库克隆下来的;bridge-utils用来查看和管理网桥,Neutron 会创建大量网桥,没这个工具你连brctl show都跑不了;python3-dev和build-essential是因为有些 Python 包需要编译 C 扩展,缺了编译工具会直接报错。

2.4 创建专用用户与免密 sudo

DevStack 强烈建议用一个非 root 的专用用户来跑,官方推荐叫stack。原因很简单:DevStack 会往这个用户的家目录写大量东西,而且很多操作需要 sudo 权限,用 root 跑反而容易出权限混乱的问题。

sudo useradd -s /bin/bash -d /opt/stack -m stack sudo passwd stack echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack sudo chmod 0440 /etc/sudoers.d/stack

NOPASSWD这一行很关键,因为 DevStack 脚本里会频繁调用 sudo,如果每次都要求输密码,脚本会卡住。配好之后切换到 stack 用户:

sudo su - stack

3. DevStack 的获取与核心配置解析

3.1 拉取 DevStack 源码

用 stack 用户操作,先克隆 DevStack 仓库:

git clone https://opendev.org/openstack/devstack cd devstack

这里有个细节:默认克隆的是 master 分支,也就是最新开发版。如果你想用某个稳定版本,可以git checkout stable/xxx,但既然标题说的是"最新版本",我们就留在 master。克隆下来之后,你可以git log -1看一下当前是哪个 commit,记下来,方便以后复现。

3.2 local.conf 的编写逻辑

DevStack 的所有配置都集中在一个叫local.conf的文件里,放在 devstack 目录下。这个文件不写的话,DevStack 会用一堆默认值,但默认值往往不适合单节点实验环境,所以我们必须自己写一份。

先看一份我实测可用的配置:

[[local|localrc]] ADMIN_PASSWORD=secret DATABASE_PASSWORD=$ADMIN_PASSWORD RABBIT_PASSWORD=$ADMIN_PASSWORD SERVICE_PASSWORD=$ADMIN_PASSWORD HOST_IP=192.168.1.100 # 关闭不需要的服务,节省资源 disable_service tempest disable_service cinder disable_service swift # 启用核心服务 enable_service n-api,n-cpu,n-cond,n-sch,n-novnc,n-crt enable_service q-svc,q-agt,q-dhcp,q-l3,q-meta enable_service horizon # 日志 LOGFILE=$DEST/logs/stack.sh.log LOGDAYS=2

逐条解释一下。最上面四个密码,DevStack 要求至少设置ADMIN_PASSWORD,其他几个如果引用它,就统一了,省得记一堆。HOST_IP必须写你本机实际的 IP,不能写 127.0.0.1,因为 OpenStack 各服务之间要通过这个 IP 通信,写回环地址会导致服务互相连不上。

disable_service这几行是资源优化的关键。Tempest 是测试套件,跑起来很吃资源,实验阶段可以先关掉;Cinder 是块存储,Swift 是对象存储,如果你不做存储相关实验,关掉能省下不少内存和端口。核心的 Nova、Neutron、Keystone、Glance、Horizon 保留。

enable_service里那些缩写对应的是各个服务的具体进程,比如n-api是 Nova API,q-svc是 Neutron Server,q-l3是三层代理。这些名字在 DevStack 的lib/目录下有定义,写错了会直接报"unknown service"。

3.3 网络配置的坑与选择

单节点网络是最容易出问题的地方。DevStack 默认会尝试用你的物理网卡做网桥,如果你的机器是远程 SSH 连着的,这一步会断网。有两种应对方式:

第一种是配一张不用的网卡专门给 OpenStack,在local.conf里指定:

PUBLIC_INTERFACE=eth1

第二种是用NEUTRON_CREATE_INITIAL_NETWORKS=False先不让它自动建网络,等装完了手动配。我一般用第一种,前提是机器上确实有第二张网卡。

还有一个参数FLOATING_RANGE,默认是172.24.4.0/24,这是给实例分配浮动 IP 用的网段。如果你本机网络跟这个段冲突,要改掉,否则路由会乱。

4. 执行安装与过程监控

4.1 启动 stack.sh 与预期耗时

配置写好之后,直接跑:

./stack.sh

这个过程第一次跑通常要 20 到 40 分钟,取决于网络速度和机器性能。它会依次做这些事:装系统依赖包、从 git 拉各个 OpenStack 组件的源码、装 Python 依赖、初始化数据库、启动各个服务、创建默认的网络和镜像。

我建议你开两个终端,一个跑stack.sh,另一个用tail -f /opt/stack/logs/stack.sh.log实时看日志。因为stack.sh的输出有时候会刷得很快,关键错误一闪而过,看日志文件更靠谱。

4.2 安装过程中的关键节点

整个安装过程有几个关键节点,你可以对照日志判断进度:

  • 依赖安装阶段:会看到大量apt install的输出,这一步慢是正常的,尤其是国内网络环境。
  • 源码克隆阶段:会逐个克隆 Nova、Neutron、Keystone 等仓库,每个仓库几百 MB。
  • 数据库初始化:会看到keystone-manage db_sync之类的命令。
  • 服务启动:会看到systemctl start或者直接screen会话的创建。

DevStack 默认用screen来管理各个服务的进程,装完之后你可以screen -ls看到一堆会话,每个会话对应一个服务。想进某个服务的控制台看输出,就screen -r 会话名,退出用Ctrl+A然后按D。

4.3 安装成功的标志

当你在终端看到类似这样的输出,基本就成功了:

This is your host IP address: 192.168.1.100 This is your host IPv6 address: ::1 Horizon is now available at http://192.168.1.100/dashboard Keystone is serving at http://192.168.1.100/identity/ The default users are: admin and demo The password: secret

这时候打开浏览器,访问那个 Horizon 地址,用 admin / secret 登录,能看到 OpenStack 的仪表盘,就说明整套东西跑起来了。

5. 安装后的验证与基本操作

5.1 用命令行验证各服务状态

光看界面还不够,我习惯用命令行确认一遍。先加载环境变量:

source /opt/stack/devstack/openrc admin admin

然后逐个检查:

openstack service list openstack endpoint list openstack network agent list openstack compute service list

service list能看到所有注册的服务,endpoint list能看到各个服务的访问端点,network agent list里所有 agent 应该是Alive状态,compute service list里 nova-compute 应该是enabled且up。

5.2 创建第一个实例的完整流程

验证服务没问题后,走一遍创建实例的流程,这是检验整套系统是否真正可用的最好方式。

先下载一个测试镜像:

wget http://download.cirros-cloud.net/0.5.2/cirros-0.5.2-x86_64-disk.img openstack image create "cirros" \ --file cirros-0.5.2-x86_64-disk.img \ --disk-format qcow2 --container-format bare --public

然后创建网络、子网、路由:

openstack network create demo-net openstack subnet create --network demo-net \ --subnet-range 10.0.0.0/24 demo-subnet openstack router create demo-router openstack router set demo-router --external-gateway public openstack router add subnet demo-router demo-subnet

最后创建实例:

openstack flavor create --ram 512 --disk 1 --vcpus 1 m1.tiny openstack keypair create demo-key > demo-key.pem chmod 600 demo-key.pem openstack server create --flavor m1.tiny --image cirros \ --nic net-id=$(openstack network show demo-net -f value -c id) \ --key-name demo-key demo-instance

创建完用openstack server list看状态,从BUILD变成ACTIVE就成功了。想 SSH 进去的话,先分配浮动 IP:

openstack floating ip create public openstack server add floating ip demo-instance <浮动IP>

然后用ssh -i demo-key.pem cirros@<浮动IP>登录,密码是gocubsgo。

6. 常见问题与排查技巧实录

6.1 安装失败的典型原因速查

现象可能原因排查方向
stack.sh 中途退出依赖装不上看日志里 apt 报错,检查网络源
服务起不来端口被占netstat -tlnp看端口冲突
数据库连不上MySQL 没起来systemctl status mysql
实例一直 BUILD计算节点异常看 nova-compute 日志
网络不通网桥配置错brctl show看网桥

6.2 几个我踩过的坑

第一个坑是HOST_IP写错。我有一次图省事写了127.0.0.1,结果 Keystone 能起来,但 Nova 连不上它,因为 Nova 拿到的 endpoint 是回环地址,跨进程通信就废了。这个错误很隐蔽,因为服务本身不报错,只是互相调不通。

第二个坑是内存不够导致 OOM。8 GB 的机器跑全套,创建实例的时候经常触发 OOM Killer,把 MySQL 或者 RabbitMQ 干掉。解决办法要么加内存,要么在local.conf里关掉更多服务,比如把 Horizon 也关了,纯命令行操作。

第三个坑是重装。DevStack 装失败之后,直接重跑stack.sh往往还是失败,因为残留的配置和数据库会干扰。正确做法是先./unstack.sh清理,再./clean.sh彻底清,然后重新跑。clean.sh会把/opt/stack下的数据都删掉,慎用但有效。

6.3 日志排查的通用思路

OpenStack 的日志分散在各个服务的目录下,比如/var/log/nova/、/var/log/neutron/、/var/log/keystone/。排查问题的通用思路是:先看 API 服务的日志,找到报错的请求 ID,然后拿这个 ID 去其他服务的日志里搜,就能串起整个调用链。

比如创建实例失败,先在/var/log/nova/nova-api.log里找到报错,记下 request-id,然后去nova-conductor.log、nova-scheduler.log、nova-compute.log里搜同一个 ID,就能看到请求在哪一步断掉的。

7. 资源优化与后续扩展方向

7.1 让单节点跑得更流畅的调整

跑起来之后,如果你觉得卡,可以做一些优化。首先是关掉不用的服务,前面已经关了 Cinder 和 Swift,如果还卡,可以把 Horizon 也关了,用命令行操作。其次是调整 MySQL 的配置,默认的innodb_buffer_pool_size很小,可以适当调大。还有就是限制 Nova 的并发,在nova.conf里把workers调小。

另外,DevStack 默认会创建一堆默认网络和路由,如果你不做网络实验,可以在local.conf里加NEUTRON_CREATE_INITIAL_NETWORKS=False,省掉这部分开销。

7.2 从单节点到多节点的思路

单节点跑通之后,如果你想扩展成多节点,核心思路是把计算节点拆出去。控制节点上跑 Keystone、Glance、Nova API、Neutron Server,计算节点上只跑 nova-compute 和 neutron-agent。两边通过local.conf里的HOST_IP和SERVICE_HOST参数关联。这个扩展过程本身就是一个很好的学习路径,能让你真正理解 OpenStack 的分布式架构。

7.3 版本升级与回滚的注意事项

DevStack 的 master 分支更新很频繁,如果你git pull之后重跑stack.sh,可能会因为代码变动导致失败。我的建议是,跑通一个版本之后,把 devstack 目录和/opt/stack下各个组件的 commit 都记录下来,需要升级的时候再整体更新。如果升级失败想回滚,就git checkout回原来的 commit,然后./unstack.sh && ./stack.sh重来。

我个人在实际操作中的体会是,DevStack 最大的价值不在于"装好了能用",而在于"装的过程逼着你去理解每个组件"。每次失败、每次看日志、每次改配置,都是在加深对 OpenStack 的理解。所以别怕它报错,报错才是学习的机会。最后再分享一个小技巧:把每次成功的local.conf和当时的 commit 记录存一份,下次重装直接抄,能省下大量试错时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询