boxmoe_header_banner_img

环境来到萌姬神域

加载中

文章导读

CentOS9上部署OpenStack-Dalmatian(2024.2版本)


avatar
lraltas 2025年7月9日 12


此文档旨在便于内部组员学习部署OpenStack服务,主要用于演示展示,并非生产用途编辑版本

04月11日第一版 编辑人:LRAltas

注意:参考此文档的部署人员应具有较高的排错能力,以及阅读官方英文教程的能力,还有较强的自行搜索问题的解决办法的能力,主要还是我写的没那么好。请任何人,根据本文档正常部署的成员,如遇非提的及报错,请及时提交相关图片以及解决办法,无解决办法的请提交报错信息,以助力更加完善该文档。

只有大家共同参与才能发现,解决更多的问题进而增加经验,提升自己的能力

OpenStack简介

OpenStack 是一个开源的 云计算管理平台,用于构建和管理 私有云公有云 基础设施。它提供了一组模块化的工具,用于控制数据中心的计算、存储和网络资源,允许用户通过 API 或仪表板进行自动化管理。

你可以把 OpenStack 想象成一个 “云工厂”,它能把一堆服务器、硬盘和网络设备变成一个可以灵活分配的 “云计算平台”

OpenStack 的核心特点

  1. 开源免费:由社区驱动,代码公开,可自由修改和部署。
  2. 模块化架构:由多个独立组件(服务)组成,可按需组合使用。
  3. 支持多种虚拟化技术:如 KVM、Xen、VMware、Hyper-V 等。
  4. 可扩展性强:适用于从小型私有云到大规模公有云部署。
  5. 兼容 AWS API:部分组件支持 Amazon Web Services (AWS) 的 API,便于混合云部署。

OpenStack 主要核心组件(包括但不只以下内容)

组件名称功能描述
Nova计算服务,管理虚拟机(VM)的生命周期(创建、调度、删除等)。
Neutron网络服务,提供虚拟网络、子网、路由器、负载均衡等网络功能。
Cinder块存储服务,为虚拟机提供持久化存储(类似 AWS EBS)。
Swift对象存储服务,用于存储大规模非结构化数据(类似 AWS S3)。
Glance镜像服务,管理虚拟机镜像(如 ISO、QCOW2 格式),供 Nova 创建实例使用。
Keystone身份认证服务,管理用户权限和访问控制(类似 AWS IAM)。
Horizon基于 Web 的管理仪表盘,提供图形化操作界面。
Heat编排服务,通过模板自动化部署云资源(类似 AWS CloudFormation)。
Ceilometer监控和计量服务,收集资源使用数据,用于计费或性能分析(后更名为 Telemetry)。

举个栗子🌰

假设你开了一家快递公司,需要管理一堆仓库、卡车和快递员:

  • Nova(计算服务) = 管理快递员(虚拟机),决定谁去送货、谁休息。
  • Cinder(块存储) = 管理仓库里的货架(硬盘),给快递员存放包裹。
  • Swift(对象存储) = 超大仓库,专门存不常用的东西(比如备份、图片、视频)。
  • Neutron(网络服务) = 规划快递路线(网络),确保包裹能送到正确地址。
  • Keystone(认证服务) = 保安系统,检查快递员和客户的身份,防止冒领。
  • Horizon(仪表盘) = 快递公司的监控大屏,老板可以随时查看运营情况。

OpenStack 的典型应用场景

  1. 私有云:企业自建云平台,用于内部 IT 资源管理。
  2. 公有云:服务商提供基于 OpenStack 的公有云服务(如早期 Rackspace、OVH)。
  3. 混合云:与 AWS/Azure 结合,实现跨云资源调度。
  4. NFV(网络功能虚拟化):电信行业用于虚拟化网络设备(如 5G 核心网)。

OpenStack 能干啥?

  1. 自己建“小阿里云”:用一堆服务器搭建私有云,像用 AWS/Aliyun 一样按需分配资源。
  2. 企业 IT 省钱:不用买 VMware 授权,用免费开源的 OpenStack 管理虚拟机。
  3. 搞云计算实验:学云计算、练手 Kubernetes(K8s)的好工具。

OpenStack 的优缺点

优点

  • 灵活可控,适合定制化需求。
  • 避免厂商锁定,兼容多种硬件和虚拟化技术。
  • 社区活跃,生态丰富(支持 Kubernetes、Terraform 等工具集成)。

缺点

  • 部署和维护复杂,学习曲线陡峭。
  • 对硬件资源要求较高(尤其是大规模部署)。
  • 版本升级可能带来兼容性问题。

优缺点(人话版)

优点

  • 免费(不像 VMware 要交钱)。
  • 灵活(想怎么改就怎么改,适合高手)。
  • 不怕被厂商绑架(AWS/Azure 用久了难迁移,OpenStack 自己掌控)。

缺点

  • 复杂(像组装乐高,需要懂很多技术)。
  • 吃硬件(服务器少了跑不动,适合大企业)。
  • 升级麻烦(新版本可能和旧设备不兼容)。

OpenStack的部署步骤

环境准备

我们所使用平台是ESXI8.0,虚拟机是选CentOS9作为部署系统,使用的OpenStack版本是2024.2的版本,代号为Dalmatian,CentOS9官方源中含有所需的相关软件仓库,选择CentOS9也就是因为其对于新版OpenStack的支持很到位,至于为什么不选择Ubuntu嘛,因为它本身权限不好搞,而且Ubuntu24的虚拟机也很抽象,感觉不稳定,所以就用了比较熟悉的CentOS9

实验所需要的虚拟机

如上图所示

网络规划

Managerment InterfaceData Interface
Controller Node192.168.1.150192.168.1.151
Compute Node192.168.1.152192.168.1.153
Block Storage Node 01192.168.1.154
Object Storage Node 01192.168.1.155

Object Storage Node此处只部署一台

按照上述架构图创建完成虚拟机之后即可开始部署

部署开始

注意:常做快照是一个好习惯,可以的话请在每一个基础环境部署之前以及部署成功之后均关机保存快照,子项目也是如此,再开始部署之前保存,在部署完成之后验证无误后在同样也进行快照保存

进行基础环境配置之前,你应该先把firewalld和selinux给禁用掉,并且将IP固定,改成静态IP确保一切都齐全后,再进行配置。

基础环境部署

在这里,你要在创建完成的虚拟机上进行基础环境的配置,基础环境有以下内容

关于部署过程中的安全问题(Security),NTP时间同步(Network Time Protocol (NTP)),安装OpenStack主要软件包(OpenStack packages),数据库服务(SQL database),消息队列服务(Message queue),高并发的分布式内存缓存服务 (Memcached),你需要按照步骤将其全部部署并验证功能是否正常。

Security部分

OpenStack 服务支持各种安全方法,包括密码、策略和加密。此外,包括数据库服务器和消息代理在内的支持服务支持密码安全。为了简化安装过程,本指南仅涵盖密码 安全性(如适用)。您可以手动创建安全密码, 但是 services 配置文件中的 database connection string 不能接受 “@” 等特殊字符。我们建议您生成 他们使用诸如 pwgen 或运行以下命令:

openssl rand -hex 10

对于 OpenStack 服务,本指南使用 SERVICE_PASS 来引用服务帐户密码,使用 SERVICE_DBPASS 来引用数据库密码。下表提供了指南中需要密码的服务及其关联引用的列表。

Password name 密码名称Description 描述
Database password (no variable used)
数据库密码(未使用变量)
Root password for the database
数据库的 root 密码
ADMIN_PASSPassword of user admin
用户 admin 的密码
CINDER_DBPASSDatabase password for the Block Storage service
Block Storage 服务的数据库密码
CINDER_PASSPassword of Block Storage service user cinder
Block Storage 服务用户 cinder 的密码
DASH_DBPASSDatabase password for the Dashboard
控制面板的数据库密码
DEMO_PASSPassword of user demo
用户 demo 密码
GLANCE_DBPASSDatabase password for Image service
图像服务的数据库密码
GLANCE_PASSPassword of Image service user glance
图片服务用户 glance 的密码
KEYSTONE_DBPASSDatabase password of Identity service
Identity 服务的数据库密码
METADATA_SECRETSecret for the metadata proxy
元数据代理的密钥
NEUTRON_DBPASSDatabase password for the Networking service
联网服务的数据库密码
NEUTRON_PASSPassword of Networking service user neutron
联网服务用户 neutron 的密码
NOVA_DBPASSDatabase password for Compute service
计算服务的数据库密码
NOVA_PASSPassword of Compute service user nova
计算服务用户 nova 的密码
PLACEMENT_PASSPassword of the Placement service user placement
Placement 服务用户配置的密码
RABBIT_PASSPassword of RabbitMQ user openstack
RabbitMQ 用户 openstack 的密码

PS:其实吧,你如果是自己做演示部署的话这一节其实可以不看,后面需要的密码你可以随便用自己喜欢的,只要符合规范并且你记得住即可。

OpenStack 和支持服务在安装和作期间需要管理权限。在某些情况下,服务对主机执行修改,这可能会干扰 Ansible 和 Puppet 等部署自动化工具。例如,一些 OpenStack 服务向 sudo 添加了一个 root 包装器,这可能会干扰安全性 政策。请参阅 Pike 的计算服务文档, 这 Queens 的计算服务文档, 或 Rocky 的计算服务文档 了解更多信息。

Networking 服务采用内核网络参数的默认值并修改防火墙规则。为避免初始安装期间出现大多数问题,我们建议您在主机上使用受支持发行版的 Stock 部署。但是,如果您选择自动部署主机,请先查看应用于它们的配置和策略,然后再继续。

NTP时间同步

配置所有主机上的NTP服务以统一所有机器之间的时钟

我们所使用NTP服务是Chrony

编辑Chrony服务的配置文件

vim /etc/chrony.conf 
#注释掉官方的NTP服务器池
#更换为以下内容
pool ntp.aliyun.com iburst
#随后保存退出

更换为

随后重启chronyd服务

systemctl restart chronyd

查看状态

设置主机启用NTP校时

timedatectl set-ntp yes
#启动后查看状态
timedatectl status
#存在以下内容即为成功
System clock synchronized: yes
              NTP service: active

其他机器同理,均需要同步时间

安装OpenStack软件包

对于RHEL/CentOS用户,可以使用以下命令查看当前仓库中是否有Dalmatian版本的软件仓库安装包

以下步骤每个节点上均需操作

dnf search openstack

存在的话可以进行下一步

启用PowerTools/CRB 存储库
#对于CentOS Stream 9有
dnf install dnf-plugins-core
dnf config-manager --set-enabled crb
启用OpenStack软件仓库
#在 CentOS Stream 上,extras 存储库提供启用 OpenStack 存储库的 RPM。CentOS 默认包含 extras 软件库,因此你只需安装组件即可启用 OpenStack 软件库
dnf install centos-release-openstack-dalmatian -y

升级节点上的所有包

为当前的版本安装适当的 OpenStack 客户端
dnf install python3-openstackclient -y

安装完成即可进行下一步

数据库服务

大多数OpenStack服务使用SQL数据库来存储信息。此中的过程中我们选择使用MariaDB还是MySQL,具体取决于发行版。OpenStack服务还支持其他 SQL 数据库,包括 PostgreSQL

数据库通常在 Controller 节点上运行

安装数据库
#这里使用mariadb
dnf install mariadb mariadb-server python3-PyMySQL -y
配置MariaDB

创建并编辑 /etc/my.cnf.d/openstack.cnf 文件(如果需要,请备份 /etc/my.cnf.d/ 中的现有配置文件)并完成以下作:

创建一个 [mysqld] 部分,并设置 bind-address key 添加到控制器点(Controller管理网卡)的管理 IP 允许其他节点通过管理网络进行访问。设置 用于启用有用选项的附加键和 UTF-8 字符集

vim /etc/my.cnf.d/openstack.cnf
#添加以下内容

[mysqld]

bind-address = MANAGEMENT_INTERFACE_IP default-storage-engine = innodb innodb_file_per_table = on max_connections = 4096 collation-server = utf8_general_ci character-set-server = utf8

好了之后保存退出

随后启动数据库服务并将其配置为在系统引导时启动

systemctl enable mariadb
systemctl start mariadb

通过运行 mysql_secure_installation 来保护数据库服务 脚本。特别是,为数据库选择合适的密码 root账户

#要允许root可以通过远程登录
mysql_secure_installation

现在数据库的部分安装完成了

消息队列

OpenStack 使用消息队列来协调服务之间的作和状态信息。消息队列服务通常在控制器节点上运行。OpenStack 支持多种消息队列服务,包括 RabbitMQqpid 的但是,大多数打包 OpenStack 的发行版都支持特定的消息队列服务。这里用 RabbitMQ 消息队列服务,是因为大多数发行版都支持它。如果您希望实现其他 Message Queue 服务,请查阅与之关联的文档。

消息队列在控制器节点上运行。

