欢迎光临
我们一直在努力

01 · 认证管理 Keystone

01 · 认证管理 Keystone

本篇导读:Keystone 是 OpenStack 的「身份证中心 + 服务目录」。任何用户或服务想使用 OpenStack,第一步都要先找 Keystone 报到。本篇从「它是谁、管什么」切入,逐个讲透九大核心概念,再带你走一遍 Dashboard 与 CLI 的完整操作,最后用两张时序图把「登录」和「创建虚拟机」背后发生的认证/鉴权链路钉死。学完你应当能独立创建域、用户、组、项目、角色、配额,并说清 Token 在各服务之间是怎么被反复校验的。

学习目标:

  • 说清 Keystone 在 OpenStack 中的定位与三件核心工作。
  • 准确复述九大概念(Domain / User / Group / Project / Role / Service / Endpoint / Token / Credential)的一句话定义与唯一性范围。
  • 区分 Authentication(认证)与 Authorization(鉴权),理解 policy 基于 Role 的访问控制。
  • 能用 Dashboard 和 CLI 两种方式完成:创建角色、用户、用户组、项目、改配额、禁用/删除用户。
  • 画得出「点击登入」和「创建一台 VM」时 Token 在 Keystone / Nova / Glance / Neutron 之间的流转时序。
  • 知道 Keystone 日志、配置文件位置,会开 debug。

  • 文章目录

    • 01 · 认证管理 Keystone
      • 一、Keystone 的定位与作用
      • 二、九大核心概念(先背一句话定义)
        • 1. Domain(域)
        • 2. User(用户)
        • 3. Group(用户组)
        • 4. Project(项目 / 租户)
        • 5. Role(角色)
        • 6. Service(服务)
        • 7. Endpoint(端点)
        • 8. Token(令牌)
        • 9. Credential(凭证)
        • 九大概念关系图
      • 三、Authentication 与 Authorization:安全的两件事
        • 鉴权是怎么落地的:policy 文件
      • 四、架构与组件(补充)
      • 五、关键配置与环境变量
        • 5.1 命令行前置:source 环境变量
        • 5.2 自定义用户的 openrc 环境变量文件(实验手册)
        • 5.3 多域登录开关(Dashboard)
        • 5.4 打开 debug 日志
      • 六、Dashboard(Horizon)操作
        • 6.1 创建角色
        • 6.2 创建用户
        • 6.3 创建用户组并加成员
        • 6.4 不同角色登录后的界面差异(重点现象)
        • 6.5 禁用与删除用户(关键区别)
        • 6.6 创建项目并改配额
      • 七、CLI 操作(命令 + 输出解读)
        • 7.1 Domain 域
        • 7.2 User 用户
        • 7.3 Group 用户组
        • 7.4 Role 角色与授权
        • 7.5 Project 项目与配额
        • 7.6 Service 与 Endpoint
      • 八、两个必背流程(时序图)
        • 8.1 点击「登入」背后发生了什么
        • 8.2 以「创建一台 VM」看整个 OpenStack 的认证链路
      • 九、易混点对比表
      • 十、补充内容(进阶拓展)
        • 10.1 【补充】Token 的种类与演进
        • 10.2 【补充】RBAC 与三种 scope、Secure RBAC
        • 10.3 【补充】联邦身份 Federation 与外部身份源
        • 10.4 【补充】域 / 项目层级树与多租户隔离
      • 十一、本篇小结
      • 十二、重点速记
      • 十三、自测题(附参考答案)
        • A. 名词解释
        • B. 选择题
        • C. 简答题

    一、Keystone 的定位与作用

    Keystone(OpenStack Identity,身份服务)是 OpenStack 的基础支持服务,所有其他服务(Nova、Glance、Cinder、Neutron、Heat……)都要围着它转。它主要做三件事:

  • 管理用户及其权限(谁能登录、能登到哪个项目、能干什么)。
  • 维护 OpenStack 各 Service 的 Endpoint 目录(告诉别人「Nova 的 API 地址是多少」)。
  • Authentication(认证)和 Authorization(鉴权):验证你是谁,再决定你能干什么。
  • 一句话记忆:Keystone = 门卫 + 通讯录。门卫查身份证发通行证(Token),通讯录写着每家服务的门牌号(Endpoint)。

    实验环境基线(贯穿全篇,务必记牢):

    项目值
    操作系统 / 版本 CentOS-Stream-8 + OpenStack Victoria
    controller 节点 192.168.108.10
    compute 节点 192.168.108.11
    Region RegionOne
    默认域 Default(另有一个系统自带的 heat 域)
    管理员账号 admin,密码统一 huawei
    命令行前置动作 source keystonerc_admin(导入 admin 环境变量)
    OS_AUTH_URL http://192.168.108.10:5000/v3
    OS_IDENTITY_API_VERSION 3
    日志目录 /var/log/keystone/keystone.log
    配置目录 /etc/keystone/(主配置 keystone.conf)

    二、九大核心概念(先背一句话定义)

    学法提示:每个概念先背「一句话标准定义」(加粗句),再记唯一性范围和易错点。

    1. Domain(域)

    一个 Domain 是一组 User、Group 或 Project 的容器,是一个虚拟的管理边界。

    • 一个域可以对应一个大机构、一个数据中心,必须全局唯一。
    • 终端用户可以在自己的 Domain 里创建多个 Project、User、Group、Role,具备对多个 Project 统一管理的能力。
    • 系统默认自带 Default 域和一个 heat 域;不特别指定域时,对象都落在 default 域下。

    2. User(用户)

    User 是可以通过 Keystone 访问 OpenStack 服务的个人、系统或某个服务。

    • User 不要求全局唯一,只需在域内唯一。
    • Keystone 用 Credential(如密码)验证 User 请求合法性;通过验证后下发一个 Token,作为后续访问的「通行证」。
    • 除了真正的人 admin,OpenStack 还为 nova、cinder、glance、neutron、heat、placement、swift、ceilometer、aodh、gnocchi 等服务创建了对应的服务 User(服务间互相调用也靠身份认证)。admin 可以管理这些服务 User。

    3. Group(用户组)

    Group 是一组 User 的容器,可以直接给 Group 分配角色。

    • 给 Group 赋角色后,组内所有 User 自动拥有该角色权限——目的是批量管理一组用户的权限,而不是一个个单独授权。
    • 把用户从组里删掉 ≠ 删除用户本体,只是退出该组。

    4. Project(项目 / 租户)

    Project 是各个服务中一组可以访问的资源集合(计算、存储、网络),用于把资源分组和隔离。

    • 资源的所有权属于 Project,而不是 User。
    • Project 不必全局唯一,只需在某个域下唯一(对比:Domain、Role 才要求全局唯一)。
    • 创建 VM、创建卷时都必须指定 Project;每个 User(含 admin)必须挂在某个 Project 里、并在该项目下被赋予角色,才能访问其资源。一个 User 可以属于多个 Project。
    • 术语:界面和文档中 Tenant / Project / Account 通用,长期倾向叫 Project;公有云里叫「租户」。公有云场景 Project 对应一个客户,私有云场景对应一个部门或项目组。
    • admin 相当于 root,具有最高权限。

    5. Role(角色)

    Role 是一组预先定义的用户权限和特权,用于执行一组特定操作;角色不同,被赋予的权限不同。

    • 只有知道 User 被赋予了什么 Role,才能判断他是否有权访问某资源。
    • Role 可以被赋予在域上(对域内所有项目都生效),也可以赋予在特定项目上(只对该项目生效)。
    • Role 必须全局唯一;Role 可以继承:在项目树中,拥有父项目的权限即自动拥有对子项目的权限。
    • 实验环境常见角色:admin、_member_(即 member,普通用户),此外还有 reader、ResellerAdmin、SwiftOperator、heat_stack_owner、heat_stack_user 等。

    6. Service(服务)

    Service 是一种 OpenStack 服务,它会对外暴露一个或多个 Endpoint,用户通过这些端点访问资源并执行操作。

    典型 Service:Compute(Nova)、Block Storage(Cinder)、Object Storage(Swift)、Image(Glance)、Networking(Neutron)、Identity(Keystone 自己)、Orchestration(Heat)、Placement 等。

    7. Endpoint(端点)

    Endpoint 是一个可以用来访问某个具体服务的网络地址,通常就是一个 URL。

    • Service 通过 Endpoint 暴露自己的 API;Keystone 负责登记和维护每个 Service 的 Endpoint。
    • 每个服务历史上有三类入口:admin / internal / public(详见后文「补充」)。

    8. Token(令牌)

    Token 是允许访问特定资源的凭证,一串由数字和字母组成的字符串。

    • User 成功 Authentication 后,Keystone 生成并签发 Token。
    • Token 用作访问 Service 的 Credential;Service 收到请求后会拿着 Token 去 Keystone 校验有效性。
    • Token 中包含 User 的 Role 信息(这是后面鉴权能成立的关键)。
    • Token 默认有效期 24 小时(实际部署常用 1 小时,见「补充」)。

    9. Credential(凭证)

    Credential 是确认用户身份的数据,用来证明「我是谁」。

    常见形式:① 用户名/密码;② Token;③ API Key;④ 其他高级方式(如证书、联邦身份)。

    九大概念关系图

    #mermaid-svg-c1oImSaGuU65KLja{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-c1oImSaGuU65KLja .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-c1oImSaGuU65KLja .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-c1oImSaGuU65KLja .error-icon{fill:#552222;}#mermaid-svg-c1oImSaGuU65KLja .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-c1oImSaGuU65KLja .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-c1oImSaGuU65KLja .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-c1oImSaGuU65KLja .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-c1oImSaGuU65KLja .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-c1oImSaGuU65KLja .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-c1oImSaGuU65KLja .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-c1oImSaGuU65KLja .marker{fill:#333333;stroke:#333333;}#mermaid-svg-c1oImSaGuU65KLja .marker.cross{stroke:#333333;}#mermaid-svg-c1oImSaGuU65KLja svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-c1oImSaGuU65KLja p{margin:0;}#mermaid-svg-c1oImSaGuU65KLja .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-c1oImSaGuU65KLja .cluster-label text{fill:#333;}#mermaid-svg-c1oImSaGuU65KLja .cluster-label span{color:#333;}#mermaid-svg-c1oImSaGuU65KLja .cluster-label span p{background-color:transparent;}#mermaid-svg-c1oImSaGuU65KLja .label text,#mermaid-svg-c1oImSaGuU65KLja span{fill:#333;color:#333;}#mermaid-svg-c1oImSaGuU65KLja .node rect,#mermaid-svg-c1oImSaGuU65KLja .node circle,#mermaid-svg-c1oImSaGuU65KLja .node ellipse,#mermaid-svg-c1oImSaGuU65KLja .node polygon,#mermaid-svg-c1oImSaGuU65KLja .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-c1oImSaGuU65KLja .rough-node .label text,#mermaid-svg-c1oImSaGuU65KLja .node .label text,#mermaid-svg-c1oImSaGuU65KLja .image-shape .label,#mermaid-svg-c1oImSaGuU65KLja .icon-shape .label{text-anchor:middle;}#mermaid-svg-c1oImSaGuU65KLja .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-c1oImSaGuU65KLja .rough-node .label,#mermaid-svg-c1oImSaGuU65KLja .node .label,#mermaid-svg-c1oImSaGuU65KLja .image-shape .label,#mermaid-svg-c1oImSaGuU65KLja .icon-shape .label{text-align:center;}#mermaid-svg-c1oImSaGuU65KLja .node.clickable{cursor:pointer;}#mermaid-svg-c1oImSaGuU65KLja .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-c1oImSaGuU65KLja .arrowheadPath{fill:#333333;}#mermaid-svg-c1oImSaGuU65KLja .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-c1oImSaGuU65KLja .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-c1oImSaGuU65KLja .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c1oImSaGuU65KLja .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-c1oImSaGuU65KLja .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c1oImSaGuU65KLja .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-c1oImSaGuU65KLja .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-c1oImSaGuU65KLja .cluster text{fill:#333;}#mermaid-svg-c1oImSaGuU65KLja .cluster span{color:#333;}#mermaid-svg-c1oImSaGuU65KLja div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-c1oImSaGuU65KLja .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-c1oImSaGuU65KLja rect.text{fill:none;stroke-width:0;}#mermaid-svg-c1oImSaGuU65KLja .icon-shape,#mermaid-svg-c1oImSaGuU65KLja .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-c1oImSaGuU65KLja .icon-shape p,#mermaid-svg-c1oImSaGuU65KLja .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-c1oImSaGuU65KLja .icon-shape .label rect,#mermaid-svg-c1oImSaGuU65KLja .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-c1oImSaGuU65KLja .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-c1oImSaGuU65KLja .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-c1oImSaGuU65KLja :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    身份与资源(都在 Domain 内)

    包含多个

    批量授权

    被授权到

    提交验证

    登录后获得

    携带访问

    可授予 User / Group / Project

    Domain 域(全局唯一)

    Group 用户组

    User 用户(域内唯一)

    Project 项目(域内唯一)

    Role 角色(全局唯一,可继承)

    Credential 凭证(密码/Token/API Key)

    Token 令牌(含 Role)

    Service 服务

    Endpoint 端点(URL)


    三、Authentication 与 Authorization:安全的两件事

    OpenStack 的安全由两部分组成:

    • Authentication(认证)=「你是谁?」——提交用户名密码等 Credential,Keystone 核对通过后发 Token。
    • Authorization(鉴权)=「你能干什么?」——Keystone 借助 Role 实现:Keystone 定义 Role、给 User/Group 分配 Role;真正「每个 Role 能干什么」由各个 Service 自己决定。

    鉴权是怎么落地的:policy 文件

    • 每个 Service 通过各自的 policy 文件对 Role 做访问控制,规则以 JSON 格式写在 policy.json。
    • 策略文件路径规则:/etc/SERVICE_NAME/policy.json,例如 /etc/keystone/policy.json、/etc/nova/policy.json、/etc/glance/policy.json。
    • packstack 安装时,Dashboard 相关策略放在 /etc/openstack-dashboard/ 下,形如 cinder_policy.json、glance_policy.json、keystone_policy.json、neutron_policy.json、nova_policy.json。
    • OpenStack 默认配置只区分 admin 和非 admin 两类角色;若要给自定义角色精细授权,需要改 policy(一般不建议改)。

    #mermaid-svg-iNrQ7N3tkCAIlz76{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iNrQ7N3tkCAIlz76 .error-icon{fill:#552222;}#mermaid-svg-iNrQ7N3tkCAIlz76 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iNrQ7N3tkCAIlz76 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .marker.cross{stroke:#333333;}#mermaid-svg-iNrQ7N3tkCAIlz76 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iNrQ7N3tkCAIlz76 p{margin:0;}#mermaid-svg-iNrQ7N3tkCAIlz76 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .cluster-label text{fill:#333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .cluster-label span{color:#333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .cluster-label span p{background-color:transparent;}#mermaid-svg-iNrQ7N3tkCAIlz76 .label text,#mermaid-svg-iNrQ7N3tkCAIlz76 span{fill:#333;color:#333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .node rect,#mermaid-svg-iNrQ7N3tkCAIlz76 .node circle,#mermaid-svg-iNrQ7N3tkCAIlz76 .node ellipse,#mermaid-svg-iNrQ7N3tkCAIlz76 .node polygon,#mermaid-svg-iNrQ7N3tkCAIlz76 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iNrQ7N3tkCAIlz76 .rough-node .label text,#mermaid-svg-iNrQ7N3tkCAIlz76 .node .label text,#mermaid-svg-iNrQ7N3tkCAIlz76 .image-shape .label,#mermaid-svg-iNrQ7N3tkCAIlz76 .icon-shape .label{text-anchor:middle;}#mermaid-svg-iNrQ7N3tkCAIlz76 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iNrQ7N3tkCAIlz76 .rough-node .label,#mermaid-svg-iNrQ7N3tkCAIlz76 .node .label,#mermaid-svg-iNrQ7N3tkCAIlz76 .image-shape .label,#mermaid-svg-iNrQ7N3tkCAIlz76 .icon-shape .label{text-align:center;}#mermaid-svg-iNrQ7N3tkCAIlz76 .node.clickable{cursor:pointer;}#mermaid-svg-iNrQ7N3tkCAIlz76 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .arrowheadPath{fill:#333333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iNrQ7N3tkCAIlz76 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iNrQ7N3tkCAIlz76 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iNrQ7N3tkCAIlz76 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iNrQ7N3tkCAIlz76 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iNrQ7N3tkCAIlz76 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iNrQ7N3tkCAIlz76 .cluster text{fill:#333;}#mermaid-svg-iNrQ7N3tkCAIlz76 .cluster span{color:#333;}#mermaid-svg-iNrQ7N3tkCAIlz76 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iNrQ7N3tkCAIlz76 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iNrQ7N3tkCAIlz76 rect.text{fill:none;stroke-width:0;}#mermaid-svg-iNrQ7N3tkCAIlz76 .icon-shape,#mermaid-svg-iNrQ7N3tkCAIlz76 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iNrQ7N3tkCAIlz76 .icon-shape p,#mermaid-svg-iNrQ7N3tkCAIlz76 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iNrQ7N3tkCAIlz76 .icon-shape .label rect,#mermaid-svg-iNrQ7N3tkCAIlz76 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iNrQ7N3tkCAIlz76 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iNrQ7N3tkCAIlz76 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iNrQ7N3tkCAIlz76 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    有效,取出 Role

    允许

    拒绝

    用户请求(携带 Token)

    目标 Service(如 Glance)

    去 Keystone 校验 Token 是否有效

    读自己的 policy.json / policy.yaml

    当前 Role 允许该操作?

    执行并返回资源

    返回 403 禁止访问


    四、架构与组件(补充)

    标注「补充」的内容理解本模块必需。

    【补充】Keystone 部署形态: Keystone 本身不是一个长驻的独立守护进程,而是跑在 HTTPD(Apache)+ WSGI 上的一组应用。改完 Dashboard 或 Keystone 配置后,常需 systemctl restart httpd 生效。

    【补充】Keystone 内部子系统(fronting services):

    子系统职责
    identity 校验 User/Credential(用户名密码、域、用户)
    assignment 管理 User/Group 与 Project/Domain 之间的角色绑定
    resource 管理 Domain、Project 层级(parent/child)
    token 签发与校验 Token(当前默认 Fernet)
    catalog 维护 Service 与 Endpoint 目录
    policy 提供策略规则

    【补充】多站点 Region: 一个 OpenStack 部署可以有多个 Region(本实验是 RegionOne)。同一套 Keystone 可以登记分布在不同 Region 的服务,客户端按 Region 选择就近访问。

    【补充】Endpoint 三类接口: 历史上每个服务登记三个 endpoint——

    • adminURL:供管理员操作,通常对内网开放;
    • internalURL:集群内部服务之间互访;
    • publicURL:终端用户从外部访问。 新版 OpenStack 已逐步弱化三入口区分,日常 openstack catalog list 看到的一般是统一地址。

    #mermaid-svg-Veg26MBTelAbP9xI{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Veg26MBTelAbP9xI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Veg26MBTelAbP9xI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Veg26MBTelAbP9xI .error-icon{fill:#552222;}#mermaid-svg-Veg26MBTelAbP9xI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Veg26MBTelAbP9xI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Veg26MBTelAbP9xI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Veg26MBTelAbP9xI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Veg26MBTelAbP9xI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Veg26MBTelAbP9xI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Veg26MBTelAbP9xI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Veg26MBTelAbP9xI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Veg26MBTelAbP9xI .marker.cross{stroke:#333333;}#mermaid-svg-Veg26MBTelAbP9xI svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Veg26MBTelAbP9xI p{margin:0;}#mermaid-svg-Veg26MBTelAbP9xI .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Veg26MBTelAbP9xI .cluster-label text{fill:#333;}#mermaid-svg-Veg26MBTelAbP9xI .cluster-label span{color:#333;}#mermaid-svg-Veg26MBTelAbP9xI .cluster-label span p{background-color:transparent;}#mermaid-svg-Veg26MBTelAbP9xI .label text,#mermaid-svg-Veg26MBTelAbP9xI span{fill:#333;color:#333;}#mermaid-svg-Veg26MBTelAbP9xI .node rect,#mermaid-svg-Veg26MBTelAbP9xI .node circle,#mermaid-svg-Veg26MBTelAbP9xI .node ellipse,#mermaid-svg-Veg26MBTelAbP9xI .node polygon,#mermaid-svg-Veg26MBTelAbP9xI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Veg26MBTelAbP9xI .rough-node .label text,#mermaid-svg-Veg26MBTelAbP9xI .node .label text,#mermaid-svg-Veg26MBTelAbP9xI .image-shape .label,#mermaid-svg-Veg26MBTelAbP9xI .icon-shape .label{text-anchor:middle;}#mermaid-svg-Veg26MBTelAbP9xI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Veg26MBTelAbP9xI .rough-node .label,#mermaid-svg-Veg26MBTelAbP9xI .node .label,#mermaid-svg-Veg26MBTelAbP9xI .image-shape .label,#mermaid-svg-Veg26MBTelAbP9xI .icon-shape .label{text-align:center;}#mermaid-svg-Veg26MBTelAbP9xI .node.clickable{cursor:pointer;}#mermaid-svg-Veg26MBTelAbP9xI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Veg26MBTelAbP9xI .arrowheadPath{fill:#333333;}#mermaid-svg-Veg26MBTelAbP9xI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Veg26MBTelAbP9xI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Veg26MBTelAbP9xI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Veg26MBTelAbP9xI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Veg26MBTelAbP9xI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Veg26MBTelAbP9xI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Veg26MBTelAbP9xI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Veg26MBTelAbP9xI .cluster text{fill:#333;}#mermaid-svg-Veg26MBTelAbP9xI .cluster span{color:#333;}#mermaid-svg-Veg26MBTelAbP9xI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Veg26MBTelAbP9xI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Veg26MBTelAbP9xI rect.text{fill:none;stroke-width:0;}#mermaid-svg-Veg26MBTelAbP9xI .icon-shape,#mermaid-svg-Veg26MBTelAbP9xI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Veg26MBTelAbP9xI .icon-shape p,#mermaid-svg-Veg26MBTelAbP9xI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Veg26MBTelAbP9xI .icon-shape .label rect,#mermaid-svg-Veg26MBTelAbP9xI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Veg26MBTelAbP9xI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Veg26MBTelAbP9xI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Veg26MBTelAbP9xI :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    controller 节点

    客户端侧

    Horizon Dashboard 浏览器

    openstack CLI / SDK

    HTTPD + WSGI 入口(端口 5000)

    identity 子系统

    assignment 子系统

    resource 子系统

    token 子系统(Fernet)

    catalog 子系统

    policy 子系统

    后端:MySQL(身份/项目/角色数据)

    Memcached(Token 缓存)

    fernet-keys 对称密钥库


    五、关键配置与环境变量

    5.1 命令行前置:source 环境变量

    操作 OpenStack CLI 前必须先导入环境变量,否则 openstack 命令不知道往哪里连、以谁的身份连:

    [root@controller ~]# source keystonerc_admin
    # 导入后命令行提示符变成:[root@controller ~(keystone_admin)]#

    5.2 自定义用户的 openrc 环境变量文件(实验手册)

    以 User_cli_01 为例:从 admin 的环境变量复制一份,再改成自己的账号:

    cp keystonerc_admin keystonerc_User_cli_01
    vim keystonerc_User_cli_01

    文件内容(关键项逐条解释):

    unset OS_SERVICE_TOKEN
    export OS_USERNAME=User_cli_01 # 自己的用户名
    export OS_PASSWORD='huawei' # 登录密码
    export OS_REGION_NAME=RegionOne # 所在 Region
    export OS_AUTH_URL=http://192.168.108.10:5000/v3 # Keystone v3 地址
    export PS1='[\\u@\\h \\W(keystone_User_cli_01)]\\$ ' # 提示符装饰
    export OS_PROJECT_NAME=admin # 以哪个项目身份登录
    export OS_USER_DOMAIN_NAME=Default # 用户所属域
    export OS_PROJECT_DOMAIN_NAME=Default # 项目所属域
    export OS_IDENTITY_API_VERSION=3 # 用 v3 API

    生效:

    source keystonerc_User_cli_01

    5.3 多域登录开关(Dashboard)

    cd /etc/openstack-dashboard/
    vim local_settings
    # 第 83 行改为:
    OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
    systemctl restart httpd # 改完必须重启 httpd

    开启后登录界面会多出「域」输入框,可选择以不同域身份登录。

    5.4 打开 debug 日志

    cd /etc/keystone/
    ls
    # 常见文件:default_catalog.templates fernet-keys keystone.conf logging.conf
    # policy.d policy.json puppet.conf sso_callback_template.html
    vim keystone.conf
    # 第 94 行改为:
    debug=True

    日志位置:/var/log/keystone/keystone.log。排查问题第一手段就是看各服务自己的日志。


    六、Dashboard(Horizon)操作

    Horizon 左侧导航 「身份管理(Identity)」 下分三块:项目(Project)、用户(User)、组(Group)、角色(Role)。

    6.1 创建角色

    路径:身份管理 > 角色 → 右上角「创建角色」→ 输入名称如 Role_web →「提交」。

    6.2 创建用户

    路径:身份管理 > 用户 →「创建用户」,填写:

    字段示例值
    用户名 User_web_01
    密码 自行设置并记录
    项目 选系统已有的 admin
    角色 选刚建的 Role_web

    照同样步骤再建 User_web_02,角色直接选 admin。

    6.3 创建用户组并加成员

  • 路径:身份管理 > 组 →「创建组」→ 名称 Group_web。
  • 在组所在行点「管理成员」→ 右上角「添加用户」→ 勾选 User_web_01、User_web_02 →「添加用户」。
  • 验证:身份管理 > 用户 → 点 User_web_01 进「概览」页 → 切到「角色分配」页签看角色;切到「组」页签看所属组。
  • 6.4 不同角色登录后的界面差异(重点现象)

    点右上角 admin →「退出」,再分别用两个用户登录:

    • **User_web_02(admin 角色)**:菜单齐全,能看到「管理员」整组菜单,以及「域 / 组 / 角色」等管理入口。
    • **User_web_01(只有 Role_web / 普通 _member_ 角色)**:导航栏明显变瘦——少了「管理员」整组,也看不到「域 / 组 / 角色」这些管理项。

    这就是「鉴权决定菜单可见性」的直观表现:Horizon 拿到 Token 后,按其中 Role 渲染菜单。

    6.5 禁用与删除用户(关键区别)

  • 身份管理 > 组 → Group_web 的「管理成员」→ 勾选 User_web_02 →「删除用户」。
    • 现象:该用户只是从组里被移除,系统里用户仍然存在,用 User_web_02 仍可登录。
  • 身份管理 > 用户 → User_web_02 行「编辑」→「禁用用户」。
    • 现象:列表 Enabled 列由 Yes 变 No;此时再用该用户登录会被拒。
  • 勾选 User_web_02 → 右上角「删除用户」→ 确认。这才是真正从系统删除。
  • 记忆三连:移出组 ≠ 删人;禁用 = 冻结账号(Enabled No);删除 = 物理消失。

    6.6 创建项目并改配额

  • 身份管理 > 项目 →「创建项目」→「项目信息」页签填名称 Project_web,其他默认。
  • 切到「项目成员」页签 → 把 User_web_01 选到右侧 → 点其角色框,只勾选 admin →「创建项目」。
  • 进项目概览 →「用户」页签可看到成员及角色。
  • 改配额:项目列表 Project_web 行 Actions 列「管理成员」旁的下拉 →「修改配额」→ 在「计算 / 卷 / 网络」页签分别改(如实例 5、卷 5、网络 5)→「保存」。
  • 验证:注销后用 User_web_01 登录,左上角切换当前项目到 Project_web,再到 项目 > 计算 > 概况 查看配额变化。

  • 七、CLI 操作(命令 + 输出解读)

    所有命令前都假定已 source keystonerc_admin。

    7.1 Domain 域

    列出域:

    openstack domain list

    输出字段:ID | Name | Enabled | Description。实验中默认有两条:heat(ID 一长串)和 default(Name 为 Default,描述 The default domain)。

    创建域:

    openstack domain create domain-test

    输出字段:description(空)、enabled=True、id(新生成的 UUID)、name=domain-test、options={}、tags=[]。再 openstack domain list 即可看到新增的 domain-test。

    删除域(两步,不能直接删):

    openstack domain set –disable domain-test # 先禁用
    openstack domain delete domain-test # 再删除
    openstack domain list # 验证已消失

    7.2 User 用户

    列出所有用户:

    openstack user list

    输出字段:ID | Name。除 admin 外,能看到 heat_admin、glance、cinder、nova、placement、neutron、swift、heat、heat-cfn、gnocchi、ceilometer、aodh 等服务账号。

    创建用户 user1(密码 HUAWEI):

    openstack user create –password HUAWEI user1

    输出字段:domain_id=default、enabled=True、id=新UUID、name=user1、options={}、password_expires_at=None(密码永不过期)。

    实验手册里更规范的写法(建用户同时指定域、项目,交互输密码):

    openstack user create –domain default –project admin –password-prompt User_cli_01
    # 按提示输入并再次确认密码

    查看用户详情:

    openstack user show user1

    输出与创建时字段一致;禁用后 enabled 会变为 False。

    禁用 / 删除用户:

    openstack user set –disable User_cli_02 # 禁用,Enabled 变 No
    openstack user show User_cli_02 # 验证 enabled 字段
    openstack user delete User_cli_02 # 真正删除
    openstack user list # 验证列表里没了

    7.3 Group 用户组

    openstack group create group1 # 创建组
    openstack group list # 列出所有组(ID|Name)
    openstack group show group1 # 组详情:description/domain_id/id/name
    openstack group add user group1 user1 # 把 user1 加入 group1
    openstack group contains user group1 user1 # 验证成员关系
    # 输出:user1 in group group1

    实验手册中一次性加多个成员、以及从组中移除:

    openstack group add user Group_cli User_cli_01 User_cli_02 # 一次加两人
    openstack group remove user Group_cli User_cli_02 # 从组移除
    openstack group contains user Group_cli User_cli_02 # 移除后不再提示 contains

    7.4 Role 角色与授权

    列出角色:

    openstack role list

    输出字段:ID | Name。实验环境可见:ResellerAdmin、SwiftOperator、admin、_member_、member、heat_stack_owner、reader、heat_stack_user。

    创建角色:

    openstack role create Role_cli

    给「组」授权(在 admin 项目上给 group1 赋 admin 角色):

    openstack role add –project admin –group group1 admin

    给「用户」授权(在 ProjectA 里给 user1 赋 admin):

    openstack role add –user user1 –project ProjectA admin

    实验手册写法:

    openstack role add –project admin –user User_cli_01 Role_cli
    openstack role add –project admin –user User_cli_02 admin
    openstack role add –project Project_cli –user User_cli_01 admin

    查看角色分配:

    openstack role assignment list –names –group group1

    输出字段:Role | User | Group | Project | Domain | System | Inherited。例如给 group1 授 admin 后会显示:

    | admin | | group1@Default | admin@Default | | | False |

    Inherited=False 表示未跨项目树继承;@Default 表示在 Default 域下。

    实验手册的过滤写法:

    openstack role assignment list –names | grep User_cli
    openstack role assignment list –names | grep User_cli_01
    openstack role assignment list –names | grep Group_cli

    7.5 Project 项目与配额

    创建项目:

    openstack project create ProjectA
    # 或显式指定域(实验手册写法):
    openstack project create –domain default Project_cli

    输出字段:description、domain_id=default、enabled=True、id、is_domain=False、name、options={}、parent_id=default(父项目默认是 default 域)、tags=[]。

    查看项目:

    openstack project list
    openstack project show ProjectA

    把项目绑定给用户 / 给用户授项目角色:

    openstack user set –project ProjectA user1
    openstack role add –user user1 –project ProjectA admin

    设置配额(教材示例:实例 3、vcpu 5、内存 5000MB):

    openstack quota set –instance 3 –cores 5 –ram 5000 ProjectA

    字段含义:–instance 实例个数、–cores vCPU 个数、–ram 内存 MB。

    实验手册的配额写法(含卷、网络):

    openstack quota show Project_cli # 查看默认配额
    openstack quota set –instance 5 –volumes 5 –networks 10 Project_cli
    openstack quota show Project_cli | grep -E "instances|volumes|networks"

    现象:用被改配额的用户登录、切到对应项目后,到 项目 > 计算 > 概况 能看到实例/CPU/内存/卷/网络上限随之变化;达到上限后再申请资源会被拒绝。

    7.6 Service 与 Endpoint

    列出所有服务:

    openstack service list

    输出字段:ID | Name | Type。常见对照:

    NameType
    keystone identity
    nova compute
    glance image
    cinderv2 / cinderv3 volumev2 / volumev3
    neutron network
    swift object-store
    heat orchestration
    heat-cfn cloudformation
    placement placement
    ceilometer metering
    aodh alarming
    gnocchi metric

    查看 Endpoint 与服务目录:

    openstack endpoint list # 列出所有端点,可见 admin/internal/public 三个入口
    openstack catalog list # 以服务目录形式列出每个服务及其 endpoint URL

    登录成功后 Keystone 返回给用户的「catalog」就是这张表,客户端靠它知道每个服务该往哪个 URL 发请求。


    八、两个必背流程(时序图)

    8.1 点击「登入」背后发生了什么

    以 admin 登录 Horizon 查看镜像为例:

  • 登录:admin 输入用户名密码 → Dashboard 把 Credential 发给 Keystone → Keystone 校验通过,签发 Token(其中包含 User 的 Role 信息)。
  • 显示操作界面:顶部显示 admin 可访问的项目为 admin;这之前 admin 已经从 Keystone 拿到了各 Service 的 Endpoints,所以能看到实例、镜像、卷等服务入口。
  • 显示镜像列表:
    • admin 把请求发到 Glance 的 Endpoint;
    • Glance 收到后先去 Keystone 询问 admin 的身份是否有效;
    • 再查 /etc/glance/policy.json 判断 admin 是否有「查看 image」权限;
    • 权限通过,Glance 才把镜像列表返回给 admin。

    "Glance"

    "Keystone"

    "Horizon Dashboard"

    "Glance"

    "Keystone"

    "Horizon Dashboard"

    #mermaid-svg-IdGE90VnQeW1Z1Ew{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IdGE90VnQeW1Z1Ew .error-icon{fill:#552222;}#mermaid-svg-IdGE90VnQeW1Z1Ew .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IdGE90VnQeW1Z1Ew .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IdGE90VnQeW1Z1Ew .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IdGE90VnQeW1Z1Ew .marker.cross{stroke:#333333;}#mermaid-svg-IdGE90VnQeW1Z1Ew svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IdGE90VnQeW1Z1Ew p{margin:0;}#mermaid-svg-IdGE90VnQeW1Z1Ew .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IdGE90VnQeW1Z1Ew text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-IdGE90VnQeW1Z1Ew .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-IdGE90VnQeW1Z1Ew .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-IdGE90VnQeW1Z1Ew .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-IdGE90VnQeW1Z1Ew .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-IdGE90VnQeW1Z1Ew #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-IdGE90VnQeW1Z1Ew .sequenceNumber{fill:white;}#mermaid-svg-IdGE90VnQeW1Z1Ew #sequencenumber{fill:#333;}#mermaid-svg-IdGE90VnQeW1Z1Ew #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-IdGE90VnQeW1Z1Ew .messageText{fill:#333;stroke:none;}#mermaid-svg-IdGE90VnQeW1Z1Ew .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IdGE90VnQeW1Z1Ew .labelText,#mermaid-svg-IdGE90VnQeW1Z1Ew .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-IdGE90VnQeW1Z1Ew .loopText,#mermaid-svg-IdGE90VnQeW1Z1Ew .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-IdGE90VnQeW1Z1Ew .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-IdGE90VnQeW1Z1Ew .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-IdGE90VnQeW1Z1Ew .noteText,#mermaid-svg-IdGE90VnQeW1Z1Ew .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-IdGE90VnQeW1Z1Ew .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IdGE90VnQeW1Z1Ew .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IdGE90VnQeW1Z1Ew .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-IdGE90VnQeW1Z1Ew .actorPopupMenu{position:absolute;}#mermaid-svg-IdGE90VnQeW1Z1Ew .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-IdGE90VnQeW1Z1Ew .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-IdGE90VnQeW1Z1Ew .actor-man circle,#mermaid-svg-IdGE90VnQeW1Z1Ew line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-IdGE90VnQeW1Z1Ew :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    "User admin"

    "输入用户名/密码,点登入"

    "提交 Credential(用户名密码)"

    "签发 Token(含 Role=admin)"

    "登录成功,顶部显示当前项目 admin"

    "按 Token 拉取 Service Endpoints 目录"

    "返回 catalog(Nova/Glance/Cinder… 地址)"

    "点击「镜像」"

    "请求镜像列表(携带 Token)"

    "校验 Token 是否有效"

    "有效,返回 Role=admin"

    "查 /etc/glance/policy.json 是否允许查看"

    "返回镜像列表"

    "渲染镜像列表"

    "User admin"

    8.2 以「创建一台 VM」看整个 OpenStack 的认证链路

  • 用户先向 Keystone 提交用户名密码换 Token。
  • 用户向 Nova 发创建 VM 请求,请求 Header 携带 Token。
  • Nova-api 收到后把 Token 转给 Keystone 校验;校验通过,Nova 才开始创建。
  • 创建 VM 不仅要 CPU/内存,还要网络、存储、镜像等资源:
    • Nova 向 Glance 申请镜像(Header 同样带 Token);
    • Nova 向 Neutron 申请网络(Header 同样带 Token);
    • Nova-api 还会把 Token 透传给 Nova-compute,compute 再向 Neutron 发网络操作请求。
  • Glance、Neutron 收到请求后,无一例外都要把 Token 再拿去 Keystone 校验一次,通过才执行。
  • 全部资源就绪、VM 创建完成后,Nova 把成功结果返回给用户。
  • 关键结论:Keystone 只校验 Token 是否有效(你是谁),而「这个 Token 能不能做这件事」由各服务自己的 policy 决定(你能干什么)。 服务之间互相调用也必须带 Token。

    "Neutron"

    "Glance"

    "Nova-compute"

    "Nova-api"

    "Keystone"

    "Neutron"

    "Glance"

    "Nova-compute"

    "Nova-api"

    "Keystone"

    #mermaid-svg-GGSPxZDZNsBMnQjH{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GGSPxZDZNsBMnQjH .error-icon{fill:#552222;}#mermaid-svg-GGSPxZDZNsBMnQjH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GGSPxZDZNsBMnQjH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GGSPxZDZNsBMnQjH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GGSPxZDZNsBMnQjH .marker.cross{stroke:#333333;}#mermaid-svg-GGSPxZDZNsBMnQjH svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GGSPxZDZNsBMnQjH p{margin:0;}#mermaid-svg-GGSPxZDZNsBMnQjH .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-GGSPxZDZNsBMnQjH text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-GGSPxZDZNsBMnQjH .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-GGSPxZDZNsBMnQjH .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-GGSPxZDZNsBMnQjH .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-GGSPxZDZNsBMnQjH .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-GGSPxZDZNsBMnQjH #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-GGSPxZDZNsBMnQjH .sequenceNumber{fill:white;}#mermaid-svg-GGSPxZDZNsBMnQjH #sequencenumber{fill:#333;}#mermaid-svg-GGSPxZDZNsBMnQjH #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-GGSPxZDZNsBMnQjH .messageText{fill:#333;stroke:none;}#mermaid-svg-GGSPxZDZNsBMnQjH .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-GGSPxZDZNsBMnQjH .labelText,#mermaid-svg-GGSPxZDZNsBMnQjH .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-GGSPxZDZNsBMnQjH .loopText,#mermaid-svg-GGSPxZDZNsBMnQjH .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-GGSPxZDZNsBMnQjH .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-GGSPxZDZNsBMnQjH .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-GGSPxZDZNsBMnQjH .noteText,#mermaid-svg-GGSPxZDZNsBMnQjH .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-GGSPxZDZNsBMnQjH .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-GGSPxZDZNsBMnQjH .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-GGSPxZDZNsBMnQjH .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-GGSPxZDZNsBMnQjH .actorPopupMenu{position:absolute;}#mermaid-svg-GGSPxZDZNsBMnQjH .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-GGSPxZDZNsBMnQjH .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-GGSPxZDZNsBMnQjH .actor-man circle,#mermaid-svg-GGSPxZDZNsBMnQjH line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-GGSPxZDZNsBMnQjH :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    "用户"

    "用户名/密码"

    "签发 Token"

    "创建 VM 请求(Header 带 Token)"

    "校验 Token"

    "有效"

    "申请镜像(带 Token)"

    "校验 Token"

    "有效,按 policy 放行"

    "返回镜像数据"

    "下发创建指令(透传 Token)"

    "申请网络资源(带 Token)"

    "校验 Token"

    "有效,按 policy 放行"

    "分配网络"

    "VM 建成"

    "创建成功"

    "用户"


    九、易混点对比表

    对比项一句话区别
    Domain vs Project Domain 是全局唯一的大容器(机构/数据中心);Project 只需域内唯一,是被配额约束的资源集合。
    User vs Group User 是单个实体;Group 是 User 的容器,给组授权 = 批量授权。
    Authentication vs Authorization 认证=你是谁;鉴权=你能干什么。
    Token vs Credential Credential 是「证明身份的数据」(密码/Token/API Key);Token 是认证成功后 Keystone 发的、用作后续凭证的字符串。
    Service vs Endpoint Service 是一项能力(如 Nova);Endpoint 是访问这项能力的具体 URL。
    域角色 vs 项目角色 域角色对域内所有项目生效;项目角色只对单个项目生效。
    移出组 vs 禁用用户 vs 删除用户 移出组=退群;禁用=Enabled 变 No,不能登录但账号还在;删除=系统里彻底消失。
    Tenant / Project / Account 同一概念不同叫法,官方长期统一为 Project,公有云叫租户。
    admin 角色 vs 普通 _member_ admin 看到「管理员」菜单和域/组/角色管理;普通用户菜单精简,看不到这些管理入口。

    十、补充内容(进阶拓展)

    以下内容教材未讲透,是面试和进阶排障高频点,均标注「补充」。

    10.1 【补充】Token 的种类与演进

    Token 类型特点
    UUID Token 早期纯随机字符串,需 Keystone 数据库存储/查询,校验一次就回一次库,性能差。
    PKI / PKIZ Token 基于签名的自包含 Token,信息多、体积大,PKIZ 做了压缩;仍需管理证书。
    Fernet Token 当前默认。不持久化到数据库,用对称密钥本地加解密;支持密钥轮转、体积小、性能高;本环境 /etc/keystone/fernet-keys/ 就是密钥库。
    JWT JSON 格式自包含令牌,联邦/OIDC 场景常见。

    Token 生命周期:默认 24 小时,生产常配为 1 小时;为减轻 Keystone 压力,校验结果常缓存到 Memcached。

    10.2 【补充】RBAC 与三种 scope、Secure RBAC

    • OpenStack 授权模型是 RBAC(基于角色的访问控制)。
    • 角色绑定可以有三种作用范围(scope):
      • project:对某个项目资源生效(最常用);
      • domain:对整个域生效;
      • system:对整个云系统级资源生效(新版引入)。
    • 策略写法从传统 policy.json 演进为 policy in code(policy.yaml)。
    • Secure RBAC 是新规范,把角色收敛为三档:admin(管理)、member(普通项目成员)、reader(只读),替代过去「只分 admin / 非 admin」的粗粒度模型。

    10.3 【补充】联邦身份 Federation 与外部身份源

    • Keystone 可作为 IdP(身份提供者) 或 SP(服务提供者),通过 SAML / OpenID Connect 对接企业统一身份,实现「一次登录访问多个云」。
    • 用户库可对接 LDAP(把公司 AD/LDAP 里的人直接映射成 OpenStack User),而不是在 Keystone 里重复建账号。
    • 应用凭证 Application Credential:给脚本/服务发一个长期凭证,避免把个人密码写进配置文件。

    10.4 【补充】域 / 项目层级树与多租户隔离

    Project 不是平的,而是一棵有父子关系的树:创建项目时 parent_id 默认是当前域;可把子项目挂在父项目下。角色可沿父子方向继承——授予父项目的角色自动作用于子项目。多租户隔离的本质就是:每个 Project 有自己的配额、自己的资源(VM、卷、网络),User 只有在某 Project 下被授了对应 Role,才能看到和操作那部分资源,天然互不可见。

    #mermaid-svg-A3ttmOzEJVHiMorF{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-A3ttmOzEJVHiMorF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-A3ttmOzEJVHiMorF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-A3ttmOzEJVHiMorF .error-icon{fill:#552222;}#mermaid-svg-A3ttmOzEJVHiMorF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-A3ttmOzEJVHiMorF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-A3ttmOzEJVHiMorF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-A3ttmOzEJVHiMorF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-A3ttmOzEJVHiMorF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-A3ttmOzEJVHiMorF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-A3ttmOzEJVHiMorF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-A3ttmOzEJVHiMorF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-A3ttmOzEJVHiMorF .marker.cross{stroke:#333333;}#mermaid-svg-A3ttmOzEJVHiMorF svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-A3ttmOzEJVHiMorF p{margin:0;}#mermaid-svg-A3ttmOzEJVHiMorF .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-A3ttmOzEJVHiMorF .cluster-label text{fill:#333;}#mermaid-svg-A3ttmOzEJVHiMorF .cluster-label span{color:#333;}#mermaid-svg-A3ttmOzEJVHiMorF .cluster-label span p{background-color:transparent;}#mermaid-svg-A3ttmOzEJVHiMorF .label text,#mermaid-svg-A3ttmOzEJVHiMorF span{fill:#333;color:#333;}#mermaid-svg-A3ttmOzEJVHiMorF .node rect,#mermaid-svg-A3ttmOzEJVHiMorF .node circle,#mermaid-svg-A3ttmOzEJVHiMorF .node ellipse,#mermaid-svg-A3ttmOzEJVHiMorF .node polygon,#mermaid-svg-A3ttmOzEJVHiMorF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-A3ttmOzEJVHiMorF .rough-node .label text,#mermaid-svg-A3ttmOzEJVHiMorF .node .label text,#mermaid-svg-A3ttmOzEJVHiMorF .image-shape .label,#mermaid-svg-A3ttmOzEJVHiMorF .icon-shape .label{text-anchor:middle;}#mermaid-svg-A3ttmOzEJVHiMorF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-A3ttmOzEJVHiMorF .rough-node .label,#mermaid-svg-A3ttmOzEJVHiMorF .node .label,#mermaid-svg-A3ttmOzEJVHiMorF .image-shape .label,#mermaid-svg-A3ttmOzEJVHiMorF .icon-shape .label{text-align:center;}#mermaid-svg-A3ttmOzEJVHiMorF .node.clickable{cursor:pointer;}#mermaid-svg-A3ttmOzEJVHiMorF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-A3ttmOzEJVHiMorF .arrowheadPath{fill:#333333;}#mermaid-svg-A3ttmOzEJVHiMorF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-A3ttmOzEJVHiMorF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-A3ttmOzEJVHiMorF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A3ttmOzEJVHiMorF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-A3ttmOzEJVHiMorF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A3ttmOzEJVHiMorF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-A3ttmOzEJVHiMorF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-A3ttmOzEJVHiMorF .cluster text{fill:#333;}#mermaid-svg-A3ttmOzEJVHiMorF .cluster span{color:#333;}#mermaid-svg-A3ttmOzEJVHiMorF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-A3ttmOzEJVHiMorF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-A3ttmOzEJVHiMorF rect.text{fill:none;stroke-width:0;}#mermaid-svg-A3ttmOzEJVHiMorF .icon-shape,#mermaid-svg-A3ttmOzEJVHiMorF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A3ttmOzEJVHiMorF .icon-shape p,#mermaid-svg-A3ttmOzEJVHiMorF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-A3ttmOzEJVHiMorF .icon-shape .label rect,#mermaid-svg-A3ttmOzEJVHiMorF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A3ttmOzEJVHiMorF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-A3ttmOzEJVHiMorF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-A3ttmOzEJVHiMorF :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Default 域

    继承

    继承

    项目树根(default 域)

    ProjectA(父项目)

    ProjectB(父项目)

    子项目 A1

    子项目 A2

    admin 角色(授予父项目 ProjectA)


    十一、本篇小结

    • Keystone 是 OpenStack 的身份中心:管用户权限、管服务 Endpoint 目录、做认证与鉴权。
    • 九大概念要成对记:Domain/User/Group/Project 是「容器与人」,Role/Service/Endpoint 是「权限与地址」,Token/Credential 是「通行证与身份证明」。
    • 唯一性范围是高频考点:Domain、Role 全局唯一;User、Project 只需域内唯一。
    • 认证(你是谁)由 Keystone 发 Token;鉴权(你能干什么)由各服务 policy + Role 决定。
    • 一次请求的标准动作链:带 Token 访问服务 → 服务拿 Token 去 Keystone 校验 → 查 policy → 放行或拒绝。
    • 操作分 Dashboard 与 CLI 两条线,命令要形成肌肉记忆:openstack user/project/group/role/domain/service/endpoint/quota 各有 list/create/show/add/set/delete。

    十二、重点速记

    速记项内容
    三件事 管用户权限、维护 Endpoint、认证 + 鉴权
    全局唯一 Domain、Role
    域内唯一 User、Project
    管理员账号 / 密码 admin / huawei
    controller IP 192.168.108.10
    OS_AUTH_URL http://192.168.108.10:5000/v3
    Region RegionOne
    日志 /var/log/keystone/keystone.log
    配置目录 /etc/keystone/(keystone.conf,debug=True 在第 94 行)
    Dashboard 多域开关 /etc/openstack-dashboard/local_settings 第 83 行 OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True,改完 systemctl restart httpd
    配额三件套 openstack quota set –instance N –cores N –ram MB 项目名
    登录前必做 source keystonerc_admin
    默认角色二分 admin vs 非 admin(_member_/member)

    口诀: 「域管容器、人在域中、组批量授权、项目分资源、角色定权限、服务挂端点、Token 当通行证、密码是凭证。」


    十三、自测题(附参考答案)

    A. 名词解释

  • Domain:一组 User/Group/Project 的容器,是虚拟管理边界,可对应一个机构或数据中心,必须全局唯一。
  • Token:User 通过 Keystone 认证后获得的访问凭证(字符串),内含 Role 信息,后续访问各服务都要携带并被 Keystone 校验,默认有效期 24 小时。
  • Endpoint:可访问某个具体 Service 的网络地址(通常是 URL),由 Keystone 统一登记维护。
  • Role:一组预定义权限的集合,全局唯一,可授予 User/Group,可在项目树中继承;决定用户能干什么。
  • B. 选择题

  • 下面哪个对象只需在「域内唯一」,不必全局唯一?(C)
    • A. Domain B. Role C. Project D. 以上都不对
  • 用户 _member_ 角色登录 Horizon 后,相比 admin 少看到哪一组菜单?(B)
    • A. 镜像 B. 「管理员」及「域/组/角色」 C. 实例 D. 卷
  • 关于从用户组里移除用户,正确的是?(A)
    • A. 只是退出该组,用户本体仍存在、仍可登录
    • B. 等同于删除用户
    • C. 等同于禁用用户
  • Keystone 校验完 Token 后,判断「能否执行某操作」依据的是?(C)
    • A. 用户密码 B. Token 长度 C. 目标服务自己的 policy 文件与 Role D. 数据库大小

    C. 简答题

  • 说出点击 Horizon「登入」后内部发生的三步。 答:① 提交用户名密码给 Keystone,校验通过签发含 Role 的 Token;② 凭 Token 从 Keystone 拉取各 Service 的 Endpoints 目录,据此渲染顶部项目和服务菜单;③ 点具体服务(如镜像)时,请求带 Token 发到该服务 Endpoint,服务再去 Keystone 校验 Token、查自己的 policy,通过才返回数据。
  • 为什么服务之间互相调用也要带 Token?只让 Keystone 校验不就够了吗? 答:Keystone 只回答「Token 有效吗、这个 User 有什么 Role」,不回答「Nova 能不能调 Neutron 建网」。每个服务要各自拿着 Token 回 Keystone 验证身份,再结合自己的 policy 决定是否执行——这样才能做到细粒度、可审计的鉴权。
  • 写出把 ProjectA 配额改为「实例 3、vCPU 5、内存 5000MB」的命令。 答:openstack quota set –instance 3 –cores 5 –ram 5000 ProjectA
  • 思考拓展(教材思考题):参照创建 ProjectA 的方式,新建 ProjectB 分给 user2 并授 admin;再建 user3 并在 ProjectA 中授 member 角色。写出关键命令。 答:
  • openstack project create ProjectB
    openstack user create –password HUAWEI user2
    openstack role add –user user2 –project ProjectB admin
    openstack user create –password HUAWEI user3
    openstack role add –user user3 –project ProjectA member

  • 实验手册思考题:直接给组 Group_cli 在 Project_cli 上授 admin 是否可行? 答:可行。openstack role add –project Project_cli –group Group_cli admin,再用 openstack role assignment list –names | grep Group_cli 验证——组里的成员因此批量获得该项目的 admin 角色,这正是 Group 批量授权的价值。
  • 赞(0)
    未经允许不得转载:171主机测评 » 01 · 认证管理 Keystone
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址