本文最后更新于 2025-04-25,文章内容可能已经过时。

部署Openstack服务器流程

安装流程

机器配置:
controller server 2h4g 50gb 以上
compute server 4h8g 100gb以上,安装cinder可以只分配50gb
cinder server 2h4g 建议300gb以上

网络状态和设计思路:
192.168.111.0/24 nat网段,用于联网
10.0.1.11.0/24 managerment网段,用于三台机器相互请求

外网ip:这里直接给了10.0.1.0 下对应的机器,为了省事,也可以绑定额外的外网ip。
条件允许的话可以给较多的外网ip,可以用于openstack的浮动ip供外网访问。

controller 双网卡,nat:192.168.111.11,managerment:10.0.1.11
compute 双网卡,nat:192.168.111.12,managerment:10.0.1.12
cinder 双网卡,nat:192.168.111.13,managerment:10.0.1.13

openstack网络关系图:

系统使用:
centos,ubuntu和redhat均可,对应官方文档进行其他的查看即可。
注意:
redhat9 可能存在问题,因为原文档并没有对于redhat9的安装流程,可能存在较多小问题需要解决。
centos 在centos8停止维护后其他国内源最高只支持到train版本,上级版本需要手动安装较为麻烦
ubuntu,支持最新的zed,使用22.0.4即可。
拓扑图即openstack关系
term.png
安装版本 Zed¶
推荐对照官方文档进行部署
官方文档https://docs.openstack.org/zed/#install-guides

1.网络和时间同步配置

1.1 时间配置

1.1.1 controller节点配置

配置时钟同步:

[root@controller ~]# yum install chrony
[root@controller ~]# vim /etc/chrony.conf
allow 10.0.1.11/24  允许其他节点网段同步时间,请配置为对应网段

增加开机服务

[root@controller ~]# systemctl enable chronyd && systemctl restart chronyd

进行测试验证

[root@controller ec2-user]# chronyc sources  
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* 169.254.169.123               3   4   377    10  -9460ns[  -12us] +/-  494us
[root@controller ec2-user]# timedatectl 
               Local time: Fri 2022-12-02 05:24:33 UTC
           Universal time: Fri 2022-12-02 05:24:33 UTC
                 RTC time: Fri 2022-12-02 05:24:33
                Time zone: UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

1.1.2 compute和cinder节点配置

安装时钟同步:

[root@controller ~]# yum install chrony
[root@controller ~]# vim /etc/chrony.conf

设置 compute节点时钟同步:

[root@compute1 ~]# vim /etc/chrony.conf   #注释其他ip,更新本地ip
  1 # Use public servers from the pool.ntp.org project.
  2 # Please consider joining the pool (http://www.pool.ntp.org/join.html).
  7 server 10.0.1.11 iburst

进行测试验证

[root@cinder ec2-user]# chronyc sources  
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* controller                    4   6     7     0   -960ns[+7745ns] +/-  696us
[root@cinder ec2-user]# timedatectl 
               Local time: Fri 2022-12-09 01:42:18 UTC
           Universal time: Fri 2022-12-09 01:42:18 UTC
                 RTC time: Fri 2022-12-09 01:42:18
                Time zone: UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

1.2 修改对应host

vim /etc/hosts

10.0.1.11 controller
10.0.1.12 compute
10.0.1.13 storage

1.2.1 修改hostname

hostnamectl set-hostname (对应hostname,不设置会导致后续openstack发现其他节点等机器名称问题)

1.3网络配置

需要配置 /etc/sysconfig/network-scripts/ifcfg-INTERFACE_NAME :

不要更改HWADDR 和 uuid

DEVICE=INTERFACE_NAME
TYPE=Ethernet
ONBOOT="yes"
BOOTPROTO="none"

1.4 redhat仓库配置

aws服务器默认是关闭了 rehl仓库的配置的,想要进行链接到openstack,首先要开启rehl仓库,但是这个需要订阅redhat才能使用其仓库:

#启用存储库,这里举例redhat9
[root@controller yum.repos.d]# subscription-manager repos --enable=rhel-9-for-x86_64-appstream-rpms   --enable=rhel-9-for-x86_64-supplementary-rpms --enable=codeready-builder-for-rhel-9-x86_64-rpms
Repository 'rhel-9-for-x86_64-appstream-rpms' is enabled for this system.
Repository 'rhel-9-for-x86_64-supplementary-rpms' is enabled for this system.
Repository 'codeready-builder-for-rhel-9-x86_64-rpms' is enabled for this system.

2安装openstack服务

2.1 安装openstack服务

全节点执行

#RDO存储库RPM安装最新的可用OpenStack版本
dnf install https://www.rdoproject.org/repos/rdo-release.el9.rpm

# 升级所有软件包
yum upgrade
# 安装openstack客户端
yum install python3-openstackclient
# 安装openstack-selinux软件包来自动管理openstack
yum install openstack-selinux

2.2 安装mariadb数据库

Controller节点执行

# 安装数据库
yum install mariadb mariadb-server python2-PyMySQL

初始化数据库并传递参数

#创建和编辑文件 (如果需要,请备份现有配置文件) 并完成以下操作
[root@controller ~]# vim /etc/my.cnf.d/openstack.cnf
[mysqld]
bind-address = 10.0.1.11

default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
# 启动数据库服务
[root@controller yum.repos.d]# systemctl enable mariadb.service
Created symlink /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/mysqld.service → /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib/systemd/system/mariadb.service.

systemctl start mariadb.service

# 初始化数据库
[root@controller ~]# mysql_secure_installation

2.3 安装RabbitMQ消息队列

在controller节点执行

yum install rabbitmq-server
# 设置开机启动
systemctl enable rabbitmq-server.service && systemctl start rabbitmq-server.service
# 创建openstack 账户,示例密码123456
rabbitmqctl add_user openstack 123456
# 为openstack用户增加配置、读取及写入相关权限
rabbitmqctl set_permissions openstack ".*" ".*" ".*"

2.4 安装Memcached缓存数据库

在controller节点执行

# 安装软件
yum install memcached python3-memcached

# 配置地址为本机
[root@controller yum.repos.d]# vim  /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 10.0.1.11,::1"

# 增加自启动
systemctl enable memcached.service && systemctl start memcached.service

2.5 安装Etcd服务

在controller节点执行

1.安装软件包

[root@controller ~]# yum install etcd

2.编辑/etc/etcd/etcd.conf文件,以控制节点管理IP地址设置相关选项,以使其他节点通过管理网络进行访问

[root@controller ec2-user]# vim /etc/etcd/etcd.conf
# [member]
ETCD_NAME="controller"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
ETCD_LISTEN_PEER_URLS="http://10.0.1.11:2380"
ETCD_LISTEN_CLIENT_URLS="http://10.0.1.11:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.1.11:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
ETCD_INITIAL_CLUSTER="controller=http://10.0.1.11:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01"
ETCD_ADVERTISE_CLIENT_URLS="http://10.0.1.11:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#ETCD_STRICT_RECONFIG_CHECK="false"
#ETCD_AUTO_COMPACTION_RETENTION="0"

开机自启动

systemctl enable etcd && systemctl start etcd

3. 安装基础服务

3.1安装keystone服务

在controller节点执行
本节描述如何在控制节点上安装和配置OpenStack身份认证服务,即称为keystone。出于可扩展性的目的,此配置部署了Fernet tokens和Apache HTTP服务器来处理请求。

3.1.1 认证服务概述

OpenStack认证服务提供单一的集成点,用于管理身份验证、授权和服务目录。

认证服务通常是用户与之交互的第一个服务。一旦经过身份验证,最终用户可以使用其身份来访问其他OpenStack服务。同样,其他OpenStack服务利用认证服务来确保用户是他们本人,并且发现部署中的其他服务在哪里。认证服务还可以与一些外部用户管理系统(如LDAP)集成。

用户和服务可以通过使用由认证服务管理的服务目录来定位其他服务。顾名思义,服务目录是OpenStack部署中可用服务的集合。每个服务可以有一个或多个端点,每个端点可以是三种类型之一:管理员、内部或公共。在生产环境中,出于安全原因,不同的端点类型可能驻留在暴露给不同类型用户的单独网络上。例如,公共API网络可能从因特网上可见,因此客户可以管理他们的云。管理API网络可能局限于管理云基础设施的组织内的操作员。内部API网络可能局限于包含OpenStack服务的主机。此外,OpenStack支持多个区域的可扩展性。为了简单起见,本指南使用管理网络来实现所有端点类型和默认的TrimOne区域。在认证服务中创建的区域、服务和端点一起构成部署的服务目录。部署中的每个OpenStack服务需要一个服务条目,其中存储在标识服务中的相应端点。这一切都可以在认证服务安装和配置之后完成。

认证服务包含这些组件:
Server
一个中央服务器使用RESTful接口提供认证和授权服务。
Drivers
驱动程序或服务后端集成到中央服务器。它们用于访问OpenStack外部的库中的身份信息,并且可能已经存在于部署OpenStack的基础设施中(例如,SQL数据库或LDAP服务器)。
Modules
中间件模块运行在使用认证服务的OpenStack组件的地址空间中。这些模块拦截服务请求,提取用户凭据,并将其发送到集中式服务器进行授权。中间件模块和OpenStack组件之间的集成使用Python Web服务器网关接口。

3.1.2 安装和配置keystone

创建keystone数据库

1.以root用户连接到数据库服务器:

$ mysql -u root -p

2.创建keystone数据库:

MariaDB [(none)]> CREATE DATABASE keystone;

3.授予keystone数据库适当的访问权限:

MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \
IDENTIFIED BY '123456';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \
IDENTIFIED BY '123456';

注意:这里密码设置为123456,可以自己更改

安装和配置keystone组件

1.安装软件包

# yum install openstack-keystone httpd python3-mod_wsgi

2.编辑并修改/etc/keystone/keystone.conf配置文件

[root@controller ~]# vim /etc/keystone/keystone.conf

在 [database]部分, 配置数据库访问权限:

[database]
# ...
connection = mysql+pymysql://keystone:123456@controller/keystone #678

注意:这里密码设置为123456,可以自己更改

# 在[token] 部分, 配置Fernet token provider
[token]
# ...
provider = fernet #2627

3.同步认证服务数据库:

# su -s /bin/sh -c "keystone-manage db_sync" keystone

4.初始化Fernet key库:

# keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
# keystone-manage credential_setup --keystone-user keystone --keystone-group keystone

5.引导身份认证服务:

在皇后区发布之前,Keystone 需要在两个单独的端口上运行 容纳运行单独的仅限管理员服务的标识 v2 API 通常在端口 35357 上。删除 v2 API 后,可以运行梯形失真 在所有接口的同一端口上。

# keystone-manage bootstrap --bootstrap-password 123456 \
  --bootstrap-admin-url http://controller:5000/v3/ \
  --bootstrap-internal-url http://controller:5000/v3/ \
  --bootstrap-public-url http://controller:5000/v3/ \
  --bootstrap-region-id RegionOne

替换管理用户的合适密码,这里为123456作为演示

配置apache http服务

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

[root@controller ~]# vim /etc/httpd/conf/httpd.conf
ServerName controller #101

2.创建到/usr/share/keystone/wsgi-keystone.conf文件的链接:

[root@controller ~]# ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/

3.启动Apache HTTP服务并配置开机启动

[root@controller ~]# systemctl enable httpd.service && systemctl start httpd.service

4.配置临时环境变量,administrative 账户

export OS_USERNAME=admin
export OS_PASSWORD=123456
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3

3.1.3 创建项目和用户

身份服务为每个OpenStack服务提供身份验证服务。身份验证服务使用域,项目,用户和角色的组合(domain, projects, users, and roles)。

1.创建域,尽管上面keystone-manage bootstrap步骤已经存在“default”域,但创建新域的正式方法是:
这里示例为bdcp

