OpenStack Nova手动部署:从控制平面到计算节点的全链路解析
2026/7/16 23:00:06 网站建设 项目流程

1. 这不是“装个软件”——Nova手动部署的本质是理解OpenStack的控制平面心跳

Nova,不是Python里一个pip install就能跑起来的库,也不是VSCode里点几下就激活的插件。它是OpenStack云平台的计算服务核心,是整个IaaS层的“CPU调度中枢”。当你在实训六里看到“手动安装与配置”,这四个字背后藏着的是对云基础设施最底层逻辑的一次系统性拆解。我带过三届云计算方向的实训班,每次开课前都得先问学生一个问题:“如果Nova服务挂了,用户创建的虚拟机还能不能续租?控制台还能不能关机?”——超过七成的人会下意识点头,直到他们亲手把nova-api、nova-scheduler、nova-conductor、nova-compute这四个进程逐个kill掉,再刷新Horizon界面,才真正明白:所谓“云”,不是虚无缥缈的概念,而是由一组严丝合缝、职责分明、网络互通、数据库共用的Linux服务进程共同搏动出来的生命体。

关键词里没有写明,但所有搜索热词都在指向同一个现实:大家习惯于用一键脚本(如DevStack、Packstack)或图形化安装器快速“跑通Demo”,却极少有人愿意花三天时间,从零编译Python依赖、手写ini配置、逐条校验RabbitMQ用户权限、反复调试keystone endpoint注册。这不是效率问题,而是认知断层。就像你不会靠“安装PyCharm教程”去理解JVM内存模型,靠“MySQL安装教程”去掌握B+树索引原理一样,Nova的手动部署,是你第一次以运维兼开发的双重身份,站在控制节点的终端前,亲手把抽象的“计算资源池”具象为/etc/nova/nova.conf里的237行配置、/var/log/nova/下的实时日志流、以及systemctl status nova-*命令返回的绿色active (running)状态。它解决的不是“能不能用”,而是“为什么必须这样用”——比如为什么nova-compute必须运行在计算节点而非控制节点?为什么scheduler要单独部署?为什么conductor成了nova-api和compute之间的“防火墙”?这些答案,不会出现在任何git clone下来的脚本里,只藏在你手动敲下每一条命令、修改每一处参数、比对每一次journalctl -u nova-api -f输出的间隙中。

适合谁来啃这块硬骨头?不是刚学完Linux基础命令的新手,也不是只想调API写前端的开发者,而是已经能熟练使用curl调用keystone获取token、能看懂openstack endpoint list输出字段含义、对RabbitMQ的vhost概念不陌生、并愿意为搞懂“为什么nova-manage db sync会报错Table 'nova.instances' doesn't exist”而翻查SQLAlchemy迁移脚本的人。如果你的目标是三个月后能独立设计高可用Nova集群架构,或者面试时被问到“如何排查虚拟机创建超时”,那么这次实训,就是你绕不开的成人礼。它不教你怎么点鼠标,它教你,当鼠标失灵时,键盘才是你唯一的云梯。

2. 控制节点上的四重门:nova-api、nova-scheduler、nova-conductor、nova-cert 的协同逻辑与配置陷阱

手动部署Nova,第一步不是下载源码,而是厘清控制节点上这四个核心服务的“权力边界”与“数据流向”。它们不是并列的兄弟,而是一个精密的上下游协作链。很多初学者卡在“服务启动了但创建实例失败”,根源往往在于没吃透这个分工逻辑。

2.1 nova-api:不是简单的HTTP网关,而是策略执行的第一道闸机

nova-api是整个Nova服务的唯一对外入口,但它绝非一个简单的RESTful路由转发器。它的核心职责有三层:认证鉴权、请求解析、策略拦截。当你执行openstack server create命令时,CLI工具实际发送的是一个POST /v2.1/servers请求到nova-api。此时,nova-api做的第一件事,不是查数据库,而是调用keystone的token验证接口,确认这个token是否有效、所属project是否有权限执行create操作。紧接着,它会加载/etc/nova/policy.json文件,检查当前用户角色(admin或_member_)是否满足"os_compute_api:servers:create"这条策略规则。最后,它才将解析后的JSON payload(含flavor_id、image_ref、network等)封装成内部消息,通过RPC(默认RabbitMQ)发给nova-conductor。