安装RabbitMQ
dnf install rabbitmq-server -y
#启动 Message Queue 服务并将其配置为在系统引导时启动:
systemctl enable rabbitmq-server
systemctl start rabbitmq-server
添加 openstack 用户
#将RABBIT_PASS替换为合适的密码。
rabbitmqctl add_user openstack RABBIT_PASS
为openstack用户添加相应的权限
rabbitmqctl set_permissions openstack ".*" ".*" ".*"

做好了之后即可进行下一步

Memcache

服务身份验证机制使用 Memcached 来缓存令牌。对于生产部署,我们建议启用防火墙、身份验证和加密的组合来保护它。

memcached服务通常在控制器节点上运行

安装Memacache
dnf install memcached python3-memcached

安装完成之后,编辑 /etc/sysconfig/memcached 文件并完成以下作

将服务配置为使用控制器节点的管理 IP 地址。这是为了允许其他节点通过管理网络进行访问

vim /etc/sysconfig/memcached
#编辑以下内容为
OPTIONS="-l 127.0.0.1,::1,controller"
#完成过后保存退出
#启动Memcached服务并将其配置为在系统引导时启动
systemctl enable memcached
systemctl start memcached
Etcd

OpenStack 服务可以使用 Etcd,这是一个分布式可靠的 key-value store,用于分布式密钥锁定、存储配置、跟踪服务活跃度等场景。

etcd 服务在 controller 节点上运行。

安装Etcd
dnf install etcd -y
配置Etcd

编辑 /etc/etcd/etcd.conf 文件并设置 ETCD_INITIAL_CLUSTERETCD_INITIAL_ADVERTISE_PEER_URLSETCD_ADVERTISE_CLIENT_URLSETCD_LISTEN_CLIENT_URLS 控制器节点的管理 IP 地址,以允许其他节点通过管理网络进行访问

#[Member]
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://MANAGEMENT_INTERFACE_IP:2380"
ETCD_LISTEN_CLIENT_URLS="http://MANAGEMENT_INTERFACE_IP:2379"
ETCD_NAME="controller"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://MANAGEMENT_INTERFACE_IP:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://MANAGEMENT_INTERFACE_IP:2379"
ETCD_INITIAL_CLUSTER="controller=http://MANAGEMENT_INTERFACE_IP:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01"
ETCD_INITIAL_CLUSTER_STATE="new"

#配置完成功后保存退出

启用开机自启并启动 etcd 服务

systemctl enable etcd
systemctl start etcd

到这里,基础环境就配置好了,接下来的就请移步安装OpenStack服务板块

安装OpenStack服务

官方的完整组件有以下内容,在此放出各个组件的官方部署教程,注意,这些只是各个组件的,并非是基础的,所有组件的部署是基于基础内容部署完成后再部署的主要服务。

注意:

  • “Telemetry”在云计算语境下通常译为”遥测”
  • 服务功能描述部分采用意译,如”Orchestration”译为”编排”而非直译”管弦乐”
  • 部分服务如”Placement”采用功能描述性译法。

OpenStack 系统由多个可独立安装的核心服务组成。这些服务根据您的云平台需求协同工作,主要包括 计算服务身份认证服务网络服务镜像服务块存储服务对象存储服务遥测服务编排服务数据库服务。您可以选择单独安装其中任意组件,并将其配置为独立运行或相互联动的整体。

本版块并不会带大家全部安装一遍所有服务,此处仅仅带大家安装一部分必须要的服务

首先先来第一个身份验证服务-Keystone

配置文件预处理

因为openstack组件的配置文件内容很多,而且绝大部分都是被#注释掉的注释项,需要配置的配置项通常都是被[]包围起来的,例如下图

所以我们可以简单地用grep把配置文件里面的配置项输出到一个新的配置文件里面方便配置,你可以用如下命令进行操作以简化配置,后续组件配置不再介绍该步骤的用途。

#将原来的配置文件进行备份
cp /etc/THE_SERVICE/xxx.conf{,.bak}
grep -Ev "^$|#" /etc/THE_SERVICE/xxx.conf.bak > /etc/THE_SERVICE/xxx.conf

#例如我们的keystone
cp /etc/keystone/keystone.conf{,.bak}
grep -Ev "^$|#" /etc/keystone/keystone.conf.bak > /etc/keystone/keystone.conf

命令解释:
grep -Ev "^$|#"
-E:启用正则表达式匹配
-v:反向选择(即不显示匹配的行)
"^$|#":匹配两种行
^$:空行(行首直接接行尾)
#:以 # 开头的行(通常是注释)
本身命令就是过滤掉配置文件中所有的空行和注释行。
/etc/THE_SERVICE/xxx.conf.bak :输入的源文件(通常是配置文件的备份版本)。
> /etc/THE_SERVICE/xxx.conf :将过滤后的内容覆盖写入到目标配置文件。

实际效果如下,过滤掉空行和配置项之后的

Identity service (Keystone) – 身份认证服务

此块介绍如何在控制节点(controller node)上安装并配置 OpenStack 身份认证服务(代号 Keystone)。出于扩展性考虑,本部署方案采用 Fernet 令牌Apache HTTP 服务器 来处理请求。

Keystone的部署在controller节点上进行

在安装和配置 Identity 服务之前,你必须创建一个数据库。

创建keystone数据库

使用数据库访问客户端以 root 用户身份连接到数据库服务器,并创建keystone的相关内容

#以root身份登录数据库
mysql -u root -p
#创建keystone数据库
CREATE DATABASE keystone;
#授予对keystone数据库的适当访问权限,请把下方KEYSTONE_DBPASS你自己设置的合适的密码
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \
IDENTIFIED BY 'KEYSTONE_DBPASS';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \
IDENTIFIED BY 'KEYSTONE_DBPASS';
#完成之后即可退出
安装keystone以及相关软件包
dnf install openstack-keystone httpd python3-mod_wsgi -y
配置keystone
cp /etc/keystone/keystone.conf{,.bak}
grep -Ev "^$|#" /etc/keystone/keystone.conf.bak > /etc/keystone/keystone.conf

编辑 /etc/keystone/keystone.conf 文件并完成以下作:

  • [database] 部分中,配置数据库访问:
vim /etc/keystone/keystone.conf

[database]

# … connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone

KEYSTONE_DBPASS替换为您为数据库选择的密码。

[token] 部分中,配置 Fernet 令牌提供程序

[token]
# ...
provider = fernet

完成后保存退出

填充keystone服务数据库
su -s /bin/sh -c "keystone-manage db_sync" keystone
初始化Fernet密钥存储库
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
引导keystone服务
keystone-manage bootstrap --bootstrap-password ADMIN_PASS \
  --bootstrap-admin-url http://MANAGERMENT_INTERFACE_IP:5000/v3/ \
  --bootstrap-internal-url http://MANAGERMENT_INTERFACE_IP:5000/v3/ \
  --bootstrap-public-url http://MANAGERMENT_INTERFACE_IP:5000/v3/ \
  --bootstrap-region-id RegionOne

ADMIN_PASS 替换为适合管理用户的密码。

MANAGERMENT_INTERFACE_IP替换成你controller节点上管理网卡的IP

配置 Apache HTTP 服务器

编辑 /etc/httpd/conf/httpd.conf文件并配置ServerName选项来引用控制器节点

vim /etc/httpd/conf/httpd.conf

#配置ServerName选项来引用控制器节点
ServerName controller

如果 ServerName 条目尚不存在,则需要添加该条目。

创建指向文件的链接/usr/share/keystone/wsgi-keystone.conf

ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/

启动 Apache HTTP 服务并将其配置为在系统引导时启动

systemctl enable httpd.service
systemctl start httpd.service
通过设置适当的环境变量脚本

用户变量脚本的主要作用是为当前用户提供必要权限的脚本,通过运行不一样的用户脚本已达到临时拥有不一样的权限,就例如在执行keystone相关操作的时候我们可能要运行admin-openrc脚本来获取到admin的相关权限,否则可能会报错,权限类的报错

vim admin-openrc

#添加以下内容
export OS_USERNAME=admin
export OS_PASSWORD=ADMIN_PASS
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://MANAGEMENT_INTERFACE_IP:5000/v3
export OS_IDENTITY_API_VERSION=3

vim demo-openrc

#添加以下内容
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=myproject
export OS_USERNAME=myuser
export OS_PASSWORD=DEMO_PASS
export OS_AUTH_URL=http://MANAGEMENT_INTERFACE_IP:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2

#脚本使用
#例如,在创建域之前我们要先运行admin-openrc脚本以获取其权限
#运行方法如下
. admin-openrc

ADMIN_PASS 替换为引导keystone服务模块中的ADMIN_PASS命令。

DEMO_PASS 替换为引导keystone服务模块中的DEMO_PASS命令。

MANAGERMENT_INTERFACE_IP替换成你controller节点上管理网卡的IP

创建域、项目、用户和角色

keystone为每个 OpenStack 服务提供身份验证服务。身份验证服务使用域、项目、用户和角色的组合。

尽管keystone-manage引导步骤中已经存在 “default”域,但创建新域的正式方法是

openstack domain create --description "An Example Domain" example
#你将看到类似于如下的输出
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | An Example Domain                |
| enabled     | True                             |
| id          | 2f4f80574fd84fe6ba9067228ae0a50c |
| name        | example                          |
| tags        | []                               |
+-------------+----------------------------------+

本指南使用一个服务项目,该项目包含您添加到环境中的每个服务的唯一用户。创建服务 项目:

openstack project create --domain default \
  --description "Service Project" service
  
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Service Project                  |
| domain_id   | default                          |
| enabled     | True                             |
| id          | b75970c0f49b4d23933f01c44223f46c |
| is_domain   | False                            |
| name        | service                          |
| options     | {}                               |
| parent_id   | default                          |
| tags        | []                               |
+-------------+----------------------------------+

常规(非管理员)任务应使用非特权项目和用户。例如,本指南创建 myproject 项目和 myuser 用户。

openstack project create --domain default \
  --description "Demo Project" myproject

  +-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Demo Project                     |
| domain_id   | default                          |
| enabled     | True                             |
| id          | 51c50f7618a44a85ab6e4fa4d04d49de |
| is_domain   | False                            |
| name        | myproject                        |
| options     | {}                               |
| parent_id   | default                          |
| tags        | []                               |
+-------------+----------------------------------+

创建 myuser 用户

openstack user create --domain default \
  --password-prompt myuser

User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| default_project_id  | None                             |
| domain_id           | default                          |
| email               | None                             |
| enabled             | True                             |
| id                  | 159f3e286d2c4c809d21e8918f5382af |
| name                | myuser                           |
| description         | None                             |
| password_expires_at | None                             |
+---------------------+----------------------------------+

创建 myrole 角色

openstack role create myrole

+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | None                             |
| domain_id   | None                             |
| id          | 1f43c85377d84bd5aef2e01fa0676fcb |
| name        | myrole                           |
| options     | {}                               |
+-------------+----------------------------------+

myrole角色添加到myproject项目和myuser用户

openstack role add --project myproject --user myuser myrole
验证操作

取消设置临时 OS_AUTH_URLOS_PASSWORD 环境变量

unset OS_AUTH_URL OS_PASSWORD

作为 admin 用户,请求身份验证令牌


openstack --os-auth-url http://controller:5000/v3 \
  --os-project-domain-name Default --os-user-domain-name Default \
  --os-project-name admin --os-username admin token issue

作为上一节中创建的 myuser 用户,请求身份验证令牌

openstack --os-auth-url http://controller:5000/v3 \
  --os-project-domain-name Default --os-user-domain-name Default \
  --os-project-name myproject --os-username myuser token issue

能够获取即为成功

可能会遇到的问题
#执行以下命令时
openstack domain create --description "An Example Domain" example
#出现报错
Failed to discover available identity versions when contacting http://192.168.1.150:5000/v3. Attempting to parse version from URL.
Unable to establish connection to http://192.168.1.150:5000/v3/auth/tokens: HTTPConnectionPool(host='192.168.1.150', port=5000): Max retries exceeded with url: /v3/auth/tokens (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7ff6650208e0>: Failed to establish a new connection: [Errno 111] 拒绝连接'))
#这个问题排查分为两步
#1.检查你有没有运行用户环境变量的脚本是否出错,是否运行了用户环境变量的脚本
#2.检查httpd服务是否在运行,运行是否正常,配置文件是否正常,以及是否创建了wsgi-keystone.conf与/etc/httpd/conf.d/的链接
Image service (Glance) – 镜像服务

本节介绍如何在控制器节点上安装和配置镜像(image)服务(代号为 glance)。为简单起见,此配置将映像存储在本地文件系统上。

Galnce服务部署在controller节点上

创建glance数据库
mysql -u root -p

#创建Glance数据库
CREATE DATABASE glance;

#授予对 glance 数据库的适当访问权限:
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' \
  IDENTIFIED BY 'GLANCE_DBPASS';
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' \
  IDENTIFIED BY 'GLANCE_DBPASS';

