OpenStack Mitaka 版本中的 domain 和 admin详解

2025-05-27 0 71

openstack 的 keystone v3 中引入了 domain 的概念。引入这个概念后,关于 admin 这个role 的定义就变得复杂了起来。

本文测试环境是社区 mitaka 版本。

1. domain,project,user,role,token 的概念和关系

1.1 概况

简单来说,

  • domain – 表示 project 和 user 的集合,在公有云或者私有云中常常表示一个客户
  • group – 一个domain 中的部分用户的集合
  • project – it基础设施资源的集合,比如虚机,卷,镜像等
  • role – 角色,表示一个 user 对一个 project resource 的权限
  • token – 一个 user 对于某个目标(project 或者 domain)的一个有限时间段内的身份令牌

它们之间的关系用一个不完整的图来表示:

OpenStack Mitaka 版本中的 domain 和 admin详解

说明:

  1. domain 可以认为是 project,user,group 的 namespace。 一个 domain 内,这些元素的名称不可以重复,但是在两个不同的domain内,它们的名称可以重复。因此,在确定这些元素时,需要同时使用它们的名称和它们的 domain 的 id 或者 name。

  2. group 是一个 domain 部分 user 的集合,其目的是为了方便分配 role。给一个 group 分配 role,结果会给 group 内的所有 users 分配这个 role。

  3. role 是全局(global)的,因此在一个 keystone 管辖范围内其名称必须唯一。role 的名称没有意义,其意义在于 policy.json 文件根据 role 的名称所指定的允许进行的操作。

  4. 简单地,role 可以只有 admin 和 member 两个,前者表示管理员,后者表示普通用户。但是,结合 domain 和 project 的限定,admin 可以分为 cloud admindomain admin 和 project admin

  5. policy.json 文件中定义了 role 对某种类型的资源所能进行的操作,比如允许 cloud admin 创建 domain,允许所有用户创建卷等

  6. project 是资源的集合,其中有一类特殊的project 是 admin project。通过指定 admin_project_domain_name 和 admin_project_name 来确定一个 admin project,然后该project 中的 admin 用户即是 cloud admin

  7. token 具有 scope 的概念,分为 unscoped token,domain-scoped token 和 project-scoped token。下文有说明。

1.2 token scope 和 scoped token

官方文档在这里,我这里写的只是我的理解。

token 是针对不同 scope 认证状态,这里的 scope 是指 project 和 domain,因此一共有三种 scoped token:

  1. project-scoped token:针对一个 project 的 token,它包含 service catalog, a set of roles, 和那个 project 的详细信息

  2. domain-scoped token:针对一个 domain 的 token,它具有有限的使用场景,只用于 domain 层面的操作。与 project-scoped 相比,它只具有优先的 sevice catalog

  3. unscoped token:当既不指定 project 也不指定 domain 为 scope ,同时 user 也没有 default project 时获得的 token,这是一种特殊的token。

下文有获取不同类型 token 的方法的描述。

2. 各种 admin

admin 是一种特别的 role。下面分两种情况讨论。

2.1 使用默认 policy.json 时候的 admin 的权限

2.1.1 identity 资源的 admin 权限

对 identiy 项目中的大多数资源的操作都需要 admin 权限,比如:

?

1

2

3

4

5
"identity:get_user": "rule:admin_required",

"identity:list_users": "rule:admin_required",

"identity:create_user": "rule:admin_required",

"identity:update_user": "rule:admin_required",

"identity:delete_user": "rule:admin_required",

也就是说,以 user 为例,如果一个用户没有 admin 角色,那么他将不能对 user 做任何操作。而 policy.json 文件中对 admin 的约束非常简单:

?

1
"admin_required": "role:admin or is_admin:1",

也就是说,满足两个条件中的一个,它就是 administrator:

  1. 他拥有 'admin' 这个 role,而这里的 ‘admin' 是写死的,因为默认就是使用这个名字,当然你可以修改它,比如创建一个 cloud_admin role,然后修改这里为 role:cloud_admin,其效果是一样的。

  2. is_admin:1:这个只是在项目启动后才使用,其判断条件是操作使用的token 和 keystone.conf 中的 admin_token 相同。

从 policy.json 文件可以看出来,只要赋予一个用户 admin 角色,那么他就是 administrator 了,可以操作 openstack cloud 内的所有资源。

2.1.2 openstack 基础设施资源的权限控制

以 cinder 为例,它也使用 policy.json 文件进行 role 的 policy 控制,它区分了 admin,project owner 和普通 user 的权限:

?

1

2

3

4

5

6

7

8

9

10
"context_is_admin": "role:admin",

"admin_or_owner": "is_admin:true or project_id:%(project_id)s",

"default": "rule:admin_or_owner",

