正确理解OpenStack 中角色的继承与隐含

作者: 王炳明 分类: OpenStack 发布时间: 2021-03-16 14:50 热度:554

1. user 、project 、domain 概念

  • user:实际操作资源的对象,也就是用户,相当于一个公司的员工
  • project:IT 基础设施资源的集合,注意 project 代表的是一系列资源,它相当于一个公司的部门
  • domain:是 project 和 user 的集合,本质上它也是代表着一系列资源的集合(从代码和数据库来看,domain 本身就只是一个特殊的 project 而已),在公有云或者私有云中常常表示一个客户。

2. user 、project 、domain 关系

user 和 project 是一对多的关系,一个用户可以拥有操作多个 project 的权限(注意:user 并不能说属于 project )

user 和 domain 是多对一的关系,一个 user 只能属于一个 domain(虽然不同 domain 下可以有同名的 user,但本质上来说是两个 user),但一个 domain 里可以有多个 user。

project 和 domain 也是 多对一的关系,一个 project 只能属于一个 domain (虽然不同 domain 下可以有同名的 project,但本质上来说是两个 project),但一个 domain 里可以有 多个 project。

3. 正确理解 Role 的用法

一个用户要想操作某个 domain 下的某个某个 project ,必须先对该用户授予访问该 project 的权限。

$ OpenStack role add --project <project> --user <user> <role>

Keystone 中的角色,只有两种类型:

  1. admin:管理员,固定以 admin 命名
  2. _member_:普通成员,只要不是admin的都是普通成员

目前 VMP 是每个用户创建一个 Role,实际上没有必要,因为在使用上面那条命令授权的时候,最后一个参数区分也只有两种,是 admin 和 不是 admin,如果不是 admin,而是普通成功,那么完全可以统一用 _member_ 这个 role,效果一样。

正确理解OpenStack 中角色的继承与隐含插图

4. 为什么要使用 Group ?

用户关联角色的方法有两种:

  1. 单个用户关联一个角色(上面已经介绍了)
  2. 多个用户组成一个 group 来关联角色

试想一下,如果有多个 user 想获得访问 project 的权限,那么角色授权的时候,要是还按照第一种方法去一个一个用户关联角色,就非常麻烦,并且你在使用命令 openstack role assignment list 去查看的时候,会查到非常多的规则,不容易阅读和理解。

$ openstack role add --project <project> --user <user> <role>

这时候就可以创建一个 group,然后将想访问某个 project 的 user 都加入这个 group,然后就可以在关联角色时指定 group 来授权了

$ openstack help group create <group_name>
$ openstack role add --project <project> --group <group_name> <role>

以后如果有某个新增用户想访问这个 project,也只要往 group 里加 user 就行了,同样地,要访问取消某用户对该 project 的授权,也只要从该 group 中剔除该用户即可,如此一来就实现了角色动态关联。

5. Token Scope 是什么

当你在创建 token 的时候,除了要提供用户及密码之外 ,可能还要指定 scope,详细的接口说明请访问:OpenStack API Documentation

根据 scope 的不同,token 可以分为 unscoped token,domain-scoped token 和 project-scoped token。

  • project-scoped token:针对一个 project 的 token
  • domain-scoped token:针对一个 domain 的 token,它具有有限的使用场景,只用于 domain 层面的操作。与 project-scoped 相比,它只具有优先的 sevice catalog
  • unscoped token:当既不指定 project 也不指定 domain 为 scope ,同时 user 也没有 default project 时获得的 token,这是一种特殊的token。

如果携带了一个 domain 的 domain token,并不是说就能访问该 domain 下的所有 project 的资源,因此类似虚拟机这种是直接属于 某个 project 的,才间接属于某个 domain 的。

6. Domain:特殊的 Project

从 keystone 的数据库表来看,并没有专门的 domain 表,所有的 domain 都是和 project 放在 project 表中的,使用如下这条命令就可以查询到所有的 domain 了。

