
搞OpenStack Queens这套环境我接着上一篇往下写。上次把基础环境、网络规划、YUM源这些准备工作搞定了这次进入重头戏——控制节点上的三个基础设施服务数据库、消息队列、缓存。为什么要单独拿一篇来讲这三个因为它们不只是给OpenStack用的而是控制节点上几乎所有核心组件Keystone、Nova、Neutron、Cinder、Glance这些都要依赖的底层服务装不好后面全得返工。我见过不少人在这一步图省事结果后面各组件之间连不上、数据写不进去、服务互相等不到排查起来非常痛苦。这篇就把我实际搭建过程中整理的步骤和经验完整写出来如果你正在装Queens控制节点可以直接照着操作少走不少弯路。1. 开工前先把三件套的角色理清楚1.1 为什么控制节点必须最先装这三样先别急着敲命令我们把原理过一遍。OpenStack里面每个组件都有自己的职责但它们之间不是孤立的需要共享数据、发送消息、缓存会话这三件事分别对应数据库、消息队列和Memcached。数据库的作用最好理解。Keystone要存项目、用户、角色、服务目录Nova要存实例的元数据Neutron要存网络和端口信息Cinder要存卷的类型和快照信息。OpenStack各组件默认都是通过SQLAlchemy访问数据库在Queens版本里官方默认用MariaDB来跑这些数据你完全可以把数据库理解成整套系统的“记忆中枢”所有组件启动时都要先连上它连不上服务就起不来。消息队列是另外一回事。OpenStack各组件之间不是直接互相调API的而是通过消息队列异步通信。比如Nova想创建一个实例它会往消息队列里发一条消息等Nova-Compute节点上的服务去消费这条消息。Queens版本默认的消息队列是RabbitMQ。你可以把消息队列想象成一个快递中转站各组件把任务包裹丢进去再由对应的服务取走处理。这样的话各组件不必同时在线也不用知道彼此的地址松耦合度非常好但前提是RabbitMQ必须稳定可用。Memcached的作用相对轻量但千万别小看它。它是内存缓存服务主要给Keystone、Nova这些组件存临时会话Token和缓存对象。就拿Keystone来说用户认证成功后会得到一个Token在Token有效期内各个服务都需要频繁校验这个Token如果每次都去查数据库性能会很难看。放在Memcached里内存读取比数据库查询快几个数量级整个系统的认证和鉴权效率就上来了。所以三件套是控制节点的大动脉我把它们放在环境搭建系列的最前面顺序也是数据库先装、消息队列其次、缓存最后这是最稳妥的流程。1.2 三件套之间的协作关系你可能会问这三个服务分别装好了就算完事吗不是它们之间其实还有一点微妙的关联。数据库和RabbitMQ本身没有直接通信关系但它们都会被同一个OpenStack组件引用。比如Nova的配置文件里既要写database连接字符串又要写transport_url指向RabbitMQ。所以装完三件套之后你最好做一次横向检查数据库能连、RabbitMQ能登录、Memcached能读写三者独立可用后面各组件才能分别连上它们。Memcached在这里比较特殊它不参与组件间的数据同步纯粹是性能辅助。所以它对网络要求不高只要控制节点和需要用到缓存的服务主要是Keystone和Nova之间能通就行。在生产环境里为了安全Memcached会只监听内网IP或特定网段而不是默认的0.0.0.0这个后面我会专门说到。另外要提醒一句这三个服务都不建议装完就扔在那里不管。安装只是第一步配置文件的几个关键参数才是真正决定后面会不会踩坑的地方。比如数据库的bind-address、字符集RabbitMQ的hostname解析、用户权限Memcached的监听地址每一个都值得单独花几分钟确认一遍。2. 基础环境准备要点2.1 主机命名与hosts解析在正式安装三件套之前我强烈建议你先确认控制节点的主机名和/etc/hosts解析。这一步很多人忽略结果RabbitMQ起不来或者集群模式下找不到节点原因往往就是主机名没对上。我的实验环境里控制节点主机名是controllerIP是管理网段的10.0.0.11。你不要小看RabbitMQ对主机名的依赖RabbitMQ在启动时会用主机名来生成节点名称默认格式是rabbit主机名。如果主机名解析不了会出现RabbitMQ启动失败或者日志里报节点名不对的怪异问题。建议在安装前先确认这些内容hostname cat /etc/hostname然后在/etc/hosts里写好本机解析10.0.0.11 controller不要自作聪明把其他节点的hosts也一起写进来控制节点只需要能解析自己和其他可能用到的节点就行。比如我后续还要装compute节点就先预留一行10.0.0.11 controller 10.0.0.31 compute12.2 时间同步、YUM源与安全策略如果上一篇文章里你没做时间同步现在补上。OpenStack组件对时间同步非常敏感尤其是Keystone的Token有效时间判断以及各组件日志的时间对齐。如果控制节点和计算节点时间差太多后续会出现“Token签发时间异常”“消息队列心跳超时”这类诡异问题。我的做法是直接用chrony安装后配置文件里指向一个可靠的NTP服务器如果内网有NTP服务器最好没有的话用公共NTP也行。安装三件套之前先跑一遍yum install chrony -y systemctl enable chronyd systemctl start chronyd chronyc sources确认时间已经同步再进入下一步。YUM源这里我默认你已经配置好了OpenStack Queens的源我上一篇已经写过了。如果没有先搞定源再装包。尤其注意Queens版本在CentOS 7上可以直接用官方源安装包命名都很规范。装MariaDB的时候我建议直接用系统源里的版本Queens和它兼容性没问题不需要额外折腾第三方源。关于防火墙和SELinux我直接说结论实验环境先把SELinux设为permissive防火墙直接关掉否则配置过程会冒出很多莫名其妙的问题。生产环境当然要认真开防火墙但那是另一个话题。这里为了把核心逻辑讲清楚先在测试环境把这些干扰因素排除setenforce 0 sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config systemctl stop firewalld systemctl disable firewalld到这里基础环境才算真正准备好下面开始装第一个服务。3. 数据库从安装MariaDB到创建OpenStack账号3.1 安装MariaDB并解决常见坑先说一句标题里写了MySQL但Queens版本官方推荐的后端其实是MariaDB。原因很简单MariaDB是MySQL的一个兼容分支OpenStack社区在Queens周期已经全面转向MariaDB。功能上你用MariaDB完全能跑OpenStack而且在CentOS 7上装起来比装MySQL更省心。安装就两个包一个服务端一个客户端yum install mariadb-server mariadb -y装完先不急着启动先改配置文件。这一步特别重要CentOS 7的MariaDB默认配置文件分散在多个地方主配置是/etc/my.cnf它会include /etc/my.cnf.d目录下的所有.cnf文件。我习惯在/etc/my.cnf.d/目录下新建一个专门给OpenStack用的配置文件不要直接改主配置方便以后维护。我见过不少新手上来就systemctl start mariadb结果启动之后数据目录千奇百怪字符集也没定到后面创建数据库表的时候全是乱码或者排序错误。我的做法是启动前先把关键参数写进配置[mysqld] bind-address 10.0.0.11 default-storage-engine innodb innodb_file_per_table on max_connections 4096 collation-server utf8_general_ci character-set-server utf8这里讲一下每个参数为什么这么配。bind-address必须写控制节点的内网IP这样其他节点才能通过管理网络连接数据库如果你写成127.0.0.1那只能本机访问计算节点连接数据库时就会直接失败。default-storage-engine选innodb这是OpenStack社区推荐的事务型存储引擎避免数据不一致。innodb_file_per_table设为on让每个表单独一个文件方便后续备份和清理。max_connections设4096OpenStack组件多、线程多默认的151连接数在繁忙时肯定不够。字符集必须指定utf8不然建表之后中文注释、Token信息都容易出编码问题。配置完后启动并设置开机自启systemctl start mariadb systemctl enable mariadb接着跑官方提供的安全初始化脚本mysql_secure_installation这个脚本会引导你设置root密码、删除匿名用户、禁止root远程登录、删除测试数据库。我建议都选是。注意root在OpenStack里不是拿来给业务组件用的后面我们要创建专门的openstack用户root只留给管理员维护用。3.2 my.cnf关键参数与初始化安全这里再展开讲一下为什么字符集和连接数这么关键。在实际OpenStack运维中数据库连接数被打满是我见过频率最高的故障之一。你想想控制节点上Keystone、Glance、Nova、Neutron、Cinder、Placement这些组件默认都会各自建立连接池连接数很快上去。max_connections设为4096不是拍脑袋我测试下来在一台4C8G的控制节点上稳定跑一个基础OpenStack环境连接数一般在800到1500之间4096基本够用。字符集方面collation-server和character-set-server必须统一。如果你只设置了character-set-server忘了collation有些版本会默认用latin1的排序规则在查询时会出现比较错误。我建议两个都写上且都用utf8的变体。安全初始化脚本跑完后验证一下数据库端口有没有监听正确ss -lntp | grep 3306正常会看到3306端口监听在10.0.0.11上如果监听在127.0.0.1上说明bind-address没生效回去检查配置。3.3 为OpenStack创建数据库账号数据库准备好了接下来创建OpenStack专用的账号。官方推荐的做法是为数据库创建一个专用用户通常叫openstack密码自己设一个复杂点的。后期所有OpenStack组件都用这个账号连接数据库通过不同库名区分各个组件的数据。先登录数据库mysql -u root -p然后执行下面这些SQLCREATE DATABASE IF NOT EXISTS keystone CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE IF NOT EXISTS glance CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE IF NOT EXISTS nova CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE IF NOT EXISTS nova_api CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE IF NOT EXISTS nova_cell0 CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE IF NOT EXISTS neutron CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE IF NOT EXISTS cinder CHARACTER SET utf8 COLLATE utf8_general_ci; GRANT ALL PRIVILEGES ON keystone.* TO openstacklocalhost IDENTIFIED BY 你的密码; GRANT ALL PRIVILEGES ON keystone.* TO openstack% IDENTIFIED BY 你的密码; GRANT ALL PRIVILEGES ON glance.* TO openstacklocalhost IDENTIFIED BY 你的密码; GRANT ALL PRIVILEGES ON glance.* TO openstack% IDENTIFIED BY 你的密码; -- 其他库照葫芦画瓢 -- ... FLUSH PRIVILEGES;我先说一个小技巧如果你后面不确定需要哪些组件也完全可以先把openstack用户建出来等安装每个组件的时候再创建对应的数据库。因为GRANT语句本身就有“数据库不存在就报错”的限制所以你最好先创建库再授权。上面这段SQL我习惯一次性把Queens主推的几个库都建好后面分组件做数据库同步时就不用再回头建库了。还有一个细节为什么授权用户要同时写localhost和%因为组件在控制节点本机连接时走socket可能表现为localhost而其他节点比如计算节点上的Nova-Compute远程连接时走TCP会匹配%。两个都授权确保本机和远程都能连上。最后验证mysql -h 10.0.0.11 -u openstack -p -e SHOW DATABASES;能列出上面创建的数据库就说明没问题。4. 消息队列RabbitMQ安装与授权4.1 安装RabbitMQRabbitMQ在Queens环境里负责所有组件间的异步消息转发。安装并不复杂但有几个细节值得注意。CentOS 7下直接yum install rabbitmq-server -y装完之后先启动一次因为后续很多操作都需要RabbitMQ服务处于运行状态systemctl start rabbitmq-server systemctl enable rabbitmq-server如果启动失败优先去看日志位置在/var/log/rabbitmq/。最典型的失败原因就是之前提到过的主机名解析问题或者Erlang版本冲突。我在干净环境里没遇到过冲突但如果你之前装过Erlang最好检查一下版本。4.2 创建用户并授权RabbitMQ默认有一个guest用户但它只能通过localhost访问OpenStack组件通常是远程连接所以不能用guest。官方推荐的做法是创建一个名为openstack的用户密码自定义。先添加用户并设置密码rabbitmqctl add_user openstack 你的密码然后把用户设置为管理员因为后续某些组件可能需要管理端权限rabbitmqctl set_user_tags openstack administrator最后授权OpenStack组件的消息队列默认使用一个叫openstack的虚拟主机vhost我们需要创建它并给用户全部权限rabbitmqctl add_vhost openstack rabbitmqctl set_permissions -p openstack openstack .* .* .*这里解释一下三个.*的含义它们分别是配置权限、写权限、读权限的通配符正则表示允许该用户在openstack这个虚拟主机上做所有操作。不要只授权一两个否则后续组件可能莫名其妙报“ACCESS_REFUSED”。检查一下用户列表rabbitmqctl list_users rabbitmqctl list_permissions -p openstack正常能看到openstack用户以及对应的权限。4.3 开启Web管理插件虽然命令行已经能管理RabbitMQ但我强烈建议顺手把Web管理插件打开后面排查消息队列拥堵、查看连通情况时图形界面非常直观。rabbitmq-plugins enable rabbitmq_management然后重启服务让插件生效systemctl restart rabbitmq-server浏览器访问http://控制节点IP:15672用openstack用户登录。注意15672是管理界面的端口消息传输本身走5672端口。如果Web管理界面打不开检查是否打开了防火墙端口或者SELinux是否拦截。我在实验环境已经关了防火墙所以直接能访问。这里我再补充一个经验RabbitMQ的Web管理界面不仅能看到队列数量还能看到每个连接的来源IP。当后面某个组件连接不上或者收不到消息时我会先来这里看有没有对应的连接记录。没有连接记录说明是客户端配置的问题不是RabbitMQ本身的问题。这个判断方法帮我省了大量排错时间。5. 缓存Memcached安装与连通验证5.1 安装与参数说明Memcached是三个服务里最轻量的安装也就一条命令yum install memcached -y但配置上有个容易踩的坑就是监听地址。默认情况下CentOS 7里Memcached监听在127.0.0.1只有本机能访问。可OpenStack其他节点也需要访问它比如计算节点上的Nova服务要校验Token时会从Memcached读取对应的缓存数据。所以要把监听地址改成控制节点的IP。编辑/etc/sysconfig/memcached修改OPTIONS那一行OPTIONS-l 10.0.0.11,::1然后启动systemctl start memcached systemctl enable memcached说下为什么这里把IPv6的::1也保留。因为某些组件默认解析localhost时可能走IPv6保留::1可以避免本机访问时的解析异常。如果你拿不准干脆写OPTIONS-l 0.0.0.0不推荐在公网环境这么做但在内网实验环境0.0.0.0最省事所有节点都能连。5.2 验证Memcached可用验证Memcached是否正常传统方法是用telnet连接11211端口然后手动发两个命令telnet 10.0.0.11 11211连接成功后输入stats回车如果返回一堆以STAT开头的统计信息说明服务正常。再输入set test_key 0 60 4 test然后输入get test_key能读到test这个值说明读写都正常。最后输入quit退出。我习惯再做一个跨节点测试就是写个小脚本从计算节点那边连接一下控制节点的Memcached。这一步能提前发现防火墙、网络路由方面的问题避免后面装计算组件时才发现缓存不通。如果你不想装telnet也可以用nc命令yum install nc -y printf stats\n | nc 10.0.0.11 11211能输出统计信息就行。Memcached这块整体上没太多玄机把监听地址改对、端口能通、启动自启设好基本就完事了。6. 三件套联调与故障排查经验6.1 整体状态核对三个服务都装完之后别急着往下走先把三件套作为一个整体做一次联调。我的核对流程是固定的全部走一遍也就两三分钟但能排除掉大部分“配置错了但没发现”的隐患。第一步检查服务状态systemctl status mariadb systemctl status rabbitmq-server systemctl status memcached三个都应该是active (running)。如果有启动失败的按之前日志去排查。第二步检查监听端口ss -lntp | grep -E 3306|5672|112113306对应MariaDB5672是RabbitMQ的消息端口11211是Memcached。这三个端口都监听在控制节点IP上才算正常。如果发现某一个只监听127.0.0.1那基本就是配置文件里的bind地址写错了。第三步做一次真实的远程连接测试。如果环境里还有一台测试机或计算节点可以从那边分别连一下三个服务。数据库可以用mysql命令RabbitMQ用rabbitmqctl status在控制节点本机跑也行Memcached用nc发stats命令。第四步检查数据库里是否能正确读写。这一步可以在控制节点执行mysql -h 10.0.0.11 -u openstack -p -e SELECT 1;能返回结果即可。RabbitMQ这边用openstack用户登录管理界面确认虚拟主机存在且连接数为0或正常即可。6.2 常见问题速查表我把自己搭建过程中遇到过的、以及帮别人排查过的问题整理成了表格三条服务的问题分开看更清楚服务症状可能原因解决办法MariaDB服务启动失败数据目录权限错误或my.cnf配置错误查看/var/log/mariadb/mariadb.log修正配置后重启MariaDB远程连接失败bind-address没改或防火墙拦截openstack用户未授权%改配置文件、授权、关闭防火墙或放行3306MariaDB中文乱码字符集没有设置utf8修改my.cnf重启mariaDB后重建库表RabbitMQ启动失败主机名解析失败、Erlang版本不兼容检查/etc/hosts、yum安装对应版本ErlangRabbitMQ组件连不上vhost没创建、用户权限没设置、密码不一致用rabbitmqctl确认vhost和用户权限RabbitMQ管理界面打不开插件没启用或端口没放行rabbitmq-plugins enable rabbitmq_management检查15672端口Memcached本机正常跨节点失败监听地址还是127.0.0.1修改OPTIONS-l 0.0.0.0重启服务Memcached读取不到缓存数据Token存储周期短或网络有抖动先ping通对端再telnet 11211确认端口这张表我建议截图存一下后面你装Keystone、Nova的时候再遇到报错先对照这张表排除底层三件套的问题能省下大量时间。6.3 我的排错心得搭建OpenStack是个系统工程控制节点的三件套只是起点但它们的质量决定了后续所有组件的稳定性。我自己踩过最深的坑是RabbitMQ的主机名问题。当时没在意hosts解析直接把rabbitmq-server启动了结果整个环境的消息队列时好时坏Nova和Neutron组件一会儿报connection refused一会儿又恢复排查了大半天才发现是主机名解析不稳定导致RabbitMQ内部节点名混乱。后来我先改/etc/hosts再重启rabbitmq-server第二天跑了一整天再没出过问题。另外一个心得是每装好一个服务立刻做一次连接验证不要三个全装完再统一验证。我后来习惯装完MariaDB就mysql -u root -p试一下装完RabbitMQ就rabbitmqctl list_users试一下装完Memcached就telnet试一下。每步验证过关了再进入下一步整个搭建过程基本不加班。最后再分享一个小技巧三件套的密码我建议统一记在一个文件里比如/etc/openstack_passwords权限设为600。后续装Keystone、Nova、Neutron的时候每个组件的配置文件几乎都要填数据库密码、RabbitMQ密码和Memcached相关配置。密码乱记后面光找密码就能折腾半小时。我自己在这里吃过亏现在每次都先建好密码文件安装时直接复制粘贴心烦的环节能少一个是一个。