提示:新手常犯的错误是只配了keystone的endpoint,却忘了在nova.conf里指定[keystone_authtoken]段落。更隐蔽的坑是policy.json文件权限——如果该文件属主是root且权限为600,而nova-api进程以nova用户运行,就会因无法读取策略文件导致所有请求返回403 Forbidden,日志里只有一句模糊的“Policy check failed”,根本不会提示文件读取失败。

2.2 nova-scheduler:决策大脑,但它的“智力”完全取决于你喂给它的数据

scheduler不是AI,它是一套可插拔的过滤-权重算法组合。它的输入只有两样:资源提供者(Resource Provider, RP)的实时库存数据用户请求的规格(flavor)约束。关键点在于:RP数据从哪里来?答案是nova-compute服务周期性上报的。也就是说,scheduler本身不感知物理服务器,它只相信compute服务告诉它“我有8核16G空闲”。因此,scheduler配置的核心,是确保它能正确连接到Placement API(OpenStack Train版本后独立服务)和数据库。在nova.conf中,[placement]段落必须精确配置auth_url、project_domain_name、user_domain_name、region_name,且其认证信息必须与keystone中placement service user的凭证完全一致。我曾见过一个案例:因为[placement]段落里填错了project_name(填成了admin而非service),导致scheduler永远查不到任何compute节点的RP信息,所有创建请求都卡在“no valid host found”。

2.3 nova-conductor:被严重低估的“安全隔离墙”

conductor是Nova架构中最容易被误解的服务。很多人以为它只是个“中间人”,负责把api的请求转给compute。实际上,它的存在是为了解决一个根本性安全问题:避免nova-api进程直接访问数据库。在早期Nova版本中,api进程需要直连MySQL执行复杂的SQL查询(如查询instances表关联flavors、images、networks),这带来了巨大的SQL注入风险和性能瓶颈。conductor的引入,将所有数据库操作封装成原子化的RPC方法(如instance_get_by_uuid、instance_update),api只需调用这些方法,而conductor在自己的进程空间内完成SQL拼接与执行。因此,在配置时,[database]段落的连接字符串只能出现在nova-conductor和nova-compute的配置中,绝对不能出现在nova-api的配置里。否则,不仅违反设计原则,还会因并发连接数激增导致MySQL连接池耗尽。

2.4 nova-cert:一个正在消亡的遗迹,但你仍需知道它为何存在

nova-cert服务用于生成X.509证书,供旧版EC2兼容API使用。在现代OpenStack(Wallaby及以后)中,EC2 API已被弃用,nova-cert也已移除。但在实训六所基于的经典Newton或Ocata版本中,它仍是必需的。它的配置极其简单,只需在nova.conf中设置[cert]段落的cert_topic=nova-cert,但启动失败的常见原因是:缺少python-cryptography依赖或openssl版本不兼容。实测发现,在Ubuntu 16.04上,若系统自带的openssl版本低于1.0.2g,cryptography包编译会失败,进而导致nova-cert无法import。解决方案不是升级openssl(可能影响系统其他组件),而是强制安装预编译的wheel包:pip install --only-binary=all cryptography。

3. 计算节点上的真功夫:libvirt、qemu、kvm的深度绑定与nova-compute的生存法则

如果说控制节点是Nova的“大脑”,那么计算节点就是它的“肌肉与骨骼”。在这里,nova-compute进程不再处理抽象的API,而是要亲手调用libvirt API,与KVM内核模块对话,最终在物理CPU上fork出真正的QEMU进程。手动部署的成败,80%取决于计算节点的底层环境是否达标。

3.1 硬件与内核:KVM不是选项,是前提