select * from project where parent_id is NULL AND is_domain=1;

Domain 实际上也是 Project,只不过他比较特殊,是最顶层的 Project

什么是最顶层?

在 project 里,有父与子的关系,通过 parent_id 这个属性来体现,从下图可以看出有很多的 project 的 父 project 都是 default,而 default 应该很熟悉了,他是默认的 domain。

正确理解OpenStack 中角色的继承与隐含插图(1)

在 vmp 集群里,目前有三个 domain,其中 default 是默认的 domain,另外两个是后面加上去的。

正确理解OpenStack 中角色的继承与隐含插图(2)

7. 帐户分级的支持

7.1 角色的继承

由于有了 Project 的父子分级的概念,再配合角色的继承功能,帐户分级就不难实现了。

Project 的父子分级上面已经介绍了,这边再介绍一下继承是如何操作的。

假设,现在有 parent-project 以它的两个子 project,分别是 sub-project-01和 sub-project-02。

并且有一个 parent-user01 拥有对 parent-project 的访问权限,而 sub-user01 可以访问 sub-project-01 ,sub-user02 可以访问 sub-project-02 。

我们的目标是:

  1. 拥有 parent-project 访问权限的 parent-user01,也要能访问它的两个子 project 。
  2. 并且后续基于 parent-project 创建的 子project,在不重新角色分配的情况下也同样能生效

方法很简单,在 parent-user01 在角色授权的时候,要执行两条命令。

  1. 一条不加 --inherited,表示 parent-user01 拥有对 parent-project 的访问权限
  2. 一条加 --inherited,表示 parent-user01 拥有对 parent-project 的所有子 project 的权限

当你加了第二条后,使用常规的命令查看,规则仍然只新增了一条。

但是如果加上 --effective 后,就会发现,这条命令会自动拆解成两条命令,每一条对应该 用户拥有对应的 project 的访问权限。

为什么是两条?因为我这边的 parent-project 下只建了两个 子 project。

正确理解OpenStack 中角色的继承与隐含插图(3)

这个 自动拆解的命令是动态生成的,不管你在什么时候,创建的子project,都会生效。

7.2 角色的隐含

要想让一个用户既拥有 admin 的权限,又拥有某个 project 的普通成员的权限,正常情况下,会创建两条规则。

但是实际不用,因为在 keystone 的角色中,还有一个隐式角色的概念。

可以让一个普通用户同时拥有另一个身份,也就是 admin 的权限。

为此,角色可以分为两种

  • 显式角色:直接指明某个用户拥有访问哪个资源的权限
  • 隐式角色:由配置推断出来的,该用户还拥有访问哪个资源的权限

要想开启隐式角色,需要进行一些配置,确保 /etc/keystone/keystone.conf如下配置,这个配置控制着一个角色是否应该包含没有那些直接指定的 token scope,相应于一个开关,默认就是开着的。

[token]
infer_roles = true

如果你不想某些角色被隐含,可以在配置中声明哪些角色不应该被隐含。/etc/keystone/keystone.conf

[assignment]
prohibited_implied_role = admin

CLI 命令,并不能创建隐含关系,只能使用 curl 命令。在下面这条命令中,前面是 admin 的 role,后面是 _member_ 的 role,表示拥有了 admin 权限的一定拥有 普通 _member_ 的权限。

curl -X PUT  -H "X-Auth-Token: OS_TOKEN" -H "Content-type: application/json"OS_AUTH_URL/roles/9b821b2920544be7a4d8f71fa99fcd35/implies/9fe2ff9ee4384b1894a90878d3e92bab

隐式角色在查看的时候,同样也是需要加 --effective 参数的。

8. 参考文章

  1. PROJECT MANAGEMENT
  2. OpenStack API Documentation
  3. OpenStack Mitaka 版本中的 domain 和 admin
明哥公众号

文章有帮助,请作者喝杯咖啡?

发表评论