$ openstack domain create --description "bdcp Domain" bdcp
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Domain                           |
| enabled     | True                             |
| id          | fc78e35834994f1a996613c5f1a122d9 |
| name        | example                          |
| tags        | []                               |
+-------------+----------------------------------+

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

$ openstack project create --domain default   --description "Service Project" service
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Service Project                  |
| domain_id   | default                          |
| enabled     | True                             |
| id          | 729c117ab8a34a8fa5e8e4ae7483b4d1 |
| is_domain   | False                            |
| name        | service                          |
| parent_id   | default                          |
| tags        | []                               |
+-------------+----------------------------------+

3.创建平台demon项目,普通(非管理员)任务应该使用非特权项目和用户。 作为示例,这里创建演示项目和用户。创建演示项目:
$ openstack project create - -domain default \

  • -description "Demo Project" demo

执行结果:

$ openstack project create --domain default --description "Demo Project" demo
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Demo Project                     |
| domain_id   | default                          |
| enabled     | True                             |
| id          | e0eee8090b0a47ca89d939b6d8af6ad1 |
| is_domain   | False                            |
| name        | demo                             |
| parent_id   | default                          |
| tags        | []                               |
+-------------+----------------------------------+

4.创建demo用户
$ openstack user create - -domain default \

  • -password-prompt demo

执行结果:

$ openstack user create --domain default  --password-prompt demo
User Password:
Repeat User Password:
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | 3c02bb34841f4995949d7901030c2998 |
| name                | demo                             |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

5.创建用户角色:

$ openstack role create user
+-----------+----------------------------------+
| Field     | Value                            |
+-----------+----------------------------------+
| domain_id | None                             |
| id        | 0e92fc47c525472685f83c390015d085 |
| name      | user                             |

6.将用户角色添加到demo项目和用户:

$ openstack role add --project demo --user demo user

注意:该命令没有输出,另外您可以重复此过程来创建其他项目和用户。

3.1.4 验证认证服务操作

1.取消设置临时OS_AUTH_URL和OS_PASSWORD环境变量:

$ unset OS_AUTH_URL OS_PASSWORD

2.作为管理员用户,请求身份验证令牌

$ 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

+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field      | Value                                                                                                                                                                                   |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| expires    | 2022-12-06T08:29:59+0000                                                                                                                                                                |
| id         | gAAAAABjju93E8mylsfXkgYX3LKb4gOmZUODWlJTPaQw6aASmMEeIBJLYBMlXftttv-j5eQb9iuo-y3kBI1LXr0Uxd_4IRYj9I8gWQwOft6zyfwfzrtUU8V1LwRvDdhYfS4LzBzQz6ZemhcFCdqQ8RO9auI-Wvpe7kzO3AEVAPTozZnpOh53qio |
| project_id | 4b7e0b39f4d948188fb28e1127b085e5                                                                                                                                                        |
| user_id    | cdd54bb2e34a4bba8314bdd4170e8b42                                                                                                                                                        |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

demo账户返回的认证token

$ openstack --os-auth-url http://controller:5000/v3 \
> --os-project-domain-name Default --os-user-domain-name Default \
> --os-project-name demo --os-username demo token issue
Password: 
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field      | Value                                                                                                                                                                                   |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| expires    | 2022-10-20T09:25:10+0000                                                                                                                                                                |
| id         | gAAAAABjUQXmaPLkztx2IkkccV4-ExRLFssWk-xNmnITuRe8SQzfz12_NSjTjXEwGw9_4jh35GfUY-BCeCQ__nYDmNin-t2doLOuW7ZoCsOFB_PYNNPikkUYqkhyOXDEfhVW1S3kQpup-a540GU1zP0CywGzG4rDXn-376L2mOa1OKxO1BUP_fw |
| project_id | e0eee8090b0a47ca89d939b6d8af6ad1                                                                                                                                                        |
| user_id    | 3c02bb34841f4995949d7901030c2998                                                                                                                                                        |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

注意:此命令使用演示用户和API端口5000的密码,该端口只允许对Identity Service API进行常规(非管理员)访问。

3.1.5创建客户端环境脚本

前面几节使用了环境变量和命令选项的组合,通过openstack客户端与Identity服务进行交互。 为了提高客户端操作的效率,OpenStack支持简单的客户端环境脚本,也称为OpenRC文件。 这些脚本通常包含所有客户端的常用选项,但也支持独特的选项。
创建脚本
为管理员和演示项目和用户创建客户端环境脚本。后续所有操作将引用这些脚本来为客户端操作加载适当的凭据。
1.创建并编辑admin-openrc文件并添加以下内容:

$ vim admin-openrc
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=admin
export OS_USERNAME=admin
export OS_PASSWORD=123456
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2

注意这里的admin用户密码为123456,替换为您在Identity Service中为admin用户设置的密码。

2.创建并编辑demo-openrc文件并添加以下内容:

$ vim demo-openrc
export OS_PROJECT_DOMAIN_NAME=Default
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_NAME=demo
export OS_USERNAME=demo
export OS_PASSWORD=123456
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
export OS_IMAGE_API_VERSION=2

注意这里的demo用户密码为123456,替换为您在Identity Service中为demo用户设置的密码。
完成以后如下,我这里创建在/root目录下:
[root@controller ~]# ll
total 24
-rw-r--r-- 1 root root 261 Oct 20 01:27 admin-openrc
-rw-------. 1 root root 2770 Oct 19 18:56 anaconda-ks.cfg
-rw-r--r-- 1 root root 259 Oct 20 01:29 demo-openrc

使用脚本
要以特定项目和用户身份运行客户端,只需在运行客户端环境脚本之前加载相关的客户端环境脚本即可。 例如:

1.加载admin-openrc文件以使用Identity服务的位置以及管理项目和用户凭据执行环境变量:

$ . admin-openrc
Request an authentication token:

2.请求身份验证令牌:

$  openstack token issue
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field      | Value                                                                                                                                                                                   |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| expires    | 2022-10-20T09:31:29+0000                                                                                                                                                                |
| id         | gAAAAABjUQdhNWFQBpr7P1hmFOdTnTDILMnjL16U0CLN2OIj58DLKP3Pq6Oc9pKcmDbfXZxcETfMM20aIEHcxzYru0eVRM_hohqQkSCjAmujK4SU-0pZYDI12NXyA57DVlwcwdzC05wEOcc74Xy8qmlXTCE2nkjU_Pn2uyLC3_cdH9TuZoGI42k |
| project_id | e5c5bdc8488a4116b8ec76b988b91c38                                                                                                                                                        |
| user_id    | 0d5ceafbc23f415896da103fd96cfc16                                                                                                                                                        |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

3.2安装Glance服务

以下操作在控制节点执行

3.2.1 创建glance数据库

1.创建glance数据库
以root用户连接到数据库:

$ mysql -u root -p

创建glance数据库:

CREATE DATABASE glance;

授予对glance数据库的正确访问权限:

GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' \
  IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' \
  IDENTIFIED BY '123456';

2.获取admin用户的环境变量

$ . admin-openrc

3.要创建服务凭据,请完成以下步骤
创建glance用户:

$ openstack user create --domain default --password-prompt glance
User Password:
Repeat User Password:
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | 82ff633f7f914904ab56813cc53fefcb |
| name                | glance                           |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

把admin角色添加到glance用户和项目中

$ openstack role add --project service --user glance admin

说明:此条命令执行不返回信息
创建glance服务实体:
[root@controller ~]# openstack service create –name glance \

  • -description “OpenStack Image” image

$ openstack service create --name glance \
>    --description "OpenStack Image" image
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | OpenStack Image                  |
| enabled     | True                             |
| id          | b9fb6532f7154c7b9a6a2187e0c3ae30 |
| name        | glance                           |
| type        | image                            |
+-------------+----------------------------------+

4.创建镜像服务API端点
openstackendpointcreate–regionRegionOne imagepublichttp://controller:9292openstackendpointcreateregionRegionOne imagepublichttp://controller:9292 openstack endpoint create –region RegionOne \ image internal http://controller:9292
$ openstack endpoint create –region RegionOne \ image admin http://controller:9292

$ openstack endpoint create --region RegionOne  image public http://controller:9292
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | ad4e712b496c4a8c980a857b91e9b043 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | b9fb6532f7154c7b9a6a2187e0c3ae30 |
| service_name | glance                           |
| service_type | image                            |
| url          | http://controller:9292           |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne  image internal http://controller:9292
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | d87587e50c8e4761970cb2f50fa7c10d |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | b9fb6532f7154c7b9a6a2187e0c3ae30 |
| service_name | glance                           |
| service_type | image                            |
| url          | http://controller:9292           |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne  image admin http://controller:9292
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 05b57a9b1fc24e299e0d47dc2a0b4676 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | b9fb6532f7154c7b9a6a2187e0c3ae30 |
| service_name | glance                           |
| service_type | image                            |
| url          | http://controller:9292           |
+--------------+----------------------------------+

3.2.2安装和配置组件

1.安装软件包:

# yum install openstack-glance

2.编辑/etc/glance/glance-api.conf文件,完成以下操作

# vim /etc/glance/glance-api.conf

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

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

在[keystone_authtoken] and [paste_deploy]部分,配置认证服务访问:

[keystone_authtoken]

www_authenticate_uri = http://controller:5000 # 4963
auth_url = http://controller:5000 #4979
memcached_servers = controller:11211 # 5025
auth_type = password #5105
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = 123456

[paste_deploy]

flavor = keystone #5863

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

[glance_store]

stores = file,http #3184
default_store = file #3237
filesystem_store_datadir = /var/lib/glance/images/ #3611

配置对oslo_limit的访问权限:[ ]

[oslo_limit]
auth_url = http://controller:5000 #5177
auth_type = password 
user_domain_id = default #5222
username = MY_SERVICE #5219
system_scope = all #5181
password = MY_PASSWORD #5228
endpoint_id = ENDPOINT_ID #5152
region_name = RegionOne #5246

3.确保MY_SERVICE帐户具有读者访问权限 系统范围资源(如限制)

$ openstack role add --user glance --user-domain Default --system all reader

填充影像服务数据库:

# su -s /bin/sh -c "glance-manage db_sync" glance

4.完成安装,启动镜像服务并设为开机启动:

# systemctl enable openstack-glance-api.service
# systemctl restart openstack-glance-api.service

3.2.3验证镜像服务:

获取管理员权限

. admin-openrc

下载cirror进行作为测试使用。

wget http://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img

使用QCOW2磁盘格式、裸容器格式和公共可见性将映像上传到映像服务,以便所有项目都可以访问它:
注意,这里的cirror镜像不支持kvm,只支持qemu类型,如果使用kvm则无法创建cirror实例进行测试

$ glance image-create --name "cirros" \
  --file cirros-0.4.0-x86_64-disk.img \
  --disk-format qcow2 --container-format bare \
  --visibility=public
+------------------+----------------------------------------------------------------------------------+
| Property         | Value                                                                            |
+------------------+----------------------------------------------------------------------------------+
| checksum         | 443b7623e27ecf03dc9e01ee93f67afe                                                 |
| container_format | bare                                                                             |
| created_at       | 2022-12-07T07:14:18Z                                                             |
| disk_format      | qcow2                                                                            |
| id               | 5c226470-a529-498f-a4da-8d686514ac93                                             |
| min_disk         | 0                                                                                |
| min_ram          | 0                                                                                |
| name             | cirros                                                                           |
| os_hash_algo     | sha512                                                                           |
| os_hash_value    | 6513f21e44aa3da349f248188a44bc304a3653a04122d8fb4535423c8e1d14cd6a153f735bb0982e |
|                  | 2161b5b5186106570c17a9e58b64dd39390617cd5a350f78                                 |
| os_hidden        | False                                                                            |
| owner            | 4b7e0b39f4d948188fb28e1127b085e5                                                 |
| protected        | False                                                                            |
| size             | 12716032                                                                         |
| status           | active                                                                           |
| tags             | []                                                                               |
| updated_at       | 2022-12-07T07:14:18Z                                                             |
| virtual_size     | 46137344                                                                         |
| visibility       | public                                                                           |
+------------------+----------------------------------------------------------------------------------+