#退出数据库
exit;

GLANCE_DBPASS 替换为合适的密码。

创建服务凭证

获取管理员凭证以获取仅限管理员的 CLI 命令的访问权限

#如果不执行此步骤,后续服务创建会报凭证错误一类的东西
. admin-openrc
创建 glance 用户
#创建 glance 用户
openstack user create --domain default --password-prompt glance

User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| default_project_id  | None                             |
| domain_id           | default                          |
| email               | None                             |
| enabled             | True                             |
| id                  | ab9980873c564a3da9bec0a416784a54 |
| name                | glance                           |
| description         | None                             |
| password_expires_at | None                             |
+---------------------+----------------------------------+
admin 角色添加到glance用户和服务项目中
openstack role add --project service --user glance admin
创建 glance 服务实体
openstack service create --name glance \
  --description "OpenStack Image" image

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
warnings.warn(
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| id          | bf5b8fe67633426ebf0b16313496ef56 |
| name        | glance                           |
| type        | image                            |
| enabled     | True                             |
| description | OpenStack Image                  |
+-------------+----------------------------------+
创建镜像(Image)服务 API 终端节点
#创建镜像服务 API 终端节点:
openstack endpoint create --region RegionOne \
image public http://controller:9292

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 6b1345b2a63240b0835ff2a456793264 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | f8c14710fbd34fdda67208e3ca63a9f8 |
| service_name | glance                           |
| service_type | image                            |
| url          | http://192.168.1.150:9292        |
+--------------+----------------------------------+

###################################################################################

openstack endpoint create --region RegionOne \
image internal http://controller:9292

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 4d801549263a4861ae025c5dfe71d0dd |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | f8c14710fbd34fdda67208e3ca63a9f8 |
| service_name | glance                           |
| service_type | image                            |
| url          | http://192.168.1.150:9292        |
+--------------+----------------------------------+

###################################################################################

openstack endpoint create --region RegionOne \
image admin http://controller:9292

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | f6357fdb1040416c93a8d81a88d49058 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | f8c14710fbd34fdda67208e3ca63a9f8 |
| service_name | glance                           |
| service_type | image                            |
| url          | http://192.168.1.150:9292        |
+--------------+----------------------------------+
安装glance软件包
dnf install openstack-glance -y
配置glance

预处理配置文件

cp /etc/glance/glance-api.conf{,.bak}
grep -Ev "^$|#" /etc/glance/glance-api.conf.bak > /etc/glance/glance-api.conf

[database] 部分中,配置数据库访问

[database]
# ...
connection = mysql+pymysql://glance:GLANCE_DBPASS@controller/glance

GLANCE_DBPASS 替换为您为镜像(Image)服务数据库选择的密码。

[keystone_authtoken][paste_deploy] 部分中,配置 Identity Service 访问

[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

[paste_deploy]

# … flavor = keystone

[glance_store]部分中,配置本地文件系统存储和镜像文件的位置

[DEFAULT]
# ...
enabled_backends=fs:file

[glance_store]

# … default_backend = fs

[fs]

filesystem_store_datadir = /var/lib/glance/images/

[oslo_limit] 部分中,配置对 keystone 的访问

[oslo_limit]
auth_url = http://controller:5000
auth_type = password
user_domain_id = default
username = glance
system_scope = all
password = GLANCE_PASS
endpoint_id = ENDPOINT_ID
region_name = RegionOne

GLANCE_PASS替换为您为 glance 用户创建的密码

ENDPOINT_ID替换为您之前创建的映像终端节点的 ID,您可以通过运行以下命令找到该 ID

#openstack endpoint create --region RegionOne \
#  image public http://controller:9292,这一步所生成的ID,我这里的是6b1345b2a63240b0835ff2a456793264
#可以用以下命令查询
openstack endpoint list --service glance --region RegionOne

确保 glance 账户对系统范围的资源(如限制)具有读取者访问权限

填充 Image 服务数据库
#填充 Image 服务数据库
su -s /bin/sh -c "glance-manage db_sync" glance

如上即为正常填充完毕

随后给glance设置开机自启并且启动glance

systemctl enable openstack-glance-api.service
systemctl start openstack-glance-api.service
验证操作

既然是镜像服务,那当然是上传一个镜像看看状态就知道正不正常了

使用 验证 Image 服务的作 CirrOS, 一个小型 Linux 映像,可帮助您测试 OpenStack 部署。

首先先获取管理员权限

. admin-openrc

下载镜像文件

mkdir /root/test_iso
cd /root/test_iso
wget https://githubfast.com/cirros-dev/cirros/releases/download/0.4.0/cirros-0.4.0-x86_64-disk.img

使用 QCOW2(QEMU Copy On Write 2)磁盘格式、裸容器格式和公共可见性将图像上传到 Image 服务,以便所有项目都可以访问它

glance image-create --name "cirros" \
  --file cirros-0.4.0-x86_64-disk.img \
  --disk-format qcow2 --container-format bare \
  --visibility=public

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+------------------+----------------------------------------------------------------------------------+
| Property         | Value                                                                            |
+------------------+----------------------------------------------------------------------------------+
| checksum         | 443b7623e27ecf03dc9e01ee93f67afe                                                 |
| container_format | bare                                                                             |
| created_at       | 2025-04-13T08:00:21Z                                                             |
| disk_format      | qcow2                                                                            |
| id               | 8906f020-b7ef-4f4c-8c8f-5e20d2a284ab                                             |
| min_disk         | 0                                                                                |
| min_ram          | 0                                                                                |
| name             | cirros                                                                           |
| os_hash_algo     | sha512                                                                           |
| os_hash_value    | 6513f21e44aa3da349f248188a44bc304a3653a04122d8fb4535423c8e1d14cd6a153f735bb0982e |
|                  | 2161b5b5186106570c17a9e58b64dd39390617cd5a350f78                                 |
| os_hidden        | False                                                                            |
| owner            | 38364586e3fb4510932301104b2a9672                                                 |
| protected        | False                                                                            |
| size             | 12716032                                                                         |
| status           | active                                                                           |
| stores           | fs                                                                               |
| tags             | []                                                                               |
| updated_at       | 2025-04-13T08:00:21Z                                                             |
| virtual_size     | 46137344                                                                         |
| visibility       | public                                                                           |
+------------------+----------------------------------------------------------------------------------+

有关 glance 参数的信息,请参阅镜像服务(glance)命令行客户端
有关映像的磁盘和容器格式的信息,请参阅 映像的磁盘和容器格式

最后再确认上传镜像并验证属性

glance image-list

这样glance就安装完成了

Placement service (Placement) – 资源放置服务

Placement服务部署在controller节点上

Placement 提供了一个 placement-api WSGI 脚本,用于使用 Apache、nginx 或其他支持 WSGI 的 Web 服务器运行服务。根据用于部署 OpenStack 的打包解决方案,WSGI 脚本可能位于 /usr/bin 中 或 /usr/local/bin 中。

创建placement数据库
mysql -u root -p

#创建placement数据库
CREATE DATABASE placement;
#授予对数据库的适当访问权限
GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' \
IDENTIFIED BY 'PLACEMENT_DBPASS';
GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' \
IDENTIFIED BY 'PLACEMENT_DBPASS';

PLACEMENT_DBPASS 替换为合适的密码

退出数据库访问客户端以进行下一步

配置用户和端点

获取管理员凭证以获取仅限管理员的 CLI 命令的访问权限

. admin-openrc

创建placement服务

openstack user create --domain default --password-prompt placement

User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| default_project_id  | None                             |
| domain_id           | default                          |
| email               | None                             |
| enabled             | True                             |
| id                  | 7e211845b77b486f95fb79c8907e4bc0 |
| name                | placement                        |
| description         | None                             |
| password_expires_at | None                             |
+---------------------+----------------------------------+

将 Placement 用户添加到具有 admin 角色的服务项目中

openstack role add --project service --user placement admin

在服务目录中创建Placement API条目

openstack service create --name placement \
  --description "Placement API" placement

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
warnings.warn(
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| id          | 3ae6b7aa438246ec8612ebadc5ef4850 |
| name        | placement                        |
| type        | placement                        |
| enabled     | True                             |
| description | Placement API                    |
+-------------+----------------------------------+

创建 Placement API 服务终端节点

openstack endpoint create --region RegionOne \
placement public http://controller:8778

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 010e3e2cc1ff49ebba59fdd8d39f72da |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 3ae6b7aa438246ec8612ebadc5ef4850 |
| service_name | placement                        |
| service_type | placement                        |
| url          | http://192.168.1.150:8778        |
+--------------+----------------------------------+

##################################################################################

openstack endpoint create --region RegionOne \
placement internal http://controller:8778

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 2354cabc24ae4e32984c933c4f039c4c |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 3ae6b7aa438246ec8612ebadc5ef4850 |
| service_name | placement                        |
| service_type | placement                        |
| url          | http://192.18.1.150:8778         |
+--------------+----------------------------------+

##################################################################################

openstack endpoint create --region RegionOne \
placement admin http://controller:8778

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | ac786f46a5cf47c189b0e64119efcce8 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 3ae6b7aa438246ec8612ebadc5ef4850 |
| service_name | placement                        |
| service_type | placement                        |
| url          | http://192.168.1.150:8778        |
+--------------+----------------------------------+
安装和配置Placement
yum install openstack-placement-api -y

预处理文件

cp /etc/placement/placement.conf{,.bak}
grep -Ev "^$|#" /etc/placement/placement.conf.bak > /etc/placement/placement.conf

编辑 /etc/placement/placement.conf 文件并完成以下操作

[placement_database] 部分中,配置数据库访问

[placement_database]
# ...
connection = mysql+pymysql://placement:PLACEMENT_DBPASS@controller/placement

PLACEMENT_DBPASS替换为您为placement数据库选择的密码

[api][keystone_authtoken]部分中,配置keystone服务访问

[api]
# ...
auth_strategy = keystone

[keystone_authtoken]

# … auth_url = http://controller:5000/v3 memcached_servers = controller:11211 auth_type = password project_domain_name = Default user_domain_name = Default project_name = service username = placement password = PLACEMENT_PASS

填充 placement 数据库

su -s /bin/sh -c "placement-manage db sync" placement
#忽略此输出中的任何弃用消息。

修改配置文件/etc/httpd/conf.d/00-placement-api.conf(官方没给这个步骤,但是你不自己动手加会报错,关于什么报错后面会在controller节点上部署nova节点上给)

在文件的最后添加:

<Directory /usr/bin>
	<IfVersion >= 2.4>
		Require all granted
	</IfVersion>
	<IfVersion < 2.4>
		Order allow,deny
		Allow from all
	</IfVersion>
</Directory>
重启httpd服务
systemctl restart httpd
验证安装

获取管理员凭证以获取仅限管理员的 CLI 命令的访问权限

. admin-openrc

执行状态检查以确保一切正常

placement-status upgrade check

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+-------------------------------------------+
| Upgrade Check Results                     |
+-------------------------------------------+
| Check: Missing Root Provider IDs          |
| Result: Success                           |
| Details: None                             |
+-------------------------------------------+
| Check: Incomplete Consumers               |
| Result: Success                           |
| Details: None                             |
+-------------------------------------------+
| Check: Policy File JSON to YAML Migration |
| Result: Success                           |
| Details: None                             |
+-------------------------------------------+

该命令的输出将因版本而异。有关详细信息 ,请参阅位置状态升级检查

可能会出现的问题

出现以下报错

Compute service (Nova) – 计算服务

nova服务分成两部分,分别部署在controller节点上与compute节点上

计算节点运行运行实例的 Compute 的管理程序部分。默认情况下,Compute 使用基于内核的 VM(KVM) 虚拟机管理程序。计算节点还运行一个网络服务代理,该代理将实例连接到虚拟网络,并通过安全组为实例提供防火墙服务。

你可以部署多个计算节点。每个节点至少需要两个网络接口。

controller节点的部署

创建nova数据库

mysql -u root -p

#创建nova_api、nova和nova_cell0数据库:
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';

NOVA_DBPASS 替换为合适的密码

退出数据库访问客户端

获取管理员凭证以获取仅限管理员的 CLI 命令的访问权限

. admin-openrc
创建Nova服务的凭证

创建 nova 用户

openstack user create --domain default --password-prompt nova

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| default_project_id  | None                             |
| domain_id           | default                          |
| email               | None                             |
| enabled             | True                             |
| id                  | c5981ffdb052447a8f3ed236cc8d593b |
| name                | nova                             |
| description         | None                             |
| password_expires_at | None                             |
+---------------------+----------------------------------+

admin 角色添加到 nova 用户

openstack role add --project service --user nova admin

创建nova服务实体

openstack service create --name nova \
  --description "OpenStack Compute" compute

  /usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| id          | b1492fba9cc64f6483845e3924ee5caa |
| name        | nova                             |
| type        | compute                          |
| enabled     | True                             |
| description | OpenStack Compute                |
+-------------+----------------------------------+
创建 Compute API 服务终端节点
openstack endpoint create --region RegionOne \
  compute public http://controller:8774/v2.1

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | dd469cbdc97c4493bbba5302d9c854b4 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | b1492fba9cc64f6483845e3924ee5caa |
| service_name | nova                             |
| service_type | compute                          |
| url          | http://192.168.1.150:8774/v2.1   |
+--------------+----------------------------------+

###################################################################################

openstack endpoint create --region RegionOne \
  compute internal http://controller:8774/v2.1

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 981341ba97be44128cff8a8990fb4047 |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | b1492fba9cc64f6483845e3924ee5caa |
| service_name | nova                             |
| service_type | compute                          |
| url          | http://192.168.1.150:8774/v2.1   |
+--------------+----------------------------------+

###################################################################################

openstack endpoint create --region RegionOne \
  compute admin http://controller:8774/v2.1

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 3e7d802c623b4b2394025fd22f9543b1 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | b1492fba9cc64f6483845e3924ee5caa |
| service_name | nova                             |
| service_type | compute                          |
| url          | http://192.168.1.150:8774/v2.1   |
+--------------+----------------------------------+
安装nova的相关软件包
yum install openstack-nova-api openstack-nova-conductor \
  openstack-nova-novncproxy openstack-nova-scheduler -y
配置controller上的nova服务

预处理配置文件

cp /etc/nova/nova.conf{,.bak}
grep -Ev "^$|#" /etc/nova/nova.conf.bak > /etc/nova/nova.conf

编辑/etc/nova/nova.conf文件并完成以下配置

[DEFAULT] 部分中,仅启用计算和元数据 API

[DEFAULT]
# ...
enabled_apis = osapi_compute,metadata

[api_database][database]部分中,配置数据库访问

[api_database]
# ...
connection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova_api

[database]

# … connection = mysql+pymysql://nova:NOVA_DBPASS@controller/nova

NOVA_DBPASS替换为您为Nova数据库选择的密码。

[DEFAULT]部分中,配置RabbitMQ消息队列访问

[DEFAULT]
# ...
transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/

[api][keystone_authtoken]部分中,配置keystone服务访问

[api]
# ...
auth_strategy = keystone

[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

NOVA_PASS 替换为您在keystone服务中为nova用户选择的密码

[service_user]部分中,配置服务用户令牌

[service_user]
send_service_user_token = true
auth_url = https://controller/identity
auth_strategy = keystone
auth_type = password
project_domain_name = Default
project_name = service
user_domain_name = Default
username = nova
password = NOVA_PASS

NOVA_PASS 替换为您在keystone服务中为nova用户选择的密码

[DEFAULT]部分中,配置my_ip选项以使用控制器节点的管理网卡IP地址

[DEFAULT]
# ...
my_ip = MANAGEMENT_HOST_IP

[vnc]部分中,将 VNC 代理配置为使用控制器节点的管理接口 IP 地址

[vnc]
enabled = true
# ...
server_listen = $my_ip
server_proxyclient_address = $my_ip

[glance]部分,配置镜像(Image)服务 API 的部分

[glance]
# ...
api_servers = http://controller:9292

[oslo_concurrency]部分中,配置锁定路径

[oslo_concurrency]
# ...
lock_path = /var/lib/nova/tmp

[placement]部分中,配置对 Placement 服务的访问权限

[placement]
# ...
region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://controller:5000/v3
username = placement
password = PLACEMENT_PASS

PLACEMENT_PASS 替换为您在创建placement时为placement service设置的密码。记得注释掉或删除 [placement] 部分中的任何其他选项。

填充 controller node上的nova数据库

填充 nova-api 数据库

su -s /bin/sh -c "nova-manage api_db sync" nova

注册 cell0 数据库

su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova

创建 cell1 单元格

su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova

填充 nova数据库

su -s /bin/sh -c "nova-manage db sync" nova

填充完数据库后可以自行到数据库中查看相关的内容是否被正确创建

验证nova cell0cell1是否已经注册

su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+-------+--------------------------------------+---------------------------------------------+-------------------------------------------------+----------+
|  名称 |                 UUID                 |                Transport URL                |                    数据库连接                   | Disabled |
+-------+--------------------------------------+---------------------------------------------+-------------------------------------------------+----------+
| cell0 | 00000000-0000-0000-0000-000000000000 |                    none:/                   | mysql+pymysql://nova:****@controller/nova_cell0 |  False   |
| cell1 | 4a7f18f7-fdc8-4544-8776-4fbe1238803c | rabbit://openstack:****@192.168.1.150:5672/ |    mysql+pymysql://nova:****@controller/nova    |  False   |
+-------+--------------------------------------+---------------------------------------------+-------------------------------------------------+----------+
完成controller node上的nova部分部署
systemctl enable \
    openstack-nova-api.service \
    openstack-nova-scheduler.service \
    openstack-nova-conductor.service \
    openstack-nova-novncproxy.service

systemctl start \
    openstack-nova-api.service \
    openstack-nova-scheduler.service \
    openstack-nova-conductor.service \
    openstack-nova-novncproxy.service
可能会出现的报错
File "/usr/lib/python3.9/site-packages/nova/scheduler/client/report.py", line 277, in _create_client
   client = self._adapter or utils.get_sdk_adapter('placement')
 File "/usr/lib/python3.9/site-packages/nova/utils.py", line 995, in get_sdk_adapter
   return getattr(conn, service_type)
 File "/usr/lib/python3.9/site-packages/openstack/service_description.py", line 89, in __get__
   proxy = self._make_proxy(instance)
 File "/usr/lib/python3.9/site-packages/openstack/service_description.py", line 293, in _make_proxy
   raise exceptions.NotSupported(
openstack.exceptions.NotSupported: The placement service for 192.168.1.150:RegionOne exists but does not have any supported versions.

关于这个报错,是在配置好controller节点的时候出现的

启动openstack-nova-scheduler.serviceopenstack-nova-conductor.serviceopenstack-nova-novncproxy.service出现服务启动失败,systemctl status openstack-nova-scheduler时出现在状态里面显示的,要多试几次,他一直在重启,状态只能看命令输入时的,所以要一直查看状态才能发现。我的问题是因为最开始在placement配置的时候没有配置/etc/httpd/conf.d/00-placement-api.conf导致的,毕竟官方没给(或许是给了但是放在了用法里面我没看到)

在compute node上配置nova

因为具体的端点在controller上已经创建过了,所以我们compute上只要安装并且配置就好了

compute node上安装Nova组件
yum install openstack-nova-compute -y
配置nova组件

预处理配置文件

cp /etc/nova/nova.conf{,.bak}
grep -Ev "^$|#" /etc/nova/nova.conf.bak > /etc/nova/nova.conf

编辑/etc/nova/nova.conf文件并完成以下作

[DEFAULT]部分中,仅启用计算和元数据 API

[DEFAULT]
# ...
enabled_apis = osapi_compute,metadata

[DEFAULT]部分中,配置RabbitMQ消息队列访问

[DEFAULT]
# ...
transport_url = rabbit://openstack:RABBIT_PASS@controller
compute_driver=libvirt.LibvirtDriver

RABBIT_PASS替换为您在在RabbitMQ中为openstack用户选择的密码

[api][keystone_authtoken] 部分中,配置keystone服务访问

[api]
# ...
auth_strategy = keystone

[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

NOVA_PASSS替换为您在keystone服务中为nova用户选择的密码。

[service_user] 部分中,配置服务用户令牌

[service_user]
send_service_user_token = true
auth_url = https://controller/identity
auth_strategy = keystone
auth_type = password
project_domain_name = Default
project_name = service
user_domain_name = Default
username = nova
password = NOVA_PASS

NOVA_PASS替换为您在keystone服务中为nova用户选择的密码

[DEFAULT]部分中,配置my_ip选项

[DEFAULT]
# ...
my_ip = MANAGEMENT_INTERFACE_IP_ADDRESS

请将MANAGEMENT_INTERFACE_IP_ADDRESS替换为计算节点上管理网络接口的 IP 地址

[vnc]部分中,启用并配置远程控制台访问

[vnc]
# ...
enabled = true
server_listen = 0.0.0.0
server_proxyclient_address = $my_ip
novncproxy_base_url = http://controller:6080/vnc_auto.html

[glance] 部分,配置镜像(Image)服务 API 的位置

[glance]
# ...
api_servers = http://controller:9292

[oslo_concurrency]部分中,配置锁定路径

[oslo_concurrency]
# ...
lock_path = /var/lib/nova/tmp

[placement]部分中,配置 Placement API

[placement]
# ...
region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://controller:5000/v3
username = placement
password = PLACEMENT_PASS

PLACEMENT_PASS替换为您为keystone服务中的 placement 用户。注释掉[placement]部分中的任何其他选项

注:您应该确定您的计算节点是否支持虚拟机的硬件加速

egrep -c '(vmx|svm)' /proc/cpuinfo

如果此命令返回值1 或更大,则您的计算节点支持硬件加速,这通常不需要额外的配置

如果此命令返回值0,则您的计算节点不支持硬件加速,您必须将libvirt配置为使用 QEMU 而不是 KVM

编辑 /etc/nova/nova.conf 文件中的 [libvirt] 部分,如下所示:

[libvirt]
# ...
virt_type = qemu
启动 Compute 服务(包括其依赖项)
systemctl enable libvirtd.service openstack-nova-compute.service
systemctl start libvirtd.service openstack-nova-compute.service
将 compute 节点添加到 cell 数据库

回到controller节点

获取管理员凭证以启用仅限管理员的 CLI 命令,然后确认数据库中有计算主机

. admin-openrc
openstack compute service list --service nova-compute 


/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+----------------+--------------+---------+------+---------+-------+-----------------+
| ID             | Binary       | Host    | Zone | Status  | State | Updated At      |
+----------------+--------------+---------+------+---------+-------+-----------------+
| 1a727e25-9c9c- | nova-compute | compute | nova | enabled | up    | 2025-04-13T17:4 |
| 48eb-9c26-b454 |              |         |      |         |       | 6:38.000000     |
| 1b913a93       |              |         |      |         |       |                 |
+----------------+--------------+---------+------+---------+-------+-----------------+

发现计算节点主机

su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
Found 2 cell mappings.
Skipping cell0 since it does not contain hosts.
Getting computes from cell 'cell1': b87d47a8-f346-41cd-ac2d-7a278da76b2a
Checking host mapping for compute host 'compute': 9f3f70da-ad3f-46d2-ba14-435b0b82cb5b
Creating host mapping for compute host 'compute': 9f3f70da-ad3f-46d2-ba14-435b0b82cb5b
Found 1 unmapped computes in cell: b87d47a8-f346-41cd-ac2d-7a278da76b2a

添加新的计算节点时,必须在控制器节点上运行 nova-managecell_v2
discover_hosts
以注册这些新计算 节点。或者,您可以在 /etc/nova/nova.conf 中:

[scheduler]
discover_hosts_in_cells_interval = 300
可能遇到的问题

openstack-nova-compute服务启动失败,可能会有以下内容

-14 01:31:07.124 3578 INFO nova.virt.libvirt.host [None req-8802004f-fa81-49ec-807b-4e5e660e1d8f - - - - - -] Secure Boot support detected
-14 01:31:07.593 3578 WARNING nova.virt.libvirt.driver [None req-8802004f-fa81-49ec-807b-4e5e660e1d8f - - - - - -] Cannot update service status on host "compute" since it is not registered.: nova.exception_Remote.ComputeHostNotFound_Remote: 计算主机 com
-14 01:31:07.643 3578 INFO nova.virt.node [None req-8802004f-fa81-49ec-807b-4e5e660e1d8f - - - - - -] Generated node identity 1d50620c-e84d-483d-abe7-a98452503cb1
-14 01:31:07.644 3578 ERROR oslo_service.service [None req-8802004f-fa81-49ec-807b-4e5e660e1d8f - - - - - -] Error starting thread.: nova.exception.InvalidNodeConfiguration: Invalid node identity configuration: Unable to write uuid to /usr/lib/python3.9
-14 01:31:07.644 3578 ERROR oslo_service.service Traceback (most recent call last):
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/virt/node.py", line 38, in write_local_node_uuid
-14 01:31:07.644 3578 ERROR oslo_service.service     with open(fn, 'x') as f:
-14 01:31:07.644 3578 ERROR oslo_service.service PermissionError: [Errno 13] Permission denied: '/usr/lib/python3.9/site-packages/compute_id'
-14 01:31:07.644 3578 ERROR oslo_service.service
-14 01:31:07.644 3578 ERROR oslo_service.service During handling of the above exception, another exception occurred:
-14 01:31:07.644 3578 ERROR oslo_service.service
-14 01:31:07.644 3578 ERROR oslo_service.service Traceback (most recent call last):
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/oslo_service/service.py", line 810, in run_service
-14 01:31:07.644 3578 ERROR oslo_service.service     service.start()
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/service.py", line 166, in start
-14 01:31:07.644 3578 ERROR oslo_service.service     self.manager.init_host(self.service_ref)
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/compute/manager.py", line 1641, in init_host
-14 01:31:07.644 3578 ERROR oslo_service.service     nodes_by_uuid = self._get_nodes(context)
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/compute/manager.py", line 1487, in _get_nodes
-14 01:31:07.644 3578 ERROR oslo_service.service     node_ids = self.driver.get_nodenames_by_uuid()
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/virt/libvirt/driver.py", line 12003, in get_nodenames_by_uuid
-14 01:31:07.644 3578 ERROR oslo_service.service     return {self._host.get_node_uuid(): self._host.get_hostname()}
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/virt/libvirt/host.py", line 1077, in get_node_uuid
-14 01:31:07.644 3578 ERROR oslo_service.service     self._node_uuid = nova.virt.node.get_local_node_uuid()
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/virt/node.py", line 105, in get_local_node_uuid
-14 01:31:07.644 3578 ERROR oslo_service.service     write_local_node_uuid(node_uuid)
-14 01:31:07.644 3578 ERROR oslo_service.service   File "/usr/lib/python3.9/site-packages/nova/virt/node.py", line 47, in write_local_node_uuid
-14 01:31:07.644 3578 ERROR oslo_service.service     raise exception.InvalidNodeConfiguration(
-14 01:31:07.644 3578 ERROR oslo_service.service nova.exception.InvalidNodeConfiguration: Invalid node identity configuration: Unable to write uuid to /usr/lib/python3.9/site-packages/compute_id: [Errno 13] Permission denied: '/usr/lib/python3.9/site-pa
-14 01:31:07.644 3578 ERROR oslo_service.service
compute.service: Deactivated successfully.

提取关键词语句

nova.exception.InvalidNodeConfiguration: Invalid node identity configuration: Unable to write uuid to /usr/lib/python3.9/site-packages/compute_id: [Errno 13] Permission denied: '/usr/lib/python3.9/site-pa

权限问题,这个问题解决办法有两种

  1. 一个是手动创建compte_id文件即可(存疑)
  2. 另一个是在nova.conf加入官方没有添加的配置项
[DEFAULT]
#...
log_dir = /var/log/nova
lock_path = /var/lock/nova
state_path = /var/lib/nova

还有可能出现以下问题

这个是发现openstack-nova-compute服务启动失败,关闭其后发现libvirtd正常,开启后openstack-nova-compute频繁重启,libvirtd出现以下错误。

● libvirtd.service - libvirt legacy monolithic daemon
     Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; preset: disable>
     Active: active (running) since Mon 2025-04-14 00:48:54 CST; 5min ago
TriggeredBy: ● libvirtd.socket
             ● libvirtd-admin.socket
             ● libvirtd-ro.socket
       Docs: man:libvirtd(8)
             https://libvirt.org/
   Main PID: 30498 (libvirtd)
      Tasks: 22 (limit: 32768)
     Memory: 28.6M
        CPU: 1.895s
     CGroup: /system.slice/libvirtd.service
             ├─18558 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.con>
             ├─18559 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.con>
             └─30498 /usr/sbin/libvirtd --timeout 120

4月 14 00:53:04 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:09 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:15 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:20 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:26 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:31 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:37 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:42 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:48 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误
4月 14 00:53:53 compute libvirtd[30498]: 读取数据时进入文件终点: 输入/输出错误

这个问题也会导致openstack-nova-compute服务启动失败

解决办法其实很简单

把这两个勾上即可

Networking service (Neutron) – 网络服务

OpenStack 用户需要有关底层网络基础架构的更多信息,以创建与基础架构完全匹配的虚拟网络。

此处会有两种网络架构可供部署人员选择

提供商网络(Provider networks)提供商网络介绍

Provider networks 是 OpenStack 中最简单的网络模型,具有以下特点:

  1. 直接映射物理网络
  • 虚拟网络(如实例的虚拟网卡)直接绑定到物理网络(如数据中心现有的 VLAN 或扁平网络)。
  • 管理员需预先配置物理网络(VLAN ID、子网等)。
  1. 无 overlay 隧道
  • 不使用 Neutron 的 VXLAN/GRE 等隧道技术,依赖底层网络设备(交换机/路由器)实现隔离和路由。
  1. 适用场景
  • 企业已有成熟物理网络,希望 OpenStack 直接复用现有基础设施。
  • 需要高性能(避免隧道封装开销)或兼容传统网络设备。

provider networks 选项以最简单的方式部署 OpenStack Networking 服务,主要是第 2 层(桥接/交换)服务和网络的 VLAN 分段。从本质上讲,它将虚拟网络桥接到物理网络,并依靠物理网络基础设施提供第 3 层(路由)服务

Self-service networks(自服务网络)自服务网络介绍

Self-service networks(自服务网络) 是 OpenStack 中更灵活的网络模型,允许 租户(项目)自行创建和管理私有网络,而无需管理员介入。

核心特点

  1. 基于 Overlay 网络技术(VXLAN/GRE)
  • 使用 Neutron 的隧道封装技术(如 VXLAN、GRE)在物理网络之上构建虚拟网络。
  • 物理网络只需提供 IP 连通性,无需预配置 VLAN。
  1. 支持租户自主管理
  • 租户可以创建自己的子网、路由器,并定义安全组规则。
  • 适用于多租户云环境,不同项目的网络完全隔离。
  1. 依赖 Neutron 高级组件
  • 需要 L3 Agent(三层路由)DHCP Agent 支持。
  • 可选 Load Balancer(Octavia)VPNaaS 等扩展服务。

自助服务网络选项通过第 3 层(路由)服务增强了提供商网络选项,这些服务使用叠加分段方法(如虚拟可扩展 LAN (VXLAN))启用自助服务网络。实质上,它使用网络地址转换 (NAT) 将虚拟网络路由到物理网络。此外,此选项还为 FWaaS 等高级服务提供了基础。

OpenStack 用户可以创建虚拟网络,而无需了解数据网络上的底层基础架构。如果对第 2 层插件进行了相应的配置,这也可以包括 VLAN 网络。

这里是第一种网络

这里是第二种网络

创建neutron数据库
mysql -u root -p

#创建neutron数据库
CREATE DATABASE neutron;

#授予对 neutron 数据库的适当访问权限
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' \
  IDENTIFIED BY 'NEUTRON_DBPASS';
GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' \
  IDENTIFIED BY 'NEUTRON_DBPASS';
  #退出数据库

NEUTRON_DBPASS替换成合适的密码

创建neutron服务

获取管理员凭证以获取仅限管理员的 CLI 命令的访问权限

. admin-openrc

创建 neutron 用户

openstack user create --domain default --password-prompt neutron

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| default_project_id  | None                             |
| domain_id           | default                          |
| email               | None                             |
| enabled             | True                             |
| id                  | 2ec4fa2ca308472ca34e9621da51b0cc |
| name                | neutron                          |
| description         | None                             |
| password_expires_at | None                             |
+---------------------+----------------------------------+

admim角色添加到neutron用户

openstack role add --project service --user neutron admin

创建 neutron 服务实体

openstack service create --name neutron \
  --description "OpenStack Networking" network

  /usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| id          | 6759eb96018f4d5a8ae2a9a41ca407de |
| name        | neutron                          |
| type        | network                          |
| enabled     | True                             |
| description | OpenStack Networking             |
+-------------+----------------------------------+

创建网络服务 API 终端节点

openstack endpoint create --region RegionOne \
  network public http://controller:9696

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 52277aa4e4c04bfaa719f0ec65f525b3 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 6759eb96018f4d5a8ae2a9a41ca407de |
| service_name | neutron                          |
| service_type | network                          |
| url          | http://192.168.1.150:9696        |
+--------------+----------------------------------+


###################################################################################


  openstack endpoint create --region RegionOne \
  network internal http://controller:9696
  
  /usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | c81d4ecb788d483aa10e3060fc5f7393 |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 6759eb96018f4d5a8ae2a9a41ca407de |
| service_name | neutron                          |
| service_type | network                          |
| url          | http://192.168.1.150:9696        |
+--------------+----------------------------------+


###################################################################################


  openstack endpoint create --region RegionOne \
  network admin http://controller:9696

  /usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 6ac15c332fcb40e1b2b330016be3ac67 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 6759eb96018f4d5a8ae2a9a41ca407de |
| service_name | neutron                          |
| service_type | network                          |
| url          | http://192.168.1.150:9696        |
+--------------+----------------------------------+
配置网络选项

选项 1 部署了最简单的架构,该架构仅支持将实例连接到提供商(外部)网络。没有自助式(专用)网络、路由器或浮动 IP 地址。只有管理员或其他特权用户才能管理提供商网络。

选项 2 使用支持将实例连接到自助服务网络的第 3 层服务对选项 1 进行了补充。演示者或其他非特权用户可以管理自助服务网络,包括在自助服务网络和提供商网络之间提供连接的路由器。此外,浮动 IP 地址使用来自外部网络(如 Internet)的自助服务网络提供与实例的连接。

自助服务网络通常使用叠加网络。叠加网络协议(如 VXLAN)包括额外的标头,这些标头会增加开销并减少有效负载或用户数据的可用空间。在不知道虚拟网络基础设施的情况下,实例会尝试使用 1500 字节的默认以太网最大传输单元 (MTU) 发送数据包。联网服务通过 DHCP 自动为实例提供正确的 MTU 值。但是,某些云映像不使用 DHCP 或忽略 DHCP MTU 选项,并且需要使用元数据或脚本进行配置。

在controller node上安装和配置Networking组件
yum install openstack-neutron openstack-neutron-ml2 \
  openstack-neutron-openvswitch ebtables -y
配置服务器组件

预处理配置文件

cp /etc/neutron/neutron.conf{,.bak}
grep -Ev "^$|#" /etc/neutron/neutron.conf.bak > /etc/neutron/neutron.conf

编辑/etc/neutron/neutron.conf文件并完成以下操作

[database] 部分中,配置数据库访问

[database]
# ...
connection = mysql+pymysql://neutron:NEUTRON_DBPASS@controller/neutron

NEUTRON_DBPASS 替换为您为NEUTRON数据库选择的密码

[DEFAULT]部分中,启用模块化第 2 层 (ML2) 插件和路由器服务

[DEFAULT]
# ...
core_plugin = ml2
service_plugins = router

[DEFAULT]部分中,配置RabbitMQ消息队列访问:

[DEFAULT]
# ...
transport_url = rabbit://openstack:RABBIT_PASS@controller

RABBIT_PASS 替换为您为在rabbitmq上为openstack帐户设置的密码。

[DEFAULT][keystone_authtoken] 部分中,配置keystone服务访问

[DEFAULT]
# ...
auth_strategy = keystone

[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

NEUTRON_PASS 替换为您为 neutron用户选择的密码。

[DEFAULT][nova]部分中,配置Networking以通知Compute网络拓扑更改

[DEFAULT]
# ...
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true

[nova]

# … auth_url = http://controller:5000 auth_type = password project_domain_name = Default user_domain_name = Default region_name = RegionOne project_name = service username = nova password = NOVA_PASS

NOVA_PASS替换为您为nova用户选择的密码。

[oslo_concurrency]部分中,配置锁定路径

lock_path = /var/lib/neutron/tmp
配置 Modular Layer 2(ML2) 插件

ML2 插件使用 Linux 桥接机制为实例构建第 2 层(桥接和交换)虚拟网络基础设施。

预处理配置文件

cp /etc/neutron/plugins/ml2/ml2_conf.ini{,.bak}
grep -Ev "^$|#" /etc/neutron/plugins/ml2/ml2_conf.ini.bak > /etc/neutron/plugins/ml2/ml2_conf.ini

编辑 /etc/neutron/plugins/ml2/ml2_conf.ini 文件并完成以下操作

[ml2] 部分中,启用平面、VLAN 和 VXLAN 网络

[ml2]
# ...
type_drivers = flat,vlan,vxlan

[ml2] 部分中,启用 VXLAN 自助服务网络

[ml2]
# ...
tenant_network_types = vxlan

[ml2] 部分中,启用 Linux 桥和第 2 层填充机制

[ml2]
# ...
mechanism_drivers = openvswitch,l2population

[ml2]部分中,启用端口安全扩展驱动程序

[ml2]
# ...
extension_drivers = port_security

[ml2_type_flat]部分中,将提供商虚拟网络配置为平面网络

[ml2_type_flat]
# ...
flat_networks = provider

[ml2_type_vxlan]部分,配置自助网络的 VXLAN 网络标识符范围

[ml2_type_vxlan]
# ...
vni_ranges = 1:1000
配置 Open vSwitch 代理

预处理配置文件

cp /etc/neutron/plugins/ml2/openvswitch_agent.ini{,.bak}
grep -Ev "^$|#" /etc/neutron/plugins/ml2/openvswitch_agent.ini.bak > /etc/neutron/plugins/ml2/openvswitch_agent.ini

编辑/etc/neutron/plugins/ml2/openvswitch_agent.ini文件并完成以下操作

[ovs] 部分中,将提供商虚拟网络映射到提供商物理网桥,并配置处理叠加网络的物理网络接口的 IP 地址

[ovs]
bridge_mappings = provider:PROVIDER_BRIDGE_NAME
local_ip = OVERLAY_INTERFACE_IP_ADDRESS

这块的意思是让你创建一个桥接网卡PROVIDER_BRIDGE_NAME是创建的桥接网卡的名称,OVERLAY_INTERFACE_IP_ADDRESS是被桥接网卡的IP

确保已创建 PROVIDER_BRIDGE_NAME 外部网桥,并将 PROVIDER_INTERFACE_NAME 接口添加到该网桥中。

网桥区分

  1. PROVIDER_BRIDGE_NAME
  • 通常指外部网桥的名称(如 br-ex),用于连接 OpenStack 虚拟网络与物理网络。
  • 在 Provider Networks(提供商网络)模式下,此网桥负责将实例流量转发到外部网络(如互联网或企业内网)。
  1. PROVIDER_INTERFACE_NAME
  • 物理网络接口的名称(如 eth0ens3),需绑定到网桥以实现物理-虚拟网络互通。
#没有的话可以用以下内容创建
ovs-vsctl add-br $PROVIDER_BRIDGE_NAME
#你可以把它桥接到第二片网卡上
ovs-vsctl add-port $PROVIDER_BRIDGE_NAME $PROVIDER_INTERFACE_NAME

#如果出现以下内容
ovs-vsctl: unix:/var/run/openvswitch/db.sock: database connection failed (No such file or directory)
#这一般意味着你的openvswitch服务没开启
#我们开启后就可以正常添加了
systemctl enable openvswitch
systemctl start openvswitch

[agent] 部分中,启用 VXLAN 叠加网络并启用第 2 层填充

[agent]
tunnel_types = vxlan
l2_population = true

[securitygroup]部分中,启用安全组并配置 Open vSwitch 本机或混合 iptables 防火墙驱动程序

[securitygroup]
# ...
enable_security_group = true
firewall_driver = openvswitch
#firewall_driver = iptables_hybrid

如果使用混合 iptables 防火墙驱动程序,请验证以下所有 sysctl 值是否都设置为 1,确保您的 Linux 作系统内核支持网桥过滤器

net.bridge.bridge-nf-call-iptables
net.bridge.bridge-nf-call-ip6tables

要启用网络桥支持,通常需要加载br_netfilter内核模块。查看作系统的文档,了解有关启用此模块的更多详细信息。

配置br_netfilter

1. 确保 br_netfilter 模块已加载

# 手动加载模块(临时生效)
sudo modprobe br_netfilter

# 检查是否加载成功
lsmod | grep br_netfilter

预期输出:

br_netfilter           32768  0
bridge                311296  1 br_netfilter

如果没有输出,说明模块加载失败,可能是内核未包含该模块(CentOS 9 应该默认支持)。


2. 永久加载 br_netfilter

# 写入模块加载配置
echo "br_netfilter" | sudo tee /etc/modules-load.d/br_netfilter.conf

# 重新加载所有内核模块配置
sudo systemctl restart systemd-modules-load

# 再次检查模块是否加载
lsmod | grep br_netfilter

3. 检查 /proc/sys/net/bridge/ 是否存在

ls /proc/sys/net/bridge/

预期输出:

bridge-nf-call-arptables  bridge-nf-call-ip6tables  bridge-nf-call-iptables
bridge-nf-filter-pppoe-tagged  bridge-nf-filter-vlan-tagged  bridge-nf-pass-vlan-input-dev

如果仍然没有 /proc/sys/net/bridge/ 目录,可能是:

  • 内核未启用 CONFIG_BRIDGE_NETFILTER(较新内核默认启用)
  • 系统未正确加载模块(尝试重启)

4. 临时解决方案(如果模块无法加载)

如果 br_netfilter 仍然无法加载,可以尝试:

更新内核(确保使用官方内核):

sudo dnf update kernel
sudo reboot

检查内核编译选项(仅限高级用户):

grep CONFIG_BRIDGE_NETFILTER /boot/config-$(uname -r)

如果返回 CONFIG_BRIDGE_NETFILTER=y,说明内核支持,但模块未加载。


5. 配置 sysctl 参数

CentOS 9 默认可能未启用 bridge-nf 调用 iptables,需要手动设置:

临时设置(立即生效,重启后失效)

sudo sysctl -w net.bridge.bridge-nf-call-iptables=1
sudo sysctl -w net.bridge.bridge-nf-call-ip6tables=1

永久设置(写入 /etc/sysctl.conf/etc/sysctl.d/

echo "net.bridge.bridge-nf-call-iptables=1" | sudo tee -a /etc/sysctl.d/99-bridge-nf.conf
echo "net.bridge.bridge-nf-call-ip6tables=1" | sudo tee -a /etc/sysctl.d/99-bridge-nf.conf

6. 重新应用 sysctl 配置

sudo sysctl -p /etc/sysctl.d/99-bridge-nf.conf

现在应该不再报错,并成功设置:

net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
配置 layer-3 Agent

第 3 层 (L3) 代理为自助式虚拟网络提供路由和 NAT 服务

编辑 /etc/neutron/l3_agent.ini 文件并完成以下作

[DEFAULT]部分中,配置 Open vSwitch 接口驱动程序

[DEFAULT]
interface_driver = openvswitch
external_network_bridge = br-ex 

其实这块官方没给,byd不知道是他们写漏了还是不想写

配置 DHCP 代理

编辑/etc/neutron/dhcp_agent.ini文件并完成以下作

[DEFAULT] 部分中,配置 Open vSwitch 接口驱动程序、Dnsmasq DHCP 驱动程序并启用隔离元数据,以便提供商网络上的实例可以通过网络访问元数据

[DEFAULT]
# ...
interface_driver = openvswitch
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = true
配置元数据代理

预处理配置文件

cp /etc/neutron/metadata_agent.ini{,.bak}
grep -Ev "^$|#" /etc/neutron/metadata_agent.ini.bak > /etc/neutron/metadata_agent.ini

编辑 /etc/neutron/metadata_agent.ini 文件并完成以下操作

[DEFAULT]部分中,配置元数据主机和共享密钥

[DEFAULT]
# ...
nova_metadata_host = controller
metadata_proxy_shared_secret = METADATA_SECRET

METADATA_SECRET 替换为元数据代理的合适密钥

配置nova服务以使用 Networking 服务

编辑 /etc/nova/nova.conf 文件并执行以下操作

[neutron] 部分,配置访问参数,启用元数据代理,并配置 secret

[neutron]
# ...
auth_url = http://controller:5000
auth_type = password
project_domain_name = Default
user_domain_name = Default
region_name = RegionOne
project_name = service
username = neutron
password = NEUTRON_PASS
service_metadata_proxy = true
metadata_proxy_shared_secret = METADATA_SECRET

NEUTRON_PASS 替换为您为 neutron用户创建的密码

METADATA_SECRET 替换为您为元数据代理选择的密钥

网络服务初始化脚本需要符号链接 /etc/neutron/plugin.ini 指向 ML2 插件配置文件 /etc/neutron/plugins/ml2/ml2_conf.ini .如果此符号链接不存在,请使用以下命令创建它

ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
填充数据库
su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf \
  --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
重新启动Nova API 服务
systemctl restart openstack-nova-api.service
启动 Networking 服务并将其配置为在系统引导时启动

对于这两个网络选项

systemctl enable neutron-server.service \
  neutron-openvswitch-agent.service neutron-dhcp-agent.service \
  neutron-metadata-agent.service

systemctl start neutron-server.service \
  neutron-openvswitch-agent.service neutron-dhcp-agent.service \
  neutron-metadata-agent.service

对于联网选项 2,还要启用并启动第 3 层服务

systemctl enable neutron-l3-agent.service
systemctl start neutron-l3-agent.service
在compute node上安装并配置Neutron

安装Neutron

dnf install openstack-neutron-openvswitch -y

预处理配置文件

cp /etc/neutron/neutron.conf{,.bak}
grep -Ev "^$|#" /etc/neutron/neutron.conf.bak > /etc/neutron/neutron.conf 

编辑 /etc/neutron/neutron.conf 文件并完成以下操作

[database] 部分中,注释掉任何connection选项,因为计算节点不直接访问数据库

[DEFAULT] 部分中,配置 RabbitMQ 消息队列访问

[DEFAULT]
# ...
transport_url = rabbit://openstack:RABBIT_PASS@controller

RABBIT_PASS 替换为您为openstatck用户所创建的密码

[oslo_concurrency]部分中,配置锁定路径

[oslo_concurrency]
# ...
lock_path = /var/lib/neutron/tmp

预处理配置文件

cp /etc/neutron/plugins/ml2/openvswitch_agent.ini{,.bak}
grep -Ev "^$|#" /etc/neutron/plugins/ml2/openvswitch_agent.ini.bak > /etc/neutron/plugins/ml2/openvswitch_agent.ini

编辑 /etc/neutron/plugins/ml2/openvswitch_agent.ini 文件并完成以下操作

[ovs] 部分中,将提供商虚拟网络映射到提供商物理网桥,并配置处理叠加网络的物理网络接口的 IP 地址

#此处不配置将会导致验证阶段缺少相应的compute节点

[ovs]

bridge_mappings = provider:PROVIDER_BRIDGE_NAME local_ip = OVERLAY_INTERFACE_IP_ADDRESS

PROVIDER_BRIDGE_NAME 替换为连接到底层提供商物理网络的网桥的名称。请参阅主机联网Open vSwitch:提供商网络了解更多信息,也就是和我们controller节点一样,我们要创建一个网桥,具体请见上述文档。

[agent] 部分中,启用 VXLAN 叠加网络并启用第 2 层填充

[agent]
tunnel_types = vxlan
l2_population = true

[securitygroup] 部分中,启用安全组并配置 Open vSwitch 本机或混合 iptables 防火墙驱动程序

[securitygroup]
# ...
enable_security_group = true
firewall_driver = openvswitch
#firewall_driver = iptables_hybrid

如果使用混合 iptables 防火墙驱动程序,请验证以下所有 sysctl 值是否都设置为 1,确保您的 Linux 作系统内核支持网桥过滤器,这一步和controller节点一样

net.bridge.bridge-nf-call-iptables
net.bridge.bridge-nf-call-ip6tables

要启用网络桥支持,通常需要加载 br_netfilter 内核模块。查看作系统的文档,了解有关启用此模块的更多详细信息。

配置 Compute 服务以使用 Networking 服务

编辑 /etc/nova/nova.conf 文件并完成以下操作

[neutron] 部分中,配置访问参数

[neutron]
# ...
auth_url = http://controller:5000
auth_type = password
project_domain_name = Default
user_domain_name = Default
region_name = RegionOne
project_name = service
username = neutron
password = NEUTRON_PASS

重新启动nova服务

systemctl restart openstack-nova-compute.service

启动 Linux 网桥代理并将其配置为在系统引导时启动

systemctl enable neutron-openvswitch-agent.service
systemctl start neutron-openvswitch-agent.service
完成之后验证服务

在controller节点上有

openstack network agent list

+-----------------------------------------------------------------+---------------------------------------------+------------------------------------------------------------------+
| Name                                                            | Alias                                       | Description                                                      |
+-----------------------------------------------------------------+---------------------------------------------+------------------------------------------------------------------+
| Address group                                                   | address-group                               | Support address group                                            |
| Address scope                                                   | address-scope                               | Address scopes extension.                                        |
| Enforce Router's Admin State Down Before Update Extension       | router-admin-state-down-before-update       | Ensure that the admin state of a router is DOWN                  |
|                                                                 |                                             | (admin_state_up=False) before updating the distributed attribute |
| agent                                                           | agent                                       | The agent management extension.                                  |
| Agent's Resource View Synced to Placement                       | agent-resources-synced                      | Stores success/failure of last sync to Placement                 |
| Allowed Address Pairs                                           | allowed-address-pairs                       | Provides allowed address pairs                                   |
| Auto Allocated Topology Services                                | auto-allocated-topology                     | Auto Allocated Topology Services.                                |
| Availability Zone                                               | availability_zone                           | The availability zone extension.                                 |
| Availability Zone Filter Extension                              | availability_zone_filter                    | Add filter parameters to AvailabilityZone resource               |
| Default Subnetpools                                             | default-subnetpools                         | Provides ability to mark and use a subnetpool as the default.    |
| DHCP Agent Scheduler                                            | dhcp_agent_scheduler                        | Schedule networks among dhcp agents                              |
| Distributed Virtual Router                                      | dvr                                         | Enables configuration of Distributed Virtual Routers.            |
| Empty String Filtering Extension                                | empty-string-filtering                      | Allow filtering by attributes with empty string value            |
| Neutron external network                                        | external-net                                | Adds external network attribute to network resource.             |
| Neutron Extra DHCP options                                      | extra_dhcp_opt                              | Extra options configuration for DHCP. For example PXE boot       |
|                                                                 |                                             | options to DHCP clients can be specified (e.g. tftp-server,      |
|                                                                 |                                             | server-ip-address, bootfile-name)                                |
| Neutron Extra Route                                             | extraroute                                  | Extra routes configuration for L3 router                         |
| Atomically add/remove extra routes                              | extraroute-atomic                           | Edit extra routes of a router on server side by atomically       |
|                                                                 |                                             | adding/removing extra routes                                     |
| Filter parameters validation                                    | filter-validation                           | Provides validation on filter parameters.                        |
| Floating IP port forwarding detail                              | floating-ip-port-forwarding-detail          | Allow list floating ip return more port forwarding data,         |
|                                                                 |                                             | include'id' and 'internal_port_id'                               |
| Floating IP Port Details Extension                              | fip-port-details                            | Add port_details attribute to Floating IP resource               |
| Neutron Service Flavors                                         | flavors                                     | Flavor specification for Neutron advanced services.              |
| Floating IP Pools Extension                                     | floatingip-pools                            | Provides a floating IP pools API.                                |
| IP address substring filtering                                  | ip-substring-filtering                      | Provides IP address substring filtering when listing ports       |
| Neutron L3 Router                                               | router                                      | Router abstraction for basic L3 forwarding between L2 Neutron    |
|                                                                 |                                             | networks and access to external networks via a NAT gateway.      |
| Neutron L3 Configurable external gateway mode                   | ext-gw-mode                                 | Extension of the router abstraction for specifying whether SNAT  |
|                                                                 |                                             | should occur on the external gateway                             |
| HA Router extension                                             | l3-ha                                       | Adds HA capability to routers.                                   |
| Router Flavor Extension                                         | l3-flavors                                  | Flavor support for routers.                                      |
| Prevent L3 router ports IP address change extension             | l3-port-ip-change-not-allowed               | Prevent change of IP address for some L3 router ports            |
| L3 Agent Scheduler                                              | l3_agent_scheduler                          | Schedule routers among l3 agents                                 |
| Multi Provider Network                                          | multi-provider                              | Expose mapping of virtual networks to multiple physical networks |
| Network MTU                                                     | net-mtu                                     | Provides MTU attribute for a network resource.                   |
| Network MTU (writable)                                          | net-mtu-writable                            | Provides a writable MTU attribute for a network resource.        |
| Network Availability Zone                                       | network_availability_zone                   | Availability zone support for network.                           |
| Network HA creation flag                                        | network_ha                                  | Network high availability creation flag.                         |
| Network IP Availability                                         | network-ip-availability                     | Provides IP availability data for each network and subnet.       |
| Pagination support                                              | pagination                                  | Extension that indicates that pagination is enabled.             |
| Port device profile                                             | port-device-profile                         | Expose the port device profile (Cyborg)                          |
| Neutron Port MAC address override                               | port-mac-override                           | Allow overriding the MAC address of a direct-physical Port via   |
|                                                                 |                                             | the active binding profile                                       |
| Neutron Port MAC address regenerate                             | port-mac-address-regenerate                 | Network port MAC address regenerate                              |
| Port NUMA affinity policy                                       | port-numa-affinity-policy                   | Expose the port NUMA affinity policy                             |
| Port NUMA affinity policy "socket"                              | port-numa-affinity-policy-socket            | Adds "socket" to the supported port NUMA affinity policies       |
| Port Binding                                                    | binding                                     | Expose port bindings of a virtual port to external application   |
| Port Bindings Extended                                          | binding-extended                            | Expose port bindings of a virtual port to external application   |
| Port Security                                                   | port-security                               | Provides port security                                           |
| project_id field enabled                                        | project-id                                  | Extension that indicates that project_id field is enabled.       |
| Provider Network                                                | provider                                    | Expose mapping of virtual networks to physical networks          |
| Quota engine limit check                                        | quota-check-limit                           | Support for checking the resource usage before applying a new    |
|                                                                 |                                             | quota limit                                                      |
| Quota management support                                        | quotas                                      | Expose functions for quotas management per project               |
| Quota details management support                                | quota_details                               | Expose functions for quotas usage statistics per project         |
| RBAC Policies                                                   | rbac-policies                               | Allows creation and modification of policies that control tenant |
|                                                                 |                                             | access to resources.                                             |
| Add address_group type to RBAC                                  | rbac-address-group                          | Add address_group type to network RBAC                           |
| Add address_scope type to RBAC                                  | rbac-address-scope                          | Add address_scope type to RBAC                                   |
| Add security_group type to network RBAC                         | rbac-security-groups                        | Add security_group type to network RBAC                          |
| Add subnetpool type to RBAC                                     | rbac-subnetpool                             | Add subnetpool type to RBAC                                      |
| If-Match constraints based on revision_number                   | revision-if-match                           | Extension indicating that If-Match based on revision_number is   |
|                                                                 |                                             | supported.                                                       |
| Resource revision numbers                                       | standard-attr-revisions                     | This extension will display the revision number of neutron       |
|                                                                 |                                             | resources.                                                       |
| Router Availability Zone                                        | router_availability_zone                    | Availability zone support for router.                            |
| Default rules for security groups                               | security-groups-default-rules               | Configure set of security group rules used as default rules for  |
|                                                                 |                                             | every new security group                                         |
| Normalized CIDR field for security group rules                  | security-groups-normalized-cidr             | Add new field with normalized remote_ip_prefix cidr in SG rule   |
| Port filtering on security groups                               | port-security-groups-filtering              | Provides security groups filtering when listing ports            |
| Remote address group id field for security group rules          | security-groups-remote-address-group        | Add new field of remote address group id in SG rules             |
| Security group rule belongs to the project's default security   | security-groups-rules-belongs-to-default-sg | Flag to determine if the security group rule belongs to the      |
| group                                                           |                                             | project's default security group                                 |
| Security group filtering on the shared field                    | security-groups-shared-filtering            | Support filtering security groups on the shared field            |
| security-group                                                  | security-group                              | The security groups extension.                                   |
| Neutron Service Type Management                                 | service-type                                | API for retrieving service providers for Neutron advanced        |
|                                                                 |                                             | services                                                         |
| Sorting support                                                 | sorting                                     | Extension that indicates that sorting is enabled.                |
| standard-attr-description                                       | standard-attr-description                   | Extension to add descriptions to standard attributes             |
| Stateful security group                                         | stateful-security-group                     | Indicates if the security group is stateful or not               |
| Subnet belongs to an external network                           | subnet-external-network                     | Informs if the subnet belongs to an external network             |
| Subnet Onboard                                                  | subnet_onboard                              | Provides support for onboarding subnets into subnet pools        |
| Subnet service types                                            | subnet-service-types                        | Provides ability to set the subnet service_types field           |
| Subnet Allocation                                               | subnet_allocation                           | Enables allocation of subnets from a subnet pool                 |
| Subnet Pool Prefix Operations                                   | subnetpool-prefix-ops                       | Provides support for adjusting the prefix list of subnet pools   |
| Tag creation extension                                          | tag-creation                                | Allow to create multiple tags for a resource                     |
| Tag support for resources with standard attribute: port,        | standard-attr-tag                           | Enables to set tag on resources with standard attribute.         |
| subnet, subnetpool, network, security_group, router,            |                                             |                                                                  |
| floatingip, policy, trunk, network_segment_range                |                                             |                                                                  |
| Resource timestamps                                             | standard-attr-timestamp                     | Adds created_at and updated_at fields to all Neutron resources   |
|                                                                 |                                             | that have Neutron standard attributes.                           |
+-----------------------------------------------------------------+---------------------------------------------+------------------------------------------------------------------+

对于自服务节点(controller)有

openstack network agent list

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| ID                                   | Agent Type         | Host       | Availability Zone | Alive | State | Binary                    |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| 298aaa2f-babc-4e3b-968a-e2c79b36f9b3 | Open vSwitch agent | controller | None              | :-)   | UP    | neutron-openvswitch-agent |
| 2e5f397f-f79c-4dd3-b812-9cb4b2aba543 | Metadata agent     | controller | None              | :-)   | UP    | neutron-metadata-agent    |
| 3f4d1a9c-1c87-4f20-b873-bbc0a82345b5 | L3 agent           | controller | nova              | :-)   | UP    | neutron-l3-agent          |
| 3f987477-b01c-4b39-af35-71845701c2ca | Open vSwitch agent | compute    | None              | :-)   | UP    | neutron-openvswitch-agent |
| c66e7560-508b-46dd-8bf0-a3ba0df71463 | DHCP agent         | controller | nova              | :-)   | UP    | neutron-dhcp-agent        |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
#要确保五个都起来了

对于自服务节点(controller)有

openstack network agent list

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| ID                                   | Agent Type         | Host       | Availability Zone | Alive | State | Binary                    |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| 298aaa2f-babc-4e3b-968a-e2c79b36f9b3 | Open vSwitch agent | controller | None              | :-)   | UP    | neutron-openvswitch-agent |
| 2e5f397f-f79c-4dd3-b812-9cb4b2aba543 | Metadata agent     | controller | None              | :-)   | UP    | neutron-metadata-agent    |
| 3f4d1a9c-1c87-4f20-b873-bbc0a82345b5 | L3 agent           | controller | nova              | :-)   | UP    | neutron-l3-agent          |
| 3f987477-b01c-4b39-af35-71845701c2ca | Open vSwitch agent | compute    | None              | :-)   | UP    | neutron-openvswitch-agent |
| c66e7560-508b-46dd-8bf0-a3ba0df71463 | DHCP agent         | controller | nova              | :-)   | UP    | neutron-dhcp-agent        |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
#要确保五个都起来了
Block Storage service (Cinder) – 块存储服务

