☰
OpenStack核心组件解析与私有云部署实战
2026/10/24 7:45:41 网站建设 项目流程

如果你刚碰到 OpenStack 这个词,第一反应多半是一台虚拟机在犹豫“我要用哪个版本”“组件是不是太多了”。我最早接触私有云时,也在这堆名词里绕了很长的路:Nova、Neutron、Cinder、Keystone 一拥而上,光看架构图就觉得头大。但我后来发现,OpenStack 要解决的事情其实非常朴素:给你一个自助式的“云”,让你像用公有云一样,在私有环境里申请虚拟机、网络和磁盘。它不是一个软件,而是一组开源项目协作起来,把物理机变成可调度的资源池。

这篇文章不打算堆概念,而是从“它到底怎么工作”“核心组件之间怎么配合”“实际操作时需要注意什么”三个角度展开,顺便把我踩过的坑、常用的排查命令、部署时的硬指标都整理进去。适合刚接触 OpenStack 的运维或开发同学,也能给正在做技术选型的人一些参考。读完你至少能回答这三个问题:OpenStack 的关键组件有哪些?它们各自干什么?我要跑起来一个最小环境,到底要经过哪些步骤?

1. 先别急着背组件,先理解它要解决的三个问题

OpenStack 能火起来,是因为它同时解决了三个级别的需求。下面拆开来聊,你能更好地理解为什么架构是今天这个样子。

第一个问题:资源怎么变成可申请的服务

没有云的时候,你申请一台服务器要走流程,然后运维去机房装系统、配置网络,几天才能交付。OpenStack 把这一步变成了一个自助门户:用户在 Horizon 或命令行里点几下,几分钟内就能拿到一台全新的虚拟机。这个过程的本质,是让计算资源、内存、磁盘、网络“商品化”。

它背后的思路是把物理资源抽象成三层视图:计算层由 Nova 管理虚拟机和宿主机,存储层由 Cinder/Glance/Swift 管理磁盘和镜像文件,网络层由 Neutron 定义虚拟网络和路由器。用户完全感觉不到物理拓扑,只需要指定 flavor、镜像和网络。

第二个问题:没有厂商锁定,怎么做到标准化操作

真实的数据中心里,硬件的品牌、型号、网络架构五花八门。OpenStack 提供了一个统一 API 层,让上层应用通过标准接口来申请和释放资源,底层的驱动交给组件各自去适配。这样你换掉某个品牌的存储,只要换对应的 Cinder 后端驱动,上层业务不用改动。

这种“接口抽象”的思路,在技术上叫插件化架构。Nova 支持多种虚拟化(KVM、QEMU、vSphere 等),Neutron 支持 ML2 插件和各种网络驱动。这也是 OpenStack 在私有云场景里能活这么多年的原因之一——它不绑定单一厂商。

第三个问题:运维层面的控制和隔离怎么做到

云环境不像公司内部几台虚拟机那么随意。多租户场景下,用户之间不能互相干扰,配额需要限制,网络需要隔离,操作需要审计。OpenStack 用 Keystone 做统一认证和权限,用 project、user、role 实现租户隔离,Quota 限制资源的最高使用量,所有 API 调用都有记录。

这里的生活类比是:物理机房像一个酒店,管理员有每间房的钥匙;OpenStack 像一个预订平台,住客只能在系统分配的房间里活动。每个租户看到的世界,完全属于自己的“虚拟房间”,彼此不知道对方的存在。

从这些角度理解,你会发现 OpenStack 的组件多不是设计冗余,而是每一块承担的职责不同,拼起来才形成完整的 IaaS 闭环。

2. 核心组件拆解:到底谁在干活

这个部分我打算按照“一个请求从登录到创建虚拟机,沿途会经过哪些组件”的顺序来讲。这样比按字母顺序背名词更容易记住逻辑。

2.1 入口处先过 Keystone

你打开 Horizon 页面,输入账号密码,第一个打交道的就是 Keystone。它负责三重事情:认证你是谁、授权你能干什么、告诉你在哪个“项目”里干活。