3.3安装compute服务

本节介绍如何在控制节点上安装和配置计算服务,代号为nova

3.3.1计算服务概述

使用OpenStack Compute来托管和管理云计算系统。OpenStack Compute是基础架构即服务(IaaS)系统的重要组成部分。主要模块是用Python实现的。
 OpenStack Compute与OpenStack Identity进行交互以进行身份验证; 用于磁盘和服务器映像的OpenStack映像服务; 和用于用户和管理界面的OpenStack Dashboard。镜像访问受到项目和用户的限制; 每个项目的限额是有限的(例如,实例的数量)。OpenStack Compute可以在标准硬件上水平扩展,并下载映像以启动实例。
OpenStack Compute包含以下内容及组件:
nova-api service
接受并响应最终用户计算API调用。该服务支持OpenStack Compute API。它执行一些策略并启动大多数编排活动,例如运行实例。
nova-api-metadata service
接受来自实例的元数据请求。nova-api-metadata通常在nova-network 安装多主机模式下运行时使用该服务。有关详细信息,请参阅计算管理员指南中的元数据服务。
nova-compute service
通过管理程序API创建和终止虚拟机实例的工作守护程序。例如:

XenAPI for XenServer/XCP
libvirt for KVM or QEMU
VMwareAPI for VMware
处理相当复杂。基本上,守护进程接受来自队列的动作并执行一系列系统命令,例如启动KVM实例并更新其在数据库中的状态。
nova-placement-api service
跟踪每个提供者的库存和使用情况。有关详情,请参阅 Placement API。
nova-scheduler service
从队列中获取虚拟机实例请求,并确定它在哪个计算服务器主机上运行。
nova-conductor module
调解nova-compute服务和数据库之间的交互。它消除了由nova-compute服务直接访问云数据库的情况 。该nova-conductor模块水平缩放。但是,请勿将其部署到nova-compute运行服务的节点上。有关更多信息,请参阅配置选项中的conductor部分 。
nova-consoleauth daemon(守护进程)
为控制台代理提供的用户授权令牌。见 nova-novncproxy和nova-xvpvncproxy。此服务必须运行以使控制台代理正常工作。您可以在群集配置中针对单个nova-consoleauth服务运行任一类型的代理。有关信息,请参阅关于nova-consoleauth。
nova-novncproxy daemon
提供通过VNC连接访问正在运行的实例的代理。支持基于浏览器的novnc客户端。
nova-spicehtml5proxy daemon
提供通过SPICE连接访问正在运行的实例的代理。支持基于浏览器的HTML5客户端。
nova-xvpvncproxy daemon
提供通过VNC连接访问正在运行的实例的代理。支持OpenStack特定的Java客户端。
The queue队列
守护进程之间传递消息的中心集线器。通常用RabbitMQ实现 ,也可以用另一个AMQP消息队列实现,例如ZeroMQ。
SQL database
存储云基础架构的大部分构建时间和运行时状态,其中包括:

Available instance types 可用的实例类型
Instances in use 正在使用的实例
Available networks 可用的网络
Projects 项目
理论上,OpenStack Compute可以支持SQLAlchemy支持的任何数据库。通用数据库是用于测试和开发工作的SQLite3,MySQL,MariaDB和PostgreSQL。

3.3.2安装placement服务

在controller节点执行
1.以root账户登录数据库

$ mysql -u root -p

2.创建数据库:placement

MariaDB [(none)]> CREATE DATABASE placement;

数据库登录授权

MariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' \
    ->   IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.002 sec)

MariaDB [(none)]> GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' \
    ->   IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.001 sec)

3.创建一个placement服务用户
登录账户

. admin-openrc

进行注册,密码默认123456

$ openstack user create --domain default --password-prompt placement
User Password:
Repeat User Password:
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | 263afbd803b34b169ecdfe2f07441f58 |
| name                | placement                        |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

4.添加placement用户为项目服务admin角色

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

5.在服务目录中创建Placement API条目:

$ openstack service create --name placement --description "Placement API" placement
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Placement API                    |
| enabled     | True                             |
| id          | 656007c5c64d4c3f91fd0dff1a32a754 |
| name        | placement                        |
| type        | placement                        |
+-------------+----------------------------------+

7.创建Placement API服务端点

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

+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 2b1b2637908b4137a9c2e0470487cbc0 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 2d1a27022e6e4185b86adac4444c495f |
| service_name | placement                        |
| service_type | placement                        |
| url          | http://controller:8778           |
+--------------+----------------------------------+

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

+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 02bcda9a150a4bd7993ff4879df971ab |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 2d1a27022e6e4185b86adac4444c495f |
| service_name | placement                        |
| service_type | placement                        |
| url          | http://controller:8778           |
+--------------+----------------------------------+

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

+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 3d71177b9e0f406f98cbff198d74b182 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 2d1a27022e6e4185b86adac4444c495f |
| service_name | placement                        |
| service_type | placement                        |
| url          | http://controller:8778           |
+--------------+----------------------------------+

8.安装和配置组件

# yum install openstack-placement-api

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

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

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

在api部分中,配置标识 服务访问:[api]、[keystone_authtoken]

[api]
# ...
auth_strategy = keystone #209

[keystone_authtoken]
# ...
auth_url = http://controller:5000/v3 #270
memcached_servers = controller:11211 #315
auth_type = password #396
project_domain_name = Default
user_domain_name = Default
project_name = service
username = placement
password = 123456

填充数据库:placement

# su -s /bin/sh -c "placement-manage db sync" placement

重启httpd服务

systemctl restart httpd
. admin-openrc

3.3.2.1 验证placement服务

在controller节点执行
获取凭据以获取对仅限管理员的 CLI 命令的访问权限:admin

. admin-openrc

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

[root@controller ~]#  placement-status upgrade check
+----------------------------------------------------------------------+
| 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                                                        |
+----------------------------------------------------------------------+

# 列出可用的资源类和特征:
$ openstack --os-placement-api-version 1.2 resource class list --sort-column name
+----------------------------+
| name                       |
+----------------------------+
| DISK_GB                    |
| IPV4_ADDRESS               |
| ...                        |

$ openstack --os-placement-api-version 1.6 trait list --sort-column name
+---------------------------------------+
| name                                  |
+---------------------------------------+
| COMPUTE_DEVICE_TAGGING                |
| COMPUTE_NET_ATTACH_INTERFACE          |
| ...                                   |

3.3.3 安装nova计算服务

在controller节点执行
1.以root账户登录数据库

$ mysql -u root -p

2.创建nova_api, nova, nova_cell0数据库

MariaDB [(none)]> CREATE DATABASE nova_api;
MariaDB [(none)]> CREATE DATABASE nova;
MariaDB [(none)]> CREATE DATABASE nova_cell0;

数据库登录授权

MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' \
  IDENTIFIED BY '123456';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' \
  IDENTIFIED BY '123456';

MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' \
  IDENTIFIED BY '123456';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' \
  IDENTIFIED BY '123456';

MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' \
  IDENTIFIED BY '123456';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' \
  IDENTIFIED BY '123456';

执行admin-openrc凭证

$ . admin-openrc

3.创建计算服务凭证

创建nova用户:

$ openstack user create --domain default --password-prompt nova
User Password:
Repeat User Password:
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | b4009760d31d4ba9a714e883fa37917e |
| name                | nova                             |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

为nova用户添加admin角色:

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

创建nova服务端点:

[root@controller ~]# openstack service create –name nova
--description “OpenStack Compute” compute

执行结果:

$ openstack service create --name nova \
  --description "OpenStack Compute" compute
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | OpenStack Compute                |
| enabled     | True                             |
| id          | 5f3b2da2fdc94e98a958323df92add16 |
| name        | nova                             |
| type        | compute                          |
+-------------+----------------------------------+

4.创建compute API 服务端点:

$ openstack endpoint create --region RegionOne \
  compute public http://controller:8774/v2.1
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 2287e8a0ac4b486d907b00e5029f647a |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 5f3b2da2fdc94e98a958323df92add16 |
| service_name | nova                             |
| service_type | compute                          |
| url          | http://controller:8774/v2.1      |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne \
  compute internal http://controller:8774/v2.1
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | b95594307cd344a69a294fcdbbe739e1 |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 5f3b2da2fdc94e98a958323df92add16 |
| service_name | nova                             |
| service_type | compute                          |
| url          | http://controller:8774/v2.1      |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne \
  compute admin http://controller:8774/v2.1
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 6db87e127cf94e62922cf3ce26b02987 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 5f3b2da2fdc94e98a958323df92add16 |
| service_name | nova                             |
| service_type | compute                          |
| url          | http://controller:8774/v2.1      |
+--------------+----------------------------------+

5.创建一个placement服务用户

$ openstack user create --domain default --password-prompt placement
User Password:
Repeat User Password:
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | 263afbd803b34b169ecdfe2f07441f58 |
| name                | placement                        |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

6.添加placement用户为项目服务admin角色

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

7.在服务目录中创建Placement API条目:

$ openstack service create --name placement --description "Placement API" placement
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | Placement API                    |
| enabled     | True                             |
| id          | 656007c5c64d4c3f91fd0dff1a32a754 |
| name        | placement                        |
| type        | placement                        |
+-------------+----------------------------------+

8.创建Placement API服务端点

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

+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 27eef77c80cc438fa16d8b60778744cd |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 4c84ff41a447470cabb1579c0509b986 |
| service_name | placement                        |
| service_type | placemen                         |
| url          | http://controller:8778           |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne placement internal http://controller:8778
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | ea46bf37bdac45b792bdb560ce5ef7b0 |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 4c84ff41a447470cabb1579c0509b986 |
| service_name | placement                        |
| service_type | placemen                         |
| url          | http://controller:8778           |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne placement admin http://controller:8778
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 3be6b68cbb1a4d81ba55e27062b2872c |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | 4c84ff41a447470cabb1579c0509b986 |
| service_name | placement                        |
| service_type | placemen                         |
| url          | http://controller:8778           |
+--------------+----------------------------------+

3.3.3.1 安装和配置组件

在controller节点执行
1.安装软件包

# yum install openstack-nova-api openstack-nova-conductor \
  openstack-nova-novncproxy openstack-nova-scheduler

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

# vim /etc/nova/nova.conf

在 [DEFAULT] 部分, 只启用计算和元数据API:

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

在该部分中,设置 :[DEFAULT]compute_driver

[DEFAULT]
# ...
compute_driver = libvirt.LibvirtDriver #51

在[api_database] 和 [database] 部分, 配置数据库访问:

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

[database]
# ...
connection = mysql+pymysql://nova:123456@controller/nova #1860

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

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

在[api] 和 [keystone_authtoken] 部分, 配置认证服务访问:

[api]
# ...
auth_strategy = keystone #906

[keystone_authtoken]
# ...
www_authenticate_uri = http://controller:5000/ #2853
auth_url = http://controller:5000/ #2868
memcached_servers = controller:11211 #2914
auth_type = password #2994
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = 123456

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

[DEFAULT]
# ...
my_ip = 10.0.1.11 #506

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

[vnc]
enabled = True #5515
# ...
server_listen = $my_ip #5521
server_proxyclient_address = $my_ip #5526

在[glance] 部分, 配置Image服务API的位置:

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

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

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

在 [placement] 部分, 配置 Placement API:

[placement]
# ...
region_name = RegionOne #4606
project_domain_name = Default #4559
project_name = service #4553
auth_type = password # 4532
user_domain_name = Default #4585
auth_url = http://controller:5000/v3 #4538
username = placement #4579
password = 123456 #4588

