OpenStack云平台搭建实战:从架构规划到故障排查全指南
搭建OpenStack云平台这事听着像是只有大厂运维才碰的东西实际上我身边不少做虚拟化、做K8s底层支撑的同行都在自己折腾这套。原因也很简单公有云虽然省事但数据面、网络面、计费面都捏在别人手里想要完全可控的私有云OpenStack几乎是目前唯一一个既有社区活跃度、又有生产验证的开源选择。这篇文章把我从规划、部署到排错全流程的经验拆开写出来。不绕弯子先从最关键的架构决策讲起再一步步给你能直接抄作业的命令和配置最后把我踩过的坑、排查过的故障一并交代清楚。无论你是刚接触OpenStack的新手还是被分配了搭建任务的运维开发这套流程应该都能帮你少走很多弯路。1. 为什么要自己搭一套OpenStack而不是直接用现成云1.1 私有云的真实需求先说一个很多人没想明白的问题你到底是需要“一朵云”还是只需要“几台虚拟机”如果是后者装个KVM、装个Proxmox VE就够了完全没必要上OpenStack。OpenStack的价值在于它把计算、存储、网络这三块资源做成了统一的、可调度的、有租户隔离的云平台。我做过的模拟项目X就是这样业务方要求为内部多个团队提供按需申请的计算资源每个团队要有独立的网络隔离、独立的账号权限、独立的镜像管理还要能通过自助界面申请资源。这种需求用单机虚拟化根本撑不起来必须有一个带认证、带配额、带网络的云管平台。OpenStack恰好就是解决这一类问题的。当然选择OpenStack也意味着接受它的复杂度。组件多、服务多、概念多任何一个环节配错都可能导致整个系统不可用。这也是为什么我建议第一次搭建时不要追求生产级的高可用先把核心组件跑通理解了服务之间的依赖关系再考虑扩展。1.2 裸机虚拟化、K8s和OpenStack的区别很多刚接触云计算的人会把OpenStack和Kubernetes混为一谈其实两者的定位完全不同。K8s管的是容器OpenStack管的是虚拟机也可以管裸机但那是Ironic组件的事。K8s的调度对象是PodOpenStack的调度对象是实例。K8s本身不关心底层的计算资源是怎么来的而OpenStack正好负责把计算资源池化、虚拟化、网络化。实际生产环境里完全可以用OpenStack作为IaaS层在它上面再部署K8s集群这样K8s的节点可以按需扩容底层资源由OpenStack统一调度。我见过一个挺典型的场景某公司原本直接用物理机部署K8s扩容一次要采购硬件、人工装机、配置网络周期动辄两周。后来改成OpenStack提供虚拟机作为K8s节点扩容时间缩短到分钟级而且节点规格可以通过flavor灵活调整资源利用率明显提升。1.3 先想清楚这几件事再动手动手之前有几个问题必须先有答案否则搭建过程中很容易反复返工。第一网络方案。Neutron支持Flat、VLAN、VXLAN等多种模式选择哪种直接影响物理交换机的配置、IP地址规划、租户网络的隔离方式。我建议第一次搭建用VLAN模式兼容性好排查问题也比VXLAN简单。第二存储方案。如果只是测试环境用本地磁盘加LVM就够了不需要单独部署Cinder。如果涉及块存储服务就要考虑后端存储怎么接是Ceph还是NFS还是其他商业存储这会显著影响架构复杂度。第三版本和部署工具。OpenStack每半年左右发一个版本社区推荐的部署工具也在变化选型时需要确认是手动部署还是自动化部署这决定了后续的工程量和维护成本。2. 环境规划与版本选型决定后续是否踩坑2.1 节点规划与硬件建议一套最精简的OpenStack环境至少需要两个节点一个控制节点一个计算节点。控制节点承载认证、镜像、调度、网络管理等服务计算节点负责运行虚拟机实例。实际搭建时我给模拟项目X分配的节点方案如下节点角色服务组件最低配置建议备注控制节点Keystone、Glance、Placement、Nova API、Neutron Server、Horizon4核CPU / 8GB内存 / 100GB硬盘建议系统盘与数据盘分开计算节点Nova Compute、Neutron Agent、KVM/QEMU8核CPU / 16GB内存 / 200GB硬盘根据业务量弹性调整可选存储节点Cinder、Ceph按容量规划测试环境可省略如果你只有一台物理服务器也可以把控制节点和计算节点放在同一台机器上但这种单节点模式只适合学习验证不适合运行真实业务。2.2 网络方案怎么选网络是OpenStack里最复杂也最容易出问题的部分。我把常见三种模式的特点整理成了一张表网络模式隔离方式优点缺点Flat不隔离配置最简单只能用于测试VLAN802.1Q虚拟局域网兼容性好、性能稳定依赖物理交换机配置VXLANOverlay隧道大规模扩展性好故障排查难度较大我个人的建议是第一次搭建用VLAN模式将物理网卡划分出管理网、数据网和外部网。管理网用于服务之间的通信数据网承载虚拟机流量外部网用于访问云主机。三个网络尽量用不同网段和不同物理网卡避免流量互相干扰。2.3 版本和部署工具的选型逻辑OpenStack的版本代号从字母A到Z按字母表命名每个字母对应一个版本。我搭建时用的是Yoga版本算是比较稳定可靠的一个版本不同发行版自带的OpenStack包版本不同需要先确认发行版软件源里提供的版本。部署工具方面有几种选择一是纯手动部署按照官方文档逐个安装配置服务。这种方式最能帮助你理解各个组件的原理但工作量大容易出错适合学习场景。二是使用RDO或PackStack这是基于某个Linux发行版的OpenStack部署工具可以用一条命令搭建基础环境适合快速验证。三是以Kolla-Ansible为代表的容器化部署方案把OpenStack服务打包成容器配合Ansible自动化编排。这种方式是目前生产环境的主流选择升级回滚方便部署一致性好。我在正式交付给某公司做内部培训时用的就是Kolla-Ansible方案。但如果你希望把OpenStack的内部机制彻底搞懂我建议至少手动部署一次核心组件这个认知价值无法替代。提示无论选择哪种部署方式都建议先在虚拟机里做一遍完整的演练。不要在物理机上一上来就跑全程OpenStack部署过程中的各种网络配置、依赖冲突、服务启动失败在小规模实验环境里更容易定位问题。3. 基础环境配置系统、网络与依赖3.1 操作系统与基础服务OpenStack对操作系统要求不低但核心原则就是使用长期支持版本避免新版本软件源不稳定。我搭建时用的是基于Linux内核的主流服务器发行版LTS版本这类系统社区支持时间长、软件包齐全、遇到问题容易搜到答案。系统装好之后第一件事就是配置主机名和hosts文件。三个节点的主机名我规划为controller、compute1在/etc/hosts中把节点IP和主机名的对应关系写清楚。这一步看似简单但很多服务之间是通过主机名通信的如果hosts配置错误后面会出现各种诡异的认证失败和服务连接超时。然后创建一个专用的系统用户用于执行OpenStack相关操作。生产实践中不建议直接用root操作因为OpenStack的配置文件、日志文件、虚拟化操作都有独立的权限体系单独的用户便于管理和审计。3.2 网卡和桥接配置实操以控制节点为例通常需要至少两块网卡一块用于管理网络一块用于外部网络。在配置网络之前先确认物理网卡的名称然后编辑网络配置文件。管理网卡的配置比较简单设置静态IP即可。外部网卡需要配置为桥接模式因为在OpenStack里外部网络是通过网桥与物理网络连接的。我用一个例子来说明cat /etc/network/interfaces.d/br-ex.cfgauto br-ex iface br-ex inet static address 192.168.68.20 netmask 255.255.255.0 gateway 192.168.68.1 dns-nameservers 192.168.68.1这段配置的含义是创建一个名为br-ex的Linux网桥给它配置静态IP地址。物理网卡上不配置IP而是把它加入网桥。这样虚拟机通过网桥就能访问外部网络配置思路跟家用路由器里的“桥接模式”是一个道理。配置完成后一定要重启网络服务并验证连通性我在早期搭建时经常遇到网卡配置冲突导致SSH断开的问题所以强烈建议在本地控制台或带外管理界面操作网络配置避免把自己锁在外面。3.3 时钟同步与软件源OpenStack的认证服务高度依赖精确时间时间偏差超过几分钟就可能导致令牌校验失败。NTP是必须配置的控制节点同步外部时间源计算节点同步控制节点。chronyc sources -v配置完成后用这条命令检查时间同步状态。如果输出显示时间源处于活跃状态说明同步正常如果显示^*或*符号说明已锁定到时间源。软件源也建议提前配置因为OpenStack组件依赖大量其他软件包默认软件源下载速度慢或者缺少必要包会导致安装中断。我记得有一次安装网络服务时因为依赖包版本冲突整整花了一个下午排查最后发现是软件源里的包版本和OpenStack版本不匹配。4. 核心组件部署从认证到计算4.1 先搭认证服务KeystoneKeystone是OpenStack所有服务的“门卫”其他所有组件在调用API之前都要先经过认证和权限校验。所以搭建顺序必须是先创建Keystone再创建后续服务否则后续组件创建用户和端点时会失败。创建Keystone的数据库、服务凭证和API端点都需要设置统一的认证信息。我习惯用一个环境变量文件统一管理这些信息每次操作前先加载export OS_PROJECT_DOMAIN_NAMEDefault export OS_USER_DOMAIN_NAMEDefault export OS_PROJECT_NAMEadmin export OS_USERNAMEadmin export OS_PASSWORD你的强密码 export OS_AUTH_URLhttp://controller:5000 export OS_IDENTITY_API_VERSION3这个环境变量文件在实际操作中非常重要。日志排查时如果API请求返回401八成就是环境变量里的密码或项目名写错了。我建议把这套环境变量放在/root/openrc这样的独立文件里每次需要执行OpenStack命令就先source一下。4.2 镜像服务Glance与镜像上传Glance负责管理虚拟机镜像可以理解成云主机模板的仓库。安装好Glance之后必须上传一个至少可用的系统镜像后续创建云主机才有模板可用。挑选镜像时我建议用官方提供的云镜像这类镜像预装了cloud-init工具能够自动完成主机名配置、SSH密钥注入、分区扩容等初始化操作。上传命令openstack image create --disk-format qcow2 --container-format bare \ --public --file ubuntu-server.qcow2 ubuntu-serverqcow2是镜像格式bare表示容器格式为裸镜像这两个参数是镜像服务要求的必填项。--public参数表示所有项目都能使用这个镜像如果不想让租户看到可以改成--private。上传完成后用openstack image list确认镜像状态是active。我遇到过一次镜像状态一直卡在queued的情况后来发现是控制节点磁盘空间不足Glance无法把镜像文件完整写入存储目录。4.3 计算服务Nova的控制与计算节点Nova是OpenStack的计算核心分为控制节点的Nova API、调度器和计算节点上的Nova Compute。控制节点负责接收创建虚拟机的请求计算节点负责真正通过KVM或QEMU启动虚拟机。配置Nova之前必须先注册Placement服务这是负责资源跟踪的组件。Placement的作用相当于一个资源台账记录每个计算节点剩余多少CPU、多少内存Nova调度器在收到创建请求后会根据Placement提供的数据决定把VM调度到哪台物理机上。我第一次部署时漏掉了Placement导致虚拟机创建一直报“No valid host was found”日志里全是调度失败的报错。后来把Placement的数据库和服务注册补齐问题马上解决了。4.4 网络服务Neutron的配置要点Neutron配置是整个部署过程中最讲究的部分因为它涉及很多网络概念网络、子网、路由、端口、安全组、DHCP代理、Open vSwitch网桥等。配置时有两个点最容易被忽略。第一Neutron的认证配置必须和Keystone保持一致。很多人在配置Neutron时只改了数据库连接、改了口令却漏了认证类型和API版本结果Neutron服务启动后无法和Keystone正常通信所有网络创建请求都返回认证失败。第二DHCP代理和L3代理要确保在正确节点上启动。控制节点上需要启动neutron-dhcp-agent为租户网络分配IP地址启动neutron-l3-agent管理虚拟路由器的NAT和南北向流量。这两个代理服务如果没起来创建网络不会报错但创建出来的虚拟机获取不到IP地址这是非常常见的问题。我习惯在配置完成后用如下命令检查代理状态openstack network agent list输出中每个代理的状态都应为Alive。如果出现xxx not running的字段就需要回到对应节点查看服务日志。5. 验证与第一台云主机的诞生5.1 命令行验证所有服务核心组件全部装完之后先不要急着在界面上操作用命令行把所有服务状态过一遍。我总结了一套快速验证流程openstack service list openstack endpoint list openstack image list openstack compute service list openstack network agent list这几条命令分别验证服务目录、API端点、镜像状态、计算节点的服务状态、网络代理状态。如果有任何一项输出异常都应该先排查清楚再继续否则后续创建云主机时会把问题复杂化。5.2 创建网络、路由与云主机现在到了最激动人心的环节——创建第一台云主机。先创建租户网络。假如规划用一个192.168.100.0/24网段给云主机分配地址openstack network create demo-net openstack subnet create demo-subnet \ --network demo-net \ --subnet-range 192.168.100.0/24 \ --dhcp为了访问外部网络还需要创建路由连接外部网络。这一步相当于给云主机加了一个默认网关没有路由的话云主机只能在租户网络内部互通无法访问外部。创建云主机的命令openstack server create --flavor m1.small --image ubuntu-server \ --network demo-net --key-name mykey my-first-instance其中m1.small是定义好的规格模板包含虚拟机的CPU、内存、磁盘大小需要提前用openstack flavor create创建。--key-name指定SSH密钥如果没有配置密钥创建后只能通过VNC控制台或密码登录这在自动化和后续运维中不太方便。创建完成后用openstack server list查看状态当状态变为ACTIVE说明云主机已经成功启动。5.3 通过Horizon可视化操作命令行之外OpenStack还提供了Horizon仪表盘。虽然不是核心组件但装上它对日常使用和排错都很有帮助。Horizon装好之后用浏览器访问控制节点的IP地址输入之前创建的账号密码就能在图形界面里创建实例、管理网络、查看控制台日志、调整安全组规则。我个人认为Horizon更适合给业务方当自助门户而运维排障时还是命令行更快更直接。业务方不需要懂OpenStack概念只需要在界面上点击申请资源运维人员则应当熟练命令行因为很多底层错误信息只会在API日志里出现界面上根本看不到。6. 常见问题与排查实录6.1 实例无法获取IP这是我遇到过最多的故障几乎每次都会有人来问。云主机创建成功状态是ACTIVE但进到系统里发现网卡没有IP地址。排查路径按顺序来先看Neutron代理是否存活再看DHCP命名空间是否创建成功然后查看DHCP租约数据库中是否有IP分配记录。这三个环节任何一个中断都会导致IP获取失败。我做过一次印象很深的排障所有代理都正常DHCP租约也有记录但虚拟机就是拿不到IP。后来查了半天发现是物理节点iptables规则把DHCP请求的UDP 67端口拦掉了。解决方式是确认OpenStack所需的防火墙端口全部放行同时检查宿主机自身的iptables规则是否干扰了虚拟机的DHCP流量。6.2 云主机创建失败与日志定位云主机创建失败的表现通常有两种同步等待的时候状态卡住或直接报错说没有可用主机。遇到这类问题我的第一反应是看Nova调度器和计算节点的日志因为创建VM的主要工作都在这两个节点上。日志路径是/var/log/nova/重点看nova-compute.log和nova-scheduler.log。我整理过一份常见问题速查表故障现象可能原因排查命令/日志实例状态一直BUILD镜像格式错误或磁盘空间不足查看nova-compute.log报No valid hostPlacement资源数据不准确检查Placement服务状态连不上VNC控制台控制台代理地址配置错误查看nova.conf中vnc配置实例访问外部超时路由或安全组规则问题openstack路由列表、安全组规则定位问题时不要只看表面报错要顺着日志里的时间戳和请求ID一层层往上翻。Nova组件之间的调用都有请求ID根据这个ID可以在各个服务日志中串联出一条完整的调用链。6.3 服务状态异常的排查路径当某个服务启动失败或状态异常时我有一套固定的排查顺序第一步确认服务进程是否存在systemctl status查看。第二步查看对应的日志文件通常位于/var/log/对应服务目录下。第三步检查配置文件的语法和权限很多服务配置错误只是启动时报错但日志写的比较模糊需要手动核对配置文件。还有一个经常被忽略的细节OpenStack各服务运行的用户和用户组不同如果日志目录权限不对服务启动时写日志就会失败导致服务重启后一直处于异常状态。我在某次部署中遇到过Neutron服务反复重启查了一圈最后发现是日志目录属主不对调整权限后服务立刻恢复了。注意生产环境中重启某个服务前务必确认是否影响正在运行的业务。例如重启计算节点上的nova-compute服务会中断该节点上所有运行中的虚拟机。在测试环境随便重启没什么关系但生产环境一定要先规划好维护窗口。7. 写在最后的运维心得OpenStack这套东西部署只是万里长征第一步。真正拉开差距的是后续的监控、告警、备份、升级、故障恢复这些运维能力。我后来在给某公司做内部支持时最深的体会是部署文档到处都是但“如何优雅地运维”才是真正有门槛的部分。我现在只要搭完一套环境会立刻把所有的配置分区、服务节点、账号信息、网络规划整理成一份清单放在团队统一的知识库里。这份清单在故障排查和人员交接时的价值比任何部署文档都大。另外强烈建议把OpenStack各服务的配置目录纳入版本管理哪怕只有两个人协作也能避免“我改了配置文件但忘了改了什么”这种尴尬局面。如果你正准备开始搭建自己的OpenStack云平台就从最精简的两节点架构开始先跑通再谈优化。等你的环境里有了监控、有了备份、有了灰度升级的流程再回头看第一天的搭建过程会发现很多当初觉得莫名的坑其实都是架构规划时埋下的雷。