OpenStack Mitaka 版本中的 domain 和 admin詳解
OpenStack 的 Keystone V3 中引入了 Domain 的概念。引入這個(gè)概念后,關(guān)于 admin 這個(gè)role 的定義就變得復(fù)雜了起來(lái)。
本文測(cè)試環(huán)境是社區(qū) Mitaka 版本。
1. Domain,project,user,role,token 的概念和關(guān)系
1.1 概況
簡(jiǎn)單來(lái)說(shuō),
- Domain - 表示 project 和 user 的集合,在公有云或者私有云中常常表示一個(gè)客戶
- Group - 一個(gè)domain 中的部分用戶的集合
- Project - IT基礎(chǔ)設(shè)施資源的集合,比如虛機(jī),卷,鏡像等
- Role - 角色,表示一個(gè) user 對(duì)一個(gè) project resource 的權(quán)限
- Token - 一個(gè) user 對(duì)于某個(gè)目標(biāo)(project 或者 domain)的一個(gè)有限時(shí)間段內(nèi)的身份令牌
它們之間的關(guān)系用一個(gè)不完整的圖來(lái)表示:
說(shuō)明:
- Domain 可以認(rèn)為是 project,user,group 的 namespace。 一個(gè) domain 內(nèi),這些元素的名稱不可以重復(fù),但是在兩個(gè)不同的domain內(nèi),它們的名稱可以重復(fù)。因此,在確定這些元素時(shí),需要同時(shí)使用它們的名稱和它們的 domain 的 id 或者 name。
- Group 是一個(gè) domain 部分 user 的集合,其目的是為了方便分配 role。給一個(gè) group 分配 role,結(jié)果會(huì)給 group 內(nèi)的所有 users 分配這個(gè) role。
- Role 是全局(global)的,因此在一個(gè) keystone 管轄范圍內(nèi)其名稱必須唯一。role 的名稱沒(méi)有意義,其意義在于 policy.json 文件根據(jù) role 的名稱所指定的允許進(jìn)行的操作。
- 簡(jiǎn)單地,role 可以只有 admin 和 member 兩個(gè),前者表示管理員,后者表示普通用戶。但是,結(jié)合 domain 和 project 的限定,admin 可以分為 cloud admin,domain admin 和 project admin。
- policy.json 文件中定義了 role 對(duì)某種類型的資源所能進(jìn)行的操作,比如允許 cloud admin 創(chuàng)建 domain,允許所有用戶創(chuàng)建卷等
- project 是資源的集合,其中有一類特殊的project 是 admin project。通過(guò)指定 admin_project_domain_name 和 admin_project_name 來(lái)確定一個(gè) admin project,然后該project 中的 admin 用戶即是 cloud admin。
- Token 具有 scope 的概念,分為 unscoped token,domain-scoped token 和 project-scoped token。下文有說(shuō)明。
1.2 Token scope 和 Scoped token
官方文檔在這里,我這里寫的只是我的理解。
Token 是針對(duì)不同 scope 認(rèn)證狀態(tài),這里的 scope 是指 project 和 domain,因此一共有三種 scoped token:
- project-scoped token:針對(duì)一個(gè) project 的 token,它包含 service catalog, a set of roles, 和那個(gè) project 的詳細(xì)信息
- domain-scoped token:針對(duì)一個(gè) domain 的 token,它具有有限的使用場(chǎng)景,只用于 domain 層面的操作。與 project-scoped 相比,它只具有優(yōu)先的 sevice catalog
- unscoped token:當(dāng)既不指定 project 也不指定 domain 為 scope ,同時(shí) user 也沒(méi)有 default project 時(shí)獲得的 token,這是一種特殊的token。
下文有獲取不同類型 token 的方法的描述。
2. 各種 admin
admin 是一種特別的 role。下面分兩種情況討論。
2.1 使用默認(rèn) policy.json 時(shí)候的 admin 的權(quán)限
2.1.1 Identity 資源的 admin 權(quán)限
對(duì) Identiy 項(xiàng)目中的大多數(shù)資源的操作都需要 admin 權(quán)限,比如:
"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",
也就是說(shuō),以 user 為例,如果一個(gè)用戶沒(méi)有 admin 角色,那么他將不能對(duì) user 做任何操作。而 policy.json 文件中對(duì) admin 的約束非常簡(jiǎn)單:
"admin_required": "role:admin or is_admin:1",
也就是說(shuō),滿足兩個(gè)條件中的一個(gè),它就是 administrator:
- 他擁有 'admin' 這個(gè) role,而這里的 ‘a(chǎn)dmin' 是寫死的,因?yàn)槟J(rèn)就是使用這個(gè)名字,當(dāng)然你可以修改它,比如創(chuàng)建一個(gè) cloud_admin role,然后修改這里為 role:cloud_admin,其效果是一樣的。
- is_admin:1:這個(gè)只是在項(xiàng)目啟動(dòng)后才使用,其判斷條件是操作使用的token 和 keystone.conf 中的 admin_token 相同。
從 policy.json 文件可以看出來(lái),只要賦予一個(gè)用戶 admin 角色,那么他就是 administrator 了,可以操作 OpenStack cloud 內(nèi)的所有資源。
2.1.2 OpenStack 基礎(chǔ)設(shè)施資源的權(quán)限控制
以 Cinder 為例,它也使用 policy.json 文件進(jìn)行 role 的 policy 控制,它區(qū)分了 admin,project owner 和普通 user 的權(quán)限:
"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",
可見(jiàn):
- 創(chuàng)建 volume:不限特定權(quán)限,只要是 user 角色就行
- 刪除 volume,獲取所有volumes:需要 admin 或者 project owner 權(quán)限,owner 是指用戶 token 的 project id 和被刪除 volume 的 project id 相同(也就是說(shuō)對(duì)于一個(gè) project 中的兩個(gè)普通用戶 user1 和 user2,user2 可以刪除 user1 創(chuàng)建的 volume,但是不可以刪除)
2.2 使用 policy.v3cloudsample.json 時(shí)候的 admin 的權(quán)限
從上面 2.1.1 可以看出,使用默認(rèn) policy.json 文件時(shí)的 admin 權(quán)限控制非常粗,不能支持 Keystone V3 API 中引入的域的概念。因此,社區(qū)提供了支持多域的 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 內(nèi) 或者在指定的 domain 內(nèi)。Cloud admin 的主要職責(zé)是
- 創(chuàng)建 domains
- 為每個(gè) domain 創(chuàng)建 domain admin
domain admin:必須擁有 admin role;token 的 domain id 必須和被操作資源(包括user,project 等) 的 domain id 相同。其主要職責(zé)包括
- 在該 domain 內(nèi)創(chuàng)建 projects
- 在該 domain 內(nèi)創(chuàng)建 users
- 分配 project 的權(quán)限給 user,包括 admin 和 user,前者就是 project admin,后者是 project user
只有 Cloud admin 擁有的一些權(quán)限:
- region 的增刪改
- service 的增刪改
- endpoint 的增刪改
- domain 的列表,增刪改
- role 增刪改
只有 Domain admin 擁有的一些權(quán)限(當(dāng)然這些權(quán)限 cloud admin 都擁有):
- 獲取特定 domain 的信息
- 列表 projects,以及增刪改
- 列表 users 和 groups
- user 增刪改
2.2.2 示例規(guī)則說(shuō)明
"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",
先來(lái)看create_project,首先要求 admin角色,需要注意的是and的后半句 domain_id:%(project.domain_id)s,這條規(guī)則的意思就是 create_project 時(shí),使用的token的 domain_id 必須等于project所在的domain的domain_id。
也就是如下場(chǎng)景:
1.為userA在domainA的范圍內(nèi)賦予admin的權(quán)限
2.userA指定domainA作為scope,申請(qǐng)一個(gè)domainA scope的tokenA
3.userA使用tokenA,去創(chuàng)建project,創(chuàng)建project時(shí)domain_id參數(shù)必須為domainA的id
4.創(chuàng)建project成功
這里有幾個(gè)關(guān)鍵點(diǎn)需要注意:
- 首先userA在domainA內(nèi)必須要有admin權(quán)限,這樣才能滿足rule:admin_required
- 其次,token需要是一個(gè)domain scope的token,這樣token中才會(huì)有domain_id
- 再次,創(chuàng)建project的時(shí)候,domain_id參數(shù)必須等于domainA的id,這樣才能滿足domain_id:%(project.domain_id)s。
這樣一條規(guī)則的意義在于,可以限制只有在domainA內(nèi)有權(quán)限的用戶才能在domainA創(chuàng)建project。
get_project 比較好理解,就是查詢的project的 domain_id 必須和token的 domain_id 相同,也就是只能查詢 token 所在范圍內(nèi)的project。
list_project 是查詢出所有的project,但是會(huì)根據(jù)token的domain_id過(guò)濾,然后剩下所有和token的domain_id相同的project。
keystone 增加了 domain 這樣一個(gè)概念之后,其實(shí)也就把 keystone 本身的資源 user、project、group 按照 domain 給做了一個(gè)劃分,可以做到在 domain 范圍內(nèi)的對(duì)于user、project和group的管理。
3. 多域(multi-domain)的相關(guān)操作
3.1 啟用多域 policy.json
1. Keystone 使用普通的 policy.json 文件,使用 admin 用戶,創(chuàng)建 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,并做如下修改(藍(lán)色部分為上一步說(shuō)創(chuàng)建的 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 目標(biāo):
--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 范圍內(nèi)的資源,包括 projects 和 users;project-scoped token 用于操作 project 范圍的資源??梢院?jiǎn)單地認(rèn)為,前者適合于 cloud admin 和 domain admin;后者合適于 project admin 和 標(biāo)準(zhǔn) user。
2. 創(chuàng)建域 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 中創(chuàng)建第一個(gè)用戶 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 中創(chuàng)建 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 中創(chuàng)建標(biāo)準(zhǔn)用戶 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 權(quán)限
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 操作
經(jīng)過(guò)測(cè)試,獲得如下結(jié)果:
1. 使用 cloud_admin 用戶在 openstack CLI 操作都正常
2. 使用 domain admin 用戶 adm1 用戶在 OpenStack CLI 中不正常
從 OpenStac CLI 文檔上看,可以通過(guò)下面的方法獲取不同 scoped token:
- --os-domain-name:同 REST API 中 的 scope/domain/name,獲取 domain-scoped token
- --os-project-name:同 REST API 中的 scope/project/name,獲取 project-scoped token
--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)
但是實(shí)際測(cè)試中,使用 --os-domain-name 無(wú)法獲取期望的 domain-scoped token:
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)
調(diào)試發(fā)現(xiàn),此時(shí)的token 自帶有 project_id,而不帶有 domain_id。還需要進(jìn)一步確認(rèn)是否是個(gè) bug。
一個(gè) workaround 是,對(duì)于這種 domain admin 用戶,需要首選獲取 domain scoped token,然后通過(guò) curl 操作,比如要獲取 domain 內(nèi)的project 列表:
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. 從結(jié)果看, Mitaka 版本的 OpenStack CLI 對(duì)多域的支持情況如下:
- 支持 cloud admin,這是通過(guò) admin domain 的方式來(lái)實(shí)現(xiàn)的
- 支持 project owner,通過(guò) project-scoped token
- 支持普通 user,通過(guò) project-scoped token
- 不支持 domain admin,因?yàn)闊o(wú)法獲取 domain-scoped token
3.4 Horizon 對(duì)多域的支持
3.4.1 準(zhǔn)備工作
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 服務(wù),此時(shí)可以使用 domain 和 username,password 登錄
4. 簡(jiǎn)單測(cè)試了一下,發(fā)現(xiàn)還是有不少問(wèn)題。
比如 cloud admin dashboard 中只能出來(lái)它所在的domain,而不能出來(lái)所有的 domains:
以domain admin 登錄,直接報(bào)錯(cuò):
以普通用戶登錄,還能顯示 Admin/System 面板。
備注:Keystone V3 中的概念較多,涉及的面較廣,本文只是說(shuō)明了一部分,甚至不是很準(zhǔn)確。接下來(lái)會(huì)根據(jù)需要持續(xù)更新。
- Fuel快速安裝OpenStack圖文教程
- 一步一步教你安裝openstack(圖文)
- openstack 重啟的服務(wù)命令整理總結(jié)
- OpenStack之日志詳細(xì)介紹
- CentOS 6.4下安裝部署OpenStack云計(jì)算平臺(tái)的方法
- Fuel 30 分鐘快速安裝OpenStack(圖文教程)
- OpenStack之虛機(jī)熱遷移的代碼詳細(xì)解析
- 什么是OpenStack 開源的云計(jì)算管理平臺(tái)項(xiàng)目
- Openstack 使用migrate進(jìn)行數(shù)據(jù)庫(kù)升級(jí)實(shí)現(xiàn)方案詳細(xì)介紹
- CentOS 一鍵安裝Openstack詳細(xì)介紹
相關(guān)文章
詳解VMware接入Openstack—使用Openstack創(chuàng)建vCenter虛擬機(jī)
本篇文章主要介紹了VMware接入Openstack—使用Openstack創(chuàng)建vCenter虛擬機(jī),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03Openstack 創(chuàng)建項(xiàng)目和虛擬機(jī)詳細(xì)介紹
這篇文章主要介紹了Openstack 創(chuàng)建項(xiàng)目和虛擬機(jī)詳細(xì)介紹的相關(guān)資料,這里舉例說(shuō)明如何實(shí)現(xiàn),圖文教程,需要的朋友可以參考下2016-11-11openstack 重啟的服務(wù)命令整理總結(jié)
這篇文章主要介紹了openstack 重啟的服務(wù)命令整理總結(jié)的相關(guān)資料,這里對(duì) openstack 的服務(wù)命令進(jìn)行了詳細(xì)的介紹,openstack 的服務(wù)命令比較多,需要的朋友可以參考下2016-11-11cURL操作Openstack對(duì)象存儲(chǔ)的ReST API詳解
這篇文章主要介紹了cURL操作Openstack對(duì)象存儲(chǔ)的ReST API詳解的相關(guān)資料,需要的朋友可以參考下2016-11-11Openstack安裝過(guò)程中遇到的問(wèn)題匯總
本文給大家分享的是作者在Centos7中安裝openstack過(guò)程中出現(xiàn)的一些問(wèn)題的匯總,以及解決的方法,有需要的小伙伴可以參考下2017-04-04詳解Openstack組件部署 — Overview和前期環(huán)境準(zhǔn)備
本篇文章主要介紹了詳解Openstack組件部署 — Overview和前期環(huán)境準(zhǔn)備,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03詳解OpenStack云平臺(tái)的網(wǎng)絡(luò)模式及其工作機(jī)制
這篇文章主要介紹了詳解OpenStack云平臺(tái)的網(wǎng)絡(luò)模式及其工作機(jī)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-12-12圖文講解OpenStack手動(dòng)分布式部署環(huán)境準(zhǔn)備(Queens版)
這篇文章主要介紹了圖文講解OpenStack手動(dòng)分布式部署環(huán)境準(zhǔn)備(Queens版),OpenStack用于部署公有云、私有云,并實(shí)現(xiàn)對(duì)云項(xiàng)目管理,需要的朋友可以參考下2023-03-03簡(jiǎn)單談?wù)凮penStack中的網(wǎng)絡(luò)隔離
這篇文章主要介紹了簡(jiǎn)單談?wù)凮penStack中的網(wǎng)絡(luò)隔離的相關(guān)資料,需要的朋友可以參考下2017-03-03