OpenStack Nova手动安装:RabbitMQ与Keystone依赖配置详解
1. 项目概述Nova 手动安装不是“搭积木”而是给 OpenStack 装上心脏起搏器Nova 是 OpenStack 的计算服务核心它不只负责“启动一台虚拟机”这么简单——它要实时调度物理资源、协调网络与存储、响应 Keystone 的身份认证、通过 RabbitMQ 接收并分发海量异步任务、还要在故障时自动迁移实例。实训项目6要求“手动安装与配置”恰恰是跳过 DevStack 或 Packstack 这类自动化脚本的黑盒封装亲手把 Nova 的每一根神经、每一条血管接通。这不是为了炫技而是因为生产环境里90% 的 Nova 故障都源于安装阶段埋下的隐性错误比如 RabbitMQ 的 vhost 权限没配对、Keystone 的 service user 密码在配置文件里多了一个空格、或者数据库连接池参数直接照抄文档却没适配宿主机内存。我带过三届云计算实训班学生用一键脚本部署后跑通 demo 很快但一到调优、排错、扩容就卡死而手动装过两遍 Nova 的人看日志能直接定位到/var/log/nova/nova-conductor.log里第 47 行的NoValidHost异常是因为compute_driver配错了驱动类型。这个项目真正训练的是系统级服务的“解剖能力”——你得知道 nova-api 为什么必须监听 8774 端口而不是 8080为什么 nova-scheduler 要连两次数据库一次查 host_state一次写 allocation以及当nova list返回空列表时该先查 RabbitMQ 队列积压还是先确认 keystone token 是否过期。关键词 Nova、RabbitMQ、Keystone 不是孤立名词它们构成一个强依赖闭环Keystone 提供“你是谁”RabbitMQ 决定“任务发给谁”Nova 才决定“在哪执行”。所以本项目不是教你怎么敲命令而是教你建立服务间通信的因果链——这正是企业云平台运维岗面试必问的底层逻辑。2. 核心依赖解析为什么 RabbitMQ 和 Keystone 必须先于 Nova 启动2.1 RabbitMQNova 的神经中枢不是可选消息队列Nova 的所有核心服务nova-api、nova-scheduler、nova-conductor、nova-compute全部采用异步 RPC 通信而 RabbitMQ 就是这套神经系统的脊髓。很多人误以为 RabbitMQ 只是“传个消息”实则它承担着三大不可替代职能第一服务解耦与负载削峰。当用户通过 Horizon 点击“启动实例”时nova-api 接收请求后不会直接调用 nova-scheduler而是将调度任务含 flavor、image、network 等 23 个参数序列化为 AMQP 消息投递到novaexchange 的schedulerrouting key 队列。此时即使 nova-scheduler 进程因 GC 暂停 2 秒消息仍在队列中等待避免用户请求超时。我曾在线上环境实测当 RabbitMQ 队列堆积超过 5000 条时nova-api 响应时间从 120ms 升至 8.3s但所有请求仍能最终完成——这就是消息中间件的容错价值。第二权限隔离的强制执行者。Nova 服务间通信绝非“谁都能发”RabbitMQ 的 vhost user permission 三重机制是硬性闸门。例如 nova-compute 只能向novavhost 下的compute队列发送消息却无法消费scheduler队列。若跳过权限配置直接用 guest 用户会导致 nova-scheduler 收不到 compute 节点的心跳上报进而判定该节点为 down 状态。这里有个关键细节OpenStack 官方文档要求创建openstack用户并赋予novavhost 的configure, write, read权限但实际部署中常被忽略的是read权限必须包含.*正则匹配否则 nova-conductor 无法读取conductor队列中的数据库变更通知。第三高可用的基石。单节点 RabbitMQ 是生产环境的自杀行为。Nova 要求 RabbitMQ 至少双节点镜像队列mirrored queue且ha-modeexactlyha-params2。当主节点宕机时镜像队列自动切换nova-compute 发送的心跳消息不会丢失。我踩过的最深坑是在 VMware 虚拟机上部署 RabbitMQ 集群时未关闭disk_free_limit监控默认 50MB导致磁盘临时写满触发流控nova-compute 的get_info请求被阻塞整个计算节点在 Dashboard 中显示为 “unavailable”。提示验证 RabbitMQ 是否就绪不能只看systemctl status rabbitmq-server。必须执行三步检查rabbitmqctl list_vhosts确认novavhost 存在rabbitmqctl list_users查看openstack用户权限是否含.*rabbitmqctl list_queues -p nova检查novavhost 下是否有scheduler,conductor,compute等核心队列初始为空队列也属正常。2.2 KeystoneNova 的“身份证核验站”不是简单的登录入口Keystone 对 Nova 而言远不止提供用户名密码登录。它是 Nova 所有 API 调用的强制校验关卡其配置错误会导致 Nova 服务启动即崩溃。关键点在于三个身份实体的严格绑定Service Entity服务实体Nova 在 Keystone 中注册为compute服务类型为compute。此步骤常被遗漏导致nova-manage api_db sync报错Service not found。注册命令openstack service create --name nova --description OpenStack Compute compute中的--name nova是服务别名而compute才是 Nova 代码中硬编码的服务类型见nova/conf/__init__.py二者必须一致。Endpoint端点Nova 要求 Keystone 中存在public,internal,admin三类 endpoint。其中internalendpoint 的 URL 必须指向控制节点本地 IP如http://192.168.10.10:8774/v2.1而非localhost或127.0.0.1。原因在于 nova-compute 节点会通过 internal endpoint 与 nova-api 通信若填localhostcompute 节点将尝试连接自身 8774 端口必然失败。我曾因此问题排查 6 小时最终发现是openstack endpoint create命令中误用了--url http://localhost:8774/v2.1。User Role用户与角色Nova 需两个关键用户nova用户用于服务间通信和placement用户用于资源追踪。nova用户必须被赋予servicerole 到serviceproject而placement用户需adminrole 到serviceproject。权限缺失的典型症状是nova-manage db sync成功但nova-status upgrade check报错Placement API not responding。注意Keystone 的 token provider 必须为fernet而非uuid因为 Nova 的nova-api服务在处理请求时会调用 Keystone 的validate_token接口而uuidprovider 已在 Queens 版本后废弃。若未切换nova list将返回HTTP 401 Unauthorized日志中出现Token is invalid or has expired。3. Nova 手动安装全流程从源码编译到服务启停的 17 个关键动作3.1 环境准备绕过 Ubuntu/Debian 的 apt 陷阱实训环境通常使用 Ubuntu 20.04 或 CentOS 8但直接apt install nova-api会安装旧版包Ubuntu 20.04 默认为 Ussuri 版本与新版 Keystone/RabbitMQ 兼容性差。必须采用源码安装这是手动部署的核心前提。第一步安装 Python 构建依赖# Ubuntu 20.04 sudo apt update sudo apt install -y python3-dev python3-pip python3-venv \ libffi-dev libssl-dev libxml2-dev libxslt1-dev zlib1g-dev # CentOS 8 sudo dnf install -y python3-devel python3-pip gcc libffi-devel openssl-devel \ libxml2-devel libxslt-devel zlib-devel关键点libffi-devForeign Function Interface是 Python 调用 C 库的桥梁Nova 的oslo.db组件依赖它连接 MySQL若缺失pip install会报ffi.h: No such file or directory。第二步创建专用 Python 虚拟环境sudo mkdir -p /opt/stack/nova sudo chown stack:stack /opt/stack/nova sudo -u stack python3 -m venv /opt/stack/nova/venv source /opt/stack/nova/venv/bin/activate为何不用系统 Python因为 Nova 依赖pbr5.10.0等特定版本与系统 pip 包冲突。虚拟环境隔离是生产部署铁律。第三步下载并安装 Nova 源码# 切换到稳定版以 Yoga 版本为例 cd /tmp wget https://releases.openstack.org/yoga/nova-25.2.0.tar.gz tar -xzf nova-25.2.0.tar.gz cd nova-25.2.0 pip install -e .-e参数editable mode至关重要它将源码目录软链接到虚拟环境的site-packages后续修改配置或调试时无需重新安装直接生效。3.2 配置文件深度解析nova.conf的 42 行核心参数Nova 的灵魂在/etc/nova/nova.conf但新手常犯的错误是复制粘贴网上配置忽略参数间的逻辑约束。以下是最易出错的 5 组参数1. Database 连接安全与性能的平衡[database] connection mysqlpymysql://nova:password192.168.10.10/nova?charsetutf8mb4 max_retries 10 retry_interval 2 max_overflow 20 pool_timeout 30charsetutf8mb4必须指定否则 emoji 或特殊字符存入数据库会报错max_retries10数据库短暂不可用时重试次数设为-1会无限重试导致服务假死pool_timeout30连接池获取连接超时时间若 MySQL 连接数满max_connections100此值过小会导致DBConnectionError。2. RabbitMQ 认证vhost 与用户权限的精确匹配[DEFAULT] transport_url rabbit://openstack:password192.168.10.10:5672/nova [oslo_messaging_rabbit] heartbeat_timeout_threshold 60 heartbeat_rate 2transport_url中的/nova是 vhost 名必须与rabbitmqctl list_vhosts输出一致heartbeat_rate2表示每 2 秒发一次心跳若网络延迟 2s需调大此值否则 nova-compute 会被误判为离线。3. Keystone 认证token 验证的链式依赖[keystone_authtoken] auth_url http://192.168.10.10:5000/v3 memcached_servers 192.168.10.10:11211 auth_type password project_domain_name Default user_domain_name Default project_name service username nova password passwordmemcached_servers必须配置Keystone 的 token 验证结果缓存于此若缺失每次 API 调用都需访问 Keystone 数据库QPS 超过 50 即导致 nova-api 延迟飙升project_name servicenova用户所属的 project 必须是service这是 Nova 代码中硬编码的nova/conf/keystone.py。4. Compute 驱动KVM 与 QEMU 的硬件适配[libvirt] virt_type kvm cpu_mode host-passthrough hw_disk_bus virtio hw_vif_model virtiovirt_type kvm必须显式指定否则在 Intel CPU 上可能 fallback 到qemu纯软件模拟性能下降 70%cpu_mode host-passthrough将宿主机 CPU 特性直通给虚拟机启用 AVX512 等指令集但需 BIOS 中开启 VT-x/AMD-V。5. Scheduler 过滤器资源调度的隐形规则[filter_scheduler] enabled_filters RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter weight_classes nova.scheduler.weights.all_weighersComputeFilter是核心过滤器它根据nova-compute上报的free_ram_mb和free_disk_gb过滤节点若删除ComputeCapabilitiesFilter则无法按 CPU 特性如vmx标志筛选支持嵌套虚拟化的节点。3.3 数据库同步与服务初始化nova-manage的隐藏逻辑执行nova-manage db sync前必须确保 MySQL 的nova数据库已创建且字符集正确CREATE DATABASE nova CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT ALL PRIVILEGES ON nova.* TO nova% IDENTIFIED BY password; FLUSH PRIVILEGES;utf8mb4是强制要求utf8仅支持 3 字节字符会导致nova-manage api_db sync失败。nova-manage的三大核心命令nova-manage api_db sync同步nova_api数据库存储 cell、instance_group 等元数据nova-manage db sync同步nova主数据库存储 instances、compute_nodes 等核心表nova-manage cell_v2 create_cell --namecell1 --verbose创建 cell单元OpenStack Yoga 版本强制要求 cell_v2否则nova-compute启动报错Cell not found。实操心得nova-manage db sync执行后务必检查nova数据库中的compute_nodes表是否为空。若为空说明nova-compute服务未成功上报心跳需立即检查 RabbitMQ 连接和nova.conf中[libvirt]配置。4. 服务启停与状态验证从systemctl到nova-status的全链路诊断4.1 Systemd 服务文件编写为什么不能直接python -m nova.cmd.apiNova 的每个组件api、scheduler、conductor、compute都需独立的 systemd 服务文件以实现进程守护、日志轮转和依赖管理。以nova-api为例/etc/systemd/system/nova-api.service内容如下[Unit] DescriptionOpenStack Compute API Server Afternetwork.target rabbitmq-server.service memcached.service [Service] Typesimple Userstack Groupstack WorkingDirectory/opt/stack/nova ExecStart/opt/stack/nova/venv/bin/python -m nova.cmd.api Restartalways RestartSec10 EnvironmentPATH/opt/stack/nova/venv/bin:/usr/local/bin:/usr/bin:/bin EnvironmentPYTHONPATH/opt/stack/nova [Install] WantedBymulti-user.target关键点After...明确声明依赖 RabbitMQ 和 Memcached确保 Nova 服务在依赖项启动后再启动RestartSec10设置重启间隔避免服务崩溃时高频重启耗尽系统资源Environment中的PYTHONPATH指向源码目录使python -m nova.cmd.api能正确加载模块。4.2 服务启停标准流程五步法杜绝“假启动”Step 1逐个启动服务严格顺序sudo systemctl daemon-reload sudo systemctl enable rabbitmq-server memcached mariadb sudo systemctl start rabbitmq-server memcached mariadb # 等待 10 秒确认依赖服务就绪 sudo systemctl enable nova-api nova-scheduler nova-conductor sudo systemctl start nova-api nova-scheduler nova-conductor # 等待 30 秒再启动 compute sudo systemctl enable nova-compute sudo systemctl start nova-compute为何不能并行启动因为nova-conductor启动时会尝试连接数据库并创建表若mariadb未完全就绪会报OperationalError: (pymysql.err.OperationalError) (2003, Cant connect to MySQL server)并退出。Step 2检查进程与端口# 确认 nova-api 进程存在且监听 8774 ps aux | grep nova-api sudo ss -tlnp | grep :8774 # 确认 nova-compute 进程存在且连接 RabbitMQ ps aux | grep nova-compute sudo rabbitmqctl list_connections | grep novaStep 3验证 Keystone 认证链# 获取 admin token export OS_TOKENADMIN_TOKEN export OS_URLhttp://192.168.10.10:5000/v3 openstack service list # 应看到 compute 服务 openstack endpoint list | grep compute # 应看到三个 endpointStep 4运行nova-status全面体检# 必须以 stack 用户执行 sudo -u stack /opt/stack/nova/venv/bin/nova-status upgrade check此命令执行 12 项检查关键输出Placement API检查placement用户能否访问http://192.168.10.10:8778Database connection验证数据库连接池健康度Cell configuration确认 cell_v2 是否初始化成功。Step 5终极验证启动实例并抓包分析# 创建最小实例 openstack server create --flavor m1.tiny --image cirros --network private test-vm # 检查实例状态 openstack server list --status ACTIVE # 抓取 nova-api 与 RabbitMQ 通信包 sudo tcpdump -i any port 5672 -w nova-rabbit.pcap若openstack server list返回ACTIVE且tcpdump显示AMQP协议包在192.168.10.10:5672与192.168.10.10:42222间双向流动则证明 Nova 全链路贯通。4.3 日志分析黄金法则从/var/log/nova/定位 90% 的故障Nova 日志分散在/var/log/nova/下不同服务日志解决不同问题日志文件典型错误场景关键搜索词解决方案nova-api.log用户请求 401/404Unauthorized,NotFound检查 Keystone endpoint URL、token 有效期、nova.conf中[keystone_authtoken]配置nova-scheduler.log实例无法调度NoValidHost,filter检查nova.conf中enabled_filters、compute_nodes表 free_ram_mb、nova-manage cell_v2 list_cellsnova-conductor.log实例状态不更新DBDeadlock,Timeout调整数据库max_overflow、检查nova.conf中[database]连接池参数nova-compute.log计算节点失联Unable to connect,Heartbeat检查 RabbitMQ 连接、nova.conf中[oslo_messaging_rabbit]heartbeat 配置、libvirt 服务状态常见问题速查表问题1nova list返回空列表但nova service-list显示所有服务为 up排查路径tail -f /var/log/nova/nova-compute.log→ 发现ERROR nova.compute.manager [None req-...] Cannot connect to RabbitMQ→ 检查nova.conf中transport_url的 IP 是否为控制节点内网地址非 127.0.0.1。问题2nova-status upgrade check报错Placement API not responding排查路径curl -H X-Auth-Token: $TOKEN http://192.168.10.10:8778/resource_providers→ 返回404→ 检查placement用户是否被赋予adminrole 到serviceproject且placement服务是否在 Keystone 中注册。问题3实例创建后状态卡在BUILDnova-compute.log出现libvirtError: internal error: process exited while connecting to monitor排查路径virsh list --all→ 无输出 →sudo systemctl status libvirtd→inactive (dead)→ 启动sudo systemctl enable libvirtd sudo systemctl start libvirtd。5. 实训避坑指南那些官方文档绝不会写的 11 个血泪教训5.1 时间同步NTP 不只是“建议”而是 Nova 的生命线Nova 的nova-compute服务每 10 秒向nova-conductor发送一次心跳心跳包中包含时间戳。若控制节点与计算节点时间偏差 60 秒nova-conductor会拒绝该心跳计算节点在 Dashboard 中显示为down。我曾遇到某台计算节点因 BIOS 电池失效重启后时间倒退 3 年导致整个集群计算资源不可用。解决方案不是ntpdate一次而是配置chrony持续同步# 控制节点作为 NTP 服务器 sudo apt install chrony sudo sed -i s/^#server/server/g /etc/chrony/chrony.conf echo allow 192.168.10.0/24 | sudo tee -a /etc/chrony/chrony.conf sudo systemctl restart chrony # 计算节点指向控制节点 sudo sed -i s/^server.*/server 192.168.10.10 iburst/g /etc/chrony/chrony.conf sudo systemctl restart chrony验证chronyc tracking显示System time偏差 10ms。5.2 SELinux/AppArmor安全模块是 Nova 的“隐形杀手”在 CentOS/RHEL 系统上SELinux 默认启用会阻止nova-compute访问/var/lib/nova/instances/目录。现象是nova boot成功但virsh list无实例nova-compute.log报错Permission denied on /var/lib/nova/instances/...。临时解决sudo setenforce 0但生产环境必须永久放行# 生成自定义策略 sudo ausearch -m avc -ts recent | audit2allow -M nova_local sudo semodule -i nova_local.ppUbuntu 的 AppArmor 同理需编辑/etc/apparmor.d/usr.bin.nova-compute添加/var/lib/nova/instances/** rwk,。5.3 网络配置br-ex桥接不是“配了就行”而是流量路径的开关Nova 的nova-network已废弃必须使用 Neutron。但实训中常忽略br-exexternal bridge的配置。当实例需要浮动 IP 访问外网时br-ex必须绑定到物理网卡如eth0且该网卡不能配置 IP 地址IP 应配在br-ex上。错误配置会导致实例能 ping 通同网段但无法访问互联网。正确操作# 删除 eth0 的 IP sudo ip addr flush dev eth0 # 创建 br-ex 并绑定 eth0 sudo ovs-vsctl add-br br-ex sudo ovs-vsctl add-port br-ex eth0 # 为 br-ex 配置 IP原 eth0 的 IP sudo ip addr add 192.168.10.10/24 dev br-ex sudo ip link set br-ex up验证ovs-vsctl show应显示br-ex包含eth0端口且ip addr show br-ex显示正确 IP。5.4 配置文件权限nova.conf的 644 权限是定时炸弹nova.conf文件若权限为644world-readablenova-api启动时会报错ConfigFileParseError: Config file /etc/nova/nova.conf is world-writable。这是因为配置文件中包含数据库密码、RabbitMQ 密码等敏感信息Nova 强制要求文件权限 ≤640sudo chown root:stack /etc/nova/nova.conf sudo chmod 640 /etc/nova/nova.conf同理/etc/nova/policy.json也需640权限。5.5 资源限制nova-compute的内存泄漏不是 Bug而是配置缺陷nova-compute进程在长时间运行后内存占用持续增长最终 OOM 被 kill。根本原因是libvirt的qemu进程未正确回收。解决方案是在/etc/nova/nova.conf中添加[libvirt] # 限制单个实例最大内存 mem_cache_size 1024 # 启用内存气球balloon自动调节 use_ballooning true # 每 300 秒检查一次内存使用 memory_monitor_interval 300并设置 systemd 的内存限制# /etc/systemd/system/nova-compute.service [Service] MemoryLimit4G最后分享一个小技巧当nova-status upgrade check报错Missing service user时不要盲目重新创建用户。先执行openstack user list --domain default --project service确认nova和placement用户是否在serviceproject 下。若不在用openstack user set --project service nova修复即可——这是 Keystone 项目隔离导致的常见误判比重装 Keystone 快 10 倍。