"admin_api": "is_admin:true",

"volume:create": "",

"volume:delete": "rule:admin_or_owner",

"volume:get": "rule:admin_or_owner",

"volume:get_all": "rule:admin_or_owner",

"volume:get_volume_metadata": "rule:admin_or_owner",

可见:

  1. 创建 volume:不限特定权限,只要是 user 角色就行

  2. 删除 volume,获取所有volumes:需要 admin 或者 project owner 权限,owner 是指用户 token 的 project id 和被删除 volume 的 project id 相同(也就是说对于一个 project 中的两个普通用户 user1 和 user2,user2 可以删除 user1 创建的 volume,但是不可以删除)

2.2 使用 policy.v3cloudsample.json 时候的 admin 的权限

从上面 2.1.1 可以看出,使用默认 policy.json 文件时的 admin 权限控制非常粗,不能支持 keystone v3 api 中引入的域的概念。因此,社区提供了支持多域的policy.v3cloudsample.json文件。

2.2.1 identity 中的 admin

?

1

2

3

4

5

6

7

8
"admin_required": "role:admin",

"cloud_admin": "role:admin and (token.is_admin_project:true or domain_id:2b871f5dba704f74923ac01b4fcd7205)",

"service_role": "role:service",

"service_or_admin": "rule:admin_required or rule:service_role",

"owner" : "user_id:%(user_id)s or user_id:%(target.token.user_id)s",

"admin_or_owner": "(rule:admin_required and domain_id:%(target.token.user.domain.id)s) or rule:owner",

"admin_and_matching_domain_id": "rule:admin_required and domain_id:%(domain_id)s",

"service_admin_or_owner": "rule:service_or_admin or rule:owner",

它定义了几种 admin

cloud admin (cloud_admin):必须拥有 admin role;其 token 在 admin project 内 或者在指定的 domain 内。cloud admin 的主要职责是

  1. 创建 domains

  2. 为每个 domain 创建 domain admin

domain admin:必须拥有 admin role;token 的 domain id 必须和被操作资源(包括user,project 等) 的 domain id 相同。其主要职责包括

  1. 在该 domain 内创建 projects

  2. 在该 domain 内创建 users

  3. 分配 project 的权限给 user,包括 admin 和 user,前者就是 project admin,后者是 project user

只有 cloud admin 拥有的一些权限:

  1. region 的增删改

  2. service 的增删改

  3. endpoint 的增删改

  4. domain 的列表,增删改

  5. role 增删改

只有 domain admin 拥有的一些权限(当然这些权限 cloud admin 都拥有):

  1. 获取特定 domain 的信息

  2. 列表 projects,以及增删改

  3. 列表 users 和 groups

  4. user 增删改

2.2.2 示例规则说明

?

1

2

3

4

5

6

7
"admin_required": "role:admin",

"identity:create_project": "rule:admin_required and domain_id:%(project.domain_id)s",

"identity:get_project": "rule:admin_required and domain_id:%(target.project.domain_id)s",

"identity:list_projects": "rule:admin_required and domain_id:%(domain_id)s",

先来看create_project,首先要求 admin角色,需要注意的是and的后半句 domain_id:%(project.domain_id)s,这条规则的意思就是 create_project 时,使用的token的 domain_id 必须等于project所在的domaindomain_id。

也就是如下场景:

1.为usera在domaina的范围内赋予admin的权限

2.usera指定domaina作为scope,申请一个domaina scope的tokena

3.usera使用tokena,去创建project,创建project时domain_id参数必须为domaina的id

4.创建project成功

这里有几个关键点需要注意:

  1. 首先usera在domaina内必须要有admin权限,这样才能满足rule:admin_required

  2. 其次,token需要是一个domain scope的token,这样token中才会有domain_id

  3. 再次,创建project的时候,domain_id参数必须等于domaina的id,这样才能满足domain_id:%(project.domain_id)s。

这样一条规则的意义在于,可以限制只有在domaina内有权限的用户才能在domaina创建project。

get_project 比较好理解,就是查询的project的 domain_id 必须和token的 domain_id 相同,也就是只能查询 token 所在范围内的project。

list_project 是查询出所有的project,但是会根据token的domain_id过滤,然后剩下所有和token的domain_id相同的project。

keystone 增加了 domain 这样一个概念之后,其实也就把 keystone 本身的资源 user、project、group 按照 domain 给做了一个划分,可以做到在 domain 范围内的对于user、project和group的管理。

3. 多域(multi-domain)的相关操作

3.1 启用多域 policy.json

1. keystone 使用普通的 policy.json 文件,使用 admin 用户,创建 admin_domain domain,cloud_admin user 并授予其 admin role

?

1

2

3
openstack domain create admin_domain

