1. 整体设计思路:为什么企业私有云首选OpenStack多节点
先说结论:OpenStack这套东西,单个节点玩不出什么花来,真正的价值在于多节点部署形成资源池。你在一台服务器上装了OpenStack,那叫技术验证;你用三台、五台甚至更多服务器把它跑起来,对外提供开箱即用的云主机,那才叫私有云平台。多节点架构的本质是把计算、存储、网络这些资源从“一台机器的能力上限”中解放出来,让它们变成一种可以按需分配、弹性伸缩的资源服务。
我在很多场合解释过为什么要用OpenStack而不是直接上KVM或者Proxmox这类方案。KVM本身是个虚拟化内核模块,它能让你在一台物理机上跑几十台虚拟机,但它不解决“你有多台物理机”的问题。你有五台物理机,每台各自跑KVM,那你的运维工作量不是减少,而是翻倍——每台机器都要单独登录、单独维护、单独管理虚拟机。OpenStack的价值在于它把这些分散的资源聚合成一个统一的资源池,你通过一套API、一个Dashboard就能管理所有宿主机上的计算实例、存储卷和虚拟网络。这就是企业环境下最核心的诉求。
这个文档对应的实施场景,我按企业在生产环境中最常见的部署形态来拆解:控制节点、计算节点、存储节点分离的三层架构。控制节点承载身份认证、镜像服务、编排、调度这些大脑组件;计算节点跑实际的工作负载,也就是你的虚拟机实例;存储节点提供块存储和后端存储池。多节点的意思不是简单的数量累加,而是角色拆分。小型实验环境可以三节点合一,但企业生产环境极少有人这么干,因为控制面和数据面混在一起,故障半径太大了。
在动手之前,先把这套平台的适用人群和前置条件说清楚。这篇内容适合两类人:一类是正在规划私有云平台的中小团队,另一类是已经被分配了“搭一套云平台”任务但无从下手的运维工程师。你需要的基础技能包括:熟悉Linux基本操作、理解网络基础概念(VLAN、网桥、路由)、知道KVM虚拟化是什么。如果你连apt或者yum安装软件包都不熟练,建议先从单机手册开始。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 规划与选型:硬件、网络、版本三方博弈
2.1 节点角色与硬件配置建议
多节点私有云的第一步不是装系统,是画架构图。我见过太多人上来就装,装到一半发现节点角色没规划好,网络不通,存储性能拉胯,最后推倒重来。规划阶段省下来的时间,会在部署阶段以十倍的价格还回去。
先定节点角色。一套标准的多节点OpenStack,至少需要三个角色:
- 控制节点(Controller):运行Keystone、Glance、Nova API、Neutron Server、Horizon这些管理面服务。它是大脑,不承担实际的虚拟机运算。
- 计算节点(Compute):运行Nova Compute和Neutron Agent,你的云主机全部跑在这上面。
- 存储节点(Storage):运行Cinder、Swift或者直接提供后端存储给Nova使用。
我见过不少所谓“生产环境”把控制节点和存储节点放在同一台物理机上,理由是“资源够用”。我不建议这么干。控制节点本身CPU和内存消耗不高,但存储节点通常是I/O密集型的,两者混布,存储的I/O波动会影响控制面的响应稳定性——云平台最忌讳的就是控制面不稳定。如果你的预算实在有限,至少保证控制节点独立,计算节点可以堆配置,存储单独划盘。
硬件配置这块,我按规模分了三个档位,可以直接拿去当参考:
| 节点角色 | 起步规模(1~2台物理机) | 中等规模(3~5台物理机) | 扩展规模(6+台物理机) |
|---|---|---|---|
| 控制节点 | 8C / 16G / 200G系统盘 | 16C / 32G / 400G系统盘 | 24C / 64G / 400G系统盘(可双机HA) |
| 计算节点 | 16C / 64G / 100G系统盘 + 本地盘跑实例 | 32C / 128G / 100G系统盘 + SSD缓存盘 | 48C / 256G / 100G系统盘 + NVMe缓存盘 |
| 存储节点 | 4C / 8G / 根据容量需求配HDD | 8C / 16G / 多块HDD + SSD做缓存 | 16C / 32G / 全闪或混闪池 |
这里说明一下,配置选型不是越贵越好,而是匹配你的实际场景。如果你们只是内部开发测试用,起步规模完全够;如果是要跑生产业务,中等规模起步。计算节点的本地盘主要用于实例的系统盘,如果使用了共享存储,本地盘的压力会小很多。
2.2 网络规划:管理网、数据网、存储网尽量分离
网络这块是OpenStack实施中最容易翻车的地方,也是规划时要花最多心思的地方。一个典型的物理网络平面至少要有三个:管理网络、租户数据网络、外部网络(或者叫浮动IP网络)。如果条件允许,存储网络也独立出来。
先说管理网络。这个网络承载OpenStack各服务之间的API通信,控制节点和计算节点之间靠它同步状态。管理网络不需要特别大的带宽,但要求稳定。一般用千兆就可以,生产环境建议走带外管理交换机,和业务流量物理隔离。
再是数据网络。虚拟机之间的东西向流量、虚拟机和外部网络的南北向流量,都走这个平面。数据网络的带宽直接决定云主机的网络体验。我在实际项目中用的都是万兆网卡,如果条件不允许,至少保证每个计算节点有独立的千兆网口给数据平面,别和管理网共用同一个网口。
存储网络单独跑iSCSI或者Ceph的集群网络。存储流量是持续性的高带宽流量,如果和管理网混用,一旦存储集群在做rebalance或者快照,控制面的响应延迟会明显上升。这也是我坚持存储网络独立的核心理由。
网络规划的另一个关键点是VLAN要么规划足够,要么直接用VXLAN。我在中型项目里喜欢用VXLAN覆盖租户网络,底层VLAN只用来做物理链路隔离,上层逻辑网络全部走VXLAN,这样租户数量不受4096个VLAN上限的约束。细节后面部署章节再展开。
2.3 发行版与OpenStack版本选择
版本选择这个问题,我建议遵循一个原则:用你已经熟悉的操作系统的官方仓库版本,或者用发行版厂商的商业支持版本,不要在版本上标新立异。
如果你选择Ubuntu,那么Yoga或者更早的Wallaby都是不错的选择,Ubuntu 22.04 LTS对应OpenStack Yoga,稳定性经过了大量生产环境的验证。如果你选择CentOS Stream或者Rocky Linux,对应的版本是OpenStack Wallaby或者Xena。我的建议是:能LTS就LTS,能跟发行版走就跟发行版走,少折腾编译安装。OpenStack本身组件够多了,再用源码编译部署,排查问题的时候你会想哭。
这个实施文档我以Ubuntu 22.04 + OpenStack Yoga为例,原因是Yoga版在功能上算是比较均衡的版本,既有新特性,又有足够的社区沉淀。实际操作中你可以用release notes对照你的发行版去调整命令,核心思路完全通用。
3. 核心组件详解:揭开OpenStack各服务的神秘面纱
OpenStack不是一个大单体软件,而是一堆服务的集合。每个服务各管一摊,互相之间通过API调用协作。理解这些服务的协作关系,是看懂实施文档的前提。
首先是Keystone(身份认证服务)。它负责统一认证和授权,所有其他服务在接收请求时都要先找它验证身份。你在Horizon里输入用户名密码,Horizon拿着这个去问Keystone“这个人合法吗?”合法,才允许你去操作虚拟机。它的Token机制,类似你去游乐园买了一张手环,只要手环在手上,园内的各个项目就不用重复买票了。
然后是Glance(镜像服务)。它管理云主机的操作系统镜像。Glance本身不存镜像内容,它只维护镜像的元数据,真正的镜像文件放在后端的存储里,可能是本地目录,可能是Swift或者Ceph。创建虚拟机时,Nova根据你选的镜像去Glance拿到镜像位置,再把它作为启动盘拉起来。
Nova(计算服务)是整个OpenStack的核心。它负责虚拟机的生命周期管理,从创建、启动、关机到删除,全部由Nova调度。Nova里最核心的组件是Nova Scheduler,它根据你指定的过滤条件从一群计算节点里挑一个合适的出来。举个例子,你要求2核4G内存的虚拟机,Nova Scheduler会过滤掉那些剩余资源不够的计算节点,再结合可用域、节点权重,最后选定一台宿主机去启动这个虚拟机。
Neutron(网络服务)提供虚拟网络能力。它管理二层网络、三层路由、安全组、浮动IP这些网络资源。Neutron是整个OpenStack里最复杂的组件,因为它要处理数据路径的转发,涉及Linux Bridge、Open vSwitch、命名空间、iptables规则这些东西。一个虚拟机创建出来,它接的虚拟网卡本质上是连到了一个Linux Bridge上,再通过路由命名空间出外网。
Cinder(块存储服务)提供持久化块存储,类似给虚拟机插一块虚拟硬盘。虚拟机系统盘坏了没关系,只要你把数据放Cinder卷上,卷本身受Cinder管理,可以随时挂载到新的虚拟机上。这就是云上数据不随实例消失的逻辑基础。
Horizon(控制台服务)就是那个Web界面。它对小白比较友好,但说实话,管理员日常操作我还是更习惯用OpenStack客户端命令行,效率高得多。Horizon更适合给普通用户自助创建虚拟机用。
这六个服务是私有云的骨架。除此之外还会有Heat(编排)、Ceilometer(计量)、Octavia(负载均衡)这些增强组件,但刚起步时不用贪多,先把六个核心服务跑稳。
4. 部署实操:从裸机到云平台的全流程
这一部分是全文的重头戏,我尽量把每步操作的意图和踩坑点都写清楚。整个部署过程大致分五个阶段:基础环境准备、控制节点服务部署、计算节点服务部署、存储节点服务部署、连通性验证与Dashboard访问。
4.1 基础环境准备:统一时间、配置域名解析
多节点部署最怕的就是节点间时间不一致。OpenStack各服务之间对时间非常敏感,Token的时效校验、消息队列的心跳、数据库的事务都建立在时间准确的基础上。所以第一步,先把所有节点的系统时间统一好。
在每个节点上都安装chrony,然后指定一台作为NTP服务器:
bash复制apt install chrony -y
控制节点上,编辑/etc/chrony/chrony.conf,允许其他节点同步:
ini复制allow 192.168.10.0/24
然后重启chrony服务:
bash复制systemctl restart chrony
各计算节点配置上游指向控制节点,编辑/etc/chrony/chrony.conf:
ini复制server 192.168.10.10 iburst
下面每台节点上执行,验证时间同步:
bash复制chronyc sources -v
看到^*标志就表示同步正常。这一步别跳过,很多莫名其妙的认证错误和数据库写入冲突,最后排查下来都是时间不同步。
接着配置域名解析。控制节点的主机名必须能被其他节点解析到。我习惯直接改/etc/hosts,不做内部DNS服务器,简单直接:
code复制192.168.10.10 controller
192.168.10.11 compute01
192.168.10.12 storage01
需要注意的是,OpenStack各服务的配置模板里大量使用controller这个主机名。如果安装的时候主机名不一致,后面要改的地方会多到怀疑人生。
4.2 数据库与消息队列先行
OpenStack几乎每个服务都要连数据库和消息队列。数据库存配置和状态,消息队列做服务间通信。这一步部署顺序靠前的原因在于,后面的服务安装之后要连这些基础组件。
安装MariaDB:
bash复制apt install mariadb-server python3-pymysql -y
创建配置文件/etc/mysql/mariadb.conf.d/99-openstack.cnf:
ini复制[mysqld]
bind-address = 192.168.10.10
default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
重启数据库服务并做安全初始化:
bash复制systemctl restart mysql
mysql_secure_installation
安装RabbitMQ消息队列:
bash复制apt install rabbitmq-server -y
添加OpenStack用户并配置权限:
bash复制rabbitmqctl add_user openstack RABBIT_PASS
rabbitmqctl set_permissions openstack ".*" ".*" ".*"
4.3 Keystone身份认证部署
Keystone是所有服务的大门。安装时要先在数据库里创建对应的库和账号:
bash复制mysql -u root -p
sql复制CREATE DATABASE keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'KEYSTONE_DBPASS';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'KEYSTONE_DBPASS';
然后安装Keystone服务:
bash复制apt install keystone -y
编辑/etc/keystone/keystone.conf,配置数据库连接:
ini复制[database]
connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone
同步数据库并初始化Fernet密钥:
bash复制su -s /bin/sh -c "keystone-manage db_sync" keystone
keystone-manage fernet_setup --keystone-user keystone --keystone-owner keystone
keystone-manage credential_setup --keystone-user keystone --keystone-owner keystone
引导身份服务:
bash复制keystone-manage bootstrap --bootstrap-password ADMIN_PASS \
--bootstrap-admin-url http://controller:5000/v3/ \
--bootstrap-internal-url http://controller:5000/v3/ \
--bootstrap-public-url http://controller:5000/v3/ \
--bootstrap-region-id RegionOne
最后配置Apache的WSGI,我遇到过很多人漏了这步导致8000端口监听不出来。确保文件存在:
bash复制ln -s /etc/apache2/conf-available/keystone.conf /etc/apache2/conf-enabled/keystone.conf
systemctl restart apache2
4.4 Glance镜像服务部署
Glance部署相对简单,主要关注镜像存储后端。这里用最简单的本地文件存储,生产环境建议换Ceph后端。
sql复制CREATE DATABASE glance;
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' IDENTIFIED BY 'GLANCE_DBPASS';
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' IDENTIFIED BY 'GLANCE_DBPASS';
安装并配置/etc/glance/glance-api.conf:
ini复制[database]
connection = mysql+pymysql://glance:GLANCE_DBPASS@controller/glance
[keystone_authtoken]
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000
memcached_servers = controller:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = GLANCE_PASS
[glance_store]
stores = file,http
default_store = file
filesystem_store_datadir = /var/lib/glance/images/
同步数据库:
bash复制su -s /bin/sh -c "glance-manage db_sync" glance
创建一个测试镜像,确认整个链路能跑通:
bash复制openstack image create "cirros" \
--file cirros-0.6.2-x86_64-disk.img \
--disk-format qcow2 \
--container-format bare \
--public
4.5 Nova计算服务部署
Nova的组件比较多,控制节点上跑Nova API、Scheduler、Conductor、Novncproxy等,计算节点上跑Nova Compute。
控制节点创建数据库:
sql复制CREATE DATABASE nova_api;
CREATE DATABASE nova;
CREATE DATABASE nova_cell0;
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';
安装控制节点相关包:
bash复制apt install nova-api nova-conductor nova-novncproxy nova-scheduler -y
编辑/etc/nova/nova.conf:
ini复制[DEFAULT]
transport_url = rabbit://openstack:RABBIT_PASS@controller
my_ip = 192.168.10.10
[api_database]
connection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova_api
[database]
connection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova
[keystone_authtoken]
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000
memcached_servers = controller:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = NOVA_PASS
[vnc]
enabled = true
server_listen = $my_ip
server_proxyclient_address = $my_ip
初始化数据库:
bash复制su -s /bin/sh -c "nova-manage api_db sync" nova
su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1" nova
su -s /bin/sh -c "nova-manage db sync" nova
计算节点上安装并配置:
bash复制apt install nova-compute -y
/etc/nova/nova.conf中关键配置:
ini复制[DEFAULT]
transport_url = rabbit://openstack:RABBIT_PASS@controller
my_ip = 192.168.10.11
[vnc]
enabled = true
server_listen = 0.0.0.0
server_proxyclient_address = $my_ip
novncproxy_base_url = http://controller:6080/vnc_auto.html
确认KVM加速是否可用,如果是在虚拟机里嵌套虚拟化,大概率会显示QEMU而不是KVM:
bash复制egrep -c '(vmx|svm)' /proc/cpuinfo
如果为0,需要在nova.conf中修改:
ini复制[libvirt]
virt_type = qemu
然后重启计算节点服务。最后回到控制节点,注册这台计算节点:
bash复制openstack compute service list --service nova-compute
su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova
4.6 Neutron网络服务部署
Neutron的部署是整个实施过程里最容易出问题的环节。这里我选用Linux Bridge + VXLAN的方案,相比Open vSwitch,Linux Bridge在排查上更直观一些。
创建Neutron数据库并安装控制节点服务:
sql复制CREATE DATABASE neutron;
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' IDENTIFIED BY 'NEUTRON_DBPASS';
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' IDENTIFIED BY 'NEUTRON_DBPASS';
bash复制apt install neutron-server neutron-plugin-ml2 neutron-linuxbridge-agent neutron-dhcp-agent neutron-metadata-agent -y
编辑/etc/neutron/neutron.conf:
ini复制[DEFAULT]
transport_url = rabbit://openstack:RABBIT_PASS@controller
service_plugins = router
allow_overlapping_ips = true
[database]
connection = mysql+pymysql://neutron:NEUTRON_DBPASS@controller/neutron
[keystone_authtoken]
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000
memcached_servers = controller:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = neutron
password = NEUTRON_PASS
在/etc/neutron/plugins/ml2/ml2_conf.ini中启用VXLAN:
ini复制[ml2]
type_drivers = flat,vlan,vxlan
tenant_network_types = vxlan
mechanism_drivers = linuxbridge
extension_drivers = port_security
[ml2_type_flat]
flat_networks = provider
[ml2_type_vxlan]
vni_ranges = 1:1000
配置Linux Bridge代理,关键参数是物理网卡名称要正确:
ini复制[linux_bridge]
physical_interface_mappings = provider:eth1
[vxlan]
enable_vxlan = true
local_ip = 192.168.10.11
[securitygroup]
enable_security_group = true
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
计算节点只需要安装neutron-linuxbridge-agent。这里我踩过的坑是:如果之前试过别的网络方案,旧的网桥会残留,导致agent启动正常但虚拟机网络不通,新装环境一般不会遇到这个问题。
4.7 Cinder块存储部署
Cinder让我单独开的坑,来自它的卷分离失败问题。OpenStack Yoga版本里,Cinder删除卷时偶尔会卡在detaching状态,卷没法彻底删掉。这个问题在社区里讨论过很多,根源在于Nova上报给Cinder的状态信息没有正确更新。我的处理方案是:升级到较新的维护版本,如果条件不允许,重启cinder-api和cinder-volume服务通常可以暂时解决。
部署过程先建库:
sql复制CREATE DATABASE cinder;
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' IDENTIFIED BY 'CINDER_DBPASS';
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' IDENTIFIED BY 'CINDER_DBPASS';
安装服务:
bash复制apt install cinder-api cinder-scheduler -y
存储节点安装cinder-volume,配置LVM后端。先在存储节点上准备好一块独立磁盘(比如/dev/sdb):
bash复制pvcreate /dev/sdb
vgcreate cinder-volumes /dev/sdb
编辑/etc/cinder/cinder.conf:
ini复制[DEFAULT]
transport_url = rabbit://openstack:RABBIT_PASS@controller
auth_strategy = keystone
[database]
connection = mysql+pymysql://cinder:CINDER_DBPASS@controller/cinder
[keystone_authtoken]
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000
memcached_servers = controller:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = cinder
password = CINDER_PASS
[lvm]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_group = cinder-volumes
target_protocol = iscsi
target_helper = tgtadm
有个重要细节,LVM默认会扫描系统里的所有磁盘,这可能导致包含操作系统磁盘的卷组也被列入Cinder管理范围。这个后果很严重,因为Cinder会把整个卷组当作可分配空间,万一误操作会损坏系统数据。必须在/etc/lvm/lvm.conf里把系统盘排除掉:
ini复制filter = [ "a/sdb/", "r/.*/" ]
5. 验证与测试:从资源池到云主机
服务都部署完,不等于平台可用了。这一步是从“服务活着”到“业务可用”的分水岭。我在交付项目时,有一个固定的冒烟测试清单,每一步都对应一个独立的故障排查出口。
首先验证身份认证:
bash复制openstack token issue
这一步能通过,说明Keystone工作正常,数据库连接无异常。如果报错,优先检查Keystone的日志/var/log/keystone/keystone.log,最常见的问题是数据库密码错或者Fernet密钥不一致。
创建项目、用户和配额:
bash复制openstack project create --domain default demo
openstack user create --domain default --password DEMO_PASS demo
openstack role add --project demo --user demo member
创建网络:
bash复制openstack network create --project demo --share demo-net
openstack subnet create --project demo --subnet-range 192.168.100.0/24 --network demo-net --dns-nameserver 8.8.8.8 demo-subnet
创建路由器连接内部网络和外部网络:
bash复制openstack router create demo-router
openstack router set --external-gateway public demo-router
openstack router add subnet demo-router demo-subnet
这里外网的public网络需要提前用provider网络创建好,对应的物理网卡要能通外网。
创建云主机:
bash复制openstack server create --flavor m1.tiny --image cirros --network demo-net --key-name mykey demo-instance
绑定浮动IP:
bash复制openstack floating ip create public
openstack server add floating ip demo-instance <FLOATING_IP>
验证网络连通性:
bash复制ping -c 3 <FLOATING_IP>
如果你能ping通这个浮动IP,恭喜,从控制面到数据面的整条链路基本没问题了。如果ping不通,按这个顺序排查:先看实例状态是否是ACTIVE,再看安全组是否放行了ICMP,再看Namespace里的iptables规则,最后抓包看物理网卡有没有流量出去。
存储验证:
bash复制openstack volume create --size 1 test-volume
openstack server add volume demo-instance test-volume
看到volumes列表里出现状态为in-use的记录,并且实例内能识别到新磁盘,Cinder链路就是通的。删除卷时如果遇到Yoga那个分离失败的bug,可以执行:
bash复制openstack server remove volume demo-instance test-volume
openstack volume delete test-volume
正常情况下两步搞定,卡住了就重启cinder-api服务再试。
6. 常见问题排查与运维笔记
我整理了这套架构下比较容易踩的坑,按频率排序:
环境里最常见的故障是主机组上出现down状态。用openstack compute service list查看,如果是nova-compute异常,SSH到计算节点,执行service nova-compute status看具体报错,大多数情况是配置文件中IP写错或者在计算节点上没安装对应的Neutron agent。
第二高频的是虚拟机创建失败,报错No valid host was found。这个错误99%是Nova调度器找不到满足条件的计算节点。可能是资源不足(某个计算节点内存满了、属于它的可用域不对),也可能单纯是计算节点的CPU mode对不上。用一条命令看清各节点的实时资源余量:
bash复制openstack host show <compute-node>
我就遇到过一次全程排错,最后发现是计算节点的reserved_host_memory_mb设置过大,导致Nova认为没有足够内存可分配。
第三高频的是网络不通,常见于浮动IP失效。先用:
bash复制ip netns exec qrouter-<router-id> ip addr
确认路由命名空间里的浮动IP是否存在。如果存在,测一下命名空间内能否ping通网关和外部IP。发现命名空间起不来的情况,多半是因为控制节点上的L3 Agent没有正确配置外部网卡的物理映射。
第四个是存储分离失败。Cinder卷无法从实例上分离,尤其Yoga这个版本有已知缺陷。社区建议升级版本,但如果你无法升级,可以尝试手动确认Nova的卷状态。命令是:
bash复制openstack server show <server-id> -f json | jq '.volumes_attached'
如果实例侧状态已经显示为空,说明是Cinder的问题,绕过Nova直接更新卷状态:
bash复制cinder reset-state --state available test-volume
这个方法可以用在测试环境,生产环境要谨慎。
7. 实施文档中的细节补充与交付建议
单独拎出来一节写文档这件事,是因为我见过太多好的技术实施,最后死在文档上。企业内部交付一套OpenStack平台,光跑通服务流程远远不够,交付物的完整度直接决定后续二线运维团队能不能接得住。
实施文档至少要包含以下几部分:首先是拓扑图,节点角色、IP地址、网络平面一张图说清楚,这是后续所有排障的基础。其次是配置清单,每台节点的关键配置文件列表和关键参数,不用全部截图,但至少让运维知道改哪些文件。然后是操作手册,如何创建项目、配额,如何给用户分配资源,如何创建镜像,这些是日常高频操作。
最后是应急预案。控制节点宕机怎么恢复?一个计算节点失联,上面的虚拟机怎么处理?存储快照怎么定期做?这些内容写清楚,比部署过程本身更值钱。
我在实际交付中多会附一个“健康检查脚本”,定时检查各服务状态、磁盘占用率、数据库连接数:
bash复制openstack-status
这个命令能看到所有核心服务的运行状态,是运维初期最常用的工具。另外建议定期关注日志目录/var/log/nova/、/var/log/neutron/的磁盘占用,日志膨胀在OpenStack里是常态化问题,最好配合logrotate用好自动切割策略。
从我的实操经验看,文档里画出来的架构图要跟实际环境一模一样,不要美化,不要理想化。比如有些节点间额外加了一条自己没有记录的物理直连网线,这会导致排障时误判数据链路,这样的坑我已经踩过不止一次。
这套平台上线后,日常运维的重点会从“部署”转移到“容量”。计算节点不会永远够用,存储空间也会慢慢逼近上限。建议在平台上线第一天就启用Ceilometer或者至少写个脚本,定时采集各节点资源水位,提前规划扩容窗口,别等资源耗尽才手忙脚乱。
OpenStack多节点私有云平台这条路,走到这里算是走通了。但平台能跑起来只是开始,怎么把它运营得稳定、安全、高效,那才是真正考验运维功力的事。
