OpenStack 认证管理:角色、用户、组、项目、配额,五样东西到底谁绑谁

发布时间:2026/10/30 6:44:30
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 规则角色是全局对象,不专属某个项目

三种绑定,记这三条就够:

  1. 用户 → 项目:多对多,靠role assignment连接(谁、在哪个项目、什么角色);
  2. 用户 → 组:多对多,进组即继承组在该项目上的角色;
  3. 配额 → 项目:一对一(按资源类别一组),跟用户无关。

于是「给新人开权限」这件事,标准动作永远是三步:建用户 → 指定主项目 → 在项目上赋角色。少一步就进不去:没建用户没身份,没主项目登录后无处落脚,没角色则没有任何 API 被放行。

二、Dashboard 路径:一条从角色到配额的完整链路

这一段有五组动作,顺序不能乱——角色要先建,建用户时才能选;用户要先建,建项目时才能加成员。

2.1 创建角色

步操作
1admin登录 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_01Role_web只有项目层视图,没有「管理员」栏
User_web_02admin有「管理员」栏,能看到全局概览

差异的根源还是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_admin

5.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 验证清单

  1. openstack role list里有Role_cli(和Role_web);
  2. openstack role assignment list --names | grep User_cli能看到「用户 + 项目 + 角色」三列;
  3. User_cli_01的环境变量下openstack project list只有admin;User_cli_02能看到全部;
  4. 组内移除后,openstack user list里该用户依然存在;
  5. 禁用后openstack user show显示enabled: False,且无法登录 Dashboard;
  6. 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 createrole(角色)建角色,只是建了个名字
openstack role addrole add把角色授给某用户 / 某组,在某个项目上
openstack role assignment listassignment(分配、指派)列出「谁 · 在哪个项目 · 什么角色」
openstack user createuser建用户(--project指定主项目)
openstack user set --disabledisable(禁用)禁用用户,可逆,令牌到期后不能登录
openstack user deletedelete删除用户,不可逆
openstack group creategroup(组)建用户组
openstack group add useradd user把用户加进组
openstack group remove userremove user把用户从组里移除(不是删用户)
openstack group contains usercontains(包含)查某用户是否在组里,返回一句话结论
openstack project createproject(项目)建项目,资源与配额的单位
openstack quota showquota(配额)查项目配额
openstack quota setquota set改项目配额,参数是复数
--password-promptprompt(提示)交互式输密码,不写进~/.bash_history
--namesnames把输出里的 32 位 ID 换成名字
--domaindomain(域)指定域,v3 里名字只在域内唯一
grep -EExtended regular expression扩展正则,等价egrep
cpcopy复制认证脚本再改,是最快的切用户办法
_member_member(成员)项目成员角色,新版写作member
Quota exceededexceed(超出)超配额报错,属资源上限不属权限
enabledenable(启用)用户状态,False即已禁用
--help—打印子命令用法;openstack help role add最省事

总结:权限是三元组(角色 + 项目 + 用户/组),配额是挂在项目上的资源上限,删除要分清「移出组」「禁用」「删用户」三种。记住这三句,Dashboard 上那几个长得很像的按钮就不会再点错。


📚同系列 · 云计算与私有云平台(其余篇目见博客主页)

blog.csdn.net/nbsxl

  • 上一篇:《OpenStack 界面管理:网页点得动、命令行却提示「找不到项目」,差的是那 11 行环境变量》
  • 相关篇:《packstack 装 OpenStack 为什么卡 40 分钟?CentOS Stream 8 双节点部署全过程》

💬 你被「组里删除用户」坑过吗?删完发现人还能登录,评论区说说当时怎么查出来的。