openstack user create --domain admin_domain --password 1111 --description "cloud admin" cloud_admin

openstack role add --domain admin_domain --user cloud_admin admin

2. 使用 policy.v3cloudsample.json

使用policy.v3cloudsample.json覆盖 /etc/keystone/policy.json,并做如下修改(蓝色部分为上一步说创建的 admin_domain 的 id):

复制代码 代码如下:


"cloud_admin": "role:admin and (token.is_admin_project:true or domain_id:2b871f5dba704f74923ac01b4fcd7205)"

3. 重启 keystone service

3.2 操作

1. 获取 cloud_admin 用户 scoped domain 'admin_domain' token

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29
cloud_admin_token=$(\\

curl http://localhost:5000/v3/auth/tokens \\

-s \\

-i \\

-h "content-type: application/json" \\

-d '

{

"auth": {

"identity": {

"methods": [

"password"

],

"password": {

"user": {

"domain": {

"name": "admin_domain"

},

"name": "cloud_admin",

"password": "password"

}

}

},

"scope": {

"domain": {

"name": "admin_domain"

}

}

}

}' | grep ^x-subject-token: | awk '{print $2}' )

注意 keystone token 分为两大类:domain-scoped token 和 project-scoped token,各自需要使用不同的 scope 目标:

?

1

2

3

4

5

6
--os-domain-name <auth-domain-name> | --os-domain-id <auth-domain-id>

domain-level authorization scope (name or id)

--os-project-name <auth-project-name> | --os-project-id

<auth-project-id>

project-level authentication scope (name or id)

其中 domain-scoped token 用于操作 domain 范围内的资源,包括 projects 和 users;project-scoped token 用于操作 project 范围的资源。可以简单地认为,前者适合于 cloud admindomain admin;后者合适于 project admin 和 标准 user。

2. 创建域 dom1

?

1

2

3

4

5

6

7

8

9

10

11

12
id_dom1=$(\\

curl http://localhost:5000/v3/domains \\

-s \\

-h "x-auth-token: $cloud_admin_token" \\

-h "content-type: application/json" \\

-d '

{

"domain": {

"enabled": true,

"name": "dom1"

}

}' | jq .domain.id | tr -d '"')

3. 在 dom1 中创建第一个用户 adm1

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
id_adm1=$(\\

curl http://localhost:5000/v3/users \\

-s \\

-h "x-auth-token: $cloud_admin_token" \\

-h "content-type: application/json" \\

-d "

{

\\"user\\": {

\\"description\\": \\"administrator of domain dom1\\",

\\"domain_id\\": \\"$id_dom1\\",

\\"enabled\\": true,

\\"name\\": \\"adm1\\",

\\"password\\": \\"password\\"

}

}" | jq .user.id | tr -d '"')

4. 赋予用户 adm1 'admin' role

?

1

2

3

4

5
curl -x put http://localhost:5000/v3/domains/${id_dom1}/users/${id_adm1}/roles/${admin_role_id} \\

-s \\

-i \\

-h "x-auth-token: $cloud_admin_token" \\

-h "content-type: application/json"

5. 获取 adm1 在 dom1 中的 token,同样是domain-scoped 的

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29
adm1_token=$(\\

curl http://localhost:5000/v3/auth/tokens \\

-s \\

-i \\

-h "content-type: application/json" \\

-d '

{

"auth": {

"identity": {

"methods": [

"password"

],

"password": {

"user": {

"domain": {

"name": "dom1"

},

"name": "adm1",

"password": "password"

}

}

},

"scope": {

"domain": {

"name": "dom1"

}

}

}

}' | grep ^x-subject-token: | awk '{print $2}' )

6. 在 dom1 中创建 prj1

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
id_prj1=$(\\

curl http://localhost:5000/v3/projects \\

-s \\

-h "x-auth-token: $adm1_token" \\

-h "content-type: application/json" \\

-d "

{

\\"project\\": {

\\"enabled\\": true,

\\"domain_id\\": \\"$id_dom1\\",

\\"name\\": \\"prj1\\"

}\\

}" | jq .project.id | tr -d '"' )

echo "id of prj1: $id_prj1"

7. 在 dom1 中创建标准用户 usr1

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
id_usr1=$(\\

curl http://localhost:5000/v3/users \\

-s \\

-h "x-auth-token: $adm1_token" \\

-h "content-type: application/json" \\

-d "

{

\\"user\\": {

\\"default_project_id\\": \\"$id_prj1\\",

\\"description\\": \\"just a user of dom1\\",

\\"domain_id\\": \\"$id_dom1\\",

\\"enabled\\": true,

\\"name\\": \\"usr1\\",

\\"password\\": \\"password\\"

}

}" | jq .user.id | tr -d '"' )

echo "id of user usr1: $id_usr1"

8. 赋予 usr1 member 权限

?

1

2

3

4

5

6

7

8

9

10

11
member_role_id=$(\\

curl http://localhost:5000/v3/roles?name=member \\

-s \\

-h "x-auth-token: $adm1_token" \\

| jq .roles[0].id | tr -d '"' )

curl -x put http://localhost:5000/v3/projects/${id_prj1}/users/${id_usr1}/roles/${member_role_id} \\

-s \\

-i \\

-h "x-auth-token: $adm1_token" \\

-h "content-type: application/json"

3.3 使用 openstack cli 操作

经过测试,获得如下结果:

1. 使用 cloud_admin 用户在 openstack cli 操作都正常

2. 使用 domain admin 用户 adm1 用户在 openstack cli 中不正常

从 openstac cli 文档上看,可以通过下面的方法获取不同 scoped token:

  1. –os-domain-name:同 rest api 中 的 scope/domain/name,获取 domain-scoped token

  2. –os-project-name:同 rest api 中的 scope/project/name,获取 project-scoped token

?

1

2

3

4
--os-domain-name <auth-domain-name> | --os-domain-id <auth-domain-id>

domain-level authorization scope (name or id)

--os-project-name <auth-project-name> | --os-project-id <auth-project-id>

project-level authentication scope (name or id)

但是实际测试中,使用 –os-domain-name 无法获取期望的 domain-scoped token:

?

1

2
root@controller:/home/sammy# openstack --os-domain-name dom1 --os-username adm1 --os-password password --os-user-domain-name dom1 user list

you are not authorized to perform the requested action: identity:list_users (http 403) (request-id: req-ea4b10-0a35-4d88-907f-bab181544f40)

调试发现,此时的token 自带有 project_id,而不带有 domain_id。还需要进一步确认是否是个 bug。

一个 workaround 是,对于这种 domain admin 用户,需要首选获取 domain scoped token,然后通过 curl 操作,比如要获取 domain 内的project 列表:

?

1

2
root@controller:/home/sammy# curl -sx get -h "x-auth-token:$adm1_token" http://mysqlserver:5000/v3/projects?domain_id=db7de29b35dd450284dc99bc0a6474ca

{"links": {"self": "http://mysqlserver:5000/v3/projects?domain_id=db7de29b35dd450284dc99bc0a6474ca", "previous": null, "next": null}, "projects": [{"is_domain": false, "description": "", "links": {"self": "http://mysqlserver:5000/v3/projects/7ff06beb0045405f8bebcda166f47f04"}, "enabled": true, "id": "7ff06beb0045405f8bebcda166f47f04", "parent_id": "db7de29b35dd450284dc99bc0a6474ca", "domain_id": "db7de29b35dd450284dc99bc0a6474ca", "name": "prj1"}

3. 从结果看, mitaka 版本的 openstack cli 对多域的支持情况如下:

  1. 支持 cloud admin,这是通过 admin domain 的方式来实现的

  2. 支持 project owner,通过 project-scoped token

  3. 支持普通 user,通过 project-scoped token

  4. 不支持 domain admin,因为无法获取 domain-scoped token

3.4 horizon 对多域的支持

3.4.1 准备工作

1. 修改 /etc/openstack-dashboard/local_settings.py 文件:

?

1

2

3

4

5

6

7

8

9

10
openstack_api_versions = {

"data-processing": 1.1,

"identity": 3,

"volume": 2,

"compute": 2,

}

# set this to true if running on multi-domain model. when this is enabled, it

# will require user to enter the domain name in addition to username for login.

openstack_keystone_multidomain_support = true

2. 将 keystone 使用的支持多域的 policy.json 文件拷贝到目录/etc/openstack-dashboard/keystone_policy.json,然后修改文件local_settings.py:

?

1

2

3
policy_files = {

'identity': 'keystone_policy.json'

}

3. 重启 horizon 服务,此时可以使用 domain 和 username,password 登录

4. 简单测试了一下,发现还是有不少问题。

比如 cloud admin dashboard 中只能出来它所在的domain,而不能出来所有的 domains:

OpenStack Mitaka 版本中的 domain 和 admin详解

domain admin 登录,直接报错:

OpenStack Mitaka 版本中的 domain 和 admin详解

以普通用户登录,还能显示 admin/system 面板。

备注:keystone v3 中的概念较多,涉及的面较广,本文只是说明了一部分,甚至不是很准确。接下来会根据需要持续更新。

原文链接:http://www.cnblogs.com/sammyliu/p/5955984.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 行业资讯 OpenStack Mitaka 版本中的 domain 和 admin详解 https://www.kuaiidc.com/68457.html

相关文章

发表评论
暂无评论