Keystone 里的核心概念有三个:project(项目,相当于租户)、user(用户)、role(角色)。实际使用时,你最常接触的操作是 source 一个 openrc 文件,然后执行 openstack command。这个 openrc 文件里写的就是 OS_PROJECT_NAME、OS_USERNAME、OS_PASSWORD、OS_AUTH_URL 等环境变量,所有命令行操作都会通过它们去 Keystone 换取一个 token。

有一个容易踩坑的点:Keystone 的 token 有过期时间,默认一般是一小时。所以运维脚本如果要跑很长时间,要注意 token 失效导致后续 API 调用返回 401,需要重新认证。

另一个坑是 Endpoint 配置。Keystone 里每个服务都要注册 publicURL、internalURL、adminURL,如果 internalURL 配的地址在计算节点上访问不通,会出现一个很诡异的现象:命令行操作正常,但虚拟机内部的 metadata 服务却拿不到信息。所以排查故障时请务必检查 endpoint 的地址是否在所有相关节点可达。

2.2 大脑和黑板:消息队列与数据库

虽然名字里没有组件,但操作系统层面有两个东西几乎是 OpenStack 的命脉:消息队列(通常用 RabbitMQ)和数据库(通常用 MariaDB)。每个服务之间不直接互相调用,而是通过消息队列传递任务,数据库则负责存放资源状态的持久化数据。

这个设计的优点是不能互相阻塞。Nova 提交一个创建虚拟机的任务到消息队列,计算节点的 nova-compute 从队列里取任务来执行,即使 nova-api 短暂重启,任务也不会丢失。

但这也带来两个运维痛点:第一,RabbitMQ 的积压会拖垮整片云,如果某节点挂掉,queue 里堆积大量消息,重启后所有任务会同时爆发,可能压垮宿主机;第二,数据库连接数上限。默认 MariaDB 的 max_connections 往往是 151,如果控制节点上任何组件异常断连、连接池没释放,很容易把数据库连接耗光。

我自己的经历:某次升级后,nova-api 的日志里连续报“service unavailable”,排了半天发现是它在轮的数据库连接没释放,连接数打满。处理办法是调整 max_connections,并且找到引起连接泄漏的服务重启一遍,而不是无脑重启数据库。

2.3 镜像仓库 Glance 解决“从哪来”

创建虚拟机之前,你得先有“光盘”——这就是镜像(image)。Glance 负责存储和分发镜像。它的核心概念是 image,你可以把它理解为格式化后的云主机系统盘快照。

创建镜像最常见的两种方式,一个是从云端下载现成的云镜像(例如 cloud-init 版的 Linux 发行版),另一个是把现有虚拟机磁盘做成快照上传。实际操作命令是:

openstack image create "my-centos" --file ./centos.qcow2 --disk-format qcow2 --container-format bare

这里有几个参数要特别注意。--disk-format决定后端如何存放,qcow2 支持稀疏占用(按需占用空间),raw 效率更高但占满空间。--container-format一般写 bare 就可以,表示没有额外的容器封装。上传完建议用openstack image list确认状态是 active,而不是 queued 或 error。

Glance 在实际生产里有一个普遍痛点:默认存储目录是本地磁盘,如果控制节点磁盘小,镜像一多就爆。建议在生产环境给 Glance 配 Ceph 或者共享存储后端,避免镜像单点。

2.4 计算核心 Nova 决定虚拟机的命

Nova 是整个 OpenStack 里最复杂的组件,连名字都很拗口:nova-api、nova-scheduler、nova-conductor、nova-compute 好几个进程一起协作。

它们各自的分工是这样的:

  • nova-api:接收用户的创建请求,做合法性校验和配额检查
  • nova-scheduler:根据可用资源选择一台合适的宿主机
  • nova-conductor:协调数据库操作,避免计算节点直接访问数据库
  • nova-compute:真正在宿主机上通过 KVM 或 QEMU 创建虚拟机

实际创建流程是:你执行openstack server create,nova-api 收到请求,检查 quota、确认镜像和 flavor,然后把消息发到 RabbitMQ。scheduler 拿到消息后根据过滤和权重算法选出宿主机,再把任务发到那台机器上的 nova-compute。nova-compute 去 Glance 下载镜像,创建虚拟磁盘,调用 Neutron 去建网卡,调 Cinder 去挂块设备,最终虚拟机启动。

