OpenStack Mitaka 版本中的 domain 和 admin

OpenStack 的 Keystone V3 中引入了 Domain 的概念。引入这个概念后,关于 admin 这个role 的定义就变得复杂了起来。

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

简单来说,

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

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

说明:

  • Domain 可以认为是 project,user,group 的 namespace。 一个 domain 内,这些元素的名称不可以重复,但是在两个不同的domain内,它们的名称可以重复。因此,在确定这些元素时,需要同时使用它们的名称和它们的 domain 的 id 或者 name。
  • Group 是一个 domain 部分 user 的集合,其目的是为了方便分配 role。给一个 group 分配 role,结果会给 group 内的所有 users 分配这个 role。
  • Role 是全局(global)的,因此在一个 keystone 管辖范围内其名称必须唯一。role 的名称没有意义,其意义在于 policy.json 文件根据 role 的名称所指定的允许进行的操作。
  • 简单地,role 可以只有 admin 和 member 两个,前者表示管理员,后者表示普通用户。但是,结合 domain 和 project 的限定,admin 可以分为 cloud admin,domain admin 和 project admin。
  • policy.json 文件中定义了 role 对某种类型的资源所能进行的操作,比如允许 cloud admin 创建 domain,允许所有用户创建卷等
  • project 是资源的集合,其中有一类特殊的project 是 admin project。通过指定 admin_project_domain_name 和 admin_project_name 来确定一个 admin project,然后该project 中的 admin 用户即是 cloud admin。
  • Token 具有 scope 的概念,分为 unscoped token,domain-scoped token 和 project-scoped token。下文有说明。

2. 各种 admin

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

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

2.1.1 Identity 资源的 admin 权限

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

    "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 的约束非常简单:

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

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

  • 他拥有 ‘admin‘ 这个 role,而这里的 ‘admin’ 是写死的,因为默认就是使用这个名字,当然你可以修改它,比如创建一个 cloud_admin role,然后修改这里为 role:cloud_admin,其效果是一样的。
  • 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 的权限:

    "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",

可见:

  • 创建 volume:不限特定权限,只要是 user 角色就行
  • 删除 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

    "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 的主要职责是

    • 创建 domains
    • 为每个 domain 创建 domain admin
  • domain admin:必须拥有 admin role;token 的 domain id 必须和被操作资源(包括user,project 等) 的 domain id 相同。其主要职责包括
    • 在该 domain 内创建 projects
    • 在该 domain 内创建 users
    • 分配 project 的权限给 user,包括 admin 和 user,前者就是 project admin,后者是 project user

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

  • region 的增删改
  • service 的增删改
  • endpoint 的增删改
  • domain 的列表,增删改
  • role 增删改

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

  • 获取特定 domain 的信息
  • 列表 projects,以及增删改
  • 列表 users 和 groups
  • user 增删改

2.2.2 示例规则说明

1 "admin_required": "role:admin",
2
3 "identity:create_project": "rule:admin_required and domain_id:%(project.domain_id)s",
4
5 "identity:get_project": "rule:admin_required and domain_id:%(target.project.domain_id)s",
6
7 "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所在的domain的domain_id。

也就是如下场景:

  1. 为userA在domainA的范围内赋予admin的权限
  2. userA指定domainA作为scope,申请一个domainA scope的tokenA
  3. userA使用tokenA,去创建project,创建project时domain_id参数必须为domainA的id
  4. 创建project成功

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

  • 首先userA在domainA内必须要有admin权限,这样才能满足rule:admin_required
  • 其次,token需要是一个domain scope的token,这样token中才会有domain_id
  • 再次,创建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

  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

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 目标:

       --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 admin 和 domain admin;后者合适于 project admin 和 标准 user。

2. 创建域 dom1

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

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

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 的

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

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

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 权限

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 中不正常

[email protected]:/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)

里面上使用 --os-domain-name dom1 获取的是 domain scoped token,但是依然被提示没有 list_users 权限。需要进一步看是否是个 bug。一个 workaround 是,对于这种 domain admin 用户,需要首选获取 domain scoped token,然后通过 curl 操作,比如要获取 domain 内的project 列表:

[email protected]:/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 对多域的支持情况如下:

  • 支持 cloud admin
  • 支持 project owner
  • 支持普通 user
  • 不支持 domain admin

3.4 Horizon 对多域的支持

3.4.1 准备工作

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

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:

POLICY_FILES = {
    ‘identity‘: ‘keystone_policy.json‘
}

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

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

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

以domain admin 登录,直接报错:

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

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

参考链接:

时间: 2024-10-25 06:44:41

OpenStack Mitaka 版本中的 domain 和 admin的相关文章

CENTOS7 安装openstack mitaka版本(最新整理完整版附详细截图和操作步骤,添加了cinder和vxlan)

