OpenStack 云平台管理实战:从 Keystone 认证到 Nova 计算调度

OpenStack管理

摘要 :本文是一篇 OpenStack 云平台管理的实战指南,系统讲解了其三大核心组件的原理与操作。内容涵盖:Keystone 认证管理 ,深入解析 Domain、User、Project、Role 等核心概念,并通过命令行演示多域登录、用户/组/项目创建、角色分配与配额修改;Glance 镜像管理 ,介绍镜像、实例与规格的区别,磁盘格式、状态机及上传镜像实验,并探讨 Swift 后端存储与命令行上传大文件;Nova 计算管理,剖析 nova-scheduler 的过滤与权重调度机制、nova-compute 的执行逻辑,并通过日志观察虚拟机创建的完整流程,最后演示实例的创建、暂停、挂起、废弃、锁定与重建等日常运维操作。全文以实验驱动,配有大量命令与截图,适合 OpenStack 运维与学习人员参考。

OpenStack认证管理-Keystone

Keystone基本概念

Domain 域,Keystone中一个虚拟概念,一个域是一组User ,Group或Project的容器
User 用户,是可以通过Keystone访问OpenStack服务的个人、系统或某个服务
Group 用户组,是一组User的容器,可以向Group中添加用户,并直接给Group分配角色
Project 项目,是各个服务中一些可以访问的资源集合,项目只需在某个域下唯一即可
Role 角色,具有一组定义的用户权限和特权以执行一组特定操作,角色不同,被赋予的权限不同
Service 服务,一种OpenStack服务,服务会对外暴露一个或多个端点,用户可以通过这些端点访问资源并执行操作
Endpoint 端点,是指一个可以用来访问某个具体服务的网络地址
Token 令牌,是允许访问特定资源的凭证
Credential 凭证,确认用户身份的数据,如用户的用户名和密码

•Domain:一个域可以对应一个大的机构、一个数据中心,并且必须全局唯一。云的终端用户可以在自己的Domain中创建多个Project、User、Group和Role。具备对多个Project进行统一管理的能力。

•User:Keystone会通过认证信息(Credential,如密码等)验证用户请求的合法性,通过验证的用户将会分配到一个特定的令牌,该令牌可以被当作后续资源访问的一个通行证,并非全局唯一,只需要在域内唯一即可。

•Group:用户组是一组User的容器,可以向Group中添加用户,并直接给Group分配角色,在这个Group中的所有用户就拥有了Group所拥有的角色权限。通过引入Group的概念,Keystone实现了对用户组的管理,达到了同时管理一组用户权限的目的。

•Project:项目是各个服务中的一些可以访问的资源集合。我们需要在创建虚拟机时指定某个项目,在Cinder创建卷时也需要指定具体的项目。用户总是被默认绑定到某些项目上,在用户访问项目的资源前,必须具有对该项目的访问权限,或者说在特定项目下被赋予了特定的角色。项目不必全局唯一,只需要在某个域下唯一即可。 在OpenStack的界面和文档中,Tenant/Project/Account这几个术语是通用的,但长期看会倾向使用Project(公有云叫租户)

•Role:一个用户所具有的角色,角色不同意味着被赋予的权限不同,只有知道用户被赋予的角色才能知道该用户是否有权限访问某资源。用户可以被赋予一个域或项目内的角色。一个用户被赋予域的角色意味着他对域内所有的项目都具有相同的角色,而特定项目的角色只具有对特定项目的访问权限。角色可以被继承,在一个项目树下,拥有父项目的访问权限也意味着同时拥有对子项目的访问权限。角色必须全局唯一。

查看domain:

bash 复制代码
[root@controller ~]# source keystonerc_admin

[root@controller ~(keystone_admin)]# openstack domain list
+----------------------------------+---------+---------+--------------------+
| ID                               | Name    | Enabled | Description        |
+----------------------------------+---------+---------+--------------------+
| 2c99588e109d427abb530cbb9aada74a | heat    | True    |                    |
| default                          | Default | True    | The default domain |
+----------------------------------+---------+---------+--------------------+

创建domain:

bash 复制代码
# 创建新的domain叫domain-test
[root@controller ~(keystone_admin)]# openstack domain create domain-test
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description |                                  |
| enabled     | True                             |
| id          | c70009318d0141c7a84b26ff427ff9d6 |
| name        | domain-test                      |
| options     | {}                               |
| tags        | []                               |
+-------------+----------------------------------+

#再次验证确实多了一个domain-test
[root@controller ~(keystone_admin)]# openstack domain list
+----------------------------------+-------------+---------+--------------------+
| ID                               | Name        | Enabled | Description        |
+----------------------------------+-------------+---------+--------------------+
| 2c99588e109d427abb530cbb9aada74a | heat        | True    |                    |
| c70009318d0141c7a84b26ff427ff9d6 | domain-test | True    |                    |
| default                          | Default     | True    | The default domain |
+----------------------------------+-------------+---------+--------------------+
[root@controller ~(keystone_admin)]#

删除domain:

bash 复制代码
[root@controller ~(keystone_admin)]# openstack domain set --disable domain-test  #设置domain禁用
[root@controller ~(keystone_admin)]# openstack domain delete domain-test
[root@controller ~(keystone_admin)]# openstack domain list
+----------------------------------+---------+---------+--------------------+
| ID                               | Name    | Enabled | Description        |
+----------------------------------+---------+---------+--------------------+
| 2c99588e109d427abb530cbb9aada74a | heat    | True    |                    |
| default                          | Default | True    | The default domain |
+----------------------------------+---------+---------+--------------------+

开启多域登录界面:

bash 复制代码
[root@controller ~(keystone_admin)]# cd /etc/openstack-dashboard/
[root@controller openstack-dashboard(keystone_admin)]# ls
cinder_policy.json  glance_policy.json  keystone_policy.json  local_settings  local_settings.d  neutron_policy.json  nova_policy.d  nova_policy.json
[root@controller openstack-dashboard(keystone_admin)]# vim local_settings
#修改配置文件83行如下,开启keystone支持多域
 83 OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
[root@controller openstack-dashboard(keystone_admin)]# systemctl restart httpd    

测试多域登录效果:


列出所有用户:

bash 复制代码
[root@controller ~(keystone_admin)]# openstack user list
+----------------------------------+------------+
| ID                               | Name       |
+----------------------------------+------------+
| 7ef9147a8abe485889ece90dce340ab1 | admin      |
| 8624a4e61d6c4b589814c369af26cb5f | heat_admin |
| 8770fb183087426eb29543f3d629b66f | glance     |
| c3eba4bb5577404285b333e4de5c1909 | cinder     |
| c286b069d5064a2b8050b3438f31ef7f | nova       |
| 66fbd238901143d1a2b9e1e848117aff | placement  |
| 7e1d63925490464c897f75275c7364e6 | neutron    |
| 1dd2bd1d566a4f4091e99441bb1da9b5 | swift      |
| 9368227a55f44dba85e10bc7c696813c | heat       |
| be5dc0149ba4402db25045a17a3d7a59 | heat-cfn   |
| e1ddffa452504776bc845f6f4114cd14 | gnocchi    |
| fda949b4ff944336bb3206d6f7e6bc4c | ceilometer |
| 10286ba1e9974e6994fe9908ab0db617 | aodh       |
+----------------------------------+------------+

创建新用户:user1

bash 复制代码
#创建用户user1密码HUAWEI
[root@controller ~(keystone_admin)]# openstack user create --password HUAWEI user1   
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | 77ae3f5b216749ef8663c3bdb5679d36 |
| name                | user1                            |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

