1. 部署之前的“灵魂拷问”:OpenStack到底值不值得自己搭
干了这么多年云计算运维,经常有人问我:“OpenStack是不是已经过时了?现在K8s不是更火吗?为什么还要学OpenStack?”
我的答案一直是:OpenStack没有死,它只是换了一种存在方式。K8s解决的是容器编排问题,OpenStack解决的是基础设施资源池化问题。企业内部私有云、运营商网络云化、科研机构高性能计算平台,这些场景大量跑在OpenStack之上。甚至很多K8s集群本身就构建在OpenStack提供的虚拟机之上。你会K8s不懂底层IaaS,就像会做饭但不认识买菜一样,卡在某一层上不去。
这篇博文我把OpenStack云计算部署的完整路径拆开讲一遍,从架构规划到环境准备,从部署工具选型到网络配置,再到验证测试和问题排查,每一步都给出我实际跑过的结论。适合刚接触OpenStack的运维工程师、准备做私有云立项的技术负责人,以及那些“文档看了不少、动手就废”的实操型学习者。
先说结论:全手动部署OpenStack不是不能做,但那是给“想彻底搞懂原理”的人准备的修行之路。如果你是为了交付一个可用的私有云环境,或者是为了在公司里快速搭建一套测试平台,用Kolla-Ansible这类自动化部署工具是更理性的选择。为什么这么说?后面我会详细讲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 部署方案选型与技术架构拆解
2.1 三种主流的OpenStack部署路径
我接触过的OpenStack部署方案主要分成三类:纯手动部署、脚本半自动化部署、容器化自动化部署。
纯手动部署就是按照官方文档一步一步敲命令、改配置文件、启动服务、做认证。这条路我当年走过一遍完整的——从Keystone开始,到Nova、Neutron、Glance、Cinder,一步步敲下来用了整整一周。好处是对组件的耦合关系理解非常深刻,坏处是效率太低、极易出错,而且每个组件版本之间都有各种兼容性暗坑。如果你主要目的是“搞懂原理”,可以走这条路;但如果你是为了交付项目,手动部署的效率完全跟不上。
脚本半自动化部署的代表是DevStack,它是OpenStack官方提供的开发测试工具,一条命令就能拉起一套all-in-one环境。DevStack确实快,但它不是为生产设计的,跑出来的环境网络配置、安全策略都是开发模式,适合功能验证和学习。还有一个叫PackStack的项目,Red Hat系产品里用得比较多,它帮你在多节点上批量安装组件,但它绑定的操作系统版本和发行版生态比较死,灵活度一般。
容器化自动化部署是目前我推荐的主流方式,代表就是Kolla-Ansible。它的核心思路非常优雅:把OpenStack的每一个服务组件都构建成Docker容器镜像,然后通过Ansible playbook在目标节点上批量编排部署这些容器。这样交付出去的OpenStack环境,底层是统一版本的容器镜像,升级、回滚、扩展都变得异常干净。
Kolla-Ansible还有两个关键变体:Kolla和Kolla-K8s。前者就是纯Docker容器化部署,后者是把OpenStack跑在Kubernetes之上。我的经验是Kolla-K8s目前在生产环境里的普及度还不高,多数团队还是选择Kolla-Ansible直接部署Docker容器,运维链路更短,排障也更直接。
2.2 节点角色与资源规划
部署OpenStack之前,第一件事是设计好节点角色。一个标准的生产最小集群至少需要三类节点:
控制节点(Controller)运行管理面服务,包括Keystone、Nova API、Neutron Server、Glance API、Cinder API、Horizon面板,以及消息队列RabbitMQ和数据库MariaDB。控制节点是整个云平台的大脑,对CPU和内存要求最高,尤其是数据库和消息队列的并发处理能力直接决定整个平台的稳定性。
计算节点(Compute)运行Nova-Compute服务和虚拟化层。这是真正加载云主机实例的地方。KVM是我最常用的Hypervisor,计算节点需要开启CPU硬件虚拟化(VT-x/AMD-V),内存资源也要留够,因为所有云主机的内存都是从这里分配的。
网络节点(Network)在传统L3 networking架构中负责路由、DHCP、浮动IP等网络功能。不过在新版本里,OpenStack已经支持了DVR(分布式虚拟路由),网络功能可以分散到计算节点上,网络节点就可以作为可选角色了。测试环境里我经常把控制节点和网络节点合在一起部署,生产环境还是建议分开。
存储节点不是必选,但建议单独规划。Cinder块存储服务需要独立的存储节点,或者对接已有的分布式存储系统。如果预算有限,也可以先用计算节点的本地存储,但这样会失去迁移和高可用能力,生产环境慎用。
资源规划方面我给出一个参考基准:三节点最小集群(一个控制节点、两个计算节点),控制节点建议8核16GB起步,计算节点根据业务需求规划,至少也要16核32GB起步。磁盘方面,控制节点系统盘100GB以上,计算节点根据云主机总量规划存储容量。这套配置支撑一个小团队几十台测试虚拟机问题不大。如果是生产环境或者规模更大,就需要单独规划网络节点、存储节点,控制节点也要做高可用。
2.3 网络架构的核心设计考量
OpenStack部署中最容易翻车的就是网络部分。Neutron负责管理虚拟网络,它牵扯到Linux Bridge、Open vSwitch、命名空间(Network Namespace)、iptables规则、路由表等一系列底层网络技术的协同工作。
我先用一张直观的部署层级来说明各层的关系:最底层是物理网络,承载管理流量、租户数据流量和外部网络流量。一般用VLAN把他们隔开,确保管理流量不被业务流量影响。中间层是Neutron创建的虚拟网络拓扑,通过命名空间、虚拟交换机和路由表实现租户隔离。最上层是云主机网卡和浮动IP等对外服务配置。
在部署方案选择上,Open vSwitch(OVS)是应用最广的机制驱动,很多复杂的网络功能如VXLAN、安全组、分布式路由都需要OVS支持。Linux Bridge则胜在简单稳定,资源占用低,适合小规模环境。我实际测试下来,在100台计算节点以内的规模下,Linux Bridge的单机稳定性和排障容易程度反而高于OVS。但如果你要大规模部署并需要VXLAN封装,还是得用OVS。
还有Provider Network和Self-Service Network这两个概念容易让新手混淆。Provider Network直接映射到物理网络,云主机拿到的IP就是物理网段IP,直连没有隔离,适合对外提供固定IP服务的场景。Self-Service Network是自己创建的隔离虚拟网络,云主机在里面拿虚拟IP,通过路由器访问外部网络,这也是最常用的多租户模式。
我在部署中最常用的网络拓扑是:管理网络走独立的物理网卡,租户网络通过VXLAN隔离,浮动IP池映射到外部物理网络的一个IP段。这个方案既能保证管理安全,又能灵活分配IP。
3. 实操准备:手把手初始化部署环境
3.1 操作系统与基础依赖
我这里推荐的操作系统是CentOS Stream 9,或者Ubuntu 22.04 LTS。为什么不用老版CentOS 7/8?因为OpenStack最新版本的官方容器镜像和依赖库很多已经开始淘汰老系统的适配了,你还要自己编译一堆东西,折腾且没必要。用CentOS Stream 9搭配最新版Kolla-Ansible,很多依赖包可以直接用系统源里的版本,省心不少。
内存资源不足时,需要用swap空间来兜底。控制节点我一般会额外划出4GB以上的swap,避免内存峰值导致服务被OOM Killer杀掉。
同时需要检查CPU是否开启虚拟化:
bash复制egrep -c '(vmx|svm)' /proc/cpuinfo
返回值大于0,说明虚拟化开启正常,否则需要到BIOS里打开VT-x/AMD-V。这一步不确认好,后面计算节点拉起云主机一定会失败。
3.2 配置主机名、hosts解析与免密登录
这一步看似基础,但很多人因为主机名解析没配好,后面部署的时候组件之间互相通信超时,排查半天发现是纯网络解析问题。
我习惯的命名方案是controller、compute1、compute2,然后修改每台机器的/etc/hosts,加入所有节点的解析记录:
bash复制192.168.100.10 controller
192.168.100.11 compute1
192.168.100.12 compute2
配置免密登录也提前做好,Ansible控制端需要能从controller免密SSH到所有compute节点。可以通过ssh-copy-id快速分发公钥。
3.3 磁盘分区与数据目录规划
磁盘规划得认真做。尤其要注意的是Docker存储目录和OpenStack数据目录不能放在同一个分区下,否则镜像和容器日志一涨,根分区被写满,整个平台直接瘫痪。
我习惯单独挂载一个大容量数据盘到/var/lib/docker,如果把默认数据目录迁移到独立磁盘位置,需要修改Docker的data-root参数,或者在部署时通过/etc/docker/daemon.json配置提前搞定。
3.4 部署前的内核参数调优
生产环境部署前,还需要统一优化内核参数。主要有这几个方面:
- 文件句柄和进程数限制,应用到所有节点:
bash复制echo "ulimit -n 655360" >> /etc/profile
- 网络栈调优,积压连接数、可用的端口范围这两项我建议提前调好:
bash复制cat >> /etc/sysctl.conf <<EOF
net.core.somaxconn = 65535
net.ipv4.ip_local_port_range = 1024 65535
fs.file-max = 2097152
EOF
sysctl -p
这些参数不提前调整,集群流量稍微上来一点就会出现连接拒绝、端口耗尽的问题,而且很难在第一时间联想到是内核参数没调。
4. 基于Kolla-Ansible的完整部署流程
4.1 安装Kolla-Ansible与Docker
Kolla-Ansible本质上是一个Ansible的角色和模块集合。安装它之前,先确认Python版本在3.8以上,然后通过pip安装:
bash复制pip install -U pip
pip install ansible-core>=2.14
pip install kolla-ansible
如果网络受限,需要配置公司内部的pypi镜像源。Docker安装则直接从操作系统官方源拉取,然后启动Docker服务并设为开机自启:
bash复制systemctl enable docker --now
这里有个细节:Docker默认的存储驱动建议选overlay2。确认方式看一眼docker info输出,如果有多个驱动被加载,可能性能会受损。
4.2 生成并定制globals.yml配置
Kolla-Ansible装好后有一个初始化命令,会帮你生成配置文件模板:
bash复制kolla-genpwd
cp -r /path/to/kolla-ansible/etc/kolla/* /etc/kolla/
修改/etc/kolla/globals.yml是最关键的步骤。我必须提醒你,这个文件里每个配置项都会直接影响最终的部署行为。我常用的核心配置参考如下:
yaml复制openstack_release: 2024.1
kolla_base_distro: "centos"
kolla_install_type: "source"
network_interface: "eth0"
neutron_external_interface: "eth1"
kolla_internal_vip_address: "192.168.100.10"
这里的kolla_install_type建议用source模式。binary模式是直接用镜像仓库里的预编译二进制包,安装更快但定制性差;source模式会比binary模式多编译一部分组件,但能保持版本一致性,出问题也更容易定位。
network_interface要改成你的管理网卡名,默认是eth0,但不少机器叫ens3或em1。neutron_external_interface则是承载浮动IP和外部网络流量的物理网卡,我习惯用独立的网卡,这样租户流量和外部流量不互相干扰,排障也清晰。
4.3 生成密码并初始化配置数据库
Kolla-Ansible支持将全部密码自动生成到一个密码文件中:
bash复制kolla-genpwd
这会在/etc/kolla/passwords.yml里生成一串随机密码。除非是为了调试,否则不要手动修改它。如果密码漏了或者想重置,也可以用kolla-genpwd -f /path/to/custom/passwords.yml单独生成。
初始化数据库和密钥对之前,先确认目标主机的Hostname映射正确、ssh免密可用,再用bootstrap命令把所有节点的依赖服务和目录结构准备好:
bash复制kolla-ansible -i /etc/kolla/multinode bootstrap-servers
等它跑完,控制节点上就会启动MariaDB、RabbitMQ、etcd和各类基础服务容器了,可以使用docker ps看看是否有这些基础容器正常运行。
4.4 正式执行部署并验证容器状态
正式部署:
bash复制kolla-ansible -i /etc/kolla/multinode deploy
这个过程根据机器性能和网络情况,从几十分钟到几个小时不等。如果中途失败,先别急着改配置重跑,去查看具体异常任务的输出和数据目录下的日志定位根因。Kolla-Ansible支持幂等重跑,修好问题后再执行一次deploy命令就行,不强求一次跑到结束。
部署成功后执行:
bash复制kolla-ansible -i /etc/kolla/multinode post-deploy
这个命令会生成一个包含环境变量的管理员认证文件,路径在/etc/kolla/admin-openrc.sh。拿到它,你才可以正常用OpenStack命令行工具操作平台。
4.5 生成初始化云环境脚本
Kolla-Ansible还有一个辅助脚本,帮你在部署完成后预置好镜像、网络和云主机类型等基础资源。通常路径在/usr/share/kolla-ansible/init-runonce。如果脚本不存在,手动创建网络和镜像也不复杂,只是需要按顺序执行几条命令。
这样一套下来,OpenStack基本就跑起来了。接下来重头戏是网络部分——这是云平台真正可用与否的分水岭。
5. 网络配置实战:从Neutron到外部网络打通
5.1 创建外部网络与租户网络
网络是整个OpenStack最容易出问题的环节,我把实际验证过的创建流程完整还原在这里。
外部网络对应物理网络中的浮动IP池,创建前先用admin环境变量文件认证管理员身份:
bash复制source /etc/kolla/admin-openrc.sh
然后创建外部网络并指定物理网卡上分出来的VLAN ID范围和网关、IP池:
bash复制openstack network create external --provider-physical-network physnet1 --provider-network-type flat
openstack subnet create external-subnet \
--network external \
--allocation-pool start=192.168.100.100,end=192.168.100.200 \
--gateway 192.168.100.1 \
--subnet-range 192.168.100.0/24
注意这里的provider-physical-network参数值physnet1必须和Neutron agent配置文件中映射的物理网络名一致。具体来说,是在neutron.conf配置里的bridge_mappings配置项里,把physnet1映射到你的网卡名,例如physnet1:eth1。
租户网络一般为项目内的虚拟机服务,默认隔离。创建命令示例:
bash复制openstack network create tenant-net
openstack subnet create tenant-subnet \
--network tenant-net \
--subnet-range 10.10.10.0/24 \
--gateway 10.10.10.1 \
--dns-nameserver 114.114.114.114
5.2 创建路由并关联接口
有了两个网络之后,需要创建路由器把它们关联起来,这样租户网络里的虚拟机才能通过浮动IP访问外部网络:
bash复制openstack router create demo-router
openstack router set demo-router --external-gateway external
openstack router add subnet demo-router tenant-subnet
到这里逻辑链路就算拉通了。接下来可以测试一下:网络命名空间内能否ping通外部网关。执行命令查看路由器的命名空间:
bash复制openstack network agent list
找到它的L3 agent所在节点,再执行:
bash复制ip netns exec qrouter-xxxxxx ping 192.168.100.1
如果网关通,说明外部网络链路正常。如果不同,逐个排查物理网络、安全组、路由表优先级。
5.3 安全组与浮动IP的配置注意点
我踩过最大的坑是忘记开安全组规则。OpenStack默认安全组只放行SSH和ICMP,如果你从外部ping不通云主机,97%的可能性是安全组规则没有放行ICMP。
手动放行命令:
bash复制openstack security group rule create --protocol icmp --ingress default
openstack security group rule create --protocol tcp --dst-port 22:22 --ingress default
另外给云主机绑定浮动IP用:
bash复制openstack floating ip create external
openstack server add floating ip <server-name> <floating-ip>
6. 核心组件联动逻辑与配置说明
6.1 服务间认证通信链路
OpenStack里的每个服务在启动时都需要向Keystone完成注册和认证,服务间的API调用也需要通过Keystone做token校验。部署时kolla-ansible已经把这一步自动实现了,服务配置文件里都写入了对应的service账号和密码。
我们用OpenStack命令行操作平台时,本质上也是先向Keystone请求一个scoped token,然后拿着token去访问Nova、Neutron等服务的API。所以当出现“401 Unauthorized”时,优先检查认证信息是否过期,重新source admin-openrc.sh或者执行openstack token issue验证一下即可。
6.2 Nova与Neutron的调度绑定
Nova创建云主机时,会先调用Placement服务查看哪个计算节点满足规格需求、哪个节点剩余资源足够,然后调用Neutron完成虚拟网卡的创建与网络接入,最后通知计算节点上的Nova-Compute通过libvirt创建KVM虚拟机。
这一串链路里任何一个环节出问题,创建云主机的动作就会卡住。我建议排查时按“API日志 → 消息队列 → 计算节点nova-compute日志”的顺序逐层看。比如你看到实例状态一直是BUILD但没有任何报错,很可能就是Neutron的网络创建超时,或者计算节点上的nova-compute进程内存溢出崩了。
6.3 Glance与Cinder的存储协同
Glance负责镜像管理,创建云主机时Nova会从Glance下载镜像到计算节点本地,作为系统盘启动。Cinder则负责块存储卷,你在Horizon里创建一块云硬盘并挂载到实例上,底层就是Cinder通过iSCSI或NFS协议把卷映射给计算节点。
我在small业务环境中,倾向于把Cinder存储在控制节点上通过NFS共享出来;而生产环境直接对接Ceph或商业存储阵列。跟Ceph对接时,记得确认openstack-ceph相关配置项里rbd pool名称、client keyring路径全部对应,否则挂载卷时会一直连接超时。
7. 部署后的功能验证清单
部署完成不等于一切正常。我每次交付环境前都会按照一个固定清单做功能验收,防止上线之后才发现问题。
我的验证清单如下:
- 查看所有服务列表:
bash复制openstack service list
确认所有服务都显示正常。
- 查看计算服务状态:
bash复制openstack compute service list
这里能确认nova-compute在哪个计算节点上是否可用,状态为上或disabled。
- 查看网络代理状态:
bash复制openstack network agent list
确认DHCP、L3、Metadata服务都处于ALIVE状态。
- 上传一个测试镜像:
bash复制openstack image create test-image --file cirros.qcow2 --disk-format qcow2 --container-format bare --public
CirrOS镜像体量小,适合做功能连通性测试。
- 创建最小规格云主机:
bash复制openstack flavor create m1.tiny --ram 512 --vcpus 1 --disk 1
openstack server create test-vm --flavor m1.tiny --image test-image --network tenant-net
- 等待虚拟机进入ACTIVE状态之后控制台登录验证,确认能ping通网关、能ping通外部IP。
这套清单跑完,平台从管理面到数据面的全部链路才算真正验证通过。
8. 部署过程中常见的坑与排查实录
部署和测试过程中,我整理了四类高频问题,这里逐条分享我的排查思路。
第一类:容器起不来或者反复重启。这问题基本集中在镜像拉取失败、磁盘空间不足、配置语法错误三类。先看docker ps -a看容器退出状态码,再docker logs看具体报错。若是镜像拉取失败,检查网络源和镜像源配置;若是磁盘不足,清理旧镜像或日志。
第二类:创建云主机一直卡在BUILD状态。这里优先查看nova-scheduler日志和nova-compute日志。最常见原因是计算节点没有开启嵌套虚拟化,或者libvirt默认驱动没配置好。另一个可能原因是内存超分关闭或者flavor规格超出节点可用资源。
第三类:租户网络内虚拟机无法上网。先验证DHCP命名空间内是否正常分配IP,然后检查路由器的外部网关是否连通,再逐段ping确认网络链路断在哪一环。如果虚拟机有IP但出不去,先看安全组是否放行ICMP和对应目的端口,再看路由器是否建立了SNAT规则。
第四类:Horizon界面打开报错。多数是控制节点的Apache容器没有正常加载缓存,或者Keystone的memcache服务宕了。重启相关容器一般能解决,但根因往往是某个服务内存超限被cgroup杀掉,注意观察宿主机的dmesg输出。
再分享两个反复遇到的环境级问题。一个是时间同步,OpenStack各服务间的token认证对时间偏移极其敏感,节点时间偏差超过五分钟就可能出现随机认证失败,务必在所有节点部署好chrony或NTP。还有一个是老生常谈的防火墙,部署前提前开放各服务端口,建议直接临时关闭firewalld,排障成本能低不少。
9. 从测试环境到生产:合规性、扩展与维护建议
测试环境跑通之后,如果想往生产推进,有几点我的个人建议可以供你参考。
首先是控制节点高可用。生产环境至少部署三个控制节点,通过Keepalived或HAProxy提供VIP负载均衡和故障切换,这会大幅提升平台可用性。Kolla-Ansible本身支持在多个控制节点上部署,但底层网络和VIP配置需要提前规划好。
其次是监控告警。用Prometheus搭配openstack-exporter把各服务指标拉起来,用Grafana展示。云平台这种组件繁多的系统,最怕的是异常的静默蔓延,而监控是把“问题”变成“告警”的唯一方式。
第三是升级和打补丁。Kolla-Ansible最大的优势之一就是升级路径清晰,可以在不中断业务的情况下逐个服务滚动升级。不过升级前务必先备份数据库、配置文件和各节点数据盘快照,核心组件的升级要选业务低峰期执行,并且准备好一套完整的回滚方案。
根据我个人的后续经验,这个部署操作手册还可以再扩展两个方向:一个是在此基础上引入Ceph作为统一存储后端,把块存储和镜像存储全部接入Ceph,这样能直接获得副本冗余和横向扩展能力;另一个是叠加K8s集群,在OpenStack上提供容器服务,形成私有云加容器云的一体化平台。两条路都值得深入研究,我也在实际项目中验证过可行性,只要底层OpenStack部署得够干净,上层扩展基本不会遇到结构性的阻碍。