出于安全原因 ,必须在 OpenStack 中配置服务令牌 ,以便 Cinder 安全运行。请密切注意描述它的特定部分:。看 https://bugs.launchpad.net/nova/+bug/2004555 了解详情。介绍

Block Storage(块存储)——相当于“移动硬盘”

是什么?

  • Block Storage(通常指 Cinder 服务)提供 块设备存储,类似于 电脑硬盘、U盘、移动硬盘
  • 它给虚拟机(VM)提供 “磁盘”,可以被格式化成 ext4、NTFS 等文件系统。

核心特点

挂载到虚拟机

像插U盘一样,把存储挂载到VM上,VM可以读写。

高性能

适合数据库、运行操作系统等需要低延迟的场景。

可扩展大小

可以动态扩容(比如从 100GB 扩大到 1TB)。

支持快照和备份

能对磁盘做快照,方便恢复数据。

使用场景

  • 虚拟机系统盘(安装操作系统)
  • 数据库存储(MySQL、PostgreSQL)
  • 高性能应用(如Redis、Kafka)

举个栗子 🌰

你买了一台新电脑(虚拟机),但硬盘不够用,于是:

  • 你插入一块 移动硬盘(Block Storage),格式化成NTFS。
  • 电脑可以像访问本地硬盘一样读写它。
  • 如果你删了虚拟机,这块“移动硬盘”还能保留数据,挂载到其他VM。