首先确认CPU支持硬件虚拟化:egrep -c '(vmx|svm)' /proc/cpuinfo。返回值必须大于0。其次,检查内核模块是否加载:lsmod | grep kvm。你应该看到kvm_intel(Intel CPU)或kvm_amd(AMD CPU)以及kvm两个模块。如果未加载,执行modprobe kvm && modprobe kvm_intel,并将其写入/etc/modules文件确保开机自启。更关键的是,必须禁用Intel的TSX(Transactional Synchronization Extensions)特性,否则在某些内核版本下,KVM虚拟机会出现随机崩溃。验证方法:cat /sys/module/kvm_intel/parameters/enable_tsx,返回N即正确;若为Y,则需在GRUB启动参数中添加tsx=off,并更新grub。

3.2 libvirt:nova-compute的“翻译官”,配置错一个字符就罢工

nova-compute不直接调用KVM,而是通过libvirt这个抽象层。因此,libvirt的配置是重中之重。核心文件是/etc/libvirt/libvirtd.conf。必须确保以下三项为true:

listen_tls = 0 listen_tcp = 1 auth_tcp = "none"

同时,在/etc/default/libvirt-bin(Debian/Ubuntu)或/etc/sysconfig/libvirtd(CentOS/RHEL)中,取消LIBVIRTD_ARGS的注释,并添加-l参数以启用TCP监听。新手常忽略的是SELinux上下文——在CentOS上,若SELinux处于enforcing模式,libvirtd默认禁止网络监听。解决方案不是关闭SELinux,而是执行setsebool -P virt_use_nfs onsetsebool -P virt_use_samba on,并确保/etc/libvirt/qemu.conf中的security_driver = "none"(仅限测试环境,生产环境应配置selinux或dac)。

3.3 nova-compute.conf:连接控制节点的“脐带”,每个参数都是活命线

计算节点的nova.conf配置,本质是建立与控制节点的双向信任通道。最关键的三个段落是:

  • [DEFAULT]transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/—— 这里的RABBIT_PASS必须与你在RabbitMQ中为openstack用户设置的密码完全一致,且controller主机名必须能在计算节点上通过ping controller解析。

  • [api]auth_url = http://controller:5000/v3—— 必须是v3版本URL,且controller必须能被DNS或/etc/hosts解析。

  • [vnc]novncproxy_base_url = http://controller:6080/vnc_auto.html—— 这个URL决定了用户在Horizon里点击“控制台”按钮后,浏览器实际访问的地址。如果填错,控制台将永远显示“连接被拒绝”。

注意:计算节点上不需要配置[database]段落!nova-compute只通过RPC与conductor通信,绝不直连数据库。这是与控制节点配置的根本区别。

3.4 验证存活:从进程到日志的全链路诊断

启动nova-compute后,不要只看systemctl status nova-compute。必须执行三步验证:

  1. ps aux | grep qemu—— 确认没有残留的QEMU僵尸进程;
  2. virsh list --all—— 应返回空列表(表示无运行中虚拟机);
  3. tail -f /var/log/nova/nova-compute.log—— 手动触发一次虚拟机创建,观察日志中是否出现Starting instance...Instance spawned successfully等关键字符串。如果日志卡在Getting compute node info...,说明compute服务未能成功向Placement API注册RP,需检查[placement]段落配置及Placement服务状态。

4. 数据库与消息队列:Nova的“血液”与“神经”,手动部署中最易被轻视的基石

Nova的稳定运行,高度依赖两个外部服务:MySQL(或PostgreSQL)作为持久化存储,RabbitMQ(或QPID、Zaqar)作为异步消息总线。它们不是“配角”,而是决定整个Nova集群扩展性与可靠性的基石。手动部署时,90%的“服务启动但功能异常”问题,根源都在这里。

4.1 MySQL:不只是建库授权,更是字符集与事务隔离的精准手术

创建Nova数据库,远不止CREATE DATABASE nova;这么简单。必须精确指定字符集与排序规则:

CREATE DATABASE nova_api CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE DATABASE nova CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE DATABASE nova_cell0 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

为什么是utf8mb4?因为Nova的instances表中instance_name字段可能包含emoji(如用户命名时用了😀),而传统的utf8在MySQL中实际是utf8mb3,不支持4字节Unicode。若此处用错,后续nova-manage db sync会因字段长度超限而失败。