#查看用户列表有没有新创建的用户user1,user1在最下面
[root@controller ~(keystone_admin)]# openstack user list
+----------------------------------+------------+
| ID                               | Name       |
+----------------------------------+------------+
| 7ef9147a8abe485889ece90dce340ab1 | admin      |
| 8624a4e61d6c4b589814c369af26cb5f | heat_admin |
| 8770fb183087426eb29543f3d629b66f | glance     |
| c3eba4bb5577404285b333e4de5c1909 | cinder     |
| c286b069d5064a2b8050b3438f31ef7f | nova       |
| 66fbd238901143d1a2b9e1e848117aff | placement  |
| 7e1d63925490464c897f75275c7364e6 | neutron    |
| 1dd2bd1d566a4f4091e99441bb1da9b5 | swift      |
| 9368227a55f44dba85e10bc7c696813c | heat       |
| be5dc0149ba4402db25045a17a3d7a59 | heat-cfn   |
| e1ddffa452504776bc845f6f4114cd14 | gnocchi    |
| fda949b4ff944336bb3206d6f7e6bc4c | ceilometer |
| 10286ba1e9974e6994fe9908ab0db617 | aodh       |
| 77ae3f5b216749ef8663c3bdb5679d36 | user1      |
+----------------------------------+------------+

#查看user1用户详细信息
[root@controller ~(keystone_admin)]# openstack user show user1
+---------------------+----------------------------------+
| Field               | Value                            |
+---------------------+----------------------------------+
| domain_id           | default                          |
| enabled             | True                             |
| id                  | 77ae3f5b216749ef8663c3bdb5679d36 |
| name                | user1                            |
| options             | {}                               |
| password_expires_at | None                             |
+---------------------+----------------------------------+

创建组group1,并将user1加入group1:

bash 复制代码
#创建组group1
[root@controller ~(keystone_admin)]# openstack group create group1
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description |                                  |
| domain_id   | default                          |
| id          | f259902c4c0242d3b392d951494e747f |
| name        | group1                           |
+-------------+----------------------------------+

#列出所有的组
[root@controller ~(keystone_admin)]# openstack group list
+----------------------------------+--------+
| ID                               | Name   |
+----------------------------------+--------+
| f259902c4c0242d3b392d951494e747f | group1 |
+----------------------------------+--------+

#查看group1组详细信息
[root@controller ~(keystone_admin)]# openstack group show group1
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description |                                  |
| domain_id   | default                          |
| id          | f259902c4c0242d3b392d951494e747f |
| name        | group1                           |
+-------------+----------------------------------+

#将user1加入group1
[root@controller ~(keystone_admin)]# openstack group add user group1 user1

#查看user1是否隶属于group1
[root@controller ~(keystone_admin)]# openstack group contains user group1 user1
user1 in group group1

查看角色role:

bash 复制代码
[root@controller ~(keystone_admin)]# openstack role list
+----------------------------------+------------------+
| ID                               | Name             |
+----------------------------------+------------------+
| 030b4ca553dc41349168eaca4fd43f42 | ResellerAdmin    |
| 461321ea6a284081b692a469a15d7938 | SwiftOperator    |
| 4ef39ef24f694c9aa6c1101622da0e92 | admin            |
| 8b24d8bef4004573a8f3cb1f5a1517a8 | _member_         |
| 973e0706bc66471a90d09f177bfb6a1d | member           |
| a3af83fe8bf84014b01feae786f83b8b | heat_stack_owner |
| ce4a3e671d9040359d6f6f55555bf429 | reader           |
| e9cd36ba1b8744878cc15a05709ab1fd | heat_stack_user  |
+----------------------------------+------------------+

给group1赋予角色admin:

bash 复制代码
[root@controller ~(keystone_admin)]# openstack role add --project admin --group group1 admin

验证group1角色:

bash 复制代码
[root@controller ~(keystone_admin)]# openstack role assignment list --names --group group1
+-------+------+----------------+---------------+--------+--------+-----------+
| Role  | User | Group          | Project       | Domain | System | Inherited |
+-------+------+----------------+---------------+--------+--------+-----------+
| admin |      | group1@Default | admin@Default |        |        | False     |
+-------+------+----------------+---------------+--------+--------+-----------+

创建ProjectA:

bash 复制代码
#创建项目ProjectA
[root@controller ~(keystone_admin)]# openstack project create ProjectA
+-------------+----------------------------------+
| Field       | Value                            |
+-------------+----------------------------------+
| description |                                  |
| domain_id   | default                          |
| enabled     | True                             |
| id          | a6aa11ee311a46889ac34e49b8da47d1 |
| is_domain   | False                            |
| name        | ProjectA                         |
| options     | {}                               |
| parent_id   | default                          |
| tags        | []                               |
+-------------+----------------------------------+

#查看验证命令
[root@controller ~(keystone_admin)]# openstack project list
[root@controller ~(keystone_admin)]# openstack project show projectA

#ProjeectA分配给用户user1
[root@controller ~(keystone_admin)]# openstack user set --project ProjectA user1

#给项目ProjectA里的用户user1赋予角色admin
[root@controller ~(keystone_admin)]# openstack role add --user user1 --project ProjectA admin

查看ProjectA现象:

思考:同样的 方式创建一个项目ProjectB,分配给用户user2,角色admin

创建一个用户user3,在项目ProjectA中的角色为member

修改ProjectA配额:

bash 复制代码
#将Project配额设置为实例3,vcpu 5,内存5000MB
[root@controller ~(keystone_admin)]# openstack quota set --instance 3 --cores 5 --ram 5000 ProjectA

修改配额实验现象:

使用user1登录,切换到ProjectA

查看OpenStack有哪些服务:

bash 复制代码
[root@controller ~(keystone_admin)]# openstack service list
+----------------------------------+------------+----------------+
| ID                               | Name       | Type           |
+----------------------------------+------------+----------------+
| 006d8f9e6a054e238a1093fe5af715bf | swift      | object-store   |
| 1abf3641147f40368f8d1c7e8b5677e1 | heat       | orchestration  |
| 2e6919aa53eb48cb99bc992b506a0e3e | glance     | image          |
| 5dfb29073cf140199cc78b2d84fac299 | keystone   | identity       |
| 5ed901220a18430f8d423f9a95d43477 | ceilometer | metering       |
| 8ec4ba00f67448ad8acedc744dce2d87 | heat-cfn   | cloudformation |
| 9a6c3edee4ba431db7d1cac840b91dcb | neutron    | network        |
| a747c0c45e544fa9b20538474ac579d1 | nova       | compute        |
| c4e445f741a943ff897eb494cca6df6e | cinderv2   | volumev2       |
| d06744c3ad6343988bb0ab60b291ffeb | placement  | placement      |
| db9e425f65ac4808ab62dc1659f58916 | cinderv3   | volumev3       |
| e11ec9b570254141bdac2ff3ec75179d | aodh       | alarming       |
| e3a0ba8fe0f844249bfa3a90ec6a6fea | gnocchi    | metric         |
+----------------------------------+------------+----------------+

查看OpenStack endpoint:

三个入口:admin\public\internal

查看catalog:

理解Keystone核心概念

作为 OpenStack 的基础支持服务,Keystone 做下面这几件事情:

  1. 管理用户及其权限
  2. 维护 OpenStack Services 的 Endpoint
  3. Authentication(认证)和 Authorization(鉴权)

学习 Keystone,得理解下面这些概念:

User

User 指代任何使用 OpenStack 的实体,可以是真正的用户,其他系统或者服务。

当 User 请求访问 OpenStack 时,Keystone 会对其进行验证。Horizon 在身份管理>用户 管理 User

除了 admin,OpenStack 也为 nova、cinder、glance、neutron 服务创建了相应的 User。 admin 也可以管理这些 User。

Credentials

Credentials 是 User 用来证明自己身份的信息,可以是:

  1. 用户名/密码
  2. Token
  3. API Key
  4. 其他高级方式

Authentication

Authentication 是 Keystone 验证 User 身份的过程。User 访问 OpenStack 时向 Keystone 提交用户名和密码形式的 Credentials,Keystone 验证通过后会给 User 签发一个 Token 作为后续访问的 Credential。