这就是 Block Storage 的工作方式!

创建Block Storage service数据库
mysql -u root -p

#创建cinder数据库
CREATE DATABASE cinder;

#授予对 cinder 数据库的适当访问权限
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' \
  IDENTIFIED BY 'CINDER_DBPASS';
GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' \
  IDENTIFIED BY 'CINDER_DBPASS';
  

CINDER_DBPASS 替换为合适的密码

创建Cinder服务

获取 admin 凭据以访问仅限管理员使用的 CLI 命令:

. admin-openrc

要创建服务凭证,请完成以下步骤

创建 cinder 用户

openstack user create --domain default --password-prompt cinder

User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| default_project_id  | None                             |
| domain_id           | default                          |
| email               | None                             |
| enabled             | True                             |
| id                  | 8f93e536cda74de5a12714b110854fb7 |
| name                | cinder                           |
| description         | None                             |
| password_expires_at | None                             |
+---------------------+----------------------------------+

admin 角色添加到 cinder 用户

openstack role add --project service --user cinder admin

创建 cinder_v3 服务实体

openstack service create --name cinderv3 \
--description "OpenStack Block Storage" volumev3

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| id          | 65980a608b1b4c139529effc667c9184 |
| name        | cinderv3                         |
| type        | volumev3                         |
| enabled     | True                             |
| description | OpenStack Block Storage          |
+-------------+----------------------------------+