3.同步nova-api数据库

[root@controller ~]# su -s /bin/sh -c "nova-manage api_db sync" nova

忽略此输出中的任何弃用消息。

4.注册cell0数据库

[root@controller ~]# su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova

5.创建cell1 cell

[root@controller ~]# su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova

6.同步nova数据库

[root@controller ~]# su -s /bin/sh -c "nova-manage db sync" nova

7.验证 nova、 cell0、 cell1数据库是否注册正确

[root@controller ~]# su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova
+-------+--------------------------------------+------------------------------------------+-------------------------------------------------+----------+
|  Name |                 UUID                 |              Transport URL               |               Database Connection               | Disabled |
+-------+--------------------------------------+------------------------------------------+-------------------------------------------------+----------+
| cell0 | 00000000-0000-0000-0000-000000000000 |                  none:/                  | mysql+pymysql://nova:****@controller/nova_cell0 |  False   |
| cell1 | c98b2f3f-0b45-4d3c-83dd-376aefd78e24 | rabbit://openstack:****@controller:5672/ |    mysql+pymysql://nova:****@controller/nova    |  False   |
+-------+--------------------------------------+------------------------------------------+-------------------------------------------------+----------+

3.3.2.2 完成安装启动服务

在controller节点执行
由于软件包的一个bug,需要在/etc/httpd/conf.d/00-placement-api.conf 文件中添加如下配置,来启用对Placement API的访问(如遇到可以进行修复,未遇到请无视):

<Directory /usr/bin>
   <IfVersion >= 2.4>
      Require all granted
   </IfVersion>
   <IfVersion < 2.4>
      Order allow,deny
      Allow from all
   </IfVersion>
</Directory>

添加配置:

[root@controller ~]# vim /etc/httpd/conf.d/00-nova-placement-api.conf
Listen 8778

<VirtualHost *:8778>
  WSGIProcessGroup nova-placement-api
  WSGIApplicationGroup %{GLOBAL}
  WSGIPassAuthorization On
  WSGIDaemonProcess nova-placement-api processes=3 threads=1 user=nova group=nova
  WSGIScriptAlias / /usr/bin/nova-placement-api
  <IfVersion >= 2.4>
    ErrorLogFormat "%M"
  </IfVersion>
  ErrorLog /var/log/nova/nova-placement-api.log #这里放在此行之后
  ############################################################### 分割线,无需增加该行
  <!--加在这里-->
  <Directory /usr/bin>
   <IfVersion >= 2.4>
      Require all granted
   </IfVersion>
   <IfVersion < 2.4>
      Order allow,deny
      Allow from all
   </IfVersion>
  </Directory>
  #SSLEngine On
  #SSLCertificateFile ...
  #SSLCertificateKeyFile ...
</VirtualHost>
Alias /nova-placement-api /usr/bin/nova-placement-api
<Location /nova-placement-api>
  SetHandler wsgi-script
  Options +ExecCGI
  WSGIProcessGroup nova-placement-api
  WSGIApplicationGroup %{GLOBAL}
  WSGIPassAuthorization On
</Location>

重新启动httpd服务

# systemctl restart httpd

启动计算服务并配置为开机启动

# 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

3.3.4 安装和配置计算节点

以下操作在计算(compute)节点执行

3.3.4.1安装和配置组件

1.安装软件包

# yum install openstack-nova-compute

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

# vim /etc/nova/nova.conf

在[DEFAULT] 部分, 只启用计算和元数据API:

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

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

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

在[api] 和 [keystone_authtoken] 部分, 配置认证服务访问:

[api]
# ...
auth_strategy = keystone #906

[keystone_authtoken]
# ...
www_authenticate_uri = http://controller:5000/ #2853
auth_url = http://controller:5000/ #2868
memcached_servers = controller:11211 #2914
auth_type = password #2994
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = 123456

在[DEFAULT] 部分, 配置 my_ip选项:

[DEFAULT]
# ...
my_ip = 10.0.1.12 #506

这里使用计算节点管理IP地址

在 [DEFAULT] 部分, 启用对网络服务的支持:(这个配置没找到)

[DEFAULT]
# ...
use_neutron = True #1766
firewall_driver = nova.virt.firewall.NoopFirewallDriver #2428

在 [vnc] 部分, 启用和配置远程控制台访问:

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

服务器组件侦听所有IP地址,并且代理组件只侦听计算节点的管理接口IP地址。 基本URL指示您可以使用Web浏览器访问此计算节点上实例的远程控制台的位置。
如果用于访问远程控制台的Web浏览器驻留在无法解析控制器主机名的主机上,则必须用控制节点的管理接口IP地址替换控制器。

在 [glance] 部分, 配置Image服务API的位置:

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

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

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

在 [placement] 部分, 配置 Placement API:

[placement]
# ...
region_name = RegionOne #4606
project_domain_name = Default #4559
project_name = service #4553
auth_type = password # 4532
user_domain_name = Default #4585
auth_url = http://controller:5000/v3 #4538
username = placement #4579
password = 123456 #4588

3.3.3.2完成安装¶

确定计算节点是否支持硬件加速 虚拟机:

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

如果此命令返回计算节点的值 大于等于1则支持硬件加速,通常不需要额外的 配置(如有问题把下面的qemu改为kvm)

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

将文件中的部分编辑为 遵循:[libvirt]/etc/nova/nova.conf

[libvirt]
# ...
virt_type = qemu #3041

启动计算服务(包括其依赖项)并将其配置为 系统引导时自动启动:

# systemctl enable libvirtd.service openstack-nova-compute.service
# systemctl start libvirtd.service openstack-nova-compute.service

3.3.3.3添加compute节点到cell数据库

以下在控制节点上执行

1.执行admin-openrc,验证有几个计算节点在数据库中

[root@controller ~]# . admin-openrc
[root@controller ~]# openstack compute service list --service nova-compute
+----+--------------+---------+------+---------+-------+----------------------------+
| ID | Binary       | Host    | Zone | Status  | State | Updated At                 |
+----+--------------+---------+------+---------+-------+----------------------------+
|  8 | nova-compute | compute | nova | enabled | up    | 2022-10-20T12:52:44.000000 |
+----+--------------+---------+------+---------+-------+----------------------------+

2.发现计算节点

[root@controller ~]# su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova

添加新计算节点时,必须在控制节点上运行nova-manage cell_v2 discover_hosts以注册这些新计算节点。 或者,您可以在/etc/nova/nova.conf中设置适当的时间间隔:

[scheduler]
discover_hosts_in_cells_interval = 300 #4897

在安装过程中,如果提示了oslo_policy文件建议转换为yaml格式,这里需要进行转换(无该问题可以无视)

[root@compute ~]# nova-manage cell_v2 discover_hosts
2022-12-13 06:57:54.005 57632 WARNING oslo_policy.policy [None req-d4c75a4c-2114-40bc-ba3d-66a76c07e8fb - - - - - -] JSON formatted policy_file support is deprecated since Victoria release. You need to use YAML format which will be default in future. You can use ``oslopolicy-convert-json-to-yaml`` tool to convert existing JSON-formatted policy file to YAML-formatted in backward compatible way: https://docs.openstack.org/oslo.policy/latest/cli/oslopolicy-convert-json-to-yaml.html.
2022-12-13 06:57:54.005 57632 WARNING oslo_policy.policy [None req-d4c75a4c-2114-40bc-ba3d-66a76c07e8fb - - - - - -] JSON formatted policy_file support is deprecated since Victoria release. You need to use YAML format which will be default in future. You can use ``oslopolicy-convert-json-to-yaml`` tool to convert existing JSON-formatted policy file to YAML-formatted in backward compatible way: https://docs.openstack.org/oslo.policy/latest/cli/oslopolicy-convert-json-to-yaml.html.

更换路径到/etc/nova(keystone等控件下):(无该问题可以无视)
这里namespace指控件名,比如nova下的policy文件就要填nova,keystone下的policy文件要填keystone

oslopolicy-convert-json-to-yaml --namespace nova \
  --policy-file policy.json \
  --output-file policy.yaml

3.3.3.4验证计算服务操作

以下操作在控制节点执行
1.列出服务组件以验证每个进程成功启动和注册:

$ . admin-openrc
$ openstack compute service list
+--------------------------------------+----------------+------------+----------+---------+-------+----------------------------+
| ID                                   | Binary         | Host       | Zone     | Status  | State | Updated At                 |
+--------------------------------------+----------------+------------+----------+---------+-------+----------------------------+
| 0de90eff-0c38-46a1-8513-22889b8c3e92 | nova-conductor | controller | internal | enabled | up    | 2022-12-09T02:59:52.000000 |
| a496b3b4-8b56-483f-a7d0-e04015558a15 | nova-scheduler | controller | internal | enabled | up    | 2022-12-09T02:59:52.000000 |
| 845c5e2c-868f-4ce9-978a-dbf48292527f | nova-compute   | compute    | nova     | enabled | up    | 2022-12-09T02:59:50.000000 |
+--------------------------------------+----------------+------------+----------+---------+-------+----------------------------+

此输出应显示在控制节点上启用三个服务组件,并在计算节点上启用一个服务组件。
2.列出身份服务中的API端点以验证与身份服务的连接:

$ openstack catalog list
+-----------+-----------+-----------------------------------------+
| Name      | Type      | Endpoints                               |
+-----------+-----------+-----------------------------------------+
| placement | placement | RegionOne                               |
|           |           |   internal: http://controller:8778      |
|           |           | RegionOne                               |
|           |           |   public: http://controller:8778        |
|           |           | RegionOne                               |
|           |           |   admin: http://controller:8778         |
|           |           |                                         |
| glance    | image     | RegionOne                               |
|           |           |   admin: http://controller:9292         |
|           |           | RegionOne                               |
|           |           |   public: http://controller:9292        |
|           |           | RegionOne                               |
|           |           |   internal: http://controller:9292      |
|           |           |                                         |
| nova      | compute   | RegionOne                               |
|           |           |   public: http://controller:8774/v2.1   |
|           |           | RegionOne                               |
|           |           |   admin: http://controller:8774/v2.1    |
|           |           | RegionOne                               |
|           |           |   internal: http://controller:8774/v2.1 |
|           |           |                                         |
| keystone  | identity  | RegionOne                               |
|           |           |   admin: http://controller:5000/v3/     |
|           |           | RegionOne                               |
|           |           |   public: http://controller:5000/v3/    |
|           |           | RegionOne                               |
|           |           |   internal: http://controller:5000/v3/  |
|           |           |                                         |
+-----------+-----------+-----------------------------------------+

3.列出Image服务中的镜像以验证与Image服务的连通性:

+--------------------------------------+--------+--------+
| ID                                   | Name   | Status |
+--------------------------------------+--------+--------+
| 5c226470-a529-498f-a4da-8d686514ac93 | cirros | active |
+--------------------------------------+--------+--------+

4.检查cells和placement API是否正常运行

[root@controller ~]# nova-status upgrade check
+--------------------------------------------------------------------+
| Upgrade Check Results                                              |
+--------------------------------------------------------------------+
| Check: Cells v2                                                    |
| Result: Success                                                    |
| Details: None                                                      |
+--------------------------------------------------------------------+
| Check: Placement API                                               |
| Result: Success                                                    |
| Details: None                                                      |
+--------------------------------------------------------------------+
| Check: Cinder API                                                  |
| Result: Success                                                    |
| Details: None                                                      |
+--------------------------------------------------------------------+
| Check: Policy File JSON to YAML Migration                          |
| Result: Success                                                    |
| Details: None                                                      |
+--------------------------------------------------------------------+
| Check: Older than N-1 computes                                     |
| Result: Success                                                    |
| Details: None                                                      |
+--------------------------------------------------------------------+