Token

Token 是由数字和字母组成的字符串,User 成功 Authentication 后 Keystone 生成 Token 并分配给 User。

  1. Token 用做访问 Service 的 Credential

  2. Service 会通过 Keystone 验证 Token 的有效性

  3. Token 的有效期默认是 24 小时

Project

Project 用于将 OpenStack 的资源(计算、存储和网络)进行分组和隔离。

根据 OpenStack 服务的对象不同,Project 可以是一个客户(公有云,也叫租户)、部门或者项目组(私有云)。

这里请注意:

  1. 资源的所有权是属于 Project 的,而不是 User。
  2. 在 OpenStack 的界面和文档中,Tenant / Project / Account 这几个术语是通用的,但长期看会倾向使用 Project
  3. 每个 User(包括 admin)必须挂在 Project 里才能访问该 Project 的资源。 一个User可以属于多个 Project。
  4. admin 相当于 root 用户,具有最高权限

Horizon 在 身份管理>项目 中管理 Project

通过 管理成员将 User 添加到 Project

Service

OpenStack 的 Service 包括 Compute (Nova)、Block Storage (Cinder)、Object Storage (Swift)、Image Service (Glance) 、Networking Service (Neutron) 等。每个 Service 都会提供若干个 Endpoint,User 通过 Endpoint 访问资源和执行操作。

Endpoint

Endpoint 是一个网络上可访问的地址,通常是一个 URL。Service 通过 Endpoint 暴露自己的 API。 Keystone 负责管理和维护每个 Service 的 Endpoint。

可以使用下面的命令来查看 Endpoint。

root@controller \~(keystone_admin)# openstack endpoint list

root@controller \~(keystone_admin)# openstack catalog list

Role

安全包含两部分:Authentication(认证)和 Authorization(鉴权)

Authentication 解决的是"你是谁?"的问题

Authorization 解决的是"你能干什么?"的问题

Keystone 借助 Role 实现 Authorization:

  1. Keystone定义Role

  2. 可以为 User 分配一个或多个 Role,Horizon 的菜单为 Identity->Project->Manage Members

  3. Service 决定每个 Role 能做什么事情 Service 通过各自的 policy.json 文件对 Role 进行访问控制。 下面是 Nova 服务 /etc/nova/policy.json 中的示例

    访问策略规则以JSON格式指定,文件名为policy.json

    策略文件的路径是/etc/SERVICE_NAME/policy.json,例如/etc/keystone/policy.json

    packstack安装策略文件路径是/etc/openstack-dashboard/SERVICE_NAME_policy.json

    OpenStack 默认配置只区分 admin 和非 admin Role。 如果需要对特定的 Role 进行授权,可以修改 policy.json(一般不要改)。下一节我们将通过例子加深对这些概念的理解。

通过例子学习keystone

上一节介绍了 Keystone 的核心概念。本节我们通过"查询可用 image"这个实际操作让大家对这些概念建立更加感性的认识。User admin 要查看 Project 中的 image

第 1 步 登录

当点击 登入 时,OpenStack 内部发生了哪些事情?请看下面

Token 中包含了 User 的 Role 信息

第 2 步 显示操作界面

Troubleshoot

OpenStack 排查问题的方法主要是通过日志。

每个 Service 都有自己的日志文件。

Keystone 主要有一个日志: keystone.log 保存在 /var/log/keystone/ 目录里。

bash 复制代码
[root@controller nova(keystone_admin)]# cd /var/log/keystone/
[root@controller keystone(keystone_admin)]# ls
keystone.log

如果需要得到最详细的日志信息,可以在 /etc/keystone/keystone.conf 中打开 debug 选项

bash 复制代码
[root@controller keystone(keystone_admin)]# cd /etc/keystone/
[root@controller keystone(keystone_admin)]# ls
default_catalog.templates  fernet-keys  keystone.conf  logging.conf  policy.d  policy.json  puppet.conf  sso_callback_template.html
[root@controller keystone(keystone_admin)]# vim keystone.conf

# 修改配置文件第94行
94 debug=True

•我们以创建VM为例,站在整个OpenStack角度来看一下,整个认证流程是怎样的。

•首先用户需要使用OpenStack,第一步就要向Keystone提供用户名密码来获取Token。当用户获取Token后,需要向Nova发送创建虚拟机请求,Nova负责调用计算资源并管理虚拟机的生命周期,所以这个创建请求要发送到Nova。请求的Head中会携带Token,当Nova-api接收到请求后,会将Token传递到Keystone进行验证是否有效合法。当验证成功后返回信息给Nova,Nova才开始进行创建VM操作。这边不具体介绍Nova如何操作,但是我们知道创建一台虚拟机,不仅需要准备CPU、内存等计算资源,还要有相应的网络、存储等资源,这里以网络资源为例,Nova-api将token透传给Nova-compute,Nova-compute会向Neutron-server发送与网络相关操作请求,请求Head中也携带Token,Neutron收到请求后也会将Token传递到Keystone验证,验证成功才执行相应操作。

•这个流程中我们可以看到,不同服务间的调用也要携带Token,并且Keystone只校验了Token的有效性,那么每个服务的操作权限控制是怎么实现的呢?

•首先用户发送基本信息给Keystone,一般是用户名和密码。Keystone经过验证后会返回一个Token给用户,用户向Nova发送创建虚拟机请求,并携带Token信息,nova接收到请求后,会拿着Token去Keystone进行验证,验证成功后开始执行创建VM操作,Nova会向Glance发送申请镜像信息并携带Token,会向Neutron发送申请网络信息也会携带Token,Glance和Neutron组件接收到请求后,都会向Keystone验证Token的有效性(图中仅用了一条线表示,请注意理解),验证通过即执行相应的操作,返回完成信息,当VM创建完成后,Nova返回创建成功信息给用户,用户即可使用虚拟机。

OpenStack镜像管理-glance

公有云(华为云)镜像概念

解释说明
  • 镜像

    是一个包含了操作系统及必要配置的弹性云服务器模板,使用镜像可以创建弹性云服务器。

  • 公共镜像

    公共镜像是云平台提供的常见的标准操作系统镜像,所有用户可见,包括操作系统以及预装的公共应用。公共镜像具有高度稳定性,皆为正版授权,您也可以根据实际需求自助配置应用环境或相关软件。

  • 私有镜像

    基于云服务器或外部镜像文件等方式创建的个人镜像,仅用户自己可见。包含操作系统、预装的公共应用以及用户的私有应用。选择私有镜像创建云服务器,可以节省您重复配置云服务器的时间。

    更多信息,请参见怎样制作私有镜像?

  • 共享镜像

    您可以接受云平台其他用户共享的私有镜像,作为自己的镜像进行使用。

    更多信息,请参见怎样共享镜像?

  • 市场镜像

    提供预装操作系统、应用环境和各类软件的优质第三方镜像。无需配置,可一键部署,满足建站、应用开发、可视化管理等个性化需求。

最主要的作用:节约时间

Glance在OpenStack中的作用
Glance架构
Glance架构

•在Newton版本及之前版本中,Glance支持REST API V1和V2。

•在V2 API版本中,Glance-Registry的内容被整合进了Glance-API。如果Glance-API接收到与镜像元数据有关的请求,则会直接操作数据库,不需要再通过Glance-Registry。

•在V1 API版本中,Glance-Registry与Glance-API一样,也是一个WSGI Server,但是Glance-Registry处理的是与镜像元数据相关的RESTful请求。Glance-API在接收到用户的RESTful请求后,如果该请求与元数据相关,则将其转发给Glance-Registry。需要注意的是,Glance-Registry提供的REST API是给Glance-API使用的 ,不对OpenStack外部用户暴露。