排查 Nova 问题时,最重要的命令是:

openstack compute service list openstack server list openstack server show <uuid>

如果openstack compute service list里有某个 nova-compute 状态显示 down,那这台宿主机就不会再接收新的虚拟机了,需要去对应节点看 nova-compute 服务是否正常、日志里有没有异常。常见原因包括宿主机磁盘满、Libvirt 连接失败、虚拟机与宿主机的时间不同步。

Nova 还有一个概念叫 cell,v2 版本引入了 cell v2 把集群划分为小片,每个 cell 有自己的数据库和消息队列。如果你跨 cell 排查问题,要留意openstack cell list的状态,而不是只看全局,否则很容易被“明明服务都正常但就是创建失败”的问题困住。

2.5 资源调度的幕后黑手:Placement 与 Scheduler

Placement 是在 OpenStack Stein 后独立出来的服务,专门跟踪每个计算节点可用资源的实时情况,如 vCPU、内存、自定义资源。nova-scheduler 在选择目标节点时,要先去 placement 查各节点的剩余容量,再结合其他过滤条件决定放到哪里。

你可以在命令行里通过openstack resource provider list和openstack resource provider show <uuid>查看资源。如果发现某节点可用资源显示为负值,排查方向一般是孤儿实例(orphaned instance)或资源上报失败。这通常是因为 nova-compute 没正常清理删除失败的虚拟机。

2.6 网络 Neutron:最容易出“玄学”的组件

Neutron 是 OpenStack 里非常核心也异常固执的组件。它的作用是提供虚拟网络,涉及到网络、子网、路由器、安全组、端口等概念。不同部署方式下,Neutron 会启动一堆 agent:neutron-dhcp-agent、neutron-l3-agent、neutron-metadata-agent、openvswitch-agent 等。

我从实际排障中总结的经验是:Neutron 大部分问题最后都指向三处——agent 状态、网络命名空间、安全组。

查看所有 agent 是否存活:

openstack network agent list

如果你创建了子网但虚拟机拿不到 IP,首先要确认 dhcp-agent 所在的控制节点上,对应子网的命名空间是否存在于ip netns list。网络命名空间是 Neutron 实现 IP 地址隔离的容器。看不到命名空间、但 agent 状态是 alive 时,说明 dhcp agent 的进程没真正生成配置,这时候要看 neutron-dhcp-agent 日志。

安全组是另一个坑。经常有人在代码里给自己的测试留 SSH 22 端口,结果怎么都登录不上,最后发现是默认安全组没放通 22 端口。安全组规则是按方向(ingress / egress)匹配的,做测试时最保险的办法是先开放一个允许所有入口流量的规则,跑通业务再逐步收紧。

MTU 问题也要重视。如果你的底层物理网络 MTU 是 1500,而 Neutron 的隧道网络(VXLAN)需要额外 50 字节封装开销,虚拟机内部网卡的 MTU 得改成 1450,否则会出现大包能通小包通不了的现象——典型的症状是 SSH 会卡住半天然后断开。

2.7 存储 Cinder 与 Swift:除了系统盘还有什么

Nova 给你的虚拟机会自带一个临时磁盘,但重启后内容会丢失。要持久化数据,就得用 Cinder 提供块存储(类似公有云的云硬盘),或者用 Swift 提供对象存储。

Cinder 的核心概念是 volume、volume type 和 snapshot。创建并挂载一块数据盘到虚拟机的命令是:

openstack volume create --size 100 my-volume openstack server add volume <server> <volume>

这里有个容易忽略的细节:Cinder 的默认分配策略默认是 thin provisioning,也就是说你在创建时指定的 100GB 不会立刻从后端扣掉 100GB 实际空间。如果你的后端存储是本地 LVM,需要考虑超分配可能导致磁盘写满的问题。建议对 volume quota 做好规划,并在监控里盯好后端存储容量使用率。