3.4 安装neutron服务

以下操作在controller节点执行
在配置 OpenStack 网络 (neutron) 服务之前,需要必须创建数据库、服务凭据和 API

1.要创建数据库,请完成以下步骤:
使用数据库访问客户端连接到数据库 服务器作为用户:root

$ mysql -u root -p

创建数据库:neutron

MariaDB [(none)] CREATE DATABASE neutron;

授予对数据库的适当访问权限,并替换为合适的密码:neutron

MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' \
  IDENTIFIED BY '123456';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' \
  IDENTIFIED BY '123456';

退出数据库访问客户端。
2.加载管理员凭据以获得仅管理员访问的CLI命令,创建服务凭证,完成以下操作:

$ . admin-openrc
# 创建 neutron用户
$ openstack user create --domain default --password-prompt neutron
User Password:
Repeat User Password:
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | c105ac4c09a64762b12942a8c7a8a395 |
| name                | neutron                          |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

添加admin角色到neutron用户

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

创建neutron服务实体

执行结果:

$ openstack service create --name neutron \
  --description "OpenStack Networking" network
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | OpenStack Networking             |
| enabled     | True                             |
| id          | e00f52c5ef8b4548af29a8e39e79e1af |
| name        | neutron                          |
| type        | network                          |
+-------------+----------------------------------+

3.创建网络服务API端点
执行结果:

$ openstack endpoint create --region RegionOne \
  network public http://controller:9696
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 96d910e8a16240f2b153359bf083ce87 |
| interface    | public                           |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | e00f52c5ef8b4548af29a8e39e79e1af |
| service_name | neutron                          |
| service_type | network                          |
| url          | http://controller:9696           |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne \
  network internal http://controller:9696
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | c7747b125c274dec8835ae4dfa032e02 |
| interface    | internal                         |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | e00f52c5ef8b4548af29a8e39e79e1af |
| service_name | neutron                          |
| service_type | network                          |
| url          | http://controller:9696           |
+--------------+----------------------------------+
$ openstack endpoint create --region RegionOne \
  network admin http://controller:9696
+--------------+----------------------------------+
| Field        | Value                            |
+--------------+----------------------------------+
| enabled      | True                             |
| id           | 25e1cb5e1fcc486abc66ee7c7febf080 |
| interface    | admin                            |
| region       | RegionOne                        |
| region_id    | RegionOne                        |
| service_id   | e00f52c5ef8b4548af29a8e39e79e1af |
| service_name | neutron                          |
| service_type | network                          |
| url          | http://controller:9696           |
+--------------+----------------------------------+

3.4.1 配置网络部分

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

选项2增加了选项1,其中支持将实例附加到自助服务网络的第3层服务。
演示或其他非特权用户可以管理自助服务网络,包括提供自助服务和提供商网络之间连接的路由器。此外,浮动IP地址可提供与使用来自外部网络(如Internet)的自助服务网络的实例的连接。 自助服务网络通常使用隧道网络。隧道网络协议(如VXLAN),选项2还支持将实例附加到提供商网络。

 Networking Option 1: Provider networks
 Networking Option 2: Self-service networks
这里选择Networking Option 2: Self-service networks

以下操作在controller节点执行

1.安装组件

# yum install openstack-neutron openstack-neutron-ml2 \
  openstack-neutron-linuxbridge ebtables

2.配置服务组件
编辑/etc/neutron/neutron.conf配置文件,并完成以下操作:

# vim /etc/neutron/neutron.conf

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

[database]

connection = mysql+pymysql://neutron:123456@controller/neutron #496

在[DEFAULT]部分, 启用模块化第2层(ML2)插件,路由器服务和overlapping IP addresses:(找不到这些配置,直接加到最上面的6,7位置)

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

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

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

在 [DEFAULT]和 [keystone_authtoken]部分, 配置认证服务访问:

[DEFAULT]
# ...
auth_strategy = keystone #9

[keystone_authtoken]
# ...
www_authenticate_uri = http://controller:5000 #622
auth_url = http://controller:5000 #637
memcached_servers = controller:11211 #683
auth_type = password #763
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 123456

在 [DEFAULT] 和[nova] 部分, 配置网络通知计算网络拓扑更改:(找不到,放到9,10,nova也找不到,为280新加)

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

[nova]
auth_url = http://controller:5000 #1385
auth_type = password
project_domain_name = default
user_domain_name = default 
region_name = RegionOne
project_name = service
username = nova
password = 123456

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

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

3.配置网络二层插件
ML2插件使用Linux桥接机制为实例构建第2层(桥接和交换)虚拟网络基础结构。

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

# vim /etc/neutron/plugins/ml2/ml2_conf.ini

在 [ml2]部分,启用 flat, VLAN, and VXLAN 网络:

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

在 [ml2]部分, 自助服务网络:

[ml2]
tenant_network_types = vxlan # 153

在 [ml2]部分, 启用Linux网桥和第2层集群机制:

[ml2]
mechanism_drivers = linuxbridge,l2population #154

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

[ml2]
extension_drivers = port_security #155

在 [ml2_type_flat] 部分, 将提供者虚拟网络配置为扁平网络:

[ml2_type_flat]
flat_networks = provider #156

在部分中,配置 VXLAN 网络标识符 自助服务网络的范围:[ml2_type_vxlan]

[ml2_type_vxlan]
vni_ranges = 1:1000

在 [securitygroup] 部分, 启用ipset以提高安全组规则的效率:

[securitygroup]
enable_ipset = true #157

3.4.2.配置linux网桥代理

Linux桥接代理为实例构建层-2(桥接和交换)虚拟网络基础结构,并处理安全组

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

# vim /etc/neutron/plugins/ml2/linuxbridge_agent.ini

在 [linux_bridge]部分, 将提供者虚拟网络映射到提供者物理网络接口

[linux_bridge]
physical_interface_mappings = provider:ens34 #154 

注意:这里的ens34物理网卡是外部网络的网卡(underlying provider physical network interface)。
在[vxlan]部分中,启用vxlan隧道网络,配置处理隧道网络的物理网络接口的IP地址,并启用

[vxlan]
enable_vxlan = true #158
local_ip = 10.0.1.11 #160
l2_population = true #162

在 [securitygroup]部分, 启用安全组并配置Linux网桥iptables防火墙驱动程序:

[securitygroup]
# ...
enable_security_group = true #165
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver #167

这里我command not found,故没有进行这个内核验证
通过验证下列所有SysTL值设置为1以确保Linux操作系统内核支持网桥过滤器:

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

如需要手动更改,请进行下列更改

$ vim /usr/lib/sysctl.d/00-system.conf 
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
$ sysctl -p #重启网络服务

5.配置三层代理

Layer-3(L3)代理为自助虚拟网络提供路由和NAT服务。

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

# vim /etc/neutron/l3_agent.ini

在 [DEFAULT]部分, 配置Linux网桥接口驱动程序和外部网络桥接器:(该配置文件不存在下属元素,手动增加上的)

[DEFAULT]
# ...
interface_driver = linuxbridge #152

7.配置DHCP代理
DHCP代理为虚拟网络提供DHCP服务。
编辑/etc/neutron/dhcp_agent.ini文件并完成以下操作:

# vim /etc/neutron/dhcp_agent.ini

在[DEFAULT]部分,配置Linux网桥接口驱动程序,Dnsmasq DHCP驱动程序,并启用隔离的元数据,以便提供商网络上的实例可以通过网络访问元数据:(该配置文件不存在下属元素,手动增加上的)

[DEFAULT]
# ...
interface_driver = linuxbridge #152
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq #154
enable_isolated_metadata = true #156

3.4.2.1 配置metadata

元数据代理为实例提供配置信息,例如凭据。
编辑 /etc/neutron/metadata_agent.ini文件并完成以下操作:(该配置文件不存在下属元素,手动增加上的)

# vim /etc/neutron/metadata_agent.ini
[DEFAULT]

nova_metadata_host = controller #327
metadata_proxy_shared_secret = 123456 #329

3.4.2.2 配置计算服务使用网络服务

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

# vim /etc/nova/nova.conf

在[neutron]部分,配置访问参数,启用元数据代理并配置秘密:

[neutron]
auth_type = password #3734
project_domain_name = default #3761
user_domain_name = default #3787
region_name = RegionOne #3808
project_name = service #3755
username = neutron #3781
password = 123456 #3790
service_metadata_proxy = true #3701
metadata_proxy_shared_secret = 123456 #3708

3.4.2.3 完成安装启动服务

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

# ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini

2.同步数据库

# 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

3.重启compute API服务

# systemctl restart openstack-nova-api.service

4.启动网络服务并设为开机启动

# systemctl enable neutron-server.service \
  neutron-linuxbridge-agent.service neutron-dhcp-agent.service \
  neutron-metadata-agent.service
# systemctl start neutron-server.service \
  neutron-linuxbridge-agent.service neutron-dhcp-agent.service \
  neutron-metadata-agent.service

5.对于联网选项2,还启用并启动第三层服务:

# systemctl enable neutron-l3-agent.service && systemctl start neutron-l3-agent.service

如果服务启动不起来,请查看log日志是否为
组件报错内容:Feature 'linuxbridge' is experimental and has to be explicitly enabled in 'cfg.CONF.experimental'
个人遇到这个问题,如果是的话,更改 /etc/neutron/neutron.conf
在 [experimental]里添加linuxbridge = true

[experimental]
linuxbridge = true

3.4.3 安装和配置计算节点的linux网桥

以下操作在计算节点完成

# yum install openstack-neutron-linuxbridge ebtables ipset

2.配置公共组件
网络通用组件配置包括身份验证机制,消息队列和插件。
编辑/etc/neutron/neutron.conf文件并完成以下操作:
在[database]部分,注释掉任何connection选项,因为计算节点不直接访问数据库。

# vim /etc/neutron/neutron.conf

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

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

在[DEFAULT]和[keystone_authtoken]部分中,配置身份服务访问:

[DEFAULT] 
#... 
auth_strategy = keystone #7

[keystone_authtoken] 
#... 
www_authenticate_uri = http://controller:5000 #619
auth_url = http://controller:5000 #634
memcached_servers = controller:11211 #680
auth_type = password #758
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 123456

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

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

3.4.3.1 配置网络部分

选择您为控制器节点选择的相同网络选项以配置特定的服务。 之后,返回此处并继续配置计算服务以使用网络服务。
 网络选项1:提供商网络
 网络选项2:自助服务网络

这里选择网络选项2:自助服务网络

1.配置Linux网桥
编辑/etc/neutron/plugins/ml2/linuxbridge_agent.ini文件并完成以下操作:

# vim /etc/neutron/plugins/ml2/linuxbridge_agent.ini

在该部分中,将提供程序虚拟网络映射到 提供程序物理网络接口:[linux_bridge]

[linux_bridge]
physical_interface_mappings = provider:ens34(对应网卡) #154

在[vxlan]部分中,启用VXLAN隧道网络,配置处理隧道网络的物理网络接口的IP地址,并启用第2层群体:

[vxlan]
enable_vxlan = true #157
local_ip = 10.0.1.12 #158
l2_population = true #159

注意:这里的10.0.1.12为计算节点隧道网络的IP地址(underlying physical network interface that handles overlay networks)
在[securitygroup]节中,启用安全组并配置Linux网桥iptables防火墙驱动程序:

[securitygroup]
# ...
enable_security_group = true #162
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver #163

2.配置计算服务使用网络服务
编辑/etc/nova/nova.conf

vim /etc/nova/nova.conf
[neutron]

auth_url = http://controller:5000 #3734
auth_type = password #3740
project_domain_name = Default #3761
user_domain_name = Default #3787
region_name = RegionOne #3808
project_name = service #3755
username = neutron #3781
password = 123456 #3790