创建块存储服务 API 端点

openstack endpoint create --region RegionOne \
  volumev3 public http://controller:8776/v3/%\(project_id\)s

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+---------------------------------------------+
| Field        | Value                                       |
+--------------+---------------------------------------------+
| enabled      | True                                        |
| id           | 2ae60f38ce354a07a127a423f1a0f9f9            |
| interface    | public                                      |
| region       | RegionOne                                   |
| region_id    | RegionOne                                   |
| service_id   | 65980a608b1b4c139529effc667c9184            |
| service_name | cinderv3                                    |
| service_type | volumev3                                    |
| url          | http://192.168.1.150:8776/v3/%(project_id)s |
+--------------+---------------------------------------------+

########################################################################

openstack endpoint create --region RegionOne \
  volumev3 internal http://controller:8776/v3/%\(project_id\)s

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+---------------------------------------------+
| Field        | Value                                       |
+--------------+---------------------------------------------+
| enabled      | True                                        |
| id           | 786d8a81213f4f298a04e2be1cf3897e            |
| interface    | internal                                    |
| region       | RegionOne                                   |
| region_id    | RegionOne                                   |
| service_id   | 65980a608b1b4c139529effc667c9184            |
| service_name | cinderv3                                    |
| service_type | volumev3                                    |
| url          | http://192.168.1.150:8776/v3/%(project_id)s |
+--------------+---------------------------------------------+