Swift 提供的是对象存储,用 HTTP API 来读写,适合存放日志、镜像备份、静态文件等海量非结构化数据。它不需要挂载到操作系统上,而是通过客户端(如 python-swiftclient)访问。在 OpenStack 里可以用openstack object store相关命令操作,也支持 S3 兼容接口。

2.8 仪表盘 Horizon 与计量 Telemetry

Horizon 是一个纯 Web 界面,可以说它就是普通用户的“控制台”。它本身不做任何资源调度,只是封装了各个组件的 API。如果你是自己搭建的云,需要特别注意 Horizon 的“配额显示”和实际配额不一定同步,有时改配额后页面要刷新一下,不然用户会疑惑“我明明加了配额怎么还提示超限”。

Telemetry 相关的组件(如 ceilometer、gnocchi、panko)负责做计量与监控。Ceilometer 会采集虚拟机 CPU、内存、网络流量等数据,存储到 Gnocchi 的时间序列数据库里。这部分部署起来比较重,如果不是必须做计费,可以晚点再上。用 Prometheus + node_exporter 做基础设施监控,对大多数运维场景已经完全够用了。

3. 从零搭一个最小 OpenStack 环境(实操向)

我不打算在这里展开所有部署细节,那样会变成一本操作手册。我只讲最关键的选择和步骤,让你知道一条可以真正跑通的路。

3.1 三种部署方式怎么选

OpenStack 的部署方式五花八门,我把常见的整理成了一张表:

部署方式适用场景核心特点上手难度
DevStack开发调试、学习组件脚本一条命令拉起全部组件,适合全裸跑一遍低
Packstack单机小规模验证用 Answer File 部署,已较少使用低
Kolla-Ansible生产环境、中小规模基于 Docker + Ansible,部署和维护简洁中
TripleO大规模生产用 OpenStack 来部署 OpenStack,较复杂高
OpenStack-Ansible生产环境基于 Ansible 部署所有服务中高

如果你是第一次接触 OpenStack,我的建议非常明确:先花两个小时用 DevStack 把它完整跑一遍,然后在命令行里反复创建、删除虚拟机,把每个组件感知一遍。直接用 Kolla 做生产或许更“正确”,但遇到故障你连“错误发生在哪一层”都判断不出来,就会非常被动。

当你要实际建生产环境,我还是推荐 Kolla-Ansible,原因有三个:第一,所有服务跑在容器里,升级回滚都方便;第二,配置集中在 globals.yml 一个文件,修改后重建对应容器即可;第三,社区活跃,出问题搜一圈能找到答案。

3.2 硬件与网络规划:宁可多给内存

这里用三节点小环境举例:控制节点 1 台,计算节点 2 台,存储就用 Ceph 或本地盘。控制节点的最低配置建议 16GB 内存、4 核 CPU、100GB 系统盘,计算节点至少 32GB 内存起步;Kolla 的控制节点上会跑 MariaDB、RabbitMQ、Keystone、Neutron 的 agent 等十几个容器,内存紧张会直接导致关键服务被系统杀掉。

网络方面建议准备两张网卡。一张作为管理网,跑 API 和内部通信;一张作为数据网,跑虚拟机租户流量。如果环境内没有可用的 VLAN 交换机,数据网建议选择 VXLAN 隧道模式,这样跨节点通信不需要额外配置物理交换机。

3.3 Kolla-Ansible 部署关键步骤

提前说明:下面的命令是基于我常用的部署路径,只节选重要的判断点,完整操作以官方文档为准。

先生成密码文件,所有服务初始密码都会自动写入。这一步非常重要,密码文件要妥善备份:

kolla-genpwd

然后编辑/etc/kolla/globals.yml,至少要修改这几个变量:

kolla_base_distro: "centos" kolla_install_type: "source" openstack_release: "xxxx" network_interface: "eth0" # 管理网卡 neutron_external_interface: "eth1" # 外部网卡,供浮动 IP 用 enable_haproxy: "no" # 单控制节点时先关掉

如果你只需要单控制节点,记得设enable_haproxy: "no",否则 Keystone 和 Horizon 会走自动生成的 VIP,而你根本没有配 Keepalived,后面会碰壁。