CENTOS7 安装openstack mitaka版本(最新整理完整版附详细截图和操作步骤,添加了cinder和vxlan,附上个节点的配置文件) 实验环境准备: 为了更好的实现分布式mitaka版本的效果.我才有的是VMware的workstations来安装三台虚拟机,分别来模拟openstack的controller节点 compute节点和cinder节点.(我的宿主机配置为 500g 硬盘 16g内存,i5cpu.强烈建议由条件的朋友将内存配置大一点,因为我之前分配的2g太卡.) 注

Neutron新进展|DragonFlow在Mitaka版本中的Roadmap

OpenStack网络在Mitaka版本中将有哪些新变化?1月11日到12日,DragonFlow的PTL——Eran Gampel,Kuryr的PTL——Gal Sagie,和他们的老大从以色列来到杭州,参加DragonFlow Meetup.UnitedStack有云的网络组同事苌智和康敬亭参与了这次讨论,并整理出Dragonflow在Mitaka版本中要完成的工作以为未来的Roadmap. 背景介绍Dragonflow是OpenStack网络组件Neutron的子项目,由华为以色列技术团队

Centos7手动安装OpenStack Mitaka版本--基本环境安装

Centos7手动安装OpenStack Mitaka版本--第一节:基本环境配置 一台控制节点 controller_ip=10.1.1.160 controller_ip2=192.168.13.147 一台计算节点 compute_ip=10.1.1.162 compute_ip2=192.168.13.144 hosts文件配置 [[email protected] ~]# cat /etc/hosts 127.0.0.1   localhost localhost.localdomai

在centos7上安装openstack mitaka版本

前言:openstack真是一个庞然大物,想要吃透还真不容易,所以在对openstack大概有了一个了解的时候,就应该是部署,虽然openstack的安装方式有rdo或者devstack等一键安装工具,但是最好浅尝辄止,有了大概的使用经验之后就应该是从头到尾的安装一遍了,不然对于那些报错,以及故障的解决一定是不够气定神闲的,因此,当你有了openstack的基本认识后,开始安装吧~ 注:openstack的官方文档写得真的是,好的不要不要的,但是看英文总是感觉有点不溜,因此在官方文档的基础上写得

openstack 之fuel 9 安装 Openstack Mitaka 版本

2015年上半年曾经在原单位安装过openstack juno版本,使用的是Mirantis公司的fuel自动化部署工具,很好用.已经很久没有关注openstack了,版本到现在为止已经到了Newton了,上一个版本是Mitaka,今天我要做的实验就是使用fuel 9 安装Mitaka版本. 我的笔记本的配置是intel i5,4核,8G,win10 64位家庭版. 首先到Mirantis官网下载fuel的安装镜像ISO: https://www.mirantis.com/software/mi

[译] OpenStack Kilo 版本中 Neutron 的新变化

OpenStack Kilo 版本,OpenStack 这个开源项目的第11个版本,已经于2015年4月正式发布了.现在是个合适的时间来看看这个版本中Neutron到底发生了哪些变化了,以及引入了哪些新的关键功能. 1. 扩展 Neutron 开发社区 (Scaling the Neutron development community) 为了更好地扩展 Neutron 开发社区的规模,我们在Kilo开发周期中主要做了两项工作:解耦核心插件以及分离高级服务.这些变化不会直接影响 OpenStac

[译] OpenStack Liberty 版本中的53个新变化

一个新的秋季,一个新的OpenStack 版本.OpenStack 的第12个版本,Liberty,在10月15日如期交付,而且目前发行版本已经备好了.那么我们期望能从过去六个月时间的开发中获得些什么呢?  正如过去几年一样,每个版本都有大量的变化和引入新的功能,但是现在,OpenStack 已经达到一个新的位置,那就是大部分的必要功能都已经齐备了,因此,现在更多的是增量式的变化-只有一些偶然性爆发的领域是例外,比如容器.  当然,这不是说容器就是过去六个月内的所有值得期待的东西.除了容器,还有

OpenStack 入门学习之四:icehouse版本中Heat的简单介绍

Heat简介 Heat是OpenStack的负责编排计划的主要项目.它可以基于模板来实现云环境中资源的初始化,依赖关系处理,部署等基本操作,也可以解决自动收缩,负载均衡等高级特性.目前Heat自身的模板格式(HOT)正在不停的改进,同时也支持AWS CloudFormation 模板(CFN),HOT的目标是在不远的将来可以完全的替代CFN. Heat提供了一个OpenStack的原生REST API和CloudFormation兼容的查询API. Heat的工作原理 Heat主要是基于模板文件

OpenStack Mitaka Dashboard

OpenStack Mitaka Dashboard 一.写在前面 这篇文章主要介绍了OpenStack Mitaka Horizon组件功能,Mitaka 版本的 Horizon新增加了不少新的功能,这里专门整理一下,写文档的过程,就是我熟悉的过程,整理成笔记以便后续自己查阅. 目前还没有深入进行功能理解,暂时只是简单的通过界面功能与上个版本稍作对比,后续将逐步完善. 如果转载,请保留作者信息. 邮箱地址:[email protected] 二.身份认证 1) .登录 Mitaka版本全部的组