OpenStack 认证管理:角色、用户、组、项目、配额,五样东西到底谁绑谁
在 Horizon 里点「创建用户」,对话框要求填项目和角色;在命令行里
openstack role add又要--project --user两个参数。这两处其实在说同一件事:OpenStack 里没有任何「直接给用户一个权限」的操作,权限永远是「某个角色,在某个项目上,授给某个用户或组」这个三元组。这篇把角色、用户、组、项目、配额五样东西的绑定关系摆开,然后把 Dashboard 和 CLI 两条路径一一对照着走一遍,最后说清「从组里删人」和「从系统删人」为什么不是一回事。
本文概要:
| 项目 | 内容 |
|---|---|
| 文章主题 | 认证管理的五对象模型;角色/用户/组/项目/配额的 Dashboard 操作路径与 CLI 命令一一对照;删除与禁用的顺序 |
| 所属类别 | 云计算 → 私有云平台 → Keystone 身份与授权 |
| 知识关键字 | domain·project·user·group·role·role assignment·quota·_member_ |
| 对应实验 | 认证管理(Dashboard 段 + CLI 段) |
先给结论,再讲路径:用户不直接持有权限,用户靠「在某个项目上被赋予某个角色」获得权限;组是用户的集合,可以整组授角色;配额不是权限,是挂在项目上的资源上限,改配额只改上限、不改权限。
一、五个对象与三种绑定关系
| 对象 | 是什么 | 关键约束 |
|---|---|---|
| 域 Domain | 最外层的隔离容器,用户、项目、组都归属某个域 | 名字全局唯一;默认域叫Default |
| 项目 Project | 资源的归属单位,也是计费/配额单位 | 名字只需在域内唯一;一个用户可以属于多个项目 |
| 用户 User | 身份主体,有独立凭据 | 必须属于某个域;可以没有默认项目 |
| 组 Group | 用户的集合,用来批量授权 | 组本身不带权限,权限来自挂在组上的角色分配 |
| 角色 Role | 权限的载体,一个名字对应一组 policy 规则 | 角色是全局对象,不专属某个项目 |
三种绑定,记这三条就够:
- 用户 → 项目:多对多,靠
role assignment连接(谁、在哪个项目、什么角色); - 用户 → 组:多对多,进组即继承组在该项目上的角色;
- 配额 → 项目:一对一(按资源类别一组),跟用户无关。
于是「给新人开权限」这件事,标准动作永远是三步:建用户 → 指定主项目 → 在项目上赋角色。少一步就进不去:没建用户没身份,没主项目登录后无处落脚,没角色则没有任何 API 被放行。
二、Dashboard 路径:一条从角色到配额的完整链路
这一段有五组动作,顺序不能乱——角色要先建,建用户时才能选;用户要先建,建项目时才能加成员。
2.1 创建角色
| 步 | 操作 |
|---|---|
| 1 | admin登录 Dashboard → 左侧「身份管理 > 角色」 |
| 2 | 右上角「创建角色」→ 名称填Role_web→ 「提交」 |
| 3 | 列表里能看到Role_web |
2.2 创建两个用户,用不同角色
| 步 | 操作 | 关键点 |
|---|---|---|
| 1 | 「身份管理 > 用户」→ 右上角「创建用户」 | — |
| 2 | 用户名User_web_01、自定义密码并记录 | 密码只在创建时设,之后只能重置 |
| 3 | 项目选admin | 这是主项目,登录后默认落这里 |
| 4 | 角色选Role_web | 新建的角色在这一步才出现 |
| 5 | 其余保持默认 → 「创建用户」 | — |
| 6 | 重复建User_web_02,角色选admin | 两个用户角色不同,后面才好对比 |
2.3 创建组并加成员
| 步 | 操作 |
|---|---|
| 1 | 「身份管理 > 组」→ 右上角「创建组」→ 名称Group_web→ 「创建组」 |
| 2 | 回到组列表 → 目标行「管理成员」 |
| 3 | 成员列表右上角「添加用户」→ 勾User_web_01、User_web_02→ 「添加用户」 |
2.4 回头核对用户的两种归属
点开用户名User_web_01进「概览」,有两个页签必须分得清:
- 「角色分配」页签:这个用户在哪些项目上是什么角色(用户 ↔ 项目);
- 「组」页签:这个用户属于哪些组(用户 ↔ 组)。
这是排查「为什么他能做这件事」的入口:先看角色分配,找不到答案再看组,因为组上的角色分配不会显示在用户的角色分配里(它显示在组的角色分配里,或通过role assignment list带--names才看得出继承关系)。
2.5 对比两个用户登录后的界面
退出admin,分别用两个用户登录:
| 用户 | 角色 | 登录后可见 |
|---|---|---|
User_web_01 | Role_web | 只有项目层视图,没有「管理员」栏 |
User_web_02 | admin | 有「管理员」栏,能看到全局概览 |
差异的根源还是policy.json:Role_web是一个自建角色,没有任何 policy 规则引用它,所以它除了「项目成员」的通用放行之外什么也带不来;admin角色被各服务的 policy 写成「放行一切」。
顺带一个容易被问到的判断题:自建角色不等于有权限。建完
Role_web不配套改policy.json,它就是个空标签。
三、两处「删除」,一处「禁用」
这是这套实验里最值得单独说的一段,因为界面上的按钮长得很像。
| 动作 | 路径 | 实际效果 |
|---|---|---|
| 从组里移除 | 身份管理 > 组 >Group_web「管理成员」→ 勾选用户 → 「删除用户」 | 只是把用户从组成员里摘掉,用户本身还在系统里 |
| 禁用用户 | 身份管理 > 用户 → 目标行「编辑」后下拉 → 「禁用用户」 | 用户的Enabled由Yes变No,不能再登录,资源与授权关系都还在 |
| 删除用户 | 身份管理 > 用户 → 勾选 → 右上角「删除用户」→ 确认 | 用户从系统消失 |
验证方法很直接:在组里「删除」User_web_02之后,去「身份管理 > 用户」列表查——它还在。这就是「组内删除 ≠ 系统删除」的实证。
禁用与删除的区别要记牢:
- 禁用是可逆的(
user set --enable就能恢复),保留全部历史归属,适合离职待交接; - 删除是不可逆的,删之前通常要求先禁用(避免带着活跃令牌的角色分配被强删导致残留);
- 删用户不会删项目,也不会删他建的资源——资源归项目,不归用户。
四、创建项目、加成员、改配额
4.1 建项目并加成员
| 步 | 操作 | 关键点 |
|---|---|---|
| 1 | 「身份管理 > 项目」→ 右上角「创建项目」 | — |
| 2 | 「项目信息」页签:名称Project_web,其余默认 | 域用Default |
| 3 | 「项目成员」页签:左侧用户列表点User_web_01后的加号 | 右侧出现已选用户 |
| 4 | 点用户后方框内的角色勾选,只勾admin | 这一步做的是role add,不是加成员 |
| 5 | 「创建项目」 | — |
| 6 | 回项目列表点Project_web→ 「用户」页签 | 核对用户与角色 |
第 4 步是重点:「把用户加进项目」和「给用户在这个项目里赋角色」是两个动作,界面上被合成一个对话框,命令行里则是两条命令(project create+role add)。
4.2 改配额
| 步 | 操作 |
|---|---|
| 1 | 「身份管理 > 项目」→Project_web行「Actions」列 → 点「管理成员」后的下拉 → 「修改配额」 |
| 2 | 三个页签分别改:计算(实例数)、卷(卷数)、网络(网络数) |
| 3 | 实例改5、卷改5、网络改5→ 「保存」 |
| 4 | 换User_web_01登录,左上角选项目Project_web |
| 5 | 「项目 > 计算 > 概况」核对配额已变 |
配额是项目级的硬上限,用户在这个项目里建实例、建卷、建网络都要先过这一关。超了会直接报Quota exceeded——这类报错不是权限问题,别去查角色。
五、CLI 段:同一套动作的命令行版本
先导入管理员身份:
sourcekeystonerc_admin5.1 角色、用户、组
# 建角色openstack role create Role_cli# 建用户(--password-prompt 交互式输密码,比明文写在命令里安全)openstack user create--domaindefault--projectadmin --password-prompt User_cli_01# 给用户在 admin 项目上赋角色openstack roleadd--projectadmin--userUser_cli_01 Role_cli# 第二个用户,角色给 adminopenstack user create--domaindefault--projectadmin --password-prompt User_cli_02 openstack roleadd--projectadmin--userUser_cli_02 admin# 查看角色分配(--names 把 ID 换成名字,否则满屏都是 32 位十六进制)openstack role assignment list--names|grepUser_cli# 建组、批量加人openstack group create Group_cli openstack groupadduser Group_cli User_cli_01 User_cli_02--password-prompt会连问两次(输入 + 确认),这是唯一一个不会把密码留在 shell 历史里的写法;直接--password huawei会进~/.bash_history。
5.2 切用户:复制一份 openrc 再改
cpkeystonerc_admin keystonerc_User_cli_01vimkeystonerc_User_cli_01# 改 OS_USERNAME / OS_PASSWORD / PS1sourcekeystonerc_User_cli_01 openstack project list# 只能看到 admin 一个项目换成User_cli_02(admin角色)再看,所有项目都能列出来。同一个命令、不同的角色、不同的返回集——这就是「授权在服务端过滤」的直观证据。
5.3 从组移除、禁用、删除
openstack group remove user Group_cli User_cli_02# 从组里移除openstack group contains user Group_cli User_cli_02# 查是否还在组里openstack userset--disableUser_cli_02# 先禁用openstack user show User_cli_02# 看 enabled: Falseopenstack user delete User_cli_02# 再删除openstack user list# 列表里已无该用户group contains user的返回是一句话结论(在/不在),不要只看退出码——很多版本无论结果如何都返回 0。
5.4 项目与配额
# 建项目openstack project create--domaindefault Project_cli# 给用户在项目上赋角色openstack roleadd--projectProject_cli--userUser_cli_01 admin openstack role assignment list--names|grepUser_cli_01# 把该用户的 openrc 里 OS_PROJECT_NAME 改成 Project_cli,再导入vimkeystonerc_User_cli_01sourcekeystonerc_User_cli_01 openstack project list# 查配额、改配额、复核openstackquotashow Project_cli openstackquotaset--instances5--volumes5--networks10Project_cli openstackquotashow Project_cli|grep-E"instances|volumes|networks"# grep -E = 扩展正则(等价 egrep);写成 grep "instances|volumes" 会当成普通字符串,筛不出东西一处版本差异,值得单独记:配额参数在
openstack客户端里是复数(--instances/--cores/--ram/--volumes/--networks),和quota show输出里的字段名一致。实验手册这一步写的是单数--instance,照着敲会报unrecognized arguments,改复数即可。
5.5 给「组」授权,而不是给「用户」
这套实验留了一道验证题:把角色授给组,看成员是否自动继承。
openstack roleadd--projectProject_cli--groupGroup_cli admin openstack role assignment list--names|grepGroup_cli结论是可行:User_cli_01在Project_cli上并没有直接的role assignment,但因为它在Group_cli里,而Group_cli在该项目上有admin,所以它照样能用。这就是生产中「按岗位建组、按组授权」的做法——新人进组即上岗,离组即失权,比逐个赋角色可维护得多。
注意role add的两个互斥参数:--user给个人,--group给一组,两个不能同时写;写错对象会导致「看起来授权成功、实际没人拿到权限」。
六、验证与易错
6.1 验证清单
openstack role list里有Role_cli(和Role_web);openstack role assignment list --names | grep User_cli能看到「用户 + 项目 + 角色」三列;User_cli_01的环境变量下openstack project list只有admin;User_cli_02能看到全部;- 组内移除后,
openstack user list里该用户依然存在; - 禁用后
openstack user show显示enabled: False,且无法登录 Dashboard; openstack quota show Project_cli中instances/volumes/networks已变为 5 / 5 / 10。
6.2 易错点
| 现象 | 原因 | 处理 |
|---|---|---|
| 建了用户,登录后一片空白 | 没选主项目,或没赋角色 | 补主项目 + 至少一个项目角色 |
role add报找不到用户/项目 | 名字拼错或不在同一域 | 用openstack user list --domain default先核对 |
| 赋了角色仍报无权 | 赋在 A 项目、当前 shell 用的是 B 项目 | 改OS_PROJECT_NAME或--project |
| 自建角色给了却什么都不能做 | 角色没被任何policy.json引用 | 要么改 policy,要么用admin/_member_ |
| 组内删人后还能登录 | 那是「移出组」,不是删用户 | 真要删去「身份管理 > 用户」删 |
| 禁用后依然能操作 | 旧 Token 未过期(默认有效期数小时) | 等过期或openstack token revoke |
quota set报unrecognized arguments | 参数写成单数 | 改复数--instances |
| 改完配额看不到变化 | 看的是 admin 项目概况,不是目标项目 | 左上角切到Project_web/Project_cli |
6.3 Dashboard 与 CLI 对照速查
| 动作 | Dashboard 路径 | CLI |
|---|---|---|
| 建角色 | 身份管理 > 角色 > 创建角色 | openstack role create <名> |
| 建用户 | 身份管理 > 用户 > 创建用户 | openstack user create --domain default --password-prompt <名> |
| 赋角色 | 创建用户时勾角色 / 项目成员页签勾角色 | openstack role add --project <项目> --user <用户> <角色> |
| 建组 | 身份管理 > 组 > 创建组 | openstack group create <名> |
| 组加人 | 组 > 管理成员 > 添加用户 | openstack group add user <组> <用户...> |
| 组删人 | 组 > 管理成员 > 删除用户 | openstack group remove user <组> <用户> |
| 禁用用户 | 用户行「编辑」下拉 > 禁用用户 | openstack user set --disable <用户> |
| 删除用户 | 用户行勾选 > 删除用户 | openstack user delete <用户> |
| 建项目 | 身份管理 > 项目 > 创建项目 | openstack project create --domain default <名> |
| 改配额 | 项目行 Actions > 修改配额 | openstack quota set --instances N --volumes N --networks N <项目> |
| 查配额 | 项目 > 计算 > 概况 | openstack quota show <项目> |
收尾建议:这一节会把角色、用户、组、项目、配额全部建一遍,做完先别急着删——后面做计算管理要拿
Project_cli建实例、做网络管理要拿它建网络。要留干净环境,删的顺序是先删实例/卷/网络 → 再删项目 → 再删用户 → 最后删角色与组,反了就会到处报「in use」。
📚 参考资料(官方文档 · 中英双语)
英文原版
- Keystone 身份概念:domain / project / user / group / role 的官方定义
- 用 CLI 管理项目、用户与角色:
role add、role assignment的标准写法 - API 保护与策略:
policy.json为什么决定「有没有权限」
中文版
- OpenStack 中文文档:官方文档中文入口
其余手册在服务器上直接查(不用联网;中文读者想系统看概念,可从中文档首页进入「管理员指南」):
openstackhelproleadd# 看清 --user / --group 互斥openstackhelpquotaset# 确认参数是复数 --instancesopenstackhelpuserset# --disable / --enableopenstack role assignment list--help# --names 的用法附:命令英文全称速查表
| 命令 / 缩写 | 英文全称 / 原意 | 作用 |
|---|---|---|
openstack role create | role(角色) | 建角色,只是建了个名字 |
openstack role add | role add | 把角色授给某用户 / 某组,在某个项目上 |
openstack role assignment list | assignment(分配、指派) | 列出「谁 · 在哪个项目 · 什么角色」 |
openstack user create | user | 建用户(--project指定主项目) |
openstack user set --disable | disable(禁用) | 禁用用户,可逆,令牌到期后不能登录 |
openstack user delete | delete | 删除用户,不可逆 |
openstack group create | group(组) | 建用户组 |
openstack group add user | add user | 把用户加进组 |
openstack group remove user | remove user | 把用户从组里移除(不是删用户) |
openstack group contains user | contains(包含) | 查某用户是否在组里,返回一句话结论 |
openstack project create | project(项目) | 建项目,资源与配额的单位 |
openstack quota show | quota(配额) | 查项目配额 |
openstack quota set | quota set | 改项目配额,参数是复数 |
--password-prompt | prompt(提示) | 交互式输密码,不写进~/.bash_history |
--names | names | 把输出里的 32 位 ID 换成名字 |
--domain | domain(域) | 指定域,v3 里名字只在域内唯一 |
grep -E | Extended regular expression | 扩展正则,等价egrep |
cp | copy | 复制认证脚本再改,是最快的切用户办法 |
_member_ | member(成员) | 项目成员角色,新版写作member |
Quota exceeded | exceed(超出) | 超配额报错,属资源上限不属权限 |
enabled | enable(启用) | 用户状态,False即已禁用 |
--help | — | 打印子命令用法;openstack help role add最省事 |
总结:权限是三元组(角色 + 项目 + 用户/组),配额是挂在项目上的资源上限,删除要分清「移出组」「禁用」「删用户」三种。记住这三句,Dashboard 上那几个长得很像的按钮就不会再点错。
📚同系列 · 云计算与私有云平台(其余篇目见博客主页)
blog.csdn.net/nbsxl
- 上一篇:《OpenStack 界面管理:网页点得动、命令行却提示「找不到项目」,差的是那 11 行环境变量》
- 相关篇:《packstack 装 OpenStack 为什么卡 40 分钟?CentOS Stream 8 双节点部署全过程》
💬 你被「组里删除用户」坑过吗?删完发现人还能登录,评论区说说当时怎么查出来的。