•在Newton版本中V1已经过时,并从Stein版本开始,Glance-Registry被废弃,由Glance-API代替,然后通过Store模块的接口实现对各种不同后台存储系统的支持,包括Glance架构图中的Amazon S3、Cinder/Swift、Ceph、Sheepdog等存储后端。

查看glalnce-api配置文件,观察与database通信的部分:

glance的配置文件在/etc/glance目录下:

bash 复制代码
#查看配置文件,不做修改
[root@controller glance]# vim /etc/glance/glance-api.conf
1619 connection=mysql+pymysql://glance:cb89fe4fee034ad6@192.168.108.10/glance

连接数据库查看现象:

mysql 复制代码
[root@controller ~]# mysql           #连接数据库
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 841
Server version: 10.3.28-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;           #查看所有数据库
+--------------------+
| Database           |
+--------------------+
| aodh               |
| cinder             |
| glance             |
| gnocchi            |
| heat               |
| information_schema |
| keystone           |
| mysql              |
| neutron            |
| nova               |
| nova_api           |
| nova_cell0         |
| performance_schema |
| placement          |
| test               |
+--------------------+
15 rows in set (0.014 sec)

MariaDB [(none)]> use glance;                       #切换到指定的glance数据库
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [glance]> show tables;                    #查看所有当前数据库中的所有表
+----------------------------------+
| Tables_in_glance                 |
+----------------------------------+
| alembic_version                  |
| image_locations                  |
| image_members                    |
| image_properties                 |
| image_tags                       |
| images                           |
| metadef_namespace_resource_types |
| metadef_namespaces               |
| metadef_objects                  |
| metadef_properties               |
| metadef_resource_types           |
| metadef_tags                     |
| migrate_version                  |
| task_info                        |
| tasks                            |
+----------------------------------+
15 rows in set (0.000 sec)
镜像image、实例instance、规格flavor三者区别

镜像、实例和规格的关系:

用户可以从同一个镜像启动任意数量的实例

每个启动的实例都是基于镜像的一个副本,实例上的任何修改都不会影响到镜像

启动实例时,必须指定一个规格,实例按照规格使用资源

Glance磁盘格式
磁盘格式 描述
vhd Xen,Microsoft,VirtualBox等使用的常见磁盘格式
vhdx vhd格式的增强版本,支持更大的磁盘容量和其他功能
vmdk VMware常见的磁盘格式
vdi VirtualBox和QEMU支持的磁盘格式
iso 光盘(例如CDROM)的存档格式
ploog Virtuozzo支持和使用的磁盘格式,用于运行OS Containers
qcow2 QEMU支持的磁盘格式,支持动态扩展和写时复制
aki Amazon Kernel Image
ari Amazon Ramdisk Image
ami Amazon Machine Image
raw 一种非结构化的磁盘镜像格式

将镜像添加到Glance时,必须指定虚拟机镜像的磁盘格式和容器格式

Glance状态机

Glance中有两种状态机:镜像状态和任务状态

镜像状态 描述
queued 已在glance-registry中保留镜像标识符,但镜像数据未上传,镜像大小未初始化
saving 镜像的原始数据正在上传到Glance中
uploading 对镜像调用了import data-put请求
importing 导入镜像中,但镜像尚未就绪
active 镜像创建完成,可以使用
deactivated 禁止任何非管理员用户访问镜像
killed 镜像上传时出错,镜像不可用
deleted Glance保留了镜像信息,但不能继续使用,镜像在一定时间后会被自动清理掉
pending_delete 类似deleted,Glance尚未删除镜像数据,处于该状态的镜像可恢复
任务状态 描述
pending 任务挂起
processing 任务正在处理中
success 任务执行成功
failure 任务执行失败
Glance状态机转换图

•queued:没有上传image数据,只有db中的元数据。

•saving:正在上传image data,当注册一个镜像使用POST /images并且当前携带了一个x-image-meta-location头,这个镜像将不会进入saving状态(镜像的数据已经是可以获得的,不能重传)。

•active:当镜像数据上传完毕,镜像就可以被使用了(可获得的),此时处于active状态。

•deactivated:表示任何非管理员用户都无权访问镜像数据,禁止下载镜像,也禁止像镜像导出和镜像克隆之类的操作(请求镜像数据的操作)。

•killed:表示上传过程中发生错误,并且镜像是不可读的。

•deleted:glance已经保存了该镜像的数据,但是该镜像不再可用,处于该状态的镜像将在不久后被自动删除。

•pending_delete: 与deleted相似,glance还没有清除镜像数据,只是处于该状态的镜像不可恢复。


上传镜像实验

此次实验上传两个镜像:

cirros-0.5.2-x86_64-disk.img

TinyCore-12.0.iso

直接先将这2个文件,拖放到controller节点的/root目录。观察两个文件磁盘格式

bash 复制代码
[root@controller ~]# ls
anaconda-ks.cfg  answers.txt  cirros-0.5.2-x86_64-disk.img  keystonerc_admin  TinyCore-12.0.iso
[root@controller ~]#
[root@controller ~]# qemu-img info cirros-0.5.2-x86_64-disk.img
image: cirros-0.5.2-x86_64-disk.img
file format: qcow2                      #磁盘格式qcow2
virtual size: 112 MiB (117440512 bytes)
disk size: 15.5 MiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    compression type: zlib
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
    extended l2: false
[root@controller ~]#
[root@controller ~]# qemu-img info TinyCore-12.0.iso
image: TinyCore-12.0.iso
file format: raw
virtual size: 20 MiB (20971520 bytes)
disk size: 20 MiB
[root@controller ~]#
bash 复制代码
[root@controller ~]# find / -name e846b42b-5024-479b-9f79-1ae181bfa14e
/var/lib/glance/images/e846b42b-5024-479b-9f79-1ae181bfa14e

去数据库中查看现象:

mysql 复制代码
[root@controller ~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 7012
Server version: 10.3.28-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| aodh               |
| cinder             |
| glance             |
| gnocchi            |
| heat               |
| information_schema |
| keystone           |
| mysql              |
| neutron            |
| nova               |
| nova_api           |
| nova_cell0         |
| performance_schema |
| placement          |
| test               |
+--------------------+
15 rows in set (0.000 sec)

MariaDB [(none)]> use glance;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [glance]> show tables;
+----------------------------------+
| Tables_in_glance                 |
+----------------------------------+
| alembic_version                  |
| image_locations                  |
| image_members                    |
| image_properties                 |
| image_tags                       |
| images                           |
| metadef_namespace_resource_types |
| metadef_namespaces               |
| metadef_objects                  |
| metadef_properties               |
| metadef_resource_types           |
| metadef_tags                     |
| migrate_version                  |
| task_info                        |
| tasks                            |
+----------------------------------+
15 rows in set (0.000 sec)

MariaDB [glance]> select id,value from image_locations;
+----+--------------------------------------------------------------------+
| id | value                                                              |
+----+--------------------------------------------------------------------+
|  1 | file:///var/lib/glance/images/e846b42b-5024-479b-9f79-1ae181bfa14e |
|  2 | file:///var/lib/glance/images/bb8a4940-3bde-428c-83b4-9c98eb430721 |
+----+--------------------------------------------------------------------+
2 rows in set (0.000 sec)
Glance镜像制作

最简单的Glance镜像制作方法是下载系统供应商官方发布的OpenStack镜像文件。大多数镜像预安装了cloud-init包,支持SSH密钥对登录和用户数据注入功能。

•镜像的具体下载链接,请参考OpenStack社区网站:

https://docs.openstack.org/image-guide/obtain-images.html。


使用swift作为Glance后端存储
bash 复制代码
#将/etc/glance/glance-api.conf中的#号开头的行(注释行),和空行过滤掉,显示出配置行
[root@controller ~]# grep -Ev '^#' /etc/glance/glance-api.conf | grep -Ev '^$'
[DEFAULT]
bind_host=0.0.0.0
bind_port=9292
workers=4
image_cache_dir=/var/lib/glance/image-cache
debug=False
log_file=/var/log/glance/api.log
log_dir=/var/log/glance
transport_url=rabbit://guest:guest@192.168.108.10:5672/
[cinder]
[cors]
[database]
connection=mysql+pymysql://glance:cb89fe4fee034ad6@192.168.108.10/glance
[file]
[glance.store.http.store]
[glance.store.rbd.store]
[glance.store.s3.store]
[glance.store.swift.store]
[glance.store.vmware_datastore.store]
[glance_store]
stores=file,http,swift
default_store=file
filesystem_store_datadir=/var/lib/glance/images/
[image_format]
[keystone_authtoken]
www_authenticate_uri=http://192.168.108.10:5000/v3
auth_type=password
auth_url=http://192.168.108.10:5000
username=glance
password=huawei
user_domain_name=Default
project_name=services
project_domain_name=Default
[oslo_concurrency]
[oslo_messaging_amqp]
[oslo_messaging_kafka]
[oslo_messaging_notifications]
driver=messagingv2
topics=notifications
[oslo_messaging_rabbit]
ssl=False
default_notification_exchange=glance
[oslo_middleware]
[oslo_policy]
policy_file=/etc/glance/policy.json
[paste_deploy]
flavor=keystone
[profiler]
[store_type_location_strategy]
[task]
[taskflow_executor]
[wsgi]

#下面为查看swift密码方式
[root@controller ~]# vim answers.txt
1137 CONFIG_SWIFT_HASH=f8715a7c2bf640b9       #这个密码配置到上面的配置文件

[root@controller ~]# vim /etc/glance/glance-api.conf
3111 default_store=swift
3982 swift_store_region = RegionOne
4090 swift_store_container = gqdglance
4118 swift_store_large_object_size = 5120
4160 swift_store_create_container_on_put = true
4182 swift_store_multi_tenant = true
4230 swift_store_admin_tenants = services
4391 swift_store_auth_address = http://192.168.108.10:5000/v3
4399 swift_store_user = swift
4408 swift_store_key = f8715a7c2bf640b9           #这里的swift密码是安装的时候决定的,随机产生的,查看answers.txt

[root@controller ~(keystone_admin)]# systemctl restart openstack-glance*  #重启glance进程

上传镜像,测试效果:

数据库中观察现象:

mysql 复制代码
[root@controller ~]# mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 23720
Server version: 10.3.28-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| aodh               |
| cinder             |
| glance             |
| gnocchi            |
| heat               |
| information_schema |
| keystone           |
| mysql              |
| neutron            |
| nova               |
| nova_api           |
| nova_cell0         |
| performance_schema |
| placement          |
| test               |
+--------------------+
15 rows in set (0.000 sec)

MariaDB [(none)]> use glance;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

MariaDB [glance]> show tables;
+----------------------------------+
| Tables_in_glance                 |
+----------------------------------+
| alembic_version                  |
| image_locations                  |
| image_members                    |
| image_properties                 |
| image_tags                       |
| images                           |
| metadef_namespace_resource_types |
| metadef_namespaces               |
| metadef_objects                  |
| metadef_properties               |
| metadef_resource_types           |
| metadef_tags                     |
| migrate_version                  |
| task_info                        |
| tasks                            |
+----------------------------------+
15 rows in set (0.000 sec)

MariaDB [glance]> select id,value from image_locations;
+----+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | value                                                                                                                                                         |
+----+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | file:///var/lib/glance/images/e846b42b-5024-479b-9f79-1ae181bfa14e                                                                                            |
|  2 | file:///var/lib/glance/images/bb8a4940-3bde-428c-83b4-9c98eb430721                                                                                            |
|  3 | swift+http://192.168.108.10:8080/v1/AUTH_03e49a46342d48ab9607b4919925e42c/gqdglance_6a5a50d9-be54-4151-bd2f-4b1c08efdb18/6a5a50d9-be54-4151-bd2f-4b1c08efdb18 |
+----+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
3 rows in set (0.000 sec)

命令行上传大文件镜像-带进度条

WEB界面上传文件没有进度条,只会转圈

命令行上传大文件:

bash 复制代码
[root@controller ~(keystone_admin)]# glance image-create --name image_centos --file CentOS-7-x86_64-Minimal-1810.iso --disk-format raw --container bare --progress

现象如下,有进度条

建议:openstack上传大文件使用命令行,web界面可能上传失败


OpenStack计算管理-nova

nova负责:

•虚拟机生命周期管理

•其他计算资源生命周期管理

nova不负责:

•承载虚拟机的物理主机自身的管理

•全面的系统状态监控

nova系统架构

DB:用于数据存储的SQL数据库。

API:接收 HTTP 请求、转换命令并通过oslo.messaging队列或 HTTP与其他组件通信的组件。

Scheduler:为虚拟机选择合适的物理主机。

Compute:虚拟机生命周期和复杂流程控制。

Conductor:处理需要协调(构建/调整大小)的请求,充当数据库代理或处理对象转换。

Placement:跟踪资源提供者的库存和使用情况。

•RPC:Remote Procedure Call,远程过程调用,是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。

•API服务器处理REST请求,通常涉及数据库读写,将RPC消息发送到其他Nova服务(可选),并生成对REST调用的响应。

•RPC消息传递是通过oslo.messaging库完成的,它是消息队列之上的抽象。

•Nova使用基于消息传递的"无共享"架构,大多数主要的nova组件可以在多个服务器上运行,并且有一个监听RPC消息的管理器。

查看控制节点,计算节点的nova服务:

控制节点:

计算节点:

nova物理部署

检查RabbitMQ服务是否正常:

bash 复制代码
[root@controller ~(keystone_admin)]# systemctl status rabbitmq-server.service

nova服务运行架构

•Nova服务各组件可分布式部署,且可通过virtDriver对接不同的虚拟化平台。

•引入nova-conductor的好处:

▫安全性上考虑。之前每个nova-compute都是直接访问数据库的。如果由于某种原因,某个计算节点被攻陷了,那攻击者就可以获取访问数据库的全部权限,肆意操作数据库。

▫方便升级。将数据库和nova-compute解耦,如果数据库的模式改变,nova-compute就不用升级了。

▫性能上考虑。之前数据库的访问在nova-compute中直接访问且数据库访问是阻塞性的,由于nova-compute只有一个os线程,所以当一个绿色线程去访问数据库的时候会阻塞其他绿色线程,导致绿色线程无法并发。但是nova-conductor是通过rpc 调用,rpc调用是绿色线程友好的,一个rpc call的执行返回前不会阻塞其他绿色线程的执行。这样就会提高了操作的并发。

查看nova.conf

bash 复制代码
[root@controller ~(keystone_admin)]# vim /etc/nova/nova.conf
nova-api、nova-conductor操作数据库由下面两行配置文件决定
1132 connection=mysql+pymysql://nova_api:d247d6a4c7f14f2f@192.168.108.10/nova_api
1763 connection=mysql+pymysql://nova:d247d6a4c7f14f2f@192.168.108.10/nova

nova-scheduler

•Nova-Scheduler:确定将虚拟机分配到哪一台物理机,分配过程主要分为两步,过滤和权重;用户创建虚拟机时会提出资源需求,例如CPU、内存、磁盘各需要多少,OpenStack将这些需求定义在flavor中,用户只需要指定flavor就可以了。

•调度过程分为两步:

▫通过过滤器选择满足条件的计算节点;

▫通过权重选择最优的节点。

下面介绍 nova-scheduler 是如何实现调度的。在 /etc/nova/nova.conf 中,nova 通过 scheduler_driver,scheduler_available_filters 和 scheduler_default_filters 这三个参数来配置 nova-scheduler。

Filter scheduler

Filter scheduler 是 nova-scheduler 默认的调度器,调度过程分为两步:

  1. 通过过滤器(filter)选择满足条件的计算节点(运行 nova-compute)
  2. 通过权重选择分值最高的服务器上创建 Instance。

scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler

Nova 允许使用第三方 scheduler,配置 scheduler_driver 即可。 这又一次体现了OpenStack的开放性。Scheduler 可以使用多个 filter 依次进行过滤,过滤之后的节点再通过计算权重选出最适合的节点。

上图是调度过程的一个示例:

  1. 最开始有 6 个计算节点 Host1-Host6

  2. 通过多个 filter 层层过滤,Host2 和 Host4 没有通过,被刷掉了

  3. Host1,Host3,Host5,Host6 计算权重,结果 Host5 得分最高,最终入选

Filter

当 Filter scheduler 需要执行调度操作时,会让 filter 对计算节点进行判断,filter 返回 True 或 False。Nova.conf 中的 available_filters 选项用于配置 scheduler 可用的 filter,默认是所有 nova 自带的 filter 都可以用于滤操作。

bash 复制代码
[root@controller ~]# vim /etc/nova/nova.conf
1931 available_filters=nova.scheduler.filters.all_filters

另外还有一个选项 enabled_filters,用于指定 scheduler 真正使用的 filter,默认值如下

bash 复制代码
[root@controller ~]# vim /etc/nova/nova.conf
1938 enabled_filters=AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter

scheduler 按照列表中的顺序依次过滤。 下面依次介绍每个 filter。

RetryFilter

RetryFilter 的作用是刷掉之前已经调度过的节点。

举个例子方便大家理解: 假设 A,B,C 三个节点都通过了过滤,最终 A 因为权重值最大被选中执行操作。 但由于某个原因,操作在 A 上失败了。 默认情况下,nova-scheduler 会重新执行过滤操作(重复次数由 scheduler_max_attempts 选项指定,默认是 3)。 那么这时候 RetryFilter 就会将 A 直接刷掉,避免操作再次失败。 RetryFilter 通常作为第一个 filter。

AvailabilityZoneFilter

为提高容灾性和提供隔离服务,可以将计算节点划分到不同的Availability Zone中。例如把一个机架上的机器划分在一个 Availability Zone 中。 OpenStack 默认有一个命名为 "nova" 的 Availability Zone,所有的计算节点初始都是放在 "nova" 中。 用户可根据需要创建自己的 Availability Zone。

nova-scheduler 在做 filtering 时,会使用 AvailabilityZoneFilter 将不属于指定 Availability Zone 的计算节点过滤掉。

实验案例:

RamFilter

RamFilter 将不能满足 flavor 内存需求的计算节点过滤掉。

对于内存有一点需要注意: 为了提高系统的资源使用率,OpenStack 在计算节点可用内存时允许 overcommit,也就是可以超过实际内存大小。 超过的程度是通过 nova.conf 中 ram_allocation_ratio 这个参数来控制的,默认值为 1.5

210 ram_allocation_ratio = 1.5

bash 复制代码
#将默认的1.5调整为5
 210 ram_allocation_ratio=5

其含义是:如果计算节点的内容为 10GB,OpenStack 则会认为它有 50GB(10*5)内存。

DiskFilter

DiskFilter 将不能满足 flavor 磁盘需求的计算节点过滤掉。Disk 同样允许 overcommit,通过 nova.conf 中 disk_allocation_ratio 控制,默认值为 1

216 #disk_allocation_ratio=

CoreFilter

CoreFilter 将不能满足 flavor vCPU 需求的计算节点过滤掉。vCPU 同样允许 overcommit,通过 nova.conf 中 cpu_allocation_ratio 控制,默认值为 16

203 cpu_allocation_ratio=16.0

这意味着一个 8 vCPU 的计算节点,nova-scheduler 在调度时认为它有 128 个 vCPU。 需要提醒的是: nova-scheduler 默认使用的 filter 并没有包含 CoreFilter。 如果要用,可以将 CoreFilter 添加到 nova.conf 的 scheduler_default_filters 配置选项中。

ComputeFilter

ComputeFilter 保证只有 nova-compute 服务正常工作的计算节点才能够被 nova-scheduler调度。ComputeFilter 显然是必选的 filter。

ComputeCapabilitiesFilter

ComputeCapabilitiesFilter 根据计算节点的特性来筛选。这个比较高级,我们举例说明。

例如我们的节点有 x86_64 和 ARM 架构的,如果想将 Instance 指定部署到 x86_64 架构的节点上,就可以利用 ComputeCapabilitiesFilter。还记得 flavor 中有个 Metadata 吗,Compute 的 Capabilitie s就在 Metadata中 指定。

"Compute Host Capabilities" 列出了所有可设置 Capabilities。

点击 "Architecture" 后面的 "+",就可以在右边的列表中指定具体的架构。

配置好后,ComputeCapabilitiesFilter 在调度时只会筛选出 x86_64 的节点。 如果没有设置 Metadata,ComputeCapabilitiesFilter 不会起作用,所有节点都会通过筛选。

ImagePropertiesFilter

ImagePropertiesFilter 根据所选 image 的属性来筛选匹配的计算节点。 跟 flavor 类似,image 也有 metadata,用于指定其属性。

例如希望某个 image 只能运行在 kvm 的 hypervisor 上,可以通过 "Hypervisor Type" 属性来指定。

点击 "+",然后在右边的列表中选择 "kvm"。

配置好后,ImagePropertiesFilter 在调度时只会筛选出 kvm 的节点。 如果没有设置 Image 的Metadata,ImagePropertiesFilter 不会起作用,所有节点都会通过筛选。

ServerGroupAntiAffinityFilter(反亲和性)

ServerGroupAntiAffinityFilter 可以尽量将 Instance 分散部署到不同的节点上。

例如有 inst1,inst2 和 inst3 三个 instance,计算节点有 A,B 和 C。 为保证分散部署,进行如下操作:

  1. 创建一个 anti-affinity 策略的 server group "group-1"

nova server-group-create --policy anti-affinity group-1

请注意,这里的 server group 其实是 instance group,并不是计算节点的 group。

  1. 依次创建 Instance inst1, inst2和inst3并放到group-1中

nova boot --image IMAGE_ID --flavor 1 --hint group=group-1 inst1

nova boot --image IMAGE_ID --flavor 1 --hint group=group-1 inst2

nova boot --image IMAGE_ID --flavor 1 --hint group=group-1 inst3

因为 group-1 的策略是 AntiAffinity,调度时 ServerGroupAntiAffinityFilter 会将 inst1, inst2 和 inst3 部署到不同计算节点 A, B 和 C。目前只能在 CLI 中指定 server group 来创建 instance。

创建 instance 时如果没有指定 server group,ServerGroupAntiAffinityFilter 会直接通过,不做任何过滤。

ServerGroupAffinityFilter

与 ServerGroupAntiAffinityFilter 的作用相反,ServerGroupAffinityFilter 会尽量将 instance 部署到同一个计算节点上。 方法类似

  1. 创建一个 affinity 策略的 server group "group-2"

nova server-group-create --policy affinity group-2

  1. 依次创建 instance inst1, inst2 和 inst3 并放到 group-2 中

nova boot --image IMAGE_ID --flavor 1 --hint group=group-2 inst1

nova boot --image IMAGE_ID --flavor 1 --hint group=group-2 inst2

nova boot --image IMAGE_ID --flavor 1 --hint group=group-2 inst3

因为 group-2 的策略是 Affinity,调度时 ServerGroupAffinityFilter 会将 inst1, inst2 和 inst3 部署到同一个计算节点。创建 instance 时如果没有指定 server group,ServerGroupAffinityFilter 会直接通过,不做任何过滤。

Weight

经过前面一堆 filter 的过滤,nova-scheduler 选出了能够部署 instance 的计算节点。如果有多个计算节点通过了过滤,那么最终选择哪个节点呢?

Scheduler 会对每个计算节点打分,得分最高的获胜。 打分的过程就是 weight,翻译过来就是计算权重值,那么 scheduler 是根据什么来计算权重值呢?

目前 nova-scheduler 的默认实现是根据计算节点空闲的内存量计算权重值: 空闲内存越多,权重越大,instance 将被部署到当前空闲内存最多的计算节点上。


创建一个实例,观看日志

先开启debug:

bash 复制代码
[root@controller ~]# vim /etc/nova/nova.conf
694 debug=True
[root@controller ~]# systemctl restart openstack-nova*

记录创建的实例id

日志

是时候完整的回顾一下 nova-scheduler 的工作过程了。整个过程都被记录到 /var/log/nova-scheduler.log的日志文件中。

bash 复制代码
[root@controller nova(keystone_admin)]# cat /var/log/nova/nova-scheduler.log | grep Filter

日志显示初始有两个 host(在我们的实验环境中就是controller 和compute),依次经过6 个 filter 的过滤(AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffin ityFilter,ServerGroupAffinityFilter),两个计算节点都通过了。那么接下来就该 weight 了:

bash 复制代码
[root@controller nova(keystone_admin)]# cat /var/log/nova/nova-scheduler.log | grep weight
2024-09-25 16:28:52.882 16246 DEBUG nova.scheduler.filter_scheduler [req-ee2f456e-9997-4d83-95b0-083b69b903da 7ef9147a8abe485889ece90dce340ab1 03e49a46342d48ab9607b4919925e42c - default
compute ram: 15217MB disk: 58368MB io_ops: 0 instances: 0, weight: 3.0],
controller ram: 15217MB disk: 54272MB io_ops: 0 instances: 0, weight: 2.9298on3.6/site-packages/nova/scheduler/filter_scheduler.py:462

经过权重比较,做种compute获胜

复制代码
[root@controller nova(keystone_admin)]# cat /var/log/nova/nova-scheduler.log | grep Select

可以看到因为compute的硬盘比 controller 多(58368 > 54272),权重值更大(3.0 > 2.928),最终选择 compute。

注意:生产环境没有故障时,不要开启deubg,浪费性能


nova-compute

•虚拟机生命周期操作的真正执行者(会调用对应的hypervisor的driver)。

•底层对接不同虚拟化的平台(KVM/VMware/XEN/Ironic等)。

•内置周期性任务,完成资源刷新,虚拟机状态同步等功能。

•资源管理模块(resource_tracker)配合插件机制,完成资源的统计。

配置compute节点配置文件,定义driver:

bash 复制代码
[root@compute ~]# vim /etc/nova/nova.conf
53 compute_driver=libvirt.LibvirtDriver
[root@compute ~]# cd /usr/lib/python3.6/site-packages/nova/virt/
[root@compute virt]# ls
arch.py          driver.py    hyperv         __init__.py          netutils.py  storage_users.py
block_device.py  event.py     image          interfaces.template  osinfo.py    virtapi.py
configdrive.py   fake.py      imagecache.py  ironic               powervm      vmwareapi
disk             hardware.py  images.py      libvirt              __pycache__  zvm

RabbitMQ性能查看


启用 RabbitMQ 管理 plugin

查看RabbitMQ服务状态:

bash 复制代码
[root@controller ~]# systemctl status rabbitmq-server.service
● rabbitmq-server.service - RabbitMQ broker
   Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/rabbitmq-server.service.d
           └─90-limits.conf
   Active: active (running) since Thu 2024-09-26 09:06:19 CST; 18min ago
 Main PID: 1721 (beam.smp)
   Status: "Initialized"
    Tasks: 91 (limit: 100416)
   Memory: 118.7M
   CGroup: /system.slice/rabbitmq-server.service
           ├─1721 /usr/lib64/erlang/erts-10.7.2.1/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 512>
           ├─2144 /usr/lib64/erlang/erts-10.7.2.1/bin/epmd -daemon
           ├─3100 erl_child_setup 16384
           ├─7806 inet_gethost 4
           └─7807 inet_gethost 4

默认安装中,我们只能用命令 rabbitmqctl 监控 RabbitMQ,比如:rabbitmqctl list_queues,rabbitmqctl list_exchanges 等子命令。这种方式不太直观,效率不高。

好在 RabbitMQ 有一个管理 plugin,提供了图形管理界面,可以在运行 RabbitMQ 的节点(一般是控制节点)执行下面的命令启用。

bash 复制代码
[root@controller ~]# rabbitmq-plugins enable rabbitmq_management
Enabling plugins on node rabbit@controller:
rabbitmq_management
The following plugins have been configured:
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_web_dispatch
Applying plugin configuration to rabbit@controller...
The following plugins have been enabled:
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_web_dispatch

started 3 plugins.

然后还需要创建一个 用户,用来登录管理控制台了。

bash 复制代码
[root@controller ~]# iptables -F
[root@controller ~]# rabbitmqctl add_user user_admin passwd_admin   #创建用户名密码
Adding user "user_admin" ...
[root@controller ~]# rabbitmqctl set_user_tags user_admin administrator rabbitmqctl set_permissions -p / user_admin ".*" ".*" ".*"    #授权
Setting tags for user "user_admin" to [administrator, rabbitmqctl, set_permissions, user_admin, .*, .*, .*] ...
[root@controller ~]#

然后就可以用 user_admin(密码 passwd_admin)登录了,地址是

http://192.168.108.10:15672

观察Unacked

Unacked Message 指的是还没有被处理的消息。正常情况下,这个值应该为 0。如不是 0,并且持续增长,那你就得注意了,这意味着RabbitMQ 出现了问题,队列开始积压,消息开始堆积,是一个严重的信号。

接下来怎么办呢?

这个时候就可以点开 Overview 后面的标签,查看到底消息是在哪个或者哪些 Connection,Channel,Exchange,Queues 中堆积,进而分析问题的根源并解决。


查看nova相关服务

nova-console控制台:

用户由多种方式访问虚拟控制台

nova-novncproxy,基于 Web 浏览器的 VNC 访问

nova-spicehtml5proxy,基于 HTML5 浏览器的 SPICE 访问

nova-xvpnvncproxy,基于 Java 客户端的 VNC 访问

bash 复制代码
[root@controller ~]# source keystonerc_admin

#查看nova组件分部安装在哪些设备上,状态是否正常
[root@controller ~(keystone_admin)]# openstack compute service list
+----+----------------+------------+----------+---------+-------+----------------------------+
| ID | Binary         | Host       | Zone     | Status  | State | Updated At                 |
+----+----------------+------------+----------+---------+-------+----------------------------+
|  1 | nova-conductor | controller | internal | enabled | up    | 2024-09-26T01:40:15.000000 |
|  2 | nova-scheduler | controller | internal | enabled | up    | 2024-09-26T01:40:17.000000 |
|  5 | nova-compute   | controller | nova     | enabled | up    | 2024-09-26T01:40:21.000000 |
|  6 | nova-compute   | compute    | nova     | enabled | up    | 2024-09-26T01:40:19.000000 |
+----+----------------+------------+----------+---------+-------+----------------------------+
[root@controller ~(keystone_admin)]#

创建虚拟机过程(简单)

  1. 客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:"帮我创建一个 Instance"

  2. API对请求做一些必要处理后,向 Messaging(RabbitMQ)发送了一条消息:"让 Scheduler 创建一个 Instance"

  3. Scheduler(nova-scheduler)从 Messaging 获取到 API 发给它的消息,然后执行调度算法,从若干计算节点中选出节点 A。

    请参考 看 nova-scheduler 如何选择计算节点

  4. Scheduler 向 Messaging 发送了一条消息:"在计算节点 A 上创建这个 Instance"

  5. 计算节点 A 的 Compute(nova-compute)从 Messaging 中获取到 Scheduler 发给它的消息,然后通过本节点的 Hypervisor Driver 创建 Instance。请参考 nova-compute 部署 instance详解

  6. 在 Instance 创建的过程中,Compute 如果需要查询或更新数据库信息,会通过 Messaging 向 Conductor(nova-conductor)发送消息,Conductor 负责数据库访问。

    如何观察现象,在配置文件中打开debug,分别tail -f (nova-api,nova-scheduler,nova-conductor,nova-compute)这些组件,然后创建实例,观察日志,就可以看到现象

创建虚拟机过程(详细)

•Step1:用户通过Dashboard/CLI 申请创建虚拟机,并以REST API 方式来请求Keystone授权。

•Step2:keystone通过用户请求认证信息,并生成auth-token返回给对应的认证请求。

•Step3:界面或命令行通过RESTful API向nova-api发送一个boot instance的请求(携带auth-token)。

•Step4:nova-api接受请求后向keystone发送认证请求,查看token是否为有效用户和token。

•Step5:keystone验证token是否有效,如有效则返回有效的认证和对应的角色(注:有些操作需要有角色权限才能操作)。

•Step6:通过认证后nova-api和数据库通讯。

•Step7:初始化新建虚拟机的数据库记录。

•Step8:nova-api通过rpc.call向nova-scheduler请求是否有创建虚拟机的资源(Host ID)。

•Step9:nova-scheduler进程侦听消息队列,获取nova-api的请求。

•Step10:nova-scheduler通过查询nova数据库中计算资源的情况,并通过调度算法计算符合虚拟机创建需要的主机。

•Step11:对于有符合虚拟机创建的主机,nova-scheduler更新数据库中虚拟机对应的物理主机信息。

•Step12:nova-scheduler通过rpc.cast向nova-compute发送对应的创建虚拟机请求的消息。

•Step13:nova-compute会从对应的消息队列中获取创建虚拟机请求的消息。

•Step14:nova-compute通过rpc.call向nova-conductor请求获取虚拟机消息。

•Step15:nova-conductor从消息队队列中拿到nova-compute请求消息。

•Step16:nova-conductor根据消息查询虚拟机对应的信息。

•Step17:nova-conductor从数据库中获得虚拟机对应信息。

•Step18:nova-conductor把虚拟机信息通过消息的方式发送到消息队列中。

•Step19:nova-compute从对应的消息队列中获取虚拟机信息消息。

•Step20:nova-compute通过keystone的RESTfull API拿到认证的token,并通过HTTP请求glance-api获取创建虚拟机所需要镜像。

•Step21:glance-api向keystone认证token是否有效,并返回验证结果。

•Step22:token验证通过,nova-compute获得虚拟机镜像信息(URL)。

•Step23:nova-compute通过keystone的RESTfull API拿到认证k的token,并通过HTTP请求neutron-server获取创建虚拟机所需要的网络信息。

•Step24:neutron-server向keystone认证token是否有效,并返回验证结果。

•Step25:token验证通过,nova-compute获得虚拟机网络信息。

•Step26:nova-compute通过keystone的RESTfull API拿到认证的token,并通过HTTP请求cinder-api获取创建虚拟机所需要的持久化存储信息。

•Step27:cinder-api向keystone认证token是否有效,并返回验证结果。

•Step28:token验证通过,nova-compute获得虚拟机持久化存储信息。

•Step29:nova-compute根据instance的信息调用配置的虚拟化驱动来创建虚拟机。


nova操作

创建实例

首先,一个实例创建最少需要以下资源:

规格

镜像

网络

有时需要短时间暂停 instance,可以通过 Pause 操作将 instance 的状态保存到宿主机的内存中。当需要恢复的时候,执行 Resume 操作,从内存中读回 instance 的状态,然后继续运行 instance。

有时需要长时间暂停 instance,可以通过 Suspend 操作将 instance 的状态保存到宿主机的磁盘上。需要恢复的时候,执行 Resume 操作,从磁盘读回 instance 的状态,然后继续运行。

这里需要对 Suspend 和 Pause 做个比较:

相同点

两者都是暂停 instance 的运行,并保存当前状态,之后可以通过 Resume 操作恢复。

不同点

  1. Suspend (挂起)将 instance 的状态保存在磁盘; Pause(暂停) 是保存在内存中,所以 Resume (恢复)被 Pause 的 instance 要比 Suspend 快。

  2. instance 被 Suspend 后,状态为 Shut Down;而被 Pause 的 instance 状态是 Paused。

  3. 虽然都是通过 Resume 操作恢复, Pause 对应的 Resume 在 OpenStack 内部被叫作 "Unpause" ; Suspend 对应的 Resume 才是真正的 "Resume" 。这个在日志中能体现出来。

废弃实例

Instance 被 Suspend 后虽然处于 Shut Down 状态,但 Hypervisor 依然在宿主机上为其预留了资源,以便在以后能够成功 Resume。如果希望释放这些预留资源,可以使用 Shelve 操作。 Shelve 会将 instance 作为 image 保存到 Glance 中,然后在宿主机上删除该instance。

锁定实例

创建普通用户用于测试:

创建好普通用户后,用普通用户登陆WEB界面,尝试删除锁定的实例,发现无法删除

尝试解锁实例,发现可以解锁

锁定实例: 防止意外删除,要先解锁,才能删除admin锁定的实例

管理员对于上锁的实例,能不能不解锁直接删除---->能

管理员上锁后,普通用户能不能直接删除--->不能

管理源创建的实例不上锁,普通用户能不能直接删除--->能

普通用户能不能解锁---->能

管理员加锁,普通用户可以解锁为什么普通用户可以解锁?

bash 复制代码
[root@controller ~(keystone_admin)]# cd /etc/openstack-dashboard/
[root@controller openstack-dashboard(keystone_admin)]# ls
cinder_policy.json  glance_policy.json  keystone_policy.json  local_settings  local_settings.d  neutron_policy.json  nova_policy.d  nova_policy.json
[root@controller openstack-dashboard(keystone_admin)]# vim nova_policy.json
69     "os_compute_api:os-lock-server:lock": "rule:admin_or_owner",
70     "os_compute_api:os-lock-server:unlock": "rule:admin_or_owner",
71     "os_compute_api:os-lock-server:unlock:unlock_override": "rule:admin_api",

发现,普通用户可以直接解锁,解锁再删除(虽然难删除一些,但是还是能删除)

!!!防止意外删除

配置让普通用户不能解锁

bash 复制代码
[root@controller openstack-dashboard(keystone_admin)]# vim nova_policy.json
69     "os_compute_api:os-lock-server:lock": "rule:admin_or_owner",
70     "os_compute_api:os-lock-server:unlock": "rule:admin_api",
71     "os_compute_api:os-lock-server:unlock:unlock_override": "rule:admin_api",

实验效果:

切换到普通用户不能够解锁,admin能够解锁(清空网页缓存)

重建实例

虚拟机奔溃了可以拿原有镜像重建实例

相关推荐
betazhou39 分钟前
Apache Seatunnel 抽取Oracle数据库测试
数据库·oracle·apache·seatunnel
devilnumber2 小时前
Oracle 与 MySQL substr 函数差异总结
java·数据库·mysql·oracle
—Miss. Z—3 小时前
计算机等级考试三级数据库技术—选择题
数据库·mysql
www_aiyuanma_vip3 小时前
PC 手机电商(MySQL 版)
数据库·mysql·智能手机
Databend3 小时前
AI 时代的数据工程挑战:从复杂链路走向统一数据底座
大数据·数据库·云计算
treacle田3 小时前
达梦数据库-Linux DM数据守护主备集群缩改为单机-记录总结
linux·服务器·数据库·主备集群改单机
SelectDB技术团队3 小时前
Apache Doris 支持同步/异步物化视图与 ROLLUP,多表加速能力优于 StarRocks
大数据·数据库·doris·技术选型·物化视图·starrock·查询加速