确保您的Linux操作系统内核支持网桥过滤器,方法是验证以下所有sysctl值均设置为1:

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

如果不为1的解决方法

$ vim /usr/lib/sysctl.d/00-system.conf 
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
$ sysctl -p

3.4.3.2 完成安装启动服务

1.重启compute服务

# systemctl restart openstack-nova-compute.service

2.设置网桥服务开机启动

# systemctl enable neutron-linuxbridge-agent.service && systemctl start neutron-linuxbridge-agent.service

3.4.3.3 验证安装

进行 network 列举

openstack network agent list

+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| ID                                   | Agent Type         | Host       | Availability Zone | Alive | State | Binary                    |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| f49a4b81-afd6-4b3d-b923-66c8f0517099 | Metadata agent     | controller | None              | True  | UP    | neutron-metadata-agent    |
| 27eee952-a748-467b-bf71-941e89846a92 | Linux bridge agent | controller | None              | True  | UP    | neutron-linuxbridge-agent |
| 08905043-5010-4b87-bba5-aedb1956e27a | Linux bridge agent | compute1   | None              | True  | UP    | neutron-linuxbridge-agent |
| 830344ff-dc36-4956-84f4-067af667a0dc | L3 agent           | controller | nova              | True  | UP    | neutron-l3-agent          |
| dd3644c9-1a3a-435a-9282-eb306b4b0391 | DHCP agent         | controller | nova              | True  | UP    | neutron-dhcp-agent        |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+

理论结果应类似于如下服务,如果有缺失需要检查系统日志。通过tail /var/log/neutron.log, tail /var/log/l3-agent.log 发现如下报错

2022-12-14 13:21:18.574 93025 ERROR neutron   File "/usr/lib/python3.9/site-packages/neutron/agent/linux/ip_lib.py", line 349, in exists
2022-12-14 13:21:18.574 93025 ERROR neutron     return privileged.interface_exists(self.name, self.namespace)
2022-12-14 13:21:18.574 93025 ERROR neutron   File "/usr/lib/python3.9/site-packages/oslo_privsep/priv_context.py", line 269, in _wrap
2022-12-14 13:21:18.574 93025 ERROR neutron     self.start()
2022-12-14 13:21:18.574 93025 ERROR neutron   File "/usr/lib/python3.9/site-packages/oslo_privsep/priv_context.py", line 283, in start
2022-12-14 13:21:18.574 93025 ERROR neutron     channel = daemon.RootwrapClientChannel(context=self)
2022-12-14 13:21:18.574 93025 ERROR neutron   File "/usr/lib/python3.9/site-packages/oslo_privsep/daemon.py", line 358, in __init__
2022-12-14 13:21:18.574 93025 ERROR neutron     raise FailedToDropPrivileges(msg)
2022-12-14 13:21:18.574 93025 ERROR neutron oslo_privsep.daemon.FailedToDropPrivileges: privsep helper command exited non-zero (1)

通过判断可以断定为权限问题,那么我们就需要给予相对应的权限
解决方案:
首先需要关闭selinux,有可能是selinux对privsep-helper的程序进行了访问控制。修改/etc/selinux/config文件:
将SELINUX=enforcing改为SELINUX=disabled
之后重启系统: reboot
查看问题是否解决

如果仍未解决,可能是neutron privsep需要使用sudo权限,但安装后默认环境没有配置,所以,要添加sudoer权限
修改vim /etc/neutron/neutron.conf文件,修改以下内容:

[privsep]
user = neutron
helper_command = sudo privsep-helper
修改 /etc/sudoers.d/neutron文件,添加以下内容后强制保存退出 (wq!)

neutron ALL = (root) NOPASSWD: ALL

3.5 安装Horizon服务

以下操作在控制节点执行

本节介绍如何在控制节点上安装和配置仪表板。
仪表板所需的唯一核心服务是身份服务。 您可以将仪表板与其他服务结合使用,例如镜像服务,计算和网络。 您还可以在具有独立服务(如对象存储)的环境中使用仪表板。

3.5.1 安装和配置组件

1.安装软件包

# yum install openstack-dashboard -y

2.编辑 /etc/openstack-dashboard/local_settings 文件并完成以下操作:

# vim /etc/openstack-dashboard/local_settings

配置仪表板以在controller节点上使用OpenStack服务 :

OPENSTACK_HOST = "controller" #118

允许您的主机访问仪表板:

ALLOWED_HOSTS = ['*']

或者ALLOWED_HOSTS = [‘one.example.com’, ‘two.example.com’]
ALLOWED_HOSTS也可以[‘*’]接受所有主机。这对开发工作可能有用,但可能不安全,不应用于生产。

配置memcache会话存储服务:

SESSION_ENGINE = 'django.contrib.sessions.backends.cache' #110

CACHES = {
    'default': {
         'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
         'LOCATION': 'controller:11211',#105
    }
}

注释掉任何其他会话存储配置。
开启身份认证API 版本v3

OPENSTACK_KEYSTONE_URL = "http://%s:5000/identity/v3" % OPENSTACK_HOST #124,原没有:5000

启用对域的支持:

OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True #125

配置API版本:

OPENSTACK_API_VERSIONS = {
    "identity": 3,
    "image": 2,
    "volume": 3,
}

配置Default为您通过仪表板创建的用户的默认域:

OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = "Default" #135 

将用户配置为通过仪表板创建的用户的默认角色:

OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user" #137 

配置时区(可选)

TIME_ZONE = "Asia/Shanghai" #468

4.如果未包括,则将以下行添加到/etc/httpd/conf.d/openstack-dashboard.conf。

# vim /etc/httpd/conf.d/openstack-dashboard.conf
WSGIApplicationGroup %{GLOBAL} #4

3.5.2 完成安装启动服务

1.完成安装,重启web服务和会话存储

# systemctl restart httpd.service memcached.service

3.5.3 登录web验证配置

在浏览器中输入http://10.0.1.11/dashboard(ubuntu为horizon),访问openstack的dashboard界面,

domain:default
用户名(管理员):admin(管理员),demo(租户)
密码:123456
Domain 为 Default

登录界面如下:

3.6 安装cinder服务

在安装和配置块存储服务之前,您需要 必须创建数据库、服务凭据和 API 终结点。

3.6.1 安装controller节点的cinder服务

3.6.1.1 创建数据库

要创建数据库,请完成以下步骤:

1.使用数据库访问客户端连接到数据库 服务器作为用户:root

$ mysql -u root -p

2.创建数据库:cinder

MariaDB [(none)]> CREATE DATABASE cinder;
授予对数据库的适当访问权限:cinder

MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' \
  IDENTIFIED BY '123456';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' \
  IDENTIFIED BY '123456';

3.退出数据库访问客户端。

3.6.1.2 创建角色

获取凭据以获取仅限管理员的访问权限 命令行命令:admin

$ . admin-openrc

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

创建用户:cinder

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

User Password:
Repeat User Password:
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | 9d7e33de3e1a498390353819bc7d245d |
| name                | cinder                           |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

将角色添加到用户:admincinder

$ openstack role add --project service --user cinder admin
  • 注意,此命令不提供输出。

创建服务实体:cinderv3

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

+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description | OpenStack Block Storage          |
| enabled     | True                             |
| id          | ab3bbbef780845a1a283490d281e7fda |
| name        | cinderv3                         |
| type        | volumev3                         |
+-------------+----------------------------------+
  • 从 Xena 版本开始,块存储服务 只需要一个服务实体。对于以前的版本,请 请参阅该特定版本的文档。

创建块存储服务 API 端点:

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

+--------------+------------------------------------------+
| Field        | Value                                    |
+--------------+------------------------------------------+
| enabled      | True                                     |
| id           | 03fa2c90153546c295bf30ca86b1344b         |
| interface    | public                                   |
| region       | RegionOne                                |
| region_id    | RegionOne                                |
| service_id   | ab3bbbef780845a1a283490d281e7fda         |
| service_name | cinderv3                                 |
| service_type | volumev3                                 |
| url          | http://controller:8776/v3/%(project_id)s |
+--------------+------------------------------------------+

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

+--------------+------------------------------------------+
| Field        | Value                                    |
+--------------+------------------------------------------+
| enabled      | True                                     |
| id           | 94f684395d1b41068c70e4ecb11364b2         |
| interface    | internal                                 |
| region       | RegionOne                                |
| region_id    | RegionOne                                |
| service_id   | ab3bbbef780845a1a283490d281e7fda         |
| service_name | cinderv3                                 |
| service_type | volumev3                                 |
| url          | http://controller:8776/v3/%(project_id)s |
+--------------+------------------------------------------+

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

+--------------+------------------------------------------+
| Field        | Value                                    |
+--------------+------------------------------------------+
| enabled      | True                                     |
| id           | 4511c28a0f9840c78bacb25f10f62c98         |
| interface    | admin                                    |
| region       | RegionOne                                |
| region_id    | RegionOne                                |
| service_id   | ab3bbbef780845a1a283490d281e7fda         |
| service_name | cinderv3                                 |
| service_type | volumev3                                 |
| url          | http://controller:8776/v3/%(project_id)s |
+--------------+------------------------------------------+

3.6.1.3 安装和配置组件¶

  1. 安装软件包:

# yum install openstack-cinder
  1. 编辑文件并完成 以下操作:/etc/cinder/cinder.conf

在本节中,配置数据库访问:[database]

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

[DEFAULT]
# ...
transport_url = rabbit://openstack:123456@controller
替换为您在 中为帐户选择的密码。RABBIT_PASSopenstackRabbitMQ

在 和 部分中, 配置身份服务访问:[DEFAULT][keystone_authtoken]

[DEFAULT]
# ...
auth_strategy = keystone

[keystone_authtoken]
# ...
www_authenticate_uri = http://controller:5000 #4739
auth_url = http://controller:5000 #4754
memcached_servers = controller:11211 #4799
auth_type = password #4880
project_domain_name = default
user_domain_name = default
project_name = service
username = cinder
password = CINDER_PASS

注意

注释掉或删除该部分中的任何其他选项。[keystone_authtoken]

在该部分中,将选项配置为 使用控制器节点的管理接口 IP 地址:[DEFAULT]my_ip

[DEFAULT]
# ...
my_ip = 10.0.1.11
在部分中,配置锁定路径:[oslo_concurrency]

[oslo_concurrency]
# ...
lock_path = /var/lib/cinder/tmp
填充块存储数据库:

# su -s /bin/sh -c "cinder-manage db sync" cinder

忽略此输出中的任何弃用消息。

3.6.1.4 将计算配置为使用块存储

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

[cinder]
os_region_name = RegionOne

3.6.1.5完成安装¶

重新启动计算 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

3.6.2 在cinder节点安装cinder服务

  1. 安装支持实用程序包:
    安装 LVM 软件包:

# yum install lvm2 device-mapper-persistent-data
  1. 启动 LVM 元数据服务并将其配置为在 系统引导:
    这里发现无法创建服务,经查询发现rhel-8已经禁止了lvm2的服务,故暂时搁置不启动服务 https://access.redhat.com/articles/3071171,

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

lvm2-lvmetad: With releases of that provide support for lvm2-lvmetad, clusters sharing access to LVM volumes must have disabled in the configuration and as a service to prevent problems resulting from inconsistent metadata caching throughout the cluster.lvm2lvm2-lvmetad

RHEL 8: The use of lvm2-lvmetad is deprecated and not supported and the attribute no longer exists in and the the systemd service no longer exists.use_lvmetad/etc/lvm/lvm.conflvm2-lvmetad

  1. 创建 LVM 物理卷:/dev/sdb

# pvcreate /dev/sdb

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

在该部分中,添加一个接受设备并拒绝所有其他设备的筛选器:devices/dev/sdb

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

筛选器数组中的每个项都以 for accept 或 for reject 开头,并包含一个正则表达式 设备名称。数组必须以 结尾才能拒绝任何 其余设备。您可以使用 vgs -vvvv 命令 以测试过滤器。arr/.*/