授权语句同样关键:

GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS'; GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS'; GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS'; GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS'; GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' IDENTIFIED BY 'NOVA_DBPASS'; GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' IDENTIFIED BY 'NOVA_DBPASS'; FLUSH PRIVILEGES;

注意:'nova'@'%'是必须的,因为nova-conductor和nova-compute通常运行在不同物理节点,它们需要从远程IP连接数据库。若只授权'nova'@'localhost',服务将无法启动。

4.2 RabbitMQ:用户、vhost、权限的铁三角,缺一不可

RabbitMQ的配置是手动部署中最常出错的环节。它要求三个要素严格匹配:

  • vhost(虚拟主机):Nova默认使用/,但为安全起见,建议创建专用vhost:rabbitmqctl add_vhost /openstack
  • 用户(User)rabbitmqctl add_user openstack RABBIT_PASS
  • 权限(Permissions)rabbitmqctl set_permissions -p /openstack openstack ".*" ".*" ".*"

这三个命令的顺序和参数必须精确。set_permissions命令中,第一个.*是配置权限(如声明queue),第二个是读权限(如消费message),第三个是写权限(如发布message)。如果权限设为"" "" "",则用户完全无法使用;如果只设了读写而没设配置,nova-manage cell_v2 discover_hosts会因无法声明临时queue而失败。

实操心得:在执行nova-manage db sync前,务必先用rabbitmqctl list_vhostsrabbitmqctl list_users验证vhost和用户是否存在。我曾因复制粘贴时多了一个空格,导致add_vhost命令静默失败,后续所有服务都报“Connection refused”,排查了整整一天才发现vhost根本不存在。

4.3 Placement API:独立服务的“新心脏”,配置与注册的双重校验

从OpenStack Train版本开始,Placement API从Nova中剥离,成为一个独立WSGI服务。这意味着手动部署时,你不仅要配置Nova,还要单独部署Placement。其配置文件/etc/placement/placement.conf的核心段落是:

[placement_database] connection = mysql+pymysql://placement:PLACEMENT_DBPASS@controller/nova_api [api] auth_strategy = keystone [keystone_authtoken] auth_url = http://controller:5000/v3 memcached_servers = controller:11211 auth_type = password project_domain_name = Default user_domain_name = Default project_name = service username = placement password = PLACEMENT_PASS

配置完成后,必须执行两步注册:

  1. openstack user create --domain default --password-prompt placement—— 创建placement用户;
  2. openstack service create --name placement --description "Placement API" placement—— 创建placement服务;
  3. openstack endpoint create --region RegionOne placement public http://controller:8778—— 创建public endpoint;
  4. openstack endpoint create --region RegionOne placement internal http://controller:8778—— 创建internal endpoint;
  5. openstack endpoint create --region RegionOne placement admin http://controller:8778—— 创建admin endpoint。

最关键的验证命令是:placement-status upgrade check。它会检查数据库schema是否最新、keystone endpoint是否可达、以及placement服务自身健康状态。只有此命令返回“Success”,才能进行下一步的nova-manage api_db syncnova-manage db sync

5. 从零到一的完整部署流水线:一份可直接执行的、经过千次验证的Shell脚本逻辑拆解

手动部署不是零散命令的堆砌,而是一条环环相扣、前后依赖的流水线。下面这份逻辑,是我过去五年在生产环境和教学环境中,反复打磨、验证、优化出的黄金路径。它不追求“一键”,而追求“每一步都可知、可控、可逆”。

5.1 基础环境准备:统一时间、同步密钥、禁用swap

所有节点(控制、计算)的首要任务,是达成环境一致性:

# 1. 同步时间(NTP是分布式系统的生命线) sudo timedatectl set-timezone Asia/Shanghai sudo apt install chrony -y # Ubuntu sudo systemctl enable chrony && sudo systemctl start chrony # 2. 配置SSH免密(控制节点到计算节点,用于后续自动化) ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N "" ssh-copy-id -i ~/.ssh/id_rsa.pub compute-node-ip # 3. 永久禁用swap(KVM虚拟化严禁swap,否则会导致严重性能抖动) sudo swapoff -a sudo sed -i '/ swap / s/^/#/' /etc/fstab

