OpenStack Nova手动安装配置决策地图

📅 2026/7/16 3:18:51
OpenStack Nova手动安装配置决策地图
1. 为什么非得“手动”装 Nova——别被一键脚本惯坏了手Nova 是 OpenStack 云平台的计算服务核心它不是个能点几下鼠标就跑起来的普通软件。你在网上搜到的“手把手教你搭建 OpenStack”“一键部署脚本”“CentOS6.5安装OpenStack脚本”绝大多数在真实生产环境或深度学习场景里第一轮就会卡死脚本默认用 MySQL 8.0但你手头的控制节点是 CentOS 7.9系统源里只有 MySQL 5.7脚本硬编码了 RabbitMQ 的 guest/guest 账号而你刚按安全规范禁用了默认账号更常见的是脚本把所有服务全塞进一个节点等你真想加计算节点时才发现网络配置、证书信任链、服务端口暴露规则全没预留扩展接口。我带过三届云计算方向的实训班每届都有至少 60% 的学生在跑通一键脚本后面对“如何让 Nova 连上另一台物理机作为计算节点”“如何修改默认的 flat 网络为 provider network”“当 nova-compute 启动失败时日志里只显示Failed to bind port该从哪条日志开始查”这类问题直接懵住。原因很简单脚本替你做了所有选择却没让你看见每个选择背后的约束条件和替代方案。手动安装 Nova本质是一次对 OpenStack 架构的“解剖式学习”。你亲手创建数据库、配置 RabbitMQ 用户、生成并分发证书、编辑 12 个以上配置文件、逐条校验服务依赖关系——这个过程不是为了炫技而是为了建立一套可迁移的判断逻辑当某天你在企业私有云里排查一个跨 AZ 的实例调度失败问题时你能立刻意识到这大概率不是 nova-scheduler 的 filter 配置错了而是 nova-conductor 和 nova-api 之间的 RPC 消息队列权限没对齐或者 keystone 的 service catalog 里 compute v2 endpoint 的 region_name 写成了大写的 REGION_ONE 而不是小写的 regionOne。所以这篇内容不叫“Nova 安装教程”它叫“Nova 手动安装与配置的决策地图”。我会带你走完每一步但重点不是命令怎么敲而是告诉你为什么这一步必须在这一步做如果跳过会埋下什么雷当报错信息和文档不一致时该信日志还是信手册这些才是你在“openstack云平台搭建”“openstack知识点”“openstack还有必要学吗”这些热搜词背后真正该拿到手的东西。2. 控制节点的底层地基操作系统、网络与基础服务准备Nova 不是空中楼阁它站在控制节点的操作系统、网络策略和基础中间件三块基石之上。很多初学者栽在第一步不是因为不会敲命令而是没看清这三块基石的“承重能力”。2.1 操作系统选型为什么坚持 CentOS 7.9而不是 Ubuntu 22.04 或 Rocky Linux当前主流 OpenStack 版本Wallaby、Xena、Yoga的官方测试矩阵里CentOS 7.9 仍是兼容性最稳定的发行版。这不是情怀是实测数据我们曾用同一套配置文件在 Ubuntu 22.04 上部署 Nova结果发现 libvirt 默认使用 systemd 的 cgroup v2而 Nova 的资源隔离逻辑大量依赖 cgroup v1 的路径结构如/sys/fs/cgroup/cpu/nova/导致 CPU 配额完全失效而在 Rocky Linux 8.6 上systemd-resolved 服务默认启用它会劫持/etc/resolv.conf造成 nova-api 无法解析 keystone 的域名报错keystoneauth1.exceptions.connection.ConnectFailure: Unable to establish connection to http://controller:5000但日志里根本不会提 DNS只会说“连接超时”。CentOS 7.9 的优势在于三点内核版本锁定3.10.0-1160.el7.x86_64稳定支持 KVM、libvirt、qemu-kvm 的所有关键特性且社区补丁最全Python 环境纯净系统自带 Python 2.7.5虽已 EOL但 OpenStack 的旧版 Nova如 Train 及之前仍强依赖它避免了 Python 3.8 的 asyncio 兼容性陷阱SELinux 策略成熟semanage port -a -t http_port_t -p tcp 8774这类端口标签操作在 CentOS 7 上有完整文档和错误码映射而在较新发行版上SELinux 策略常被默认禁用反而掩盖了真正的权限问题。提示如果你必须用较新系统请务必先确认所用 OpenStack 版本的官方支持矩阵。例如OpenStack Zed 开始全面转向 Python 3.9此时再硬套 CentOS 7 就是自找麻烦。选型的第一原则永远是“版本对齐”而非“最新最好”。2.2 网络规划controller 节点的三张网卡一张都不能少“controller” 这个词在 OpenStack 里不是虚名它意味着这台机器要同时处理三类流量且必须物理或逻辑隔离管理网络Management NetworkNova 服务之间、Nova 与 Keystone/Glance/Neutron 的 API 通信。这是你 SSH 登录、执行openstack server list的通道。必须走固定 IP建议用 10.0.0.0/24 网段。API 网络API Network面向租户的外部访问入口比如用户通过 Horizon 控制台或 openstack CLI 创建虚拟机请求最终落到 controller 的 8774 端口。它需要能被外部网络路由通常绑定在第二张网卡IP 如 192.168.10.10/24。实例网络Instance NetworkNova 为虚拟机分配的浮动 IPFloating IP所归属的网络。它不直接连 controller但 controller 上的 neutron-server 和 l3-agent 必须能路由此网段。典型配置是 172.16.0.0/16网关设为 172.16.0.1。很多实训环境只配一张网卡然后用 VLAN 子接口模拟多网段。这在实验室可行但会带来两个隐形成本iptables 规则爆炸每增加一个子网就要加一条-A INPUT -i eth0.100 -p tcp --dport 8774 -j ACCEPT规则数超过 50 条后iptables-restore加载时间从 0.2 秒飙升到 3 秒Nova 服务启动变慢MTU 错配风险VLAN 子接口的 MTU 默认是 1500但底层物理网卡若启用了 Jumbo Frame9000会导致 nova-network 的 DHCP 请求包被静默丢弃现象是虚拟机获取不到 IP日志里只有dnsmasq: failed to bind DHCP server socket排查时极易误判为 dnsmasq 配置错误。注意在 VMware 虚拟机中配置多网卡时务必检查虚拟交换机的“混杂模式Promiscuous Mode”是否设为“接受”。否则controller 无法收到计算节点发来的 ARP 请求nova-scheduler 将永远找不到可用主机。2.3 基础服务安装MySQL、RabbitMQ、Memcached 的“最小可行配置”Nova 依赖三个基础服务但它们的配置远不止“装上就行”MySQL 5.7.36推荐版本字符集必须强制设为utf8mb4否则当用户给虚拟机起名含 emoji如 -web-server时nova-api 会因Incorrect string value报错退出关键参数调整# 在 /etc/my.cnf 的 [mysqld] 段下添加 innodb_file_per_tableON max_connections1000 wait_timeout28800 character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ciinnodb_file_per_tableON是必须项它让每个表有独立的.ibd文件Nova 的instances表在高并发创建时若共享表空间I/O 争用会直接拖垮整个数据库。RabbitMQ 3.8.27创建 Nova 专用用户权限必须精确到 virtual hostrabbitmqctl add_user nova RABBIT_NOVA_PASS rabbitmqctl add_vhost /openstack rabbitmqctl set_permissions -p /openstack nova .* .* .*注意virtual host 名必须是/openstack不能是/或/nova。Nova 的rabbitmq_hosts配置项默认拼接的是amqp://nova:RABBIT_NOVA_PASScontroller:5672/openstack如果 vhost 名不匹配服务启动时日志只显示Connection closed不会提示 vhost 错误。Memcached 1.4.15启动参数必须包含-l 127.0.0.1,::1即只监听本地 IPv4 和 IPv6。OpenStack 的 token 缓存机制要求 memcached 与 nova-api 进程在同一台机器且不对外暴露。若写成-l 0.0.0.0扫描工具会直接告警“memcached 未授权访问漏洞”。这三步做完用systemctl status mysql rabbitmq-server memcached确认状态为active (running)再执行mysql -u root -p -e SHOW DATABASES;和rabbitmqctl list_vhosts验证服务可连通。跳过验证等于没装。3. Nova 的心脏数据库、用户与 Endpoint 的原子级初始化Nova 的服务注册不是“启动进程”那么简单它是一套基于 Keystone 的身份认证、服务目录和数据持久化的原子操作。任何一步出错后续所有服务都会在启动时卡在“等待 keystone 认证”阶段。3.1 数据库初始化不只是建库更是字符集与权限的精准手术Nova 需要三个数据库nova_api、nova、nova_cell0。很多人以为nova_cell0是可选的这是严重误解。从 OpenStack Train 版本起nova_cell0是强制存在的它存储所有 cell单元的元数据包括cell_mappings和host_mappings表。如果漏建nova-manage db sync会报错Table nova_cell0.cell_mappings doesnt exist且无法通过--local-cell参数绕过。创建命令必须带字符集声明mysql -u root -p -e CREATE DATABASE nova_api CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql -u root -p -e CREATE DATABASE nova CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql -u root -p -e CREATE DATABASE nova_cell0 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;接着是授予权限。这里有个极易踩的坑Nova 的配置文件nova.conf中database.connection项写的是mysqlpymysql://nova:NOVA_DBPASScontroller/nova但很多人在 GRANT 时只给了novalocalhost而 Nova 服务实际连接时用的是novacontroller因为配置里 host 是 controller不是 localhost。正确命令是mysql -u root -p -e GRANT ALL PRIVILEGES ON nova_api.* TO novacontroller IDENTIFIED BY NOVA_DBPASS; mysql -u root -p -e GRANT ALL PRIVILEGES ON nova.* TO novacontroller IDENTIFIED BY NOVA_DBPASS; mysql -u root -p -e GRANT ALL PRIVILEGES ON nova_cell0.* TO novacontroller IDENTIFIED BY NOVA_DBPASS; mysql -u root -p -e FLUSH PRIVILEGES;提示FLUSH PRIVILEGES;不是可选项。MySQL 的权限缓存机制会导致新授权延迟生效Nova 启动时若连不上数据库日志里不会说“权限不足”只会报pymysql.err.OperationalError: (1045, Access denied for user novacontroller)让人误以为密码错了。3.2 Keystone 服务注册Endpoint 的 URL 拼写一个斜杠都不能错Nova 在 Keystone 中注册为compute服务其 Endpoint端点URL 必须严格匹配nova.conf中的osapi_compute_listen和metadata_listen配置。常见错误是 URL 末尾多了一个/比如写成http://controller:8774/v2.1/而实际应该为http://controller:8774/v2.1无结尾斜杠。完整注册流程# 1. 创建 service entity openstack service create --name nova --description OpenStack Compute compute # 2. 创建 public, internal, admin 三个 endpoint # 注意publicurl 和 internalurl 的协议、host、port、path 必须完全一致仅 scheme 可不同http/https openstack endpoint create --region RegionOne compute public http://controller:8774/v2.1 openstack endpoint create --region RegionOne compute internal http://controller:8774/v2.1 openstack endpoint create --region RegionOne compute admin http://controller:8774/v2.1 # 3. 创建 nova 用户并赋予 admin 角色 openstack user create --domain default --password-prompt nova openstack role add --project service --user nova admin验证是否成功openstack endpoint list | grep compute # 应输出三行每行包含 RegionOne、compute、public/internal/admin、http://controller:8774/v2.1如果openstack endpoint list里没有 compute或者 URL 显示为http://controller:8774/v2.1/带斜杠那么nova-api启动后任何openstack server list请求都会返回The resource could not be found.。因为 nova-api 会去 Keystone 查compute的 endpoint拿到错误 URL 后再向那个错误地址发起二次请求自然 404。3.3 Cell 初始化nova-manage 的隐藏开关与 cell0 的不可替代性nova-manage是 Nova 的管理命令行工具它负责数据库同步和 cell 初始化。很多人执行nova-manage db sync后就以为完了其实最关键的一步是nova-manage cell_v2 create_cell。标准流程# 1. 同步主数据库nova 和 nova_api su -s /bin/sh -c nova-manage db sync nova # 2. 创建 cell0必须先于 cell1 su -s /bin/sh -c nova-manage cell_v2 create_cell --namecell0 --verbose nova # 3. 创建 cell1即默认 cell对应 controller 本身 su -s /bin/sh -c nova-manage cell_v2 create_cell --namecell1 --transport-url rabbit://nova:RABBIT_NOVA_PASScontroller:5672/openstack --database-connection mysqlpymysql://nova:NOVA_DBPASScontroller/nova nova # 4. 列出所有 cell确认状态为 up su -s /bin/sh -c nova-manage cell_v2 list_cells novacreate_cell --namecell0这条命令会自动创建nova_cell0数据库的 schema并在nova数据库的cell_mappings表中插入一条记录。如果跳过这步nova-manage cell_v2 list_cells会显示cell0 is not mapped且nova-scheduler无法启动日志报错CellMappingNotFound: Cell mapping not found for cell0。注意--transport-url中的rabbit://协议必须小写RABBIT_NOVA_PASS必须与 RabbitMQ 中设置的密码完全一致包括大小写和特殊字符。我们曾遇到一个案例密码里有一个符号没做 URL 编码导致nova-manage解析 transport-url 时把当作用户名/密码分隔符transport-url 被截断cell1 创建失败。4. Nova 核心服务配置nova.conf 的 12 个关键段落与 37 个必填参数/etc/nova/nova.conf是 Nova 的“宪法”全文 2000 行但真正决定服务能否跑通的是其中 12 个核心段落里的 37 个参数。我把它们按功能归为四类全局标识、数据库与消息队列、API 服务、调度与计算。4.1 全局标识段[DEFAULT]11 个参数的生死线这一段定义 Nova 的“身份证”错一个整个服务拒绝启动。参数必填值为什么必须这样填实测后果transport_urlrabbit://nova:RABBIT_NOVA_PASScontroller:5672/openstack必须与 RabbitMQ 的 vhost 和用户密码完全匹配nova-api启动失败日志Failed to connect to rabbitmqmy_ip10.0.0.11controller 的管理网 IPNova 用它生成本机的host字段scheduler 依据此字段筛选主机若填错nova-scheduler永远找不到 controller 作为候选主机use_neutronTrue启用 Neutron 网络服务禁用已废弃的 nova-network若为 Falseopenstack network list无输出虚拟机无法联网firewall_drivernova.virt.firewall.NoopFirewallDriver在 controller 上禁用 iptables 防火墙驱动计算节点才启用若用默认IptablesFirewallDrivercontroller 会尝试操作不存在的 br-int 网桥报错Device br-int does not existenabled_apisosapi_compute,metadata启用计算 API 和元数据 API禁用已废弃的 ec2api若漏掉metadata虚拟机无法从169.254.169.254获取 metadatacloud-init 失败其他关键参数state_path /var/lib/nova必须指向有写权限的目录chown -R nova:nova /var/lib/novalog_dir /var/log/nova确保/var/log/nova目录存在且属主为 novalock_path /var/lib/nova/tmp分布式锁路径必须是本地磁盘不能是 NFSrpc_response_timeout 180RPC 响应超时调高避免 scheduler 因网络抖动误判主机 downdefault_schedule_zone nova默认可用区必须与openstack availability zone list输出一致4.2 数据库与消息段[api_database]和[database]两套连接字符串的分工Nova 用两个数据库连接[api_database]只读nova_api库用于 API 层快速查询如openstack server list[database]读写nova和nova_cell0库用于持久化实例状态、主机映射等配置示例[api_database] connection mysqlpymysql://nova:NOVA_DBPASScontroller/nova_api [database] connection mysqlpymysql://nova:NOVA_DBPASScontroller/nova致命陷阱很多人把两个 connection 都指向nova库导致nova-api进程在高并发时大量 SELECT 查询阻塞nova库的写操作nova-compute更新实例状态变慢最终触发conductor的 heartbeat timeout实例状态卡在building。4.3 API 服务段[oslo_middleware]和[api]安全与性能的平衡术[oslo_middleware]控制 API 的中间件链[oslo_middleware] enable_proxy_headers_parsing True # 必须开启否则 Horizon 通过反向代理访问时remote_addr 会是 proxy IP而非真实用户 IP[api]段控制 API 服务器行为[api] auth_strategy keystone # 必须为 keystone不能是 noauth2仅测试用 use_forwarded_for True # 启用 X-Forwarded-For配合 nginx 反向代理4.4 调度与计算段[scheduler]和[filter_scheduler]让虚拟机落在正确的地方[scheduler]段指定调度器类型[scheduler] driver nova.scheduler.filter_scheduler.FilterScheduler # 必须是此值其他如 chance_scheduler 已废弃[filter_scheduler]段定义过滤器[filter_scheduler] available_filters nova.scheduler.filters.all_filters enabled_filters RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter # 这是生产环境推荐的最小启用集禁用 RamFilter 和 DiskFilter 可避免因资源统计不准导致调度失败经验ComputeCapabilitiesFilter依赖nova-compute上报的capabilities如果 controller 上没运行nova-compute正常此 filter 会静默跳过。但若你误在 controller 上也启了nova-compute它会上报cpu_info为{arch: x86_64, model: core2duo, ...}而实际计算节点是EPYCscheduler 会因 CPU 模型不匹配拒绝调度。所以controller 上nova-compute服务必须systemctl disable nova-compute。5. 服务启动、日志诊断与“Failed to bind port”类报错的黄金排查链路服务启动不是systemctl start nova-api一下就完事。Nova 由 5 个核心服务组成它们有严格的启动顺序和依赖关系。一次成功的启动必须满足“顺序正确、日志干净、端口就位”三个条件。5.1 五服务启动顺序谁先谁后差一秒都不行Nova 的服务依赖是单向链式nova-api→nova-scheduler→nova-conductor→nova-novncproxy→nova-consoleauthnova-api是入口必须最先启动nova-scheduler依赖nova-api的数据库连接和 RabbitMQ必须在nova-api启动后启动nova-conductor依赖nova-api和nova-scheduler的 RPC 通道必须第三启动nova-novncproxy依赖nova-api和nova-consoleauth必须第四启动nova-consoleauth是最轻量的但它必须在nova-novncproxy之前启动否则 VNC 控制台会提示Authentication failed。启动命令序列systemctl enable openstack-nova-api openstack-nova-scheduler openstack-nova-conductor openstack-nova-novncproxy openstack-nova-consoleauth systemctl start openstack-nova-api sleep 5 systemctl start openstack-nova-scheduler sleep 5 systemctl start openstack-nova-conductor sleep 5 systemctl start openstack-nova-consoleauth sleep 3 systemctl start openstack-nova-novncproxysleep不是摆设。nova-api启动后需要约 3 秒完成数据库连接池初始化和 WSGI 服务器加载nova-scheduler启动时会向 RabbitMQ 发送一条scheduler的 RPC 声明若此时nova-conductor没就绪这条声明会丢失导致后续调度请求无响应。5.2 日志诊断三板斧从journalctl到grep的精准定位当systemctl status openstack-nova-api显示failed不要急着重启。按以下顺序查第一板斧看服务状态详情systemctl status openstack-nova-api -l # -l 参数显示完整日志重点关注最后一行 Process: XXX ExecStart... 后的 error第二板斧查实时 journal 日志journalctl -u openstack-nova-api -f --since 2 minutes ago # -f 实时跟踪--since 限定时间范围避免刷屏第三板斧关键词深度 grep# 查数据库连接错误 grep -n OperationalError\|pymysql /var/log/nova/nova-api.log # 查 RabbitMQ 连接错误 grep -n AMQP\|rabbit /var/log/nova/nova-api.log # 查端口绑定失败最常见 grep -n bind\|address already in use /var/log/nova/nova-api.log5.3 “Failed to bind port 8774” 的完整排查链路从端口到 SELinux这是实训中最高频的报错。表面看是端口被占但根因可能有七种Step 1确认端口是否真被占用ss -tuln | grep :8774 # 若输出为空说明端口空闲问题在 Nova 自身 # 若输出类似 LISTEN 0 128 *:8774 *:* users:((python2,pid1234,fd5))则 pid 1234 占用了Step 2检查 Nova 配置中的监听地址nova.conf中[DEFAULT]段osapi_compute_listen 0.0.0.0 osapi_compute_listen_port 8774 # 必须是 0.0.0.0不能是 127.0.0.1否则只监听本地Step 3检查防火墙firewall-cmd --list-ports | grep 8774 # 若无输出开放端口 firewall-cmd --permanent --add-port8774/tcp firewall-cmd --reloadStep 4检查 SELinux 端口标签semanage port -l | grep http_port_t # 应包含 http_port_t tcp 8774 # 若无添加 semanage port -a -t http_port_t -p tcp 8774Step 5检查 nova-api 进程是否已僵尸化ps aux | grep nova-api | grep -v grep # 若看到多个 python2 进程且 PPID 不是 1说明有残留 pkill -f nova-api rm -f /var/run/nova/nova-api.pidStep 6检查 /var/run/nova 目录权限ls -ld /var/run/nova # 必须是 drwxr-xr-x. 2 nova nova否则 nova-api 无法创建 pid 文件 chown nova:nova /var/run/novaStep 7终极验证——手动启动看报错sudo -u nova /usr/bin/nova-api --config-file /etc/nova/nova.conf # 此命令前台运行错误信息直接打印在终端比 journalctl 更原始、更准确实战心得我在某次实训中ss -tuln | grep :8774显示端口空闲但nova-api死活启动不了。最后用strace -f -e tracebind /usr/bin/nova-api --config-file /etc/nova/nova.conf 21 | grep -i 8774发现bind 系统调用返回EACCES (Permission denied)这才想起 SELinux 的http_port_t标签没加。strace是排查“权限类”报错的终极武器值得每个 OpenStack 从业者掌握。6. 验证与收尾从openstack server list到nova-status upgrade check的闭环检验启动成功只是起点验证才是确认 Nova 真正“活了”的唯一标准。验证必须覆盖 API 可达性、服务健康度、数据一致性三个层面缺一不可。6.1 API 可达性验证curl openstack CLI 的双重保险先用curl绕过 CLI 的封装直击 API# 获取 token curl -i \ -H Content-Type: application/json \ -d { auth: { identity: { methods: [password], password: { user: { name: admin, domain: { name: default }, password: ADMIN_PASS } } }, scope: { project: { name: admin, domain: { name: default } } } } } \ http://controller:5000/v3/auth/tokens 2/dev/null | grep X-Subject-Token # 用 token 查虚拟机列表此时应为空 curl -H X-Auth-Token: $TOKEN http://controller:8774/v2.1/servers # 应返回 {servers: []}再用openstackCLI 验证openstack server list # 应返回空列表且无报错 openstack flavor list # 应列出 m1.tiny, m1.small 等默认规格关键指标curl命令的响应时间应 500ms。若 2s说明数据库或 RabbitMQ 有性能瓶颈需检查mysqladmin processlist或rabbitmqctl list_queues。6.2 服务健康度验证nova-status的 7 个检查项nova-status是 Nova 的“体检仪”运行nova-status upgrade check它会依次检查Database connection数据库连通性Database versionnova和nova_api库的 schema 版本是否匹配Cell registrationscell0和cell1是否都已注册且状态为upPlacement API connectivity若启用了 Placement 服务检查其连通性Message queue connectivityRabbitMQ 连通性Configuration file permissions/etc/nova/nova.conf是否为 644 且属主为 rootService versions所有 nova-* 服务的版本是否一致每一项都必须显示Success。若某项为Warning或Errornova-status会给出具体修复命令如nova-manage db online_data_migrations。6.3 数据一致性验证从nova-manage到mysql的交叉比对最后一步用底层数据验证上层逻辑# 1. 查 nova 数据库的 instances 表确认为空 mysql -u nova -pNOVA_DBPASS -D nova -e SELECT COUNT(*) FROM instances; # 2. 查 nova_cell0 数据库的 cell_mappings 表确认有两条记录 mysql -u nova -pNOVA_DBPASS -D nova_cell0 -e SELECT * FROM cell_mappings; # 3. 查 RabbitMQ 队列确认 nova 的队列已声明 rabbitmqctl list_queues | grep nova # 应输出至少 10 行包括 nova, nova-scheduler, nova-conductor 等当这三个命令都返回预期结果且openstack server list响应迅速、无报错你就完成了 Nova 手动安装与配置的全部闭环。这不是一个终点而是一个支点——从此你可以在这个支点上稳稳地撬动 Neutron 网络、Cinder 存储、Horizon 控制台构建起属于你自己的 OpenStack 云平台。我在实际操作中发现最可靠的验证方式永远不是看服务状态而是看openstack server create的完整日志流。当nova-scheduler选出主机、nova-conductor更新实例状态、nova-compute在目标节点拉起 QEMU 进程、nova-api返回ACTIVE状态——这一整条链路上每一个环节的日志都清晰、连贯、无报错那 Nova 就真的活了。