安装软件包:

# yum install openstack-cinder targetcli

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

在本节中,配置数据库访问:[database]

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

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

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

配置身份服务访问:[DEFAULT][keystone_authtoken]

[DEFAULT]
# ...
auth_strategy = keystone #399

[keystone_authtoken]
# ...
www_authenticate_uri = http://controller:5000 #4739
auth_url = http://controller:5000 #4754
memcached_servers = controller:11211 #4800
auth_type = password #4880
project_domain_name = default
user_domain_name = default
project_name = service
username = cinder
password = 123456
[DEFAULT]
# ...
my_ip = 10.0.1.13 #447

在本节中,使用 LVM 驱动程序、卷组、iSCSI 协议、 和适当的 iSCSI 服务。如果该部分不存在, 创建它:[lvm]cinder-volumes[lvm]

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

在本节中,启用 LVM 后端:[DEFAULT]

[DEFAULT]
# ...
enabled_backends = lvm #503
[DEFAULT]
# ...
glance_api_servers = http://controller:9292 #410

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

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

完成安装¶
启动块存储卷服务,包括其依赖项 并将它们配置为在系统引导时启动:

# systemctl enable openstack-cinder-volume.service target.service
# systemctl start openstack-cinder-volume.service target.service

4 前端开发范例

4.1 简单的文件替换

首先,对于图片文件的存储地址为,/usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img
前端页面分别存储在dashboard下的页面和部分存储在/usr/lib/python2.7/site-packages/horizon/templates 和 /usr/share/openstack-dashboard

这里我们简单来改一下icon和logo,首先,需要生成一个svg图片
然后将其上传到图片地址:

cd /usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img
# 选择文件上传
rz

然后我们进行页面的修改,举例,我们修改登录的logo

vim /usr/lib/python2.7/site-packages/horizon/templates/auth/_splash.html
# 修改为上传的图片名,我这里是user,所以为user

<div class="text-center">
  <img class="splash-logo" src={% themable_asset "img/user.svg" %}>
</div>

4.2 页面定制即基础理论介绍

这里仅作对于我版本的范例介绍,对于官方文档也给予了自定义的方法,会对应安装版本进行示例:
简单的修改:
https://docs.openstack.org/horizon/zed/configuration/customizing.html
主题修改:
https://docs.openstack.org/horizon/zed/configuration/themes.html
组件修改:
https://docs.openstack.org/horizon/zed/configuration/branding.html

一个标准的Dashboard页面。一个dashboard面板可以分为三层:

Dashboard—>PanelGroup—>Panel,即UI结构最上面为Header,左上边为logo,然后是Dashboard,包括项目,管理员,身份管理

每一个Dashboard都可以理解为是Django中的一个APP,Django中的APP可以理解成对业务逻辑模块化的一种手段,里面可以包含自己独有的URL设定、模板和业务逻辑代码。

每个Dashboard下面有若干个PanelGroup,比如项目下有计算和网络两个PanelGroup。

每个PanelGroup下有若干个Panel,比如计算下有概况,实例,卷,镜像,密钥对这几个Panel。点开Panel之后右侧部分显示的是Panel Body,Panel Body中显示的是Data Table View。

除了Data Table View之外还有一种是Tab View样式,如图系统信息所示:

这里的Dashboard即logo下的菜单

TabView.png

SystemInfo.png

Openstack Horizon 组件 部署上去后,源码分两部分:

1.一部分是Dashboard页面的源码,目录在/usr/share/openstack-dashboard

2.另一部分是Horizon模块的horizon界面库文件(dashboard界面通用组件的库),目录在/usr/lib/python2.7/site-packages/horizon

horizon采用django框架编写(django是一个强大的mvc 框架。具体参考djangobook中文版 http://djangobook.py3k.cn/2.0/。)

horizon中主要是一些在Django基础上编写的通用组件,包括表格(table),标签页(tab),表单(form),导航(browser),工作流(flow)。

这些代码和openstack的具体业务逻辑没有什么关系,如果要做一个新的Django项目,理论上也可以复用这些代码。

horizon/base.py中还实现了一套Dashboard/Panel机制,使得Horzion面板上所有的Dashboard都是“可插拔”的,所有的Panel都是“动态加载”的。

具体文件路径如下所示:

查看当前horizon文件夹

[root@controller horizon]# tree -d -L 1
.
├── browsers
├── conf
├── contrib
├── forms
├── hacking
├── locale
├── management
├── middleware
├── static
├── tables
├── tabs
├── templates
├── templatetags
├── test
├── utils
└── workflows

16 directories

查看当前dashboard文件夹

[root@controller openstack_dashboard]# tree -d -L 1
.
├── api
├── contrib
├── dashboards
├── django_pyscss_fix
├── enabled
├── local
├── locale
├── management
├── static
├── templates
├── templatetags
├── test
├── themes
├── usage
├── utils
└── wsgi

16 directories

浏览一遍该文件可以看到代码结构还是非常清晰的。

其中class Admin即是描述管理员Dashboard的类,它继承了horizon(/usr/lib/python2.7/site-packages/horizon)中的Dashboard基类(描述一级菜单的基类),class Admin中有几个属性,分别为name、slug、panels、default_panel、permissions,根据基类提供的信息可以知道它们分别代表的是名称、id、该Dashboard下的panels、默认panel、权限。

除此之外,还有一个class SystemPanels,可以看到它是继承horizon中的PanelGroup,根据openstack三级菜单结构可以知道它应该就是描述的二级菜单了,class SystemPanels有slug、name、panels三个属性,分别代表的是id、名称、属于它的panel。最后有一个horizon.register就是注册Dashboard了。

现在看来,如果要增加一个panel到Admin这个菜单下面,无非需要做两步:

1、一个描述panel的文件夹。

2、在这个class SystemPanels下的panels属性中增加一个panel的id。

4.3 定制示例

接下来就要看看代表panel的文件夹下有什么东西了。进入instances(实例)文件夹,目录结构如下:

[root@controller admin]# cd instances/
[root@controller instances]# ls
forms.py      __init__.pyo  tables.pyc  templates  urls.pyc
forms.pyc     panel.py      tables.pyo  tests.py   urls.pyo
forms.pyo     panel.pyc     tabs.py     tests.pyc  views.py
__init__.py   panel.pyo     tabs.pyc    tests.pyo  views.pyc
__init__.pyc  tables.py     tabs.pyo    urls.py    views.pyo
[root@controller instances]# tree 
.
├── forms.py
├── forms.pyc
├── forms.pyo
├── __init__.py
├── __init__.pyc
├── __init__.pyo
├── panel.py
├── panel.pyc
├── panel.pyo
├── tables.py
├── tables.pyc
├── tables.pyo
├── tabs.py
├── tabs.pyc
├── tabs.pyo
├── templates
│   └── instances
│       ├── _live_migrate.html
│       └── live_migrate.html
├── tests.py
├── tests.pyc
├── tests.pyo
├── urls.py
├── urls.pyc
├── urls.pyo
├── views.py
├── views.pyc
└── views.pyo

2 directories, 26 files

该文件夹下的东西就是描述Panel instances(实例)的相关文件了。看这文件结构应该就是一个django app了。分别看看各个文件:

forms.py是表单,描述的是弹出框之类的,现在主要目的是增加一个panel,暂且不看。

panel.py应该就是描述这个panel基本信息的文件了,这个必须看看

[root@controller instances]# vim panel.py
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2012 Nebula, Inc.
#
#    not use this file except in compliance with the License. You may obtai
n
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITH
OUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See t
he
#    License for the specific language governing permissions and limitation
s   
#    under the License.
    
from django.utils.translation import ugettext_lazy as _
                     
import horizon


class Instances(horizon.Panel):
    name = _("Instances")
    slug = 'instances'
    permissions = ('openstack.services.compute',)
    policy_rules = ((("compute", "context_is_admin"),
                     ("compute", "os_compute_api:servers:detail")),)

可以看到以上代码结构与dashboard.py是非常类似的。这里class Instances继承了horzion中的Panel这个基类,很明显这就是描述panel的基类了。这Instances现在有三个属性,分别是name(名称)、slug(id)、permissions(权限)。注意最后一行代码,这行代码是import的前面我所说到的dashboard.py。最后一行也就是说Admin的Dashboard类用register方法注册了该panel,层级关系非常清晰。

tables.py顾名思义是描述表格之类的,看看它的代码,(这里省略了部分代码)

from django.core import urlresolvers
from django.template.defaultfilters import title
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy
from keystoneclient import exceptions as keystone_exceptions

from horizon import tables
from horizon.utils import filters

from openstack_dashboard import api
from openstack_dashboard.dashboards.project.instances import audit_tables
from openstack_dashboard.dashboards.project.instances \
    import tables as project_tables
from openstack_dashboard import policy
from openstack_dashboard.views import get_url_with_pagination


class AdminEditInstance(project_tables.EditInstance):
    url = "horizon:admin:instances:update"


class AdminConsoleLink(project_tables.ConsoleLink):
    url = "horizon:admin:instances:detail"

因为该文件是描述表格的,在这省略了部分代码,只看关键描述表格的这部分。class AdminInstancesTable继承的是DataTable这个基类,看看代码的结构可以很容易看出tables.Column就是描述表格的每一列的,其中class Meta顾名思义是描述该表格的元数据的类。它有表格的名字、动作、表动作等属性。

templates是静态模板,先只看看template 下的 live_migrate.html

[root@controller instances]# vim live_migrate.html 
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "Live Migrate" %}{% endblock %}

{% block main %}
  {% include 'admin/instances/_live_migrate.html' %}
{% endblock %}

该模板继承了base.html,然后一个标题块block title、一个主要部分block main

tests.py为测试代码;

urls.py是决定了界面的url;

from django.conf.urls import patterns
from django.conf.urls import url

from openstack_dashboard.dashboards.admin.instances import views


INSTANCES = r'^(?P<instance_id>[^/]+)/%s$'


urlpatterns = patterns(
    'openstack_dashboard.dashboards.admin.instances.views',
    url(r'^$', views.AdminIndexView.as_view(), name='index'),
    url(INSTANCES % 'update', views.AdminUpdateView.as_view(), name='update'),
    url(INSTANCES % 'detail', views.DetailView.as_view(), name='detail'),
    url(INSTANCES % 'console', 'console', name='console'),
    url(INSTANCES % 'vnc', 'vnc', name='vnc'),
    url(INSTANCES % 'spice', 'spice', name='spice'),
    url(INSTANCES % 'rdp', 'rdp', name='rdp'),
    url(INSTANCES % 'live_migrate', views.LiveMigrateView.as_view(),
        name='live_migrate'),
)

该文件每个url对应了views的一个函数或者类,index是描述主页的,其它url是相关功能的url。

...
class AdminIndexView(tables.DataTableView):
    table_class = project_tables.AdminInstancesTable
    template_name = 'admin/instances/index.html'
    page_title = _("Instances")

    def has_more_data(self, table):
        return self._more

    def get_data(self):
        ...

views.py处理用户请求,从urls.py中反应过来,获取数据。

现在只是增加panel,只看看描述index页面的类。class AdminIndexView继承的是DataTableView这个类,这个类有table_class、template_name等几个属性,可以比较明显的看出它应该就是为那个表格类服务的了,主要功能就是获取数据,设置页面title、指定静态模板了。

那么现在就可以模仿以上这个结构自行增加一个panel了,构造一个类似的文件夹:

mypanel
|--__init__.py
|--panel.py
|--tables.py
|--templates
  |--mypanel
    |--index.html
|--urls.py
|--views.py

原生构建方法:

1、panel.py

import horizon

from openstack_dashboard.dashboards.admin import dashboard


