02.OpenStack管理
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:
[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:
# 创建新的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:
[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 |
+----------------------------------+---------+---------+--------------------+
开启多域登录界面:
[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
测试多域登录效果:


列出所有用户:
[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
#创建用户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:
#创建组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:
[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:
[root@controller ~(keystone_admin)]# openstack role add --project admin --group group1 admin
验证group1角色:
[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:
#创建项目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配额:

#将Project配额设置为实例3,vcpu 5,内存5000MB
[root@controller ~(keystone_admin)]# openstack quota set --instance 3 --cores 5 --ram 5000 ProjectA
openstack quota set --instance 3 -cores 5 --ram 5000 ProjectA
修改配额实验现象:
使用user1登录,切换到ProjectA


查看OpenStack有哪些服务:
[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:

查看catalog:


理解Keystone核心概念
作为 OpenStack 的基础支持服务,Keystone 做下面这几件事情:
- 管理用户及其权限
- 维护 OpenStack Services 的 Endpoint
- Authentication(认证)和 Authorization(鉴权)
学习 Keystone,得理解下面这些概念:
User
User 指代任何使用 OpenStack 的实体,可以是真正的用户,其他系统或者服务。

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

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

Credentials
Credentials 是 User 用来证明自己身份的信息,可以是:
- 用户名/密码
- Token
- API Key
- 其他高级方式

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

Token
Token 是由数字和字母组成的字符串,User 成功 Authentication 后 Keystone 生成 Token 并分配给 User。
-
Token 用做访问 Service 的 Credential
-
Service 会通过 Keystone 验证 Token 的有效性
-
Token 的有效期默认是 24 小时
Project
Project 用于将 OpenStack 的资源(计算、存储和网络)进行分组和隔离。
根据 OpenStack 服务的对象不同,Project 可以是一个客户(公有云,也叫租户)、部门或者项目组(私有云)。
这里请注意:
- 资源的所有权是属于 Project 的,而不是 User。
- 在 OpenStack 的界面和文档中,Tenant / Project / Account 这几个术语是通用的,但长期看会倾向使用 Project
- 每个 User(包括 admin)必须挂在 Project 里才能访问该 Project 的资源。 一个User可以属于多个 Project。
- 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:
-
Keystone定义Role

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

-
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 步 显示操作界面

请注意,顶部显示 admin 可访问的 Project 为 “admin” ”。 其实在此之前发生了一些事情:

同时,admin 可以访问 实例, 镜像 卷等服务

这是因为 admin 已经从 Keystone 拿到了各 Service 的 Endpoints

第 3 步 显示 镜像 列表
点击 “镜像”,会显示镜像列表

背后发生了这些事:
首先 admin 将请求发送到 Glance 的 Endpoint

Glance 向 Keystone 询问 admin 身份是否有效

接下来 Glance 会查看 /etc/glance/policy.json 判断 admin 是否有查看 image 的权限

权限判定通过,Glance 将 image 列表发给 admin。
Troubleshoot
OpenStack 排查问题的方法主要是通过日志。
每个 Service 都有自己的日志文件。
Keystone 主要有一个日志: keystone.log 保存在 /var/log/keystone/ 目录里。
[root@controller nova(keystone_admin)]# cd /var/log/keystone/
[root@controller keystone(keystone_admin)]# ls
keystone.log
如果需要得到最详细的日志信息,可以在 /etc/keystone/keystone.conf 中打开 debug 选项
[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.html3/7
[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目录下:
#查看配置文件,不做修改
[root@controller glance]# vim /etc/glance/glance-api.conf
1619 connection=mysql+pymysql://glance:cb89fe4fee034ad6@192.168.108.10/glance
连接数据库查看现象:
[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目录。观察两个文件磁盘格式
[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 ~]#




点击上图右上角问号可以看到帮助

上传成功:

点击镜像

cirros-0.5.2上传后ID为e846b42b-5024-479b-9f79-1ae181bfa14e

镜像上传到哪里去了?
[root@controller ~]# find / -name e846b42b-5024-479b-9f79-1ae181bfa14e
/var/lib/glance/images/e846b42b-5024-479b-9f79-1ae181bfa14e
去数据库中查看现象:
[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后端存储

#将/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进程

上传镜像,测试效果:



查看具体ID
6a5a50d9-be54-4151-bd2f-4b1c08efdb18

点击对象存储、容器

数据库中观察现象:
[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界面上传文件没有进度条,只会转圈


命令行上传大文件:
[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服务是否正常:
[root@controller ~(keystone_admin)]# systemctl status rabbitmq-server.service

nova服务运行架构

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

nova-conductor

•引入nova-conductor的好处:
▫安全性上考虑。之前每个nova-compute都是直接访问数据库的。如果由于某种原因,某个计算节点被攻陷了,那攻击者就可以获取访问数据库的全部权限,肆意操作数据库。
▫方便升级。将数据库和nova-compute解耦,如果数据库的模式改变,nova-compute就不用升级了。
▫性能上考虑。之前数据库的访问在nova-compute中直接访问且数据库访问是阻塞性的,由于nova-compute只有一个os线程,所以当一个绿色线程去访问数据库的时候会阻塞其他绿色线程,导致绿色线程无法并发。但是nova-conductor是通过rpc 调用,rpc调用是绿色线程友好的,一个rpc call的执行返回前不会阻塞其他绿色线程的执行。这样就会提高了操作的并发。
查看nova.conf
[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 默认的调度器,调度过程分为两步:
- 通过过滤器(filter)选择满足条件的计算节点(运行 nova-compute)
- 上创建 Instance。
scheduler_driver=nova.scheduler.filter_scheduler.FilterScheduler
Nova 允许使用第三方 scheduler,配置 scheduler_driver 即可。 这又一次体现了OpenStack的开放性。Scheduler 可以使用多个 filter 依次进行过滤,过滤之后的节点再通过计算权重选出最适合的节点。

上图是调度过程的一个示例:
-
最开始有 6 个计算节点 Host1-Host6
-
通过多个 filter 层层过滤,Host2 和 Host4 没有通过,被刷掉了
-
Host1,Host3,Host5,Host6 计算权重,结果 Host5 得分最高,最终入选
Filter
当 Filter scheduler 需要执行调度操作时,会让 filter 对计算节点进行判断,filter 返回 True 或 False。Nova.conf 中的 available_filters 选项用于配置 scheduler 可用的 filter,默认是所有 nova 自带的 filter 都可以用于滤操作。
[root@controller ~]# vim /etc/nova/nova.conf
1931 available_filters=nova.scheduler.filters.all_filters
另外还有一个选项 enabled_filters,用于指定 scheduler 真正使用的 filter,默认值如下
[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。

创建 Instance 时,需要指定将 Instance 部署到在哪个 Availability Zone中。

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

将controller节点加入到gpu_az
将compute节点加入nogpu_az

创建gpu_az选择controller节点


同理,创建nogpu_az选择compute节点


AZ创建完后的现象:

思考:
此刻创建一个实例instance_gpu,该实例要用GPU,创建实例时,选择哪个AZ?–>gpu_az—>controller
此刻创建一个实例instance_nogup,该实例用不到GPU,创建实例时,选择哪个AZ?–>nogpu_az–>compute
前置条件,创建一个网络用于后面创建实例




创建规格


上传镜像


创建instance_gpu


选择使用cirros-0.5.2镜像

选择规格


创建instance_nogpu参考上面创建instance_gpu步骤


[root@controller ~]# vim /etc/nova/nova.conf
694 debug=True
[root@controller ~]# systemctl restart openstack-nova*
[root@controller ~]# tail /var/log/nova/nova-scheduler.log -f
然后,参考前面创建实例的步骤,web界面创再建一个虚拟机,选择AZ,会用到AvailabitZoneFilter规则,观察log现象


RamFilter
RamFilter 将不能满足 flavor 内存需求的计算节点过滤掉。
对于内存有一点需要注意: 为了提高系统的资源使用率,OpenStack 在计算节点可用内存时允许 overcommit,也就是可以超过实际内存大小。 超过的程度是通过 nova.conf 中 ram_allocation_ratio 这个参数来控制的,默认值为 1.5
210 ram_allocation_ratio = 1.5
#将默认的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。 为保证分散部署,进行如下操作:
- 创建一个 anti-affinity 策略的 server group “group-1”
nova server-group-create --policy anti-affinity group-1
请注意,这里的 server group 其实是 instance group,并不是计算节点的 group。
- 依次创建 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 部署到同一个计算节点上。 方法类似
- 创建一个 affinity 策略的 server group “group-2”
nova server-group-create --policy affinity group-2
- 依次创建 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:
[root@controller ~]# vim /etc/nova/nova.conf
694 debug=True
[root@controller ~]# systemctl restart openstack-nova*

记录创建的实例id


日志
是时候完整的回顾一下 nova-scheduler 的工作过程了。整个过程都被记录到 /var/log/nova-scheduler.log的日志文件中。
[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 了:
[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:
[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服务状态:
[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 的节点(一般是控制节点)执行下面的命令启用。
[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.
然后还需要创建一个 用户,用来登录管理控制台了。
[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 访问
[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)]#
创建虚拟机过程(简单)

-
客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(nova-api)发送请求:“帮我创建一个 Instance”
-
API对请求做一些必要处理后,向 Messaging(RabbitMQ)发送了一条消息:“让 Scheduler 创建一个 Instance”
-
Scheduler(nova-scheduler)从 Messaging 获取到 API 发给它的消息,然后执行调度算法,从若干计算节点中选出节点 A。
请参考 看 nova-scheduler 如何选择计算节点 -
Scheduler 向 Messaging 发送了一条消息:“在计算节点 A 上创建这个 Instance”
-
计算节点 A 的 Compute(nova-compute)从 Messaging 中获取到 Scheduler 发给它的消息,然后通过本节点的 Hypervisor Driver 创建 Instance。请参考 nova-compute 部署 instance详解
-
在 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操作
创建实例
首先,一个实例创建最少需要以下资源:
规格
镜像
网络
创建规格


创建镜像


创建网络




创建实例




如果创建实例是灰的,点击下一步,寻找创建的网络
关闭实例

启动实例

软重启与硬重启区别

soft reboot 与 hard reboot 的区别在于:
-
soft reboot 只是重启操作系统,整个过程中, instance 依然处于运行状态。相当于在 linux 中执行 reboot 命令
-
hard reboot 是重启 instance,相当于关机之后再开机
暂停实例与挂起实例区别

有时需要短时间暂停 instance,可以通过 Pause 操作将 instance 的状态保存到宿主机的内存中。当需要恢复的时候,执行 Resume 操作,从内存中读回 instance 的状态,然后继续运行 instance。
有时需要长时间暂停 instance,可以通过 Suspend 操作将 instance 的状态保存到宿主机的磁盘上。需要恢复的时候,执行 Resume 操作,从磁盘读回 instance 的状态,然后继续运行。
这里需要对 Suspend 和 Pause 做个比较:
相同点
两者都是暂停 instance 的运行,并保存当前状态,之后可以通过 Resume 操作恢复。
不同点
-
Suspend (挂起)将 instance 的状态保存在磁盘; Pause(暂停) 是保存在内存中,所以 Resume (恢复)被 Pause 的 instance 要比 Suspend 快。
-
instance 被 Suspend 后,状态为 Shut Down;而被 Pause 的 instance 状态是 Paused。
-
虽然都是通过 Resume 操作恢复, Pause 对应的 Resume 在 OpenStack 内部被叫作 “Unpause” ; Suspend 对应的 Resume 才是真正的 “Resume” 。这个在日志中能体现出来。
废弃实例

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


创建普通用户用于测试:

创建好普通用户后,用普通用户登陆WEB界面,尝试删除锁定的实例,发现无法删除
尝试解锁实例,发现可以解锁
锁定实例: 防止意外删除,要先解锁,才能删除admin锁定的实例
管理员对于上锁的实例,能不能不解锁直接删除---->能
管理员上锁后,普通用户能不能直接删除—>不能
管理源创建的实例不上锁,普通用户能不能直接删除—>能
普通用户能不能解锁---->能
管理员加锁,普通用户可以解锁为什么普通用户可以解锁?
[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",
发现,普通用户可以直接解锁,解锁再删除(虽然难删除一些,但是还是能删除)
!!!防止意外删除
配置让普通用户不能解锁
[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能够解锁(清空网页缓存)
重建实例
虚拟机奔溃了可以拿原有镜像重建实例


OpenStack块存储管理-cinder
cinder的配置文件位置:/etc/cinder
cinder的日志文件位置:/var/log/cidner
openstack存储类型

OpenStack持久化存储简介

Cinder作用
Cinder在虚拟机与具体存储设备之间引入了一层“逻辑存储卷”的抽象,Cinder本身不是一种存储技术,并没有实现对块设备的实际管理和服务
Cinder只是提供了一个中间的抽象层,为后端不同的存储技术,提供了统一的接口
不同的块设备服务厂商在Cinder中以驱动的形式实现上述接口与OpenStack进行整合
Cinder架构

•Cinder Client封装Cinder提供的rest接口,以CLI形式供用户使用。
•Cinder API对外提供rest API,对操作需求进行解析,对API进行路由寻找相应的处理方法。包含卷的增删改查(包括从源卷、镜像、快照创建)、快照增删改查、备份、volume type管理、挂载/卸载(Nova调用)等。
•Cinder Scheduler负责收集backend上报的容量、能力信息,根据设定的算法完成卷到指定cinder-volume的调度。
•Cinder Volume多节点部署,使用不同的配置文件、接入不同的backend设备,由各存储厂商插入driver代码与设备交互完成设备容量和能力信息收集、卷操作。
•Cinder Backup实现将卷的数据备份到其他存储介质(目前SWIFT/Ceph/TSM提供了驱动)。
•SQL DB提供存储卷、快照、备份、service等数据,支持MySQL、PG、MSSQL等SQL数据库。
查看控制节点cinder进程:
[root@controller ~]# ps -e | grep cinder
1746 ? 00:00:03 cinder-schedule
1748 ? 00:00:04 cinder-api
1772 ? 00:00:03 cinder-backup
1791 ? 00:00:04 cinder-volume
2812 ? 00:00:00 cinder-backup
2931 ? 00:00:00 cinder-volume
2959 ? 00:00:00 cinder-api
2961 ? 00:00:00 cinder-api
2964 ? 00:00:00 cinder-api
2967 ? 00:00:00 cinder-api
查看cinder-volume默认支持的存储设备:
[root@controller ~]# cd /usr/lib/python3.6/site-packages/cinder/volume/drivers/
[root@controller drivers]# ls
datera huawei lenovo nfs.py rbd.py storpool.py windows
dell_emc ibm linstordrv.py nimble.py remotefs.py stx zadara.py
fujitsu infinidat.py lvm.py prophetstor rsd.py synology
fusionstorage infortrend macrosan pure.py san veritas_access
hedvig __init__.py nec __pycache__ sandstone veritas_cnfs.py
hitachi inspur netapp qnap.py solidfire.py vmware
hpe kaminario nexenta quobyte.py spdk.py vzstorage.py
Cinder架构说明

•Cinder默认使用LVM(Logical Volume Manager)作为后端存储(Backend Storage),而LVM通过在操作系统与物理存储资源之间引入逻辑卷(Logical Volume)的抽象来解决传统磁盘分区管理工具的问题。
•LVM将众多不同的物理存储资源(物理卷、Physical Volume,如磁盘分区)组成卷组。LVM从卷组中创建一个逻辑卷,然后将ext3、ReiserFS等文件系统安装在这个逻辑卷上。
•除了LVM,目前Cinder已经以驱动的形式支持众多存储技术或存储厂商的设备作为后端存储,如SAN(Storage Area Network)、Ceph、Sheepdog,以及EMC、华为等厂商的设备。

实验环境后端存储就是LVM(安装时决定的):
[root@controller ~]# vim answers.txt
536 CONFIG_CINDER_BACKEND=lvm
544 CONFIG_CINDER_VOLUMES_CREATE=y
547 CONFIG_CINDER_VOLUME_NAME=cinder-volumes
554 CONFIG_CINDER_VOLUMES_SIZE=20G
实验环境查看:
[root@controller ~]# vgdisplay cinder-volumes
--- Volume group ---
VG Name cinder-volumes
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 8
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 1
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size <20.60 GiB
PE Size 4.00 MiB
Total PE 5273
Alloc PE / Size 5020 / <19.61 GiB
Free PE / Size 253 / 1012.00 MiB
VG UUID ODOHA8-u2MO-RAtc-y43r-1r1u-PIn8-XOFuhi
Cinder架构部署:以SAN存储为例

- Cinder-api,Cinder-Scheduler,Cinder-Volume可以选择部署到一个节点上,也可以分别部署
- API采用AA模式,HAproxy作为LB,分发请求到多个Cinder API
- Scheduler也采用AA模式,由rabbitmq以负载均衡模式向3个节点分发任务,并同时从rabbitmq收取Cinder volume上报的能力信息,调度时,scheduler通过在DB中预留资源从而保证数据一致性
- Cinder Volume也采用AA模式,同时上报同一个backend容量和能力信息,并同时接受请求进行处理
- RabbitMQ,支持主备或集群
- MySQL,支持主备或集群
Cinder-api

Cinder API
- 检查参数合法性(用户输入,权限,资源是否存在等)
- 准备创建的参数字典,预留和提交配额
- 在数据库中创建对应的数据记录
- 通过消息队列将请求和参数发送到Scheduler
查看cinder API服务状态:
[root@controller ~]# systemctl status openstack-cinder-api.service
● openstack-cinder-api.service - OpenStack Cinder API Server
Loaded: loaded (/usr/lib/systemd/system/openstack-cinder-api.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2024-09-27 09:44:47 CST; 1h 7min ago
Main PID: 1748 (cinder-api)
Tasks: 5 (limit: 100416)
Memory: 501.2M
CGroup: /system.slice/openstack-cinder-api.service
├─1748 /usr/bin/python3 /usr/bin/cinder-api --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile />
├─2959 /usr/bin/python3 /usr/bin/cinder-api --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile />
├─2961 /usr/bin/python3 /usr/bin/cinder-api --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile />
├─2964 /usr/bin/python3 /usr/bin/cinder-api --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile />
└─2967 /usr/bin/python3 /usr/bin/cinder-api --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf --logfile />
Sep 27 09:44:47 controller systemd[1]: Started OpenStack Cinder API Server.
Cinder-scheduler

•和Nova Scheduler类似,Cinder Scheduler也是经过Filter筛选符合条件的后端,然后使用Weigher计算后端进行权重排序,最终选择出最合适的后端存储。
Cinder Scheduler服务
提取接收到的请求参数
通过配置的filter和输入参数对后端进行过滤
Availability_zone_filter
Capacity_filter
Capabilities_filter
Affinity_filter(SameBackendFilter/DifferentBackendFilter)
……
Weigher计算后端进行权重
CapacityWeigher/AllocatedCapacityWeigher
ChanceWeigher
GoodnessWeigher
……
选取最优的Backend并通过消息队列将请求发送到指定的后端
查看配置文件:
[root@controller ~]# cd /etc/cinder/
[root@controller cinder]# ls
api-paste.ini cinder.conf resource_filters.json rootwrap.conf rootwrap.d volumes
[root@controller cinder]# vim cinder.conf
592 #scheduler_default_filters = AvailabilityZoneFilter,CapacityFilter,CapabilitiesFilter
593
595 #scheduler_default_weighers = CapacityWeigher
596
601 # Default scheduler driver to use (string value)
602 #scheduler_driver = cinder.scheduler.filter_scheduler.FilterScheduler
AvailabilityZoneFilter
为提高容灾性和提供隔离服务,可以将存储节点和计算节点划分到不同的 Availability Zone 中。例如把一个机架上的机器划分在一个 Availability Zone 中。OpenStack 默认有一个命名为“nova”的 Availability Zone,所有的节点初始都是放在“nova”中。用户可以根据需要创建自己的 Availability Zone。
创建 Volume 时,用户会指定 Volume 的大小。CapacityFilter 的作用是将存储空间不能满足 Volume 创建需求的存储节点过滤掉。
配置cinder配置文件cinder.conf
[root@controller ~]# cd /etc/cinder/
[root@controller cinder]# ls
api-paste.ini cinder.conf resource_filters.json rootwrap.conf rootwrap.d volumes
[root@controller cinder]# vim cinder.conf
592 scheduler_default_filters = AvailabilityZoneFilter,CapacityFilter,CapabilitiesFilter
#该配置文件的节点的AZ设置为az1
395 storage_availability_zone=az1
#创建卷时,不指定az默认使用nova AZ
401 default_availability_zone=nova
[root@controller cinder]# systemctl restart openstack-cinder*
验证AZ实验:
#cinder.conf配置文件配置401 default_availability_zone=nova,创建卷时不指定AZ则使用nova AZ,而该节点属于az1 AZ,创建失败
[root@controller ~]# source keystonerc_admin
[root@controller ~(keystone_admin)]# openstack volume create --size 1 volume1
Availability zone 'nova' is invalid. (HTTP 400) (Request-ID: req-c4e2d4d1-d299-4267-b2a1-22fcd676a6ea)
#cinder配置文件配置395 storage_availability_zone=az1,该节点属于AZ az1节点,创建AZ az2卷,被AvailabilityZoneFilter过滤
[root@controller ~(keystone_admin)]# openstack volume create --size 1 --availability-zone az2 volume1
Availability zone 'az2' is invalid. (HTTP 400) (Request-ID: req-749dad9d-d5fb-4122-95aa-ab03d0c5a955)
#cinder配置文件配置395 storage_availability_zone=az1,该节点属于AZ az1节点,创建AZ az1卷,创建成功
[root@controller ~(keystone_admin)]# openstack volume create --size 1 --availability-zone az1 volume1
+---------------------+--------------------------------------+
| Field | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | az1 |
| bootable | false |
| consistencygroup_id | None |
| created_at | 2024-09-27T06:02:35.368543 |
| description | None |
| encrypted | False |
| id | 43746d03-a0c5-4232-8f1b-6023ffe83545 |
| migration_status | None |
| multiattach | False |
| name | volume1 |
| properties | |
| replication_status | None |
| size | 1 |
| snapshot_id | None |
| source_volid | None |
| status | creating |
| type | iscsi |
| updated_at | None |
| user_id | 7ef9147a8abe485889ece90dce340ab1 |
+---------------------+--------------------------------------+
CapacityFilter
创建 Volume 时,用户会指定 Volume 的大小。CapacityFilter 的作用是将存储空间不能满足 Volume 创建需求的存储节点过滤掉。
CapabilitiesFilter
不同的 Volume Provider 有自己的特性(Capabilities),比如是否支持 thin provision 等。Cinder 允许用户创建 Volume 时通过 Volume Type 指定需要的 Capabilities。


创建卷的时候,卷类型指定为iscsi,那么后端使用的是LVM,为何?
由卷类型,扩展规格决定


接下来查看配置文件:
[root@controller ~(keystone_admin)]# vim /etc/cinder/cinder.conf
5261 [lvm]
5262 volume_backend_name=lvm
5263 volume_driver=cinder.volume.drivers.lvm.LVMVolumeDriver
5264 target_ip_address=192.168.108.10
5265 target_helper=lioadm
5266 volume_group=cinder-volumes
5267 volumes_dir=/var/lib/cinder/volumes
Cinder-volume

Cinder Volume服务
- 提取接收到的请求参数
- 调用对应的Driver在后端创建实际的卷
- 使用Driver返回的模型更新数据库中的记录
Cinder挂载流程

挂卷流程: 挂卷是通过Nova和Cinder的配合最终将远端的卷连接到虚拟机所在的Host节点上,并最终通过虚拟机管理程序映射到内部的虚拟机中
•Nova调用Cinder API创建卷,传递主机的信息,如hostname,iSCSI initiator name,FC WWPNs。
•Cinder API将该信息传递给Cinder Volume。
•Cinder Volume通过创建卷时保存的host信息找到对应的Cinder Driver。
•Cinder Driver通知存储允许该主机访问该卷,并返回该存储的连接信息(如iSCSI iqn,portal,FC Target WWPN,NFS path等)。
•Nova调用针对于不同存储类型进行主机识别磁盘的代码( Cinder 提供了brick模块用于参考)实现识别磁盘或者文件设备。
•Nova通知Cinder已经进行了挂载。
•Nova将主机的设备信息传递给hypervisor来实现虚拟机挂载磁盘。

OpenStack对象存储-Swift
swift在openstack中的作用

- Swift并不是文件系统或者实时的数据存储系统,它称为对象存储,用于永久类型的静态数据的长期存储,这些数据可以检索、调整,必要时进行更新
- 最适合存储的数据类型的例子是虚拟机镜像、图片存储、邮件存储和存档备份
- 因为没有中心单元或主控结点,Swift提供了更强的扩展性、冗余和持久性
使用命令swift stat可以显示Swift中的帐户、容器和对象的信息。
Swift为帐户,容器和对象分别定义了Ring(环)将虚拟节点(分区)映射到一组物理存储设备上,包括Account Ring、 Container Ring 、 Object Ring。
Ring记录了存储对象与物理位置的映射关系,通过Zone、 Device、 Partition和Replica来维护映射信息。


华为OBS体验







直到安装结束

点进控制台













Swift实验

控制节点新添加一块20GB磁盘
一。新添磁盘分成两个区,并格式化
分区一:挂载到obs1目录
分区二:挂载到obs2目录

新建两个分区
将两个分区格式化为xfs格式

下面为默认挂给swift的虚拟设备分区,将其卸载

[root@controller ~]# umount /srv/node/swiftloopback #卸载原来的swift虚拟设备分区
[root@controller ~]# cd /srv/node #切换到swift目录
[root@controller node]# ls
swiftloopback
[root@controller node]# rm -rf swiftloopback/ #删除原来的swift挂载目录
[root@controller node]# mkdir obs1 obs2 #创建新的挂载目录,分别挂载sdb1,sbd2
配置挂载文件,将obs1–sdb1,obs2–sdb2分别挂载关联
[root@controller node]# vim /etc/fstab #下面三行话,一句注释,两句添加
#/srv/loopback-device/swiftloopback /srv/node/swiftloopback ext4 noatime,nodiratime,nofail,loop,user_xattr 0 0
/dev/sdb1 /srv/node/obs1 xfs defaults 0 0
/dev/sdb2 /srv/node/obs2 xfs defaults 0 0
[root@controller node]# mount -a #挂载
mount: (hint) your fstab has been modified, but systemd still uses
the old version; use 'systemctl daemon-reload' to reload.
[root@controller node]# df #查看现象
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 3904608 0 3904608 0% /dev
tmpfs 3924792 4 3924788 1% /dev/shm
tmpfs 3924792 17652 3907140 1% /run
tmpfs 3924792 0 3924792 0% /sys/fs/cgroup
/dev/mapper/cs-root 73364480 6867104 66497376 10% /
/dev/mapper/cs-home 131081692 946964 130134728 1% /home
/dev/sda1 1038336 234124 804212 23% /boot
tmpfs 784956 0 784956 0% /run/user/0
/dev/sdb1 10475520 106088 10369432 2% /srv/node/obs1
/dev/sdb2 10474496 106088 10368408 2% /srv/node/obs2
修改obs1目录和obs2目录权限
[root@controller node]# chown swift:swift obs1
[root@controller node]# chown swift:swift obs2
[root@controller node]# ll
total 0
drwxr-xr-x 2 swift swift 6 Sep 29 14:04 obs1
drwxr-xr-x 2 swift swift 6 Sep 29 14:04 obs2
创建swfit ring:
[root@controller node]# cd /etc/swift/
[root@controller swift]# ls
account.builder account-server.conf container-reconciler.conf container-server.conf object-expirer.conf object-server.conf swift.conf
account.ring.gz backups container.ring.gz internal-client.conf object.ring.gz proxy-server
account-server container.builder container-server object.builder object-server proxy-server.conf
[root@controller swift]# swift-ring-builder container.builder create --help
swift-ring-builder <builder_file> create <part_power> <replicas>
<min_part_hours>
Creates <builder_file> with 2^<part_power> partitions and <replicas>.
<min_part_hours> is number of hours to restrict moving a partition more
than once.
[root@controller swift]# swift-ring-builder container.builder create 12 2 1
[root@controller swift]# swift-ring-builder account.builder create 12 2 1
[root@controller swift]# swift-ring-builder object.builder create 12 2 1
#12表示ring分区数量为2^12
#2表示2个副本
#1表示最少1个小时后才能更改ring配置
创建ring映射关系:
#查看配置文件,分别查看account,container,obeject的bind_port记录下来
[root@controller swift]# cat account-server.conf | grep bind_port
bind_port = 6002
[root@controller swift]# cat container-server.conf | grep bind_port
bind_port = 6001
[root@controller swift]# cat object-server.conf | grep bind_port
bind_port = 6000
[root@controller swift]# swift-ring-builder account.builder add z1-192.168.108.10:6002/obs1 100
WARNING: No region specified for z1-192.168.108.10:6002/obs1. Defaulting to region 1.
[root@controller swift]# swift-ring-builder account.builder add z2-192.168.108.10:6002/obs2 100
[root@controller swift]# swift-ring-builder container.builder add z1-192.168.108.10:6001/obs1 100
[root@controller swift]# swift-ring-builder container.builder add z2-192.168.108.10:6001/obs2 100
[root@controller swift]# swift-ring-builder object.builder add z1-192.168.108.10:6000/obs1 100
[root@controller swift]# swift-ring-builder object.builder add z2-192.168.108.10:6000/obs2 100
再平衡:
[root@controller swift]# swift-ring-builder account.builder rebalance
Reassigned 8192 (200.00%) partitions. Balance is now 0.00. Dispersion is now 0.00
[root@controller swift]# swift-ring-builder object.builder rebalance
Reassigned 8192 (200.00%) partitions. Balance is now 0.00. Dispersion is now 0.00
[root@controller swift]# swift-ring-builder container.builder rebalance
Reassigned 8192 (200.00%) partitions. Balance is now 0.00. Dispersion is now 0.00
实验测试:



上传成功

#刚才上传的文件,2副本,分别在obs1目录,obs2目录各存了一份
[root@controller obs1]# find /srv/node -name *data
/srv/node/`obs1`/objects/317/0fe/13d34c83bb5eed122321759e90f6e0fe/1727591964.07735.data
/srv/node/`obs2`/objects/317/0fe/13d34c83bb5eed122321759e90f6e0fe/1727591964.07735.data
OpenStack编排管理-heat
heat作用
Heat是一种通过OpenStack原生REST API使用声明性模板格式编排复合云应用程序的服务,提供与其他OpenStack核心项目的紧密集成
- Heat模板以文本文件的形式描述了云应用程序的基础架构,文本文件可供用户读写,并且支持通过版本控制工具进行管理
- Heat模板指定资源之间的关系,使得Heat能够调用OpenStack API以正确的顺序创建用户所需的基础架构,从而完全启动用户的应用程序
heat与其他服务之间的关系

•Heat是位于Nova、Neutron等服务之上的一个组件,它充当了OpenStack对外接口的角色,用户不需要直接接触OpenStack其他服务,只需把对各种资源的需求写在Heat模版里,Heat就会自动调用相关服务的接口来配置资源,从而满足用户的需求。
heat架构

•用户在Horizon中或者命令行中提交包含模板和参数输入的请求,Horizon或者命令行工具会把请求转化为REST格式的API调用,然后调用Heat-api或者是Heat-api-cfn。Heat-api 和Heat-api-cfn会验证模板的正确性,然后通过消息队列传递给Heat Engine来处理请求。
•Heat中的模板是OpenStack资源的集合(虚拟机、网络、存储、告警、浮动IP、安全组、伸缩组、嵌套stack等),通过定义模板,可以将需要创建的资源在模板中描述,用此模板可以多次创建需要的资源。
heat组件

•Heat-api:提供REST API服务,是其他组件与Heat交互的入口,接收API请求并传送给heat-engine。
•Heat-api-cfn:提供兼容AWS CloudFormation的API,接收API请求并转发给heat-engine。
•Heat-engine:Heat的核心,主要实现任务调度、资源生命周期管理等作用,自身并不提供资源创建功能,只负责编排资源后交由其他组件去处理。
#查看heat相关进程
[root@controller ~]# ps -e | grep heat
1721 ? 00:00:02 heat-api-cfn
1722 ? 00:00:02 heat-api
1776 ? 00:00:08 heat-engine
2717 ? 00:00:00 heat-api-cfn
2722 ? 00:00:00 heat-api-cfn
2728 ? 00:00:00 heat-api-cfn
2730 ? 00:00:00 heat-api-cfn
2751 ? 00:00:00 heat-api
2752 ? 00:00:00 heat-api
2754 ? 00:00:00 heat-api
2756 ? 00:00:00 heat-api
3048 ? 00:00:00 heat-engine
3056 ? 00:00:00 heat-engine
3057 ? 00:00:00 heat-engine
3059 ? 00:00:00 heat-engine
#查看heat相关服务
[root@controller ~]# systemctl status openstack-heat-*
heat engine架构

heat模板

Heat模板默认编写语言-YAML语法
- YAML Ain’t Markup Language
- 使用缩进(一个或多个空格)排版
- 序列项用短划线表示
- MAP中的key-value对用冒号表示
heat模板结构

heat web实验
前期工作:


创建网络




查看刚才创建的网络

记录public_net id:

创建image

记录image id


编写hot模板
把下面这段写到heat.txt文件中
heat.txt
heat_template_version: 2018-08-31
description: Simple template to deploy a stack with one virtual machine instances
parameters:
image_name_1:
type: string
label: Image ID
description: SCOIMAGE Specify an image name for instance1
default: 732c9cee-2652-4a4e-8c09-19745d6e15b5 #替换自己的image id
public_net:
type: string
label: Network ID
description: SCONETWORK Network to be used for the compute instance
default: a6e27f03-e762-4c46-a997-a7a6848d5849 #替换自己的外网 id
resources:
mykey:
type: OS::Nova::KeyPair
properties:
save_private_key: true
name: mykey
web_secgroup:
type: OS::Neutron::SecurityGroup
properties:
rules:
- protocol: tcp
remote_ip_prefix: 0.0.0.0/0
port_range_min: 22
port_range_max: 22
- protocol: icmp
private_net:
type: OS::Neutron::Net
properties:
name: private_net
private_subnet:
type: OS::Neutron::Subnet
properties:
network_id: { get_resource: private_net }
cidr: "192.168.99.0/24"
ip_version: 4
vrouter:
type: OS::Neutron::Router
properties:
external_gateway_info:
network: { get_param: public_net }
vrouter_interface:
type: OS::Neutron::RouterInterface
properties:
router_id: { get_resource: vrouter }
subnet_id: { get_resource: private_subnet }
instance_port:
type: OS::Neutron::Port
properties:
network: { get_resource: private_net }
security_groups:
- default
- { get_resource: web_secgroup }
fixed_ips:
- subnet_id: { get_resource: private_subnet }
floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network_id: { get_param: public_net }
association:
type: OS::Neutron::FloatingIPAssociation
properties:
floatingip_id: { get_resource: floating_ip }
port_id: { get_resource: instance_port }
instance1:
type: OS::Nova::Server
properties:
image: { get_param: image_name_1 }
key_name: { get_resource: mykey }
flavor: Flavor_web #替换自己创建的flavor名字
networks:
- port : { get_resource : instance_port }
outputs:
private_key:
description: Private key
value: { get_attr: [ mykey, private_key ] }
创建堆栈:


选择heat.txt


创建完成


OpenStack网络管理-neutron
物理网络与虚拟网络区别

Switch:物理交换机
vSwitch:虚拟交换机
NIC:网络接口卡、网络适配器、网卡
vNIC:虚拟网卡
Switch有很多品牌:cisco、华为
vSwitch有很多软件:linuxbridge、ovs、ovn
•Neutron最为核心的工作是对二层物理网络的抽象与管理,物理服务器虚拟化后,虚拟机的网络功能由虚拟网卡(vNIC)和虚拟交换机提供,各个vNIC连接在vSwitch的端口上,最后这些vSwitch通过物理服务器的物理网卡访问外部的物理网络。
Linux网络虚拟化技术
网卡虚拟化:
- TAP
- TUN
- VETH PAIR
交换机虚拟化:
- linux bridge
- open vswitch
网络隔离:
- network namespace
Linux网卡虚拟化TAP/TUN/VETH

TAP设备:模拟一个二层的网络设备,可以接收和发送二层网包
TUN设备:模拟一个三层的网络设备,可以接收和发送三层网包
VETH:虚拟ethernet接口,通常以pair的方式出现,一端发出的网包,会被另一端接收,可以形成两个网桥之间的通道
•TAP/TUN提供了一台主机内用户空间的数据传输机制。它虚拟了一套网络接口,这套接口和物理的接口无任何区别,可以配置IP,可以路由流量,不同的是,它的流量只在主机内流通。
•TAP/TUN有些许的不同,TUN只操作三层的IP包,而TAP操作二层的以太网帧。
•Veth-Pair是成对出现的一种虚拟网络设备,一端连接着协议栈,一端连接着彼此,数据从一端出,从另一端进。它的这个特性常常用来连接不同的虚拟网络组件,构建大规模的虚拟网络拓扑,比如连接Linux Bridge、OVS、LXC容器等。一个很常见的案例就是它被用于OpenStack Neutron,构建非常复杂的网络形态。
Linux bridge

Linux bridge:工作于二层的网络设备,功能类似于物理交换机
Bridge可以绑定Linux上的其他网络设备,并将这些设备虚拟化为端口
当一个设备被绑定到bridge时,就相当于物理交换机端口插入了一条连接着终端的网线
使用brctl命令配置Linux bridge:
brctl addbr BRIDGE
brctl addif BRIDGE DEVICE
•Linux Bridge结构如上图所示,Bridge设备br0绑定了实际设备eth0与虚拟设备tap0和tap1,但是对于Hypervisor的网络协议栈上层来说,只能看到br0,并不会关心桥接的细节。
•当这些设备接收到数据包时,会将其提交给br0决定数据包的去向,br0会根据MAC地址与端口的映射关系进行转发。
•因为Bridge工作在二层,所以绑定在br0上的从设备eth0、tap0与tap1均不需要再设置IP地址,对于上层路由器来说,它们都位于同一子网,因此只需为br0设置IP地址。因为br0具有自己的IP地址,br0可以被加入路由表,并利用它来发送数据,但是最终实际的发送过程则是由某个从设备来完成。
•即使eth0原本具有自己的IP地址,但是在被绑定到br0上后,它的IP地址会失效,用户程序不能接收到这个IP地址的数据。只有目的地址为br0的IP地址的数据包才会被Linux接收。
•brctl addbr BRIDGE:表示添加BRIDGE。
•brctl addif BRIDGE DEVICE:表示添加接口到bridge。
OVS

Open vSwitch是产品级的虚拟交换机
Linux bridge更适用于小规模,主机内部间通信场景
Open vSwitch更适合于大规模、多主机间通信场景
华为的FusionCompute用的就是DVS(基于EVS,EVS基于OVS)
Open vSwitch常用的命令:
- ovs-vsctl add-br BRIDGE
- ovs-vsctl add-port PORT
- ovs-vsctl show BRIDGE
- ovs-vsctl dump-ports-desc BRIDGE
- ovs-vsctl dump-flows BRIDGE
•Open vSwitch负责连接vNIC与物理网卡,同时桥接同一物理Server内的各个vNIC。其实Linux Bridge已经能够很好地充当这样的角色,为什么我们还需要Open vSwitch?
•因为Open vSwitch的引入使得云环境中对虚拟网络的管理及对网络状态和流量的监控变得更容易。
•我们可以像配置物理交换机一样,将接入Open vSwitch的各个VM分配到不同的VLAN中以实现网络的隔离。我们也可以在Open vSwitch端口上为VM配置QoS,同时Open vSwitch也支持包括NetFlow、sFlow等很多标准的管理接口和协议,我们可以通过这些接口完成流量监控等工作。
•Open vSwitch在云环境中的各种虚拟化平台(如Xen与KVM)上实现了分布式的虚拟交换机(Distributed Virtual Switch),一个物理Server上的vSwitch可以透明地与另一个物理Server上的vSwitch连接在一起。
Neutron功能概述
从今天开始,我们将学习 OpenStack 的 Networking Service,Neutron。
Neutron 的难度会比前面所有模块都大一些,内容也多一些。为了帮助大家更好的掌握 Neutorn,也会分析地更详细一些。
Neutron 概述
传统的网络管理方式很大程度上依赖于管理员手工配置和维护各种网络硬件设备;而云环境下的网络已经变得非常复杂,特别是在多租户场景里,用户随时都可能需要创建、修改和删除网络,网络的连通性和隔离不已经太可能通过手工配置来保证了。
如何快速响应业务的需求对网络管理提出了更高的要求。传统的网络管理方式已经很难胜任这项工作,而“软件定义网络(software-defined networking, SDN)”所具有的灵活性和自动化优势使其成为云时代网络管理的主流。
Neutron 的设计目标是实现“网络即服务(Networking as a Service)”。为了达到这一目标,在设计上遵循了基于 SDN 实现网络虚拟化的原则,在实现上充分利用了 Linux 系统上的各种网络相关的技术。
在这一章,我们将讨论 Neutron 的功能和它的各个组件,学习部署和配置 OpenStack 网络的不同方法,会涉及软件和硬件设备多个层面。
Neutron 功能
Neutron 为整个 OpenStack 环境提供网络支持,包括二层交换,三层路由,负载均衡,防火墙和 VPN 等。Neutron 提供了一个灵活的框架,通过配置,无论是开源还是商业软件都可以被用来实现这些功能。
二层交换 Switching
Nova 的 Instance 是通过虚拟交换机连接到虚拟二层网络的。Neutron 支持多种虚拟交换机,包括 Linux 原生的 Linux Bridge 和 Open vSwitch。 Open vSwitch(OVS)是一个开源的虚拟交换机,它支持标准的管理接口和协议。
利用 Linux Bridge 和 OVS,Neutron 除了可以创建传统的 VLAN 网络,还可以创建基于隧道技术的 Overlay 网络,比如 VxLAN 和 GRE(Linux Bridge 目前只支持 VxLAN)。在后面章节我们会学习如何使用和配置 Linux Bridge 和 Open vSwitch。
三层路由 Routing
Instance 可以配置不同网段的 IP,Neutron 的 router(虚拟路由器)实现 instance 跨网段通信。router 通过 IP forwarding,iptables 等技术来实现路由和 NAT。我们将在后面章节讨论如何在 Neutron 中配置 router 来实现 instance 之间,以及与外部网络的通信。
负载均衡 Load Balancing
Openstack 在 Grizzly 版本第一次引入了 Load-Balancing-as-a-Service(LBaaS),提供了将负载分发到多个 instance 的能力。LBaaS 支持多种负载均衡产品和方案,不同的实现以 Plugin 的形式集成到 Neutron,目前默认的 Plugin 是 HAProxy。我们会在后面章节学习 LBaaS 的使用和配置。
防火墙 Firewalling
Neutron 通过下面两种方式来保障 instance 和网络的安全性。
Security Group
通过 iptables 限制进出 instance 的网络包。
**Firewall-as-a-Service
**FWaaS,限制进出虚拟路由器的网络包,也是通过 iptables 实现。
Neutron网络基本概念
上次我们讨论了 Neutron 提供的功能,接下来我们学习 Neutron 模块几个重要的概念。Neutron 管理的网络资源包括 Network,subnet 和 port,下面依次介绍。
network
network 是一个隔离的二层广播域。Neutron 支持多种类型的 network,包括 local, flat, VLAN, VxLAN 和 GRE。
local
local 网络与其他网络和节点隔离。local 网络中的 instance 只能与位于同一节点上同一网络的 instance 通信,local 网络主要用于单机测试。
flat
flat 网络是无 vlan tagging 的网络。flat 网络中的 instance 能与位于同一网络的 instance 通信,并且可以跨多个节点。
vlan
vlan 网络是具有 802.1q tagging 的网络。vlan 是一个二层的广播域,同一 vlan 中的 instance 可以通信,不同 vlan 只能通过 router 通信。vlan 网络可跨节点,是应用最广泛的网络类型。
vxlan
vxlan 是基于隧道技术的 overlay 网络。vxlan 网络通过唯一的 segmentation ID(也叫 VNI)与其他 vxlan 网络区分。vxlan 中数据包会通过 VNI 封装成 UDP 包进行传输。因为二层的包通过封装在三层传输,能够克服 vlan 和物理网络基础设施的限制。
gre
gre 是与 vxlan 类似的一种 overlay 网络。主要区别在于使用 IP 包而非 UDP 进行封装。

不同 network 之间在二层上是隔离的。
以 vlan 网络为例,network A 和 network B 会分配不同的 VLAN ID,这样就保证了 network A 中的广播包不会跑到 network B 中。当然,这里的隔离是指二层上的隔离,借助路由器不同 network 是可能在三层上通信的。
network 必须属于某个 Project( Tenant 租户),Project 中可以创建多个 network。Project 与 network 之间是 1对多关系。
subnet
subnet 是一个 IPv4 或者 IPv6 地址段。instance 的 IP 从 subnet 中分配。每个 subnet 需要定义 IP 地址的范围和掩码。
network 与 subnet 是 1对多 关系。一个 subnet 只能属于某个 network;一个 network 可以有多个 subnet,这些 subnet 可以是不同的 IP 段,但不能重叠。下面的配置是有效的:
network A subnet A-a: 10.10.1.0/24 {“start”: “10.10.1.1”, “end”: “10.10.1.50”}
subnet A-b: 10.10.2.0/24 {“start”: “10.10.2.1”, “end”: “10.10.2.50”}
但下面的配置则无效,因为 subnet 有重叠
networkA subnet A-a: 10.10.1.0/24 {“start”: “10.10.1.1”, “end”: “10.10.1.50”}
subnet A-b: 10.10.1.0/24 {“start”: “10.10.1.51”, “end”: “10.10.1.100”}
这里不是判断 IP 是否有重叠,而是 subnet 的 CIDR 重叠(都是 10.10.1.0/24)。但是,如果 subnet 在不同的 network 中,CIDR 和 IP 都是可以重叠的,比如
network A subnet A-a: 10.10.1.0/24 {“start”: “10.10.1.1”, “end”: “10.10.1.50”}
networkB subnet B-a: 10.10.1.0/24 {“start”: “10.10.1.1”, “end”: “10.10.1.50”}
这里大家不免会疑惑: 如果上面的IP地址是可以重叠的,那么就可能存在具有相同 IP 的两个 instance,这样会不会冲突? 简单的回答是:不会!
具体原因: 因为 Neutron 的 router 是通过 Linux network namespace 实现的。network namespace 是一种网络的隔离机制。通过它,每个 router 有自己独立的路由表。上面的配置有两种结果:
-
如果两个 subnet 是通过同一个 router 路由,根据 router 的配置,只有指定的一个 subnet 可被路由。
-
如果上面的两个 subnet 是通过不同 router 路由,因为 router 的路由表是独立的,所以两个 subnet 都可以被路由。
这里只是先简单做个说明,我们会在后面三层路由的章节详细分析这种场景。
port
port 可以看做虚拟交换机上的一个端口。port 上定义了 MAC 地址和 IP 地址,当 instance 的虚拟网卡 VIF(Virtual Interface) 绑定到 port 时,port 会将 MAC 和 IP 分配给 VIF。
subnet 与 port 是 1对多 关系。一个 port 必须属于某个 subnet;一个 subnet 可以有多个 port。
小节
下面总结了 Project,Network,Subnet,Port 和 VIF 之间关系。
Project 1 : m Network 1 : m Subnet 1 : m Port 1 : 1 VIF m : 1 Instance
下一节我们讨论 Neutron 的架构。
Neutron架构
前面我们讨论了 Neutron 的基本概念,接下来我们开始分析 Neutron 的架构。
Neutron 架构
与 OpenStack 的其他服务的设计思路一样,Neutron 也是采用分布式架构,由多个组件(子服务)共同对外提供网络服务。

Neutron 由如下组件构成:
Neutron Server
对外提供 OpenStack 网络 API,接收请求,并调用 Plugin 处理请求。
Plugin
处理 Neutron Server 发来的请求,维护 OpenStack 逻辑网络状态, 并调用 Agent 处理请求。
Agent
处理 Plugin 的请求,负责在 network provider 上真正实现各种网络功能。
network provider
提供网络服务的虚拟或物理网络设备,例如 Linux Bridge,Open vSwitch 或者其他支持 Neutron 的物理交换机。
Queue
Neutron Server,Plugin 和 Agent 之间通过 Messaging Queue 通信和调用。
Database
存放 OpenStack 的网络状态信息,包括 Network, Subnet, Port, Router 等。
[root@controller ~(keystone_admin)]# mysql
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 8516
Server version: 10.3.10-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)]> use neutron;
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 [neutron]> show tables;
+-----------------------------------------+
| Tables_in_neutron |
+-----------------------------------------+
| address_scopes |
| agents |
| alembic_version |
| allowedaddresspairs |
| arista_provisioned_nets |
| arista_provisioned_tenants |
| arista_provisioned_vms |
| auto_allocated_topologies |
| bgp_peers |
| bgp_speaker_dragent_bindings |
| bgp_speaker_network_bindings |
| bgp_speaker_peer_bindings |
| bgp_speakers |
| brocadenetworks |
| brocadeports |
| cisco_csr_identifier_map |
| cisco_hosting_devices |
| cisco_ml2_apic_contracts |
| cisco_ml2_apic_host_links |
| cisco_ml2_apic_names |
| cisco_ml2_n1kv_network_bindings |
| cisco_ml2_n1kv_network_profiles |
| cisco_ml2_n1kv_policy_profiles |
| cisco_ml2_n1kv_port_bindings |
| cisco_ml2_n1kv_profile_bindings |
| cisco_ml2_n1kv_vlan_allocations |
| cisco_ml2_n1kv_vxlan_allocations |
| cisco_ml2_nexus_nve |
| cisco_ml2_nexusport_bindings |
| cisco_port_mappings |
| cisco_router_mappings |
| consistencyhashes |
| default_security_group |
| dnsnameservers |
| dvr_host_macs |
| externalnetworks |
| extradhcpopts |
| firewall_policies |
| firewall_rules |
| firewalls |
| flavors |
| flavorserviceprofilebindings |
| floatingipdnses |
| floatingips |
| ha_router_agent_port_bindings |
| ha_router_networks |
| ha_router_vrid_allocations |
| healthmonitors |
| ikepolicies |
| ipallocationpools |
| ipallocations |
| ipamallocationpools |
| ipamallocations |
| ipamsubnets |
| ipsec_site_connections |
| ipsecpeercidrs |
| ipsecpolicies |
| logs |
| lsn |
| lsn_port |
| maclearningstates |
| members |
| meteringlabelrules |
| meteringlabels |
| ml2_brocadenetworks |
| ml2_brocadeports |
| ml2_distributed_port_bindings |
| ml2_flat_allocations |
| ml2_geneve_allocations |
| ml2_geneve_endpoints |
| ml2_gre_allocations |
| ml2_gre_endpoints |
| ml2_nexus_vxlan_allocations |
| ml2_nexus_vxlan_mcast_groups |
| ml2_port_binding_levels |
| ml2_port_bindings |
| ml2_ucsm_port_profiles |
| ml2_vlan_allocations |
| ml2_vxlan_allocations |
| ml2_vxlan_endpoints |
| multi_provider_networks |
| network_segment_ranges |
| networkconnections |
| networkdhcpagentbindings |
| networkdnsdomains |
| networkgatewaydevicereferences |
| networkgatewaydevices |
| networkgateways |
| networkqueuemappings |
| networkrbacs |
| networks |
| networksecuritybindings |
| networksegments |
| neutron_nsx_network_mappings |
| neutron_nsx_port_mappings |
| neutron_nsx_router_mappings |
| neutron_nsx_security_group_mappings |
| nexthops |
| nsxv_edge_dhcp_static_bindings |
| nsxv_edge_vnic_bindings |
| nsxv_firewall_rule_bindings |
| nsxv_internal_edges |
| nsxv_internal_networks |
| nsxv_port_index_mappings |
| nsxv_port_vnic_mappings |
| nsxv_router_bindings |
| nsxv_router_ext_attributes |
| nsxv_rule_mappings |
| nsxv_security_group_section_mappings |
| nsxv_spoofguard_policy_network_mappings |
| nsxv_tz_network_bindings |
| nsxv_vdr_dhcp_bindings |
| nuage_net_partition_router_mapping |
| nuage_net_partitions |
| nuage_provider_net_bindings |
| nuage_subnet_l2dom_mapping |
| poolloadbalanceragentbindings |
| poolmonitorassociations |
| pools |
| poolstatisticss |
| portbindingports |
| portdataplanestatuses |
| portdnses |
| portforwardings |
| portqueuemappings |
| ports |
| portsecuritybindings |
| portuplinkstatuspropagation |
| providerresourceassociations |
| provisioningblocks |
| qos_bandwidth_limit_rules |
| qos_dscp_marking_rules |
| qos_fip_policy_bindings |
| qos_minimum_bandwidth_rules |
| qos_network_policy_bindings |
| qos_policies |
| qos_policies_default |
| qos_port_policy_bindings |
| qos_router_gw_policy_bindings |
| qospolicyrbacs |
| qosqueues |
| quotas |
| quotausages |
| reservations |
| resourcedeltas |
| router_extra_attributes |
| routerl3agentbindings |
| routerports |
| routerroutes |
| routerrules |
| routers |
| securitygroupportbindings |
| securitygrouprbacs |
| securitygrouprules |
| securitygroups |
| segmenthostmappings |
| serviceprofiles |
| sessionpersistences |
| standardattributes |
| subnet_service_types |
| subnetpoolprefixes |
| subnetpools |
| subnetroutes |
| subnets |
| subports |
| tags |
| trunks |
| tz_network_bindings |
| vcns_router_bindings |
| vips |
| vpnservices |
+-----------------------------------------+
171 rows in set (0.001 sec)
OVN网络整体实验
[root@controller ~]# source keystonerc_admin
[root@controller ~(keystone_admin)]# openstack network agent list
+--------------------------------------+----------------------+------------+-------------------+-------+-------+----------------------------+
| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
+--------------------------------------+----------------------+------------+-------------------+-------+-------+----------------------------+
| 6e7f51ef-117d-4b7f-b650-599aa5a3cfd7 | OVN Controller agent | compute | | :-) | UP | ovn-controller |
| b1374481-f227-5e89-9a3f-8a3708d59251 | OVN Metadata agent | compute | | :-) | UP | neutron-ovn-metadata-agent |
| 46cd64c9-2f35-4dfb-9351-e0b1693daf8b | OVN Controller agent | controller | | :-) | UP | ovn-controller |
| 497883dc-f0f1-5780-87b4-630075557d30 | OVN Metadata agent | controller | | :-) | UP | neutron-ovn-metadata-agent |
+--------------------------------------+----------------------+------------+-------------------+-------+-------+----------------------------+
确认配置
[root@controller ~]# vim /etc/neutron/plugins/ml2/ml2_conf.ini
#按G跳到末尾
[ml2]
type_drivers=geneve,flat
tenant_network_types=geneve
mechanism_drivers=ovn
path_mtu=0
extension_drivers=port_security,qos
[securitygroup]
enable_security_group=True
[ml2_type_geneve]
max_header_size=38
vni_ranges=10:100
[ml2_type_flat]
flat_networks=*
[ovn]
ovn_nb_connection=tcp:192.168.108.10:6641
ovn_sb_connection=tcp:192.168.108.10:6642
ovn_metadata_enabled=True
创建外部网络




#查看现象
[root@controller ~]# ovn-nbctl show
switch e69d7e37-9a0d-4abe-81c8-9d10c2246178 (neutron-e79063ae-1291-42b2-8519-ec0ce0a421e1) (aka waiwang)
port 43b284b0-ebc8-4bd3-8c59-77dcec8d33dd
type: localport
addresses: ["fa:16:3e:be:d3:41 192.168.108.100"]
port provnet-50a84802-b570-4cad-be3e-cb934c259c48
type: localnet
addresses: ["unknown"]
创建内网neiwang-1,192.168.11.0/24




查看现象:
[root@controller ~]# ovn-nbctl show
switch 9e269a0c-5049-4c20-b602-ce42d722017c (neutron-c5a25fa7-559f-4e62-8bf0-7ebcd8c8a1f1) (aka neiwang-1)
port 3b975511-7c63-495e-969c-1424e69770dc
type: localport
addresses: ["fa:16:3e:dd:ea:9d 192.168.11.2"]
switch e69d7e37-9a0d-4abe-81c8-9d10c2246178 (neutron-e79063ae-1291-42b2-8519-ec0ce0a421e1) (aka waiwang)
port 43b284b0-ebc8-4bd3-8c59-77dcec8d33dd
type: localport
addresses: ["fa:16:3e:be:d3:41 192.168.108.100"]
port provnet-50a84802-b570-4cad-be3e-cb934c259c48
type: localnet
addresses: ["unknown"]
创建路由器router1,连接内网与外网




观察现象

[root@controller ~]# ovn-nbctl show
switch 9e269a0c-5049-4c20-b602-ce42d722017c (neutron-c5a25fa7-559f-4e62-8bf0-7ebcd8c8a1f1) (aka neiwang-1)
port 9da6f7af-22e3-44fc-8465-90334f8abeea
type: router
router-port: lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
port 3b975511-7c63-495e-969c-1424e69770dc
type: localport
addresses: ["fa:16:3e:dd:ea:9d 192.168.11.2"]
switch e69d7e37-9a0d-4abe-81c8-9d10c2246178 (neutron-e79063ae-1291-42b2-8519-ec0ce0a421e1) (aka waiwang)
port 43b284b0-ebc8-4bd3-8c59-77dcec8d33dd
type: localport
addresses: ["fa:16:3e:be:d3:41 192.168.108.100"]
port c0354999-1e15-436f-b15f-be2d3b17c5b4
type: router
router-port: lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
port provnet-50a84802-b570-4cad-be3e-cb934c259c48
type: localnet
addresses: ["unknown"]
router 9374d9e7-b8b0-4d6e-924d-c9fdef6662e5 (neutron-a75adc8f-9668-4fe1-b6eb-b4573d574ae0) (aka router1)
port lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
mac: "fa:16:3e:78:18:6c"
networks: ["192.168.11.1/24"]
port lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
mac: "fa:16:3e:82:b8:23"
networks: ["192.168.108.185/24"]
gateway chassis: [46cd64c9-2f35-4dfb-9351-e0b1693daf8b]
nat d6fae190-e948-475c-b5b1-a9258a8b7c65
external ip: "192.168.108.185"
logical ip: "192.168.11.0/24"
type: "snat"
创建两实例绑到neiwang-1
创建实例需要(镜像,规格,网络) 镜像 规格自定义,网络使用neiwang-1




此处网络一定要选择内网neiwang-1

效果如下


VM1 ping 通 VM2

观察OVN现象
[root@controller ~]# ovn-nbctl show
switch 9e269a0c-5049-4c20-b602-ce42d722017c (neutron-c5a25fa7-559f-4e62-8bf0-7ebcd8c8a1f1) (aka neiwang-1)
port 0e42719e-b450-4fbf-a222-be6402b2bb93
addresses: ["fa:16:3e:33:e8:8b 192.168.11.4"]
port 9da6f7af-22e3-44fc-8465-90334f8abeea
type: router
router-port: lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
port 3ff7bcb4-c9be-4e6d-b14c-cff503adfae6
addresses: ["fa:16:3e:bd:e5:c5 192.168.11.169"]
port 3b975511-7c63-495e-969c-1424e69770dc
type: localport
addresses: ["fa:16:3e:dd:ea:9d 192.168.11.2"]
switch e69d7e37-9a0d-4abe-81c8-9d10c2246178 (neutron-e79063ae-1291-42b2-8519-ec0ce0a421e1) (aka waiwang)
port 43b284b0-ebc8-4bd3-8c59-77dcec8d33dd
type: localport
addresses: ["fa:16:3e:be:d3:41 192.168.108.100"]
port c0354999-1e15-436f-b15f-be2d3b17c5b4
type: router
router-port: lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
port provnet-50a84802-b570-4cad-be3e-cb934c259c48
type: localnet
addresses: ["unknown"]
router 9374d9e7-b8b0-4d6e-924d-c9fdef6662e5 (neutron-a75adc8f-9668-4fe1-b6eb-b4573d574ae0) (aka router1)
port lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
mac: "fa:16:3e:78:18:6c"
networks: ["192.168.11.1/24"]
port lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
mac: "fa:16:3e:82:b8:23"
networks: ["192.168.108.185/24"]
gateway chassis: [46cd64c9-2f35-4dfb-9351-e0b1693daf8b]
nat d6fae190-e948-475c-b5b1-a9258a8b7c65
external ip: "192.168.108.185"
logical ip: "192.168.11.0/24"
type: "snat"
d722017c (neutron-c5a25fa7-559f-4e62-8bf0-7ebcd8c8a1f1) (aka neiwang-1)
port 9da6f7af-22e3-44fc-8465-90334f8abeea
type: router
router-port: lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
port 3b975511-7c63-495e-969c-1424e69770dc
type: localport
addresses: [“fa:16:3e:dd:ea:9d 192.168.11.2”]
switch e69d7e37-9a0d-4abe-81c8-9d10c2246178 (neutron-e79063ae-1291-42b2-8519-ec0ce0a421e1) (aka waiwang)
port 43b284b0-ebc8-4bd3-8c59-77dcec8d33dd
type: localport
addresses: [“fa:16:3e:be:d3:41 192.168.108.100”]
port c0354999-1e15-436f-b15f-be2d3b17c5b4
type: router
router-port: lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
port provnet-50a84802-b570-4cad-be3e-cb934c259c48
type: localnet
addresses: [“unknown”]
router 9374d9e7-b8b0-4d6e-924d-c9fdef6662e5 (neutron-a75adc8f-9668-4fe1-b6eb-b4573d574ae0) (aka router1)
port lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
mac: “fa:16:3e:78:18:6c”
networks: [“192.168.11.1/24”]
port lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
mac: “fa:16:3e:82:b8:23”
networks: [“192.168.108.185/24”]
gateway chassis: [46cd64c9-2f35-4dfb-9351-e0b1693daf8b]
nat d6fae190-e948-475c-b5b1-a9258a8b7c65
external ip: “192.168.108.185”
logical ip: “192.168.11.0/24”
type: “snat”
创建两实例绑到neiwang-1
创建实例需要(镜像,规格,网络) 镜像 规格自定义,网络使用neiwang-1
[外链图片转存中...(img-wWL36ez4-1779065923373)]
[外链图片转存中...(img-wSpX1AOA-1779065923373)]
[外链图片转存中...(img-JfAWWrHN-1779065923374)]
[外链图片转存中...(img-rzeODXuv-1779065923374)]
此处网络一定要选择内网neiwang-1
[外链图片转存中...(img-psp3qosc-1779065923374)]
效果如下
[外链图片转存中...(img-BsMQGuY8-1779065923374)]
[外链图片转存中...(img-cpMpTRmL-1779065923374)]
VM1 ping 通 VM2
[外链图片转存中...(img-xWmHO32x-1779065923374)]
观察OVN现象
```bash
[root@controller ~]# ovn-nbctl show
switch 9e269a0c-5049-4c20-b602-ce42d722017c (neutron-c5a25fa7-559f-4e62-8bf0-7ebcd8c8a1f1) (aka neiwang-1)
port 0e42719e-b450-4fbf-a222-be6402b2bb93
addresses: ["fa:16:3e:33:e8:8b 192.168.11.4"]
port 9da6f7af-22e3-44fc-8465-90334f8abeea
type: router
router-port: lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
port 3ff7bcb4-c9be-4e6d-b14c-cff503adfae6
addresses: ["fa:16:3e:bd:e5:c5 192.168.11.169"]
port 3b975511-7c63-495e-969c-1424e69770dc
type: localport
addresses: ["fa:16:3e:dd:ea:9d 192.168.11.2"]
switch e69d7e37-9a0d-4abe-81c8-9d10c2246178 (neutron-e79063ae-1291-42b2-8519-ec0ce0a421e1) (aka waiwang)
port 43b284b0-ebc8-4bd3-8c59-77dcec8d33dd
type: localport
addresses: ["fa:16:3e:be:d3:41 192.168.108.100"]
port c0354999-1e15-436f-b15f-be2d3b17c5b4
type: router
router-port: lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
port provnet-50a84802-b570-4cad-be3e-cb934c259c48
type: localnet
addresses: ["unknown"]
router 9374d9e7-b8b0-4d6e-924d-c9fdef6662e5 (neutron-a75adc8f-9668-4fe1-b6eb-b4573d574ae0) (aka router1)
port lrp-9da6f7af-22e3-44fc-8465-90334f8abeea
mac: "fa:16:3e:78:18:6c"
networks: ["192.168.11.1/24"]
port lrp-c0354999-1e15-436f-b15f-be2d3b17c5b4
mac: "fa:16:3e:82:b8:23"
networks: ["192.168.108.185/24"]
gateway chassis: [46cd64c9-2f35-4dfb-9351-e0b1693daf8b]
nat d6fae190-e948-475c-b5b1-a9258a8b7c65
external ip: "192.168.108.185"
logical ip: "192.168.11.0/24"
type: "snat"
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)