OpenStack管理
摘要:本文全面介绍了OpenStack认证管理服务Keystone的核心概念与实践操作。首先详细解析了Keystone的八大基本概念(Domain、User、Group、Project、Role、Service、Endpoint、Token、Credential)及其相互关系,然后通过命令行实操演示了域管理、用户管理、组管理、项目创建与配额设置等关键操作。接着深入剖析了Keystone的三大核心功能:用户权限管理、服务端点维护、认证与鉴权,并详细解释了User、Credentials、Authentication、Token、Project、Service、Endpoint、Role等核心概念的工作机制。最后通过"查询可用image"的实际操作示例,完整展示了OpenStack内部认证流程,包括登录验证、Token获取、服务端点访问和权限验证等关键步骤,帮助读者建立对Keystone认证体系的系统性理解。
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)]# lscinder_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支持多域83OPENSTACK_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 user1user1ingroup 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修改配额实验现象:
使用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:
三个入口:admin\public\internal
查看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)]# lskeystone.log如果需要得到最详细的日志信息,可以在 /etc/keystone/keystone.conf 中打开 debug 选项
[root@controller keystone(keystone_admin)]# cd /etc/keystone/[root@controller keystone(keystone_admin)]# lsdefault_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行94debug=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返回创建成功信息给用户,用户即可使用虚拟机。