########################################################################

openstack endpoint create --region RegionOne \
  volumev3 admin http://controller:8776/v3/%\(project_id\)s

  /usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+--------------+---------------------------------------------+
| Field        | Value                                       |
+--------------+---------------------------------------------+
| enabled      | True                                        |
| id           | 3fb7c382c81f4868b6baeba3e907fd58            |
| interface    | admin                                       |
| region       | RegionOne                                   |
| region_id    | RegionOne                                   |
| service_id   | 65980a608b1b4c139529effc667c9184            |
| service_name | cinderv3                                    |
| service_type | volumev3                                    |
| url          | http://192.168.1.150:8776/v3/%(project_id)s |
+--------------+---------------------------------------------+

  
安装并配置组件

安装软件包

yum install openstack-cinder -y

预处理配置文件

cp /etc/cinder/cinder.conf{,.bak}
grep -Ev "^$|#" /etc/cinder/cinder.conf.bak > /etc/cinder/cinder.conf

编辑 /etc/cinder/cinder.conf文件并完成以下操作

[database] 部分,配置数据库访问

[database]
# ...
connection = mysql+pymysql://cinder:CINDER_DBPASS@controller/cinder

CINDER_DBPASS 替换为您为块存储数据库选择的密码

[DEFAULT] 部分,配置 RabbitMQ 消息队列访问