接下来的命令流程是:

kolla-ansible bootstrap-servers kolla-ansible prechecks kolla-ansible deploy

prechecks会检查各节点磁盘可用空间、Python 版本、容器网络等,如果有不通过的项会直接报红。这个阶段最容易出问题的是 DNS 和 yum 源,很多节点初始化失败都是因为源不通。建议在 hosts 文件里把仓库地址加入/etc/hosts。

部署完成后生成管理员环境变量文件:

kolla-ansible post-deploy source /etc/kolla/admin-openrc.sh

这时候可以看下整体状态:

openstack service list openstack compute service list openstack network agent list

如果这三个列表里服务状态都是 UP / alive,恭喜,最基础的 OpenStack 已经跑起来了。

3.4 从镜像到第一台虚拟机

现在做一次完整的流程闭环。先上传一个镜像,然后创建网络、创建虚拟机。

openstack image create "ubuntu2204" \ --file ubuntu2204.qcow2 \ --disk-format qcow2 \ --container-format bare openstack network create test-net openstack subnet create test-subnet \ --network test-net \ --subnet-range 192.168.100.0/24 \ --gateway 192.168.100.1 \ --dns-nameserver 223.5.5.5 openstack server create test-vm \ --flavor m1.small \ --image ubuntu2204 \ --network test-net

等虚拟机进入 active 状态后,如果你在同一个网络里已经创建了路由器并连通了网络,或者在 Horizon 里打开了控制台,就能看到登录界面。如果想用 SSH 直连虚拟机,需要在创建子网时打开 DHCP,并确保安全组放通了 22 端口。

创建完第一台虚拟机,我强烈建议立刻做两个动作:第一,快照一个干净的镜像,后面测试省很多时间:openstack server image create test-vm --name my-snapshot;第二,记下你创建网络、子网、路由器的顺序,因为删除时的顺序正好相反,如果你先删了路由器,那就别想直接把子网删掉。

4. 我已经替你踩过的坑:常见问题与排查实录

这个部分我想按照“症状—可能原因—处理建议”的方式整理出来,都是我实际遇到过的问题。每一个我都尽量写出排查路径,而不是只说结论。

4.1 服务状态显示 down,但日志无异常

先确认时间同步。OpenStack 服务之间通过消息队列做调度,节点时间差超过一定范围,服务会被认为失联。我遇到过某台计算节点时间慢了 5 分钟,nova-compute 被标记为 down,所有新建节点都不往上面调度。解决办法是启用 NTP 服务统一各节点时间。

另一个原因是服务注册时的 hostname 与解析结果不一致。某个服务启动时根据 hostname 注册到数据库中,如果该节点更改主机名或 DNS 解析不稳定,后面重启或检查时会匹配不上。排查时直接看数据库对应表里的 host 字段和实际 hostname 是否一致。

4.2 虚拟机一直显示 BUILD,卡住不动

创建虚拟机的任务卡死在 BUILD 状态,排障思路按下面顺序来:

  • 看控制节点消息队列是否积压:rabbitmqctl list_queues如果有很高的 message 数,说明某个计算节点处理跟不上或 down 了。
  • 看目标计算节点的 nova-compute 日志是否存在异常,重点找 “error” “timeout” 这类关键词。
  • 看openstack server show <id> --fit-width里的 fault 字段,有些错误信息会直接写在这里,例如 “No valid host was found”。这时要在 flavor 里确认资源是否足够。
  • 最后确认 placement 上报资源的数值是否正常,某些情况下磁盘字段为 0,创建请求就无法完成。

4.3 虚拟机创建成功,但 SSH 连不上

连不上可能是网络问题也可能不是。先打开 Horizon 的 VNC 控制台看看虚拟机里网络接口的 IP 是什么,有没有拿到地址。

如果拿不到地址,多半是 DHCP 出问题。检查模拟器对应网络命名空间内的 dnsmasq 进程是否在跑:ps aux | grep dnsmasq。不在跑就重启 neutron-dhcp-agent,并看日志里是否有“port not bound”之类的提示。