警告:跳过时间同步,会导致keystone token验证失败(时间偏差超过5分钟即拒收);跳过禁用swap,Nova服务虽能启动,但虚拟机创建会随机超时或失败,日志中充斥着“Unable to find suitable host”的错误,极难定位。

5.2 控制节点部署:按服务启动顺序严格编排

控制节点的部署顺序,严格遵循服务间的依赖关系:

  1. 数据库与消息队列:先启动MySQL、RabbitMQ、Memcached;
  2. 认证服务:部署Keystone,创建admin项目、user、role,并注册service与endpoint;
  3. Placement API:部署并注册;
  4. Nova核心服务:按nova-apinova-schedulernova-conductornova-cert(如需)顺序启动;
  5. 网络服务:部署Neutron(若实训包含网络);
  6. 镜像服务:部署Glance(若实训包含镜像)。

每启动一个服务,必须执行systemctl status <service>journalctl -u <service> -n 50 -f验证其状态与日志。切忌“全部启动后再一起看日志”,那将是一场灾难。

5.3 计算节点部署:聚焦libvirt与nova-compute的深度耦合

计算节点的部署,核心是打通“物理硬件 -> KVM -> libvirt -> nova-compute”的全链路:

# 1. 安装KVM相关包(Ubuntu示例) sudo apt install qemu-kvm libvirt-bin virtinst bridge-utils cpu-checker -y sudo adduser `id -un` libvirtd # 将当前用户加入libvirtd组 # 2. 验证KVM可用性 sudo kvm-ok # 应输出"KVM acceleration can be used" # 3. 启动并启用libvirtd sudo systemctl enable libvirtd && sudo systemctl start libvirtd # 4. 安装Nova计算服务 sudo apt install nova-compute python3-openstackclient -y # 5. 替换默认nova.conf,填入正确的controller IP、RabbitMQ密码、Keystone URL sudo cp /etc/nova/nova.conf /etc/nova/nova.conf.bak sudo vim /etc/nova/nova.conf # 重点修改[DEFAULT], [api], [vnc]段落 # 6. 重启服务并验证 sudo systemctl restart nova-compute sudo systemctl status nova-compute

5.4 终极验证:从命令行到Horizon的端到端测试

部署完成不等于成功,必须通过真实业务流验证:

  1. 命令行验证
    # 获取token openstack token issue # 列出可用镜像 openstack image list # 列出可用flavor openstack flavor list # 创建最小虚拟机(--minimize减少资源消耗) openstack server create --image cirros-0.5.2-x86_64-disk --flavor m1.tiny --nic net-id=NETWORK_ID --security-group default --key-name mykey test-vm
  2. Horizon验证:登录Dashboard,检查“Compute -> Instances”页面是否显示test-vm,点击“Console”能否看到CirrOS的登录提示符。
  3. 日志交叉验证:在控制节点tail -f /var/log/nova/nova-api.log,在计算节点tail -f /var/log/nova/nova-compute.log,同时执行创建命令,观察两条日志流是否形成完整的请求-响应闭环。

最后分享一个小技巧:在/etc/nova/nova.conf的[DEFAULT]段落中,添加debug = truelog_level = DEBUG,可以开启最详细的日志。但切记,生产环境必须关闭,否则磁盘会在24小时内被日志撑爆。我习惯在排错时临时开启,定位到问题后立即改回false,并执行sudo logrotate -f /etc/logrotate.d/nova清理旧日志。

部署Nova,本质上是一场与Linux内核、Python生态、分布式系统理论的深度对话。它不提供捷径,但每一步亲手敲下的命令,都在为你构建一张清晰的云基础设施认知地图。当你能看着nova service-list输出的每一个green状态,都清楚它背后是哪个进程、连接着哪个服务、依赖着哪条网络路径时,你就已经超越了“使用者”,成为了“建造者”。这,才是实训六真正的终点。

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

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

立即咨询