[DEFAULT]
# ...
transport_url = rabbit://openstack:RABBIT_PASS@controller

RABBIT_PASS 替换为你在 RabbitMQ 中为 openstack 账户设置的密码

[DEFAULT][keystone_authtoken] 部分,配置身份认证服务访

[DEFAULT]
# ...
auth_strategy = keystone

[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

CINDER_PASS 替换为你在身份服务中为 cinder 用户设置的密码

[DEFAULT] 部分,配置 my_ip 选项以使用控制节点的管理接口 IP 地址

[DEFAULT]
# ...
my_ip = MANAGERMENT_INTERFACE_IP

Data_Interface_of_Block_Node字段换成block node上的唯一一个ip

[oslo_concurrency] 部分,配置锁路径

[oslo_concurrency]
# ...
lock_path = /var/lib/cinder/tmp

填充块存储数据库

su -s /bin/sh -c "cinder-manage db sync" cinder
配置计算服务以使用块存储

编辑/etc/nova/nova.conf文件并添加以下内容

[cinder]
os_region_name = RegionOne

重启计算 API 服务

systemctl restart openstack-nova-api.service

启动块存储服务并配置它们在系统启动时自动运行

systemctl enable openstack-cinder-api.service openstack-cinder-scheduler.service
systemctl start openstack-cinder-api.service openstack-cinder-scheduler.service
安装并配置存储节点

注意:在存储节点上安装和配置块存储服务之前,您必须准备好存储设备。

安装支持性工具包

安装 LVM 软件包

yum install lvm2 device-mapper-persistent-data -y

对于 CentOS 8 或更高版本无需此操作,因其自带的 LVM 版本已不再使用 lvmetad 服务

systemctl enable lvm2-lvmetad.service
systemctl start lvm2-lvmetad.service

创建 LVM 物理卷 /dev/sdb

pvcreate /dev/sdb
#成功的话会输出以下内容
Physical volume "/dev/sdb" successfully created

创建 LVM 卷组 cinder-volumes

vgcreate cinder-volumes /dev/sdb
#成功的话会输出以下内容
Volume group "cinder-volumes" successfully created

块存储服务在此卷组中创建逻辑卷

只有实例能够访问块存储卷。然而,底层操作系统管理与卷关联的设备。默认情况下,LVM 卷扫描工具会扫描 /dev 目录以查找包含卷的块存储设备。如果项目在其卷上使用 LVM,扫描工具会检测到这些卷并尝试缓存它们,这可能导致底层操作系统和项目卷出现各种问题。您必须重新配置 LVM,使其仅扫描包含 cinder-volumes 卷组的设备。编辑 /etc/lvm/lvm.conf 文件并完成以下操作

devices 部分,添加一个过滤器以接受 /dev/sdb 设备并拒绝所有其他设备

devices {
...
filter = [ "a/sdb/", "r/.*/"]

过滤器数组中的每个条目以 a (接受)或 r (拒绝)开头,并包含设备名称的正则表达式。数组必须以 r/.*/ 结尾以拒绝其余设备。您可以使用 vgs -vvvv 命令测试过滤器警告部分

如果您的存储节点在操作系统磁盘上使用 LVM,则还必须将相关设备添加到过滤器中。例如,如果

/dev/sda 设备包含操作系统:

filter = [ "a/sda/", "a/sdb/", "r/.*/"]

同样,如果您的计算节点在操作系统磁盘上使用 LVM,则还必须修改这些节点上 /etc/lvm/lvm.conf 文件中的过滤器,使其仅包含操作系统磁盘。例如,如果 /dev/sda 设备包含操作系统:

filter = [ "a/sda/", "r/.*/"]
安装并配置组件

安装软件包

yum install openstack-cinder targetcli -y

预处理配置文件

cp /etc/cinder/cinder.conf{,.bak}
grep -Ev "^$|#" /etc/cinder/cinder.conf.bak > /etc/cinder/cinder.conf

编辑 /etc/cinder/cinder.conf 文件并完成以下操作

[database] 部分,配置数据库访问

[database]
# ...
connection = mysql+pymysql://cinder:CINDER_DBPASS@controller/cinder

CINDER_DBPASS 替换为您为块存储数据库选择的密码

[DEFAULT] 部分,配置 RabbitMQ 消息队列访问

[DEFAULT]
# ...
transport_url = rabbit://openstack:RABBIT_PASS@controller

[DEFAULT][keystone_authtoken] 部分,配置身份认证服务访问

[DEFAULT]
# ...
auth_strategy = keystone

[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

CINDER_PASS 替换为你在身份服务中为 cinder 用户设置的密码

[DEFAULT] 部分,配置 my_ip 选项

[DEFAULT]
# ...
my_ip = MANAGEMENT_INTERFACE_IP_ADDRESS

MANAGEMENT_INTERFACE_IP_ADDRESS 替换为您存储节点管理网络接口的 IP 地址

[lvm] 部分,使用 LVM 驱动配置 LVM 后端, cinder-volumes 卷组,iSCSI 协议及适当的 iSCSI 服务。若 [lvm] 部分不存在,请创建

[lvm]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_group = cinder-volumes
target_protocol = iscsi
target_helper = lioadm

[DEFAULT] 部分,启用 LVM 后端

[DEFAULT]
# ...
enabled_backends = lvm

[DEFAULT] 部分,配置镜像服务 API 的位置

[DEFAULT]
# ...
glance_api_servers = http://controller:9292

[oslo_concurrency] 部分,配置锁路径

[oslo_concurrency]
# ...
lock_path = /var/lib/cinder/tmp
完成安装

启动块存储卷服务及其依赖项,并配置它们在系统启动时自动运行

systemctl enable openstack-cinder-volume.service target.service
systemctl start openstack-cinder-volume.service target.service
验证块存储服务的运行情况

导入 admin 凭证以获取管理员专用 CLI 命令的访问权限

. admin-openrc

列出服务组件以验证每个进程是否成功启动

openstack volume service list

/usr/lib/python3.9/site-packages/requests/__init__.py:86: RequestsDependencyWarning: Unable to find acceptable character detection dependency (chardet or charset_normalizer).
  warnings.warn(
+----------------+------------+------+---------+-------+----------------+
| Binary         | Host       | Zone | Status  | State | Updated At     |
+----------------+------------+------+---------+-------+----------------+
| cinder-        | controller | nova | enabled | up    | 2025-04-15T11: |
| scheduler      |            |      |         |       | 39:16.000000   |
| cinder-volume  | block@lvm  | nova | enabled | up    | 2025-04-15T11: |
|                |            |      |         |       | 39:10.000000   |
+----------------+------------+------+---------+-------+----------------+
#官方给的其实有个backup,因为我没部署Swift这个所以就没有,应该没有吧
安装并配置Skyline

安装Docker

安装Docker的部分请在我的另一篇文章中查看

创建Skyline数据库

在安装和配置 Skyline 服务之前,您必须先创建一个数据库

mysql -u root -p

#创建 skyline 数据库
CREATE DATABASE skyline DEFAULT CHARACTER SET \
 utf8 DEFAULT COLLATE utf8_general_ci;

#授予对 skyline 数据库的适当访问权限
GRANT ALL PRIVILEGES ON skyline.* TO 'skyline'@'localhost' \
  IDENTIFIED BY 'SKYLINE_DBPASS';
GRANT ALL PRIVILEGES ON skyline.* TO 'skyline'@'%' \
  IDENTIFIED BY 'SKYLINE_DBPASS';

SKYLINE_DBPASS 替换为合适的密码

创建服务凭证

导入 admin 凭证以获取管理员专用 CLI 命令的访问权限

. admin-openrc

要创建服务凭证,请完成以下步骤

创建 skyline 用户

openstack user create --domain default --password-prompt skyline

User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| default_project_id  | None                             |
| domain_id           | default                          |
| email               | None                             |
| enabled             | True                             |
| id                  | 4f28c0b1f1344ae8943f9bfd111e8d1e |
| name                | skyline                          |
| description         | None                             |
| password_expires_at | None                             |
+---------------------+----------------------------------+

admin 角色添加到 skyline 用户

openstack role add --project service --user skyline admin
安装并配置组件

我们将从 Docker 镜像安装 Skyline 服务

Docker Hub 拉取 Skyline 服务镜像

sudo docker pull 99cloud/skyline:latest

确保已创建 skyline 的某些文件夹

sudo mkdir -p /etc/skyline /var/log/skyline /var/lib/skyline /var/log/nginx

配置 /etc/skyline/skyline.yaml文件

修改 /etc/skyline/skyline.yaml 中的相关配置。配置的详细介绍可参阅 OpenStack 天窗设置。

default:
  database_url: mysql://skyline:SKYLINE_DBPASS@DB_SERVER:3306/skyline
  debug: true
  log_dir: /var/log
openstack:
  keystone_url: http://KEYSTONE_SERVER:5000/v3/
  system_user_password: SKYLINE_SERVICE_PASSWORD

SKYLINE_DBPASSDB_SERVERKEYSTONE_SERVERSKYLINE_SERVICE_PASSWORD 替换为正确的值。

运行容器

运行引导服务器

sudo docker run -d --name skyline_bootstrap \
  -e KOLLA_BOOTSTRAP="" \
  -v /etc/skyline/skyline.yaml:/etc/skyline/skyline.yaml \
  -v /var/log:/var/log \
  --net=host 99cloud/skyline:latest

 
#你如果能看到如下信息,则证明服务运行正常
+ echo '/usr/local/bin/gunicorn -c /etc/skyline/gunicorn.py skyline_apiserver.main:app'
+ mapfile -t CMD
++ xargs -n 1
++ tail /run_command
+ [[ -n 0 ]]
+ cd /skyline-apiserver/
+ make db_sync
alembic -c skyline_apiserver/db/alembic/alembic.ini upgrade head
2022-08-19 07:49:16.004 | INFO     | alembic.runtime.migration:__init__:204 - Context impl MySQLImpl.
2022-08-19 07:49:16.005 | INFO     | alembic.runtime.migration:__init__:207 - Will assume non-transactional DDL.
+ exit 0

清理引导服务器

sudo docker rm -f skyline_bootstrap

运行 skyline

sudo docker run -d --name skyline --restart=always \
  -v /etc/skyline/skyline.yaml:/etc/skyline/skyline.yaml \
  -v /var/log:/var/log \
  --net=host 99cloud/skyline:latest
https://xxxxx:9999是你的skyline服务面板位置


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码