如果 IP 拿到了但 SSH 不通,安全组是第一嫌疑。命令查看是否有 ingress 规则放通 22 端口:

openstack security group rule list

如果规则都在但依旧连不通,查看虚拟机所在网络的 MTU。前面讲过 VXLAN 场景的 MTU 问题,如果你发现 ping 小包正常但 SSH 卡顿,大概率就是 MTU 不匹配。

4.4 控制节点内存耗尽,服务全部假死

这是 Kolla 部署最常遇到的问题之一。控制节点同时跑着 MariaDB、RabbitMQ、Keystone、Neutron 的 DHCP 和 metadata agent、Horizon,内存轻易就飙到 90%。这类问题多数是因为 MySQL 的 buffer pool 设置过大,或 RabbitMQ 缓存了太多未消费消息。

处理建议:先看free -h是不是 swap 已经爆了,然后用docker stats看哪些容器内存占用最大。可以在 /etc/kolla/globals.yml 里配置 Docker 容器内存限制,但太激进会导致容器被 OOM killer 杀掉,反而不稳定。更稳妥的办法是控制节点加内存,或把非必要组件(如 ceilometer、swift)拆分到独立节点。

4.5 镜像上传后 status 不是 active 而是 queued

第一次上传大镜像时很容易遇到。Glance 上传是先存文件再入库,如果文件大、网络慢,状态会一直 queued。还有一个原因是磁盘空间不足:Glance 把镜像临时写入本地 /var/lib/glance,分区满了就永远无法 active。

排查时执行openstack image show <id>看 errors 字段;同时到控制节点检查磁盘空间。生产上建议给 Glance 配共享存储,比如直接把后端切到 Ceph RBD,这样镜像不会只存在一台机器上,后续计算节点拉取镜像也更快。

4.6 排障速查表

症状优先排查点常用命令
虚拟机卡 BUILD消息队列、placement 资源openstack server show ...、rabbitmqctl list_queues
服务状态 down时间同步、hostname 一致性chronyc tracking、openstack compute service list
虚拟机拿不到 IPDHCP agent、网络命名空间openstack network agent list、ip netns list、`ps aux
SSH 连不上安全组、浮动 IP、MTUopenstack security group rule list、ping测试
数据盘块打不满空间Cinder 后端超分配df -h、openstack volume show、检查 LVM 剩余
Horizon 登录 500Keystone endpoint、容器是否存活docker ps、openstack endpoint list、查看 keystone 日志
API 502/504HAProxy 配置、后端服务过载docker ps、openstack service list

5. 学习路径与最后建议

如果你已经读到这,大概率是准备动手了。我最后分享一个对我帮助很大的学习路径:先下载一个 Ubuntu 或 CentOS 云镜像,用 DevStack 在本地虚拟机里完整跑一遍,强制自己用命令行而不是网页完成所有操作;然后创建两到三个镜像、网络、路由器,实现两台不同网络的虚拟机能互相 ping 通;最后再做一次“删除全部资源”的练习。别小看这个练习,你在删除过程中会明白依赖顺序,比如有子网占用时不能删网络,有路由器占用时不能删子网。

接着可以进到 Kolla-Ansible 的真实部署,把 MySQL、RabbitMQ 无法启动、节点初始化失败这些坑都趟一遍。你有前面裸跑的底子,这些故障都能有比较清晰的排查方向。OpenStack 的生态很庞杂,我见过不少同学一头扎进源码里啃,结果被各种版本组合绕晕。反过来,从“我要在几台机器上跑出一朵自己可控的云”这个目标出发,按需去查组件,反而走得快。

我第一次部署成功时,看着openstack server list里活生生的 active 状态,那种感觉是真的开心。后来每次排障,也都会想起当时为了搞清 DHCP 为什么拿不到 IP 而连续折腾一个下午的场景。OpenStack 不是一个拿来即用、开箱即美的项目,它更像一整套需要精心养育的生命体。如果你能接受这个设定,愿意从最小场景开始动手,那它给你的回报——一套真正自主可控的私有云——也足够值得。

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

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

立即咨询