class Mypanel(horizon.Panel):
    name = "mypanel"
    slug = 'mypanel'
    permissions = ('openstack.roles.admin', 'openstack.services.compute')


dashboard.Admin.register(Mypanel)

2、tables.py(非必要)

from horizon import tables

class MypanelTable(tables.DataTable):
    column1 = tables.Column("column1", verbose_name="column1")
    class Meta(object):
        name = "mypaneltable"
        verbose_name = "mypaneltable"

3、index.html

{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "ssssss" %}{% endblock %}

{% block main %}
{% endblock %}

4、urls.py

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from django.conf.urls import url

from openstack_dashboard.dashboards.admin.ssd import views


urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
]

5、views.py

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from horizon import views


class IndexView(views.APIView):
    # A very simple class-based view...
    template_name = 'admin/ssd/index.html'

    def get_data(self, request, context, *args, **kwargs):
        # Add data to the context here...
        return context

直接指令生成

上述操作也可进行指令生成操作,openstack dashboard默认增加了自动脚本

python manage.py startpanel ssd                 --dashboard=openstack_dashboard.dashboards.admin                 --target=openstack_dashboard/dashboards/admin/ssd

等同于手动方法,手动增加一个index.html

index.html

{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "ssssss" %}{% endblock %}

{% block main %}
{% endblock %}

除此之外,在admin中的dashboard.py加上这个panel的slug。
官方有两种方式,不过官方推荐第二种“可插拔”方式,那我们只看这种“可插拔”配置。

cd /usr/share/openstack-dashboard/openstack_dashboard/enabled
这个enabled目录就是可插拔的配置目录:
目录中的编号排序,即代表页面中,一个个panel的从上到下的排序,

如文件:_2020_admin_overview_panel.py和_2040_admin_hypervisors_panel.py,2020在2040的前面,所以界面上Admin这个PanelGroup中,Overview Panel 在 Hypervisors Panel 的上面。

个人建议用标号进行分割,这里是tree了所有,然后在最后增加标号

_3080_identity_mappings_panel.py
_3080_identity_mappings_panel.pyc
_3080_identity_mappings_panel.pyo
_50_admin_add_panel.py.example
_60_admin_remove_panel.py.example
_70_admin_default_panel.py.example
_80_admin_add_panel_group.py.example
_90_admin_add_panel_to_group.py.example

看到最后为3080.即增加3081配置文件

[root@controller enabled]# vim _3081_project_ssd_panel.py
PANEL='ssd'
PANEL_DASHBOARD='admin'
PANEL_GROUP='admin'
ADD_PANEL='openstack_dashboard.dashboards.admin.ssd.panel.Ssd'

然后重启httpd服务,查看页面
systemctl restart httpd.service

5 问题解决答疑

5.1 log 日志问题,即解决方法

由于openstack默认以root账户进行安装,没有权限,那么只能通过手动给权限的方式来进行日志修改操作。
举例,配置nova日志方式:
首先,配置服务配置的[DEFAULT] 添加 log_file ,例如配置nova /etc/nova/nova.conf

[DEFAULT]
log_dir = /var/log/nova/

如果无权限,那么需要增加权限,确保openstack有权限进行io操作。不然服务会报 ERROR: Permission denied: ‘/var/log/nova/nova.log’

chown -R nova:nova /var/log/nova/nova.log

5.2 nova-conductor问题

通过查看nova-conductor日志,我们可以看到

[root@controller nova]# tail nova-conductor.log 
its middleware, NoAuthMiddleware[V2_18], will be removed in a future release.
).  Its value may be silently ignored in the future.
2022-12-14 15:17:14.035 5839 INFO nova.service [-] Starting conductor node (version 26.0.0-1.el9s)
2022-12-14 15:17:14.038 5840 INFO nova.service [-] Starting conductor node (version 26.0.0-1.el9s)
2022-12-14 15:17:14.045 5830 WARNING oslo_config.cfg [None req-10060318-2e75-4dd0-a317-ee62254c1f28 - - - - - -] Deprecated: Option "api_servers" from group "glance" is deprecated for removal (
Support for image service configuration via standard keystoneauth1 Adapter
options was added in the 17.0.0 Queens release. The api_servers option was
retained temporarily to allow consumers time to cut over to a real load
balancing solution.
).  Its value may be silently ignored in the future.

通过判断,我们可以看到是 oslo_config.cfg报了 glance的api_servers配置过时,可以无视,根据日志所报应该是不影响使用。

5.3 dashboard问题

[root@controller httpd]# tail openstack_dashboard-error.log 
[Thu Dec 15 02:34:18.643087 2022] [wsgi:error] [pid 35220:tid 35504]   argspec = inspect.getargspec(function)
[Thu Dec 15 02:34:18.645898 2022] [wsgi:error] [pid 35220:tid 35504] /usr/lib64/python3.9/site-packages/scss/selector.py:26: FutureWarning: Possible nested set at position 329
[Thu Dec 15 02:34:18.645912 2022] [wsgi:error] [pid 35220:tid 35504]   SELECTOR_TOKENIZER = re.compile(r'''
[Thu Dec 15 02:34:18.801128 2022] [wsgi:error] [pid 35219:tid 35471] [remote 1.170.237.85:42760] WARNING django.request Not Found: /dashboard/static/dashboard/js/output.989d06bb6631.js
[Thu Dec 15 02:34:19.286847 2022] [wsgi:error] [pid 35220:tid 35504] [remote 1.170.237.85:19248] WARNING django.request Not Found: /dashboard/static/dashboard/css/output.361cca58bb99.css
[Thu Dec 15 02:34:19.784599 2022] [wsgi:error] [pid 35218:tid 35380] [remote 1.170.237.85:42756] WARNING django.request Not Found: /dashboard/static/dashboard/css/output.eb176ae6294a.css
[Thu Dec 15 02:34:20.174661 2022] [wsgi:error] [pid 35219:tid 35485] [remote 1.170.237.85:42762] WARNING django.request Not Found: /dashboard/static/horizon/lib/bootstrap_datepicker/locales/bootstrap-datepicker.zh-CN.js
[Thu Dec 15 02:34:20.324739 2022] [wsgi:error] [pid 35220:tid 35504] [remote 1.170.237.85:42768] WARNING django.request Not Found: /dashboard/static/dashboard/js/angular_template_cache_preloads.c5640a808718.js
[Thu Dec 15 02:34:20.325363 2022] [wsgi:error] [pid 35218:tid 35379] [remote 1.170.237.85:42770] WARNING django.request Not Found: /dashboard/static/dashboard/js/output.5e3096d425c4.js
[Thu Dec 15 02:34:20.399979 2022] [wsgi:error] [pid 35219:tid 35471] [remote 1.170.237.85:42762] WARNING django.request Not Found: /dashboard/static/dashboard/img/logo-splash.svg

重建dashboard配置,官网没有指明部署时配置过就不需要再配置

cd /usr/share/openstack-dashboard
python manage.py make_web_conf --apache > /etc/httpd/conf.d/openstack-dashboard.conf

登录到dashboard将出现权限错误和显示混乱,需要建立策略的软链接部署时配置过就不需要再配置

ln -s /etc/openstack-dashboard /usr/share/openstack-dashboard/openstack_dashboard/conf

在local_settings底下新增根目录指向
vim /etc/openstack-dashboard/local_settings

WEBROOT = '/dashboard/'

vim /etc/httpd/conf.d/openstack-dashboard.conf
将原有的配置注释掉,添加以下配置

#WSGIScriptAlias / /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py
#Alias /static /usr/share/openstack-dashboard/static
WSGIScriptAlias /dashboard /usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
Alias /dashboard/static /usr/share/openstack-dashboard/static

重启httpd及memcached

systemctl restart httpd.service
systemctl restart memcached.service

5.4 nova问题(创建instances文件即可)

对于nova-compute缺少instances文件夹

[root@compute nova]# tail nova-compute.log 
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager   File "/usr/lib/python3.9/site-packages/nova/compute/resource_tracker.py", line 885, in update_available_resource
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager     resources = self.driver.get_available_resource(nodename)
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager   File "/usr/lib/python3.9/site-packages/nova/virt/libvirt/driver.py", line 9446, in get_available_resource
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager     disk_info_dict = self._get_local_gb_info()
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager   File "/usr/lib/python3.9/site-packages/nova/virt/libvirt/driver.py", line 7812, in _get_local_gb_info
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager     info = libvirt_utils.get_fs_info(CONF.instances_path)
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager   File "/usr/lib/python3.9/site-packages/nova/virt/libvirt/utils.py", line 369, in get_fs_info
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager     hddinfo = os.statvfs(path)
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager FileNotFoundError: [Errno 2] No such file or directory: '/usr/lib/python3.9/site-packages/instances'
2022-12-16 08:10:44.691 712 ERROR nova.compute.manager 

后续会再创建镜像虚拟机的时候需要权限,通过5.1增加即可。

5.5 镜像问题

对于亚马逊AWS存在如下问题,cpu不支持默认的virtio格式,换成cirrus格式即可

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

6. 使用范例

对于openstack搭建好后,在使用上也存在一些方法。这里举例镜像,实例,网络的创建作为范例所示
官方的instance 文档:https://docs.openstack.org/install-guide/launch-instance.html
官方的image 地址:https://docs.openstack.org/image-guide/obtain-images.html
官方的一些镜像默认打包成了qcow2,且很小,对于磁盘有很大帮助,当然也可以自己手动制作其他格式,这里就不演示了。
对于QEMU和KVM,官方的建议是使用qcow2格式。官方默认镜像没有密码,推荐使用密钥登录。
对于cirror镜像,我们必须使用qemu才能进行测试,kvm默认是不支持的。

6.1 镜像创建

对于镜像创建,我们使用以下代码,替换中间的文件名和镜像名。
注意,disk-format和container的格式需要根据个人需求进行指定

glance image-create --name "IMAGE_NAME" \
  --file IMAGE_FILE_NAME \
  --disk-format DISK_FORMAT_TYPE --container-format CONTAINER_FORMAT_TYPE \
  --visibility=public

当然,也可指定镜像的最低配额限制,这里前端就能进行限制就不再代码进行演示了。

6.2 实例创建

对于实例创建,首先我们需要创建网段,这里我们使用安装流程的网络环境2作为网络环境。

首先,创建provider网段,使用管理员身份进行创建
provider-net.png

这里的配置provider对应如下flat_networks名称。

/etc/neutron/plugins/ml2/ml2_conf.ini
[ml2_type_flat]
flat_networks = provider

配置对应子网数据,我这里的net网段为192.168.111.0/24,请根据实际情况进行配置
provider-subnet.png
dhcp和dns对应实际情况进行配置。

创建好了provider网络,我们需要切换到一个普通用户来进行self-service的网络配置:
demo-net.png
这里我们举例网络为172.16.1.0/24

dhcp和dns对应实际情况进行配置。
demo-subnet.png

最后,为了使内部self-service网络可以连接到外部网络,我们需要使用一个路由进行网络的连接。
demo-router.png
选择外部网络为provider,这样接上的self网络即可通过路由访问外网。

打开网络拓扑图标(当然也可以直接增加接口),这里为了演示更直观所以使用
增加self网络连接到路由的接口
demo-router-addinterface.png

之后,我们就可以创建实例了。这里举例使用ubuntu 的mirror,需要外挂cinder节点硬盘的话就增加卷并指定大小,不需要的话使用compute内置硬盘也可以。
instance-create-image.png

选择实例类型,因为已经指定了cinder的外挂卷,所以使用 无compute磁盘配额即可
instance-create-instancetype.png

选择我们刚刚创建的self网络即可。
instance-create-network.png
剩余的安全组,密钥和网络接口等根据个人所需进行配置即可。

创建好实例后,如不能ssh,那么请开放安全组ssh端口。

进行连接后进行网络测试。
f

网络拓扑展示:
network-img.png