1 2 3 4 5 6 7 作者:李晓辉 联系方式: 1. 微信:Lxh_Chat 2. 邮箱:939958092@qq.com
作用域概述 在 OpenStack 的身份服务 v3 之前,用户和项目的关系是一对一的,用户只能属于一个项目。这就像是你只能在一个班级里,不能同时参加多个班级的活动。
但随着身份服务 v3 的引入,用户和项目的关系变成了多对多。用户现在是属于“域”(Domain)的,而项目也可以属于同一个域。这样,一个用户可以属于多个项目,一个项目也可以有多个用户。
具体来说:
域(Domain) :可以理解为一个大的组织或公司。比如,一个公司可以有多个部门,每个部门都可以有自己的项目。
用户(User) :就是具体的个人。你、我、他都可以是一个用户。
项目(Project) :可以理解为一个具体的任务或团队。比如,一个公司有多个部门,每个部门都可以有自己的项目。
在身份服务 v3 中:
用户属于一个或多个域。
项目属于一个或多个域。
用户可以通过域来关联到多个项目。
这就像是在一个公司里,你(用户)可以同时属于多个部门(项目),因为这些部门都属于同一个公司(域)。这样就更灵活了,方便你在不同的项目里工作,不用局限于一个项目了。
让我们重温一下域和项目之类的关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 +--------------------+ | OpenStack | +--------------------+ | +-----------------------------------------+ | | +------------------+ +------------------+ | Domain 1 | | Domain 2 | +------------------+ +------------------+ | | +------------------+ +------------------+ | Project 1 | | Project 3 | +------------------+ +------------------+ | Project 2 | | Project 4 | +------------------+ +------------------+ | | +------------------+ +------------------+ | Group A | | Group C | +------------------+ +------------------+ | Group B | | Group D | +------------------+ +------------------+ | | +------------------+ +------------------+ | User A | | User C | +------------------+ +------------------+ | User B | | User D | +------------------+ +------------------+
创建域 创建了一个lxh-domain的域
1 2 3 4 5 6 7 8 9 10 11 (overcloud) [stack@director ~]$ openstack domain create lxh-domain +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | | | enabled | True | | id | 750c06bbb1ca4179a41fc866eb48d13c | | name | lxh-domain | | options | {} | | tags | [] | +-------------+----------------------------------+
创建普通项目 在lxh-domain中创建一个项目,名为lxh-project1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 (overcloud) [stack@director ~]$ openstack project create lxh-project1 --domain lxh-domain +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | | | domain_id | 750c06bbb1ca4179a41fc866eb48d13c | | enabled | True | | id | 733e55768ff44a7ab5d5dd8368cc365a | | is_domain | False | | name | lxh-project1 | | options | {} | | parent_id | 750c06bbb1ca4179a41fc866eb48d13c | | tags | [] | +-------------+----------------------------------+
创建嵌套项目 一个project相当于一个集团公司的事业群,这是一个超级大部门,在这个超级大部门中,会存在很多小的子公司或者小部门,此时可以用嵌套项目来完成
在lxh-project1中,创建一个lxh-sub-project1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 (overcloud) [stack@director ~]$ openstack project create lxh-sub-project1 --parent lxh-project1 --domain lxh-domain +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | | | domain_id | 750c06bbb1ca4179a41fc866eb48d13c | | enabled | True | | id | d7ef9bad79964f1a8c4143cb5d71ef45 | | is_domain | False | | name | lxh-sub-project1 | | options | {} | | parent_id | 733e55768ff44a7ab5d5dd8368cc365a | | tags | [] | +-------------+----------------------------------+
在项目中创建用户 在 OpenStack 中创建一个新用户 lxhuser
,并将其分配到名为 lxh-sub-project1
的子项目中,同时指定该用户属于 lxh-domain
域,并设置密码为 lixiaohui
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 (overcloud) [stack@director ~]$ openstack user create --project lxh-sub-project1 --domain lxh-domain lxhuser --password lixiaohui +---------------------+----------------------------------+ | Field | Value | +---------------------+----------------------------------+ | default_project_id | d7ef9bad79964f1a8c4143cb5d71ef45 | | domain_id | 750c06bbb1ca4179a41fc866eb48d13c | | enabled | True | | id | 21462c6e77e54b52ae115200d1587e80 | | name | lxhuser | | options | {} | | password_expires_at | None | +---------------------+----------------------------------+ (overcloud) [stack@director ~]$ openstack user list --domain lxh-domain +----------------------------------+---------+ | ID | Name | +----------------------------------+---------+ | 21462c6e77e54b52ae115200d1587e80 | lxhuser | +----------------------------------+---------+
管理角色和权限 在OpenStack环境里,用户在登录时得指定一个项目,不然就没办法验证身份。所以,每个用户至少得被分配到一个项目里,才能正常使用。身份验证这块是靠基于角色的访问控制(RBAC)来搞定的。管理员可以通过给用户或者用户组分配不同的角色,来决定他们能访问哪些域和项目,这样就能灵活地控制权限啦。
授予用户管理员角色 在OpenStack中给用户lxhuser
分配admin
角色,使其能够访问lxh-project1
项目,同时用户和项目都属于lxh-domain
域。
1 (overcloud) [stack@director ~]$ openstack role add --user lxhuser --user-domain lxh-domain --project lxh-project1 --project-domain lxh-domain admin
1 2 3 4 5 (overcloud) [stack@director ~]$ openstack role assignment list --user lxhuser --user-domain lxh-domain --names +-------+---------------------+-------+-------------------------+------------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +-------+---------------------+-------+-------------------------+------------+--------+-----------+ | admin | lxhuser@lxh-domain | | lxh-project1@lxh-domain | | | False |
角色继承 如果启用了角色继承,当组 lxhgroup
在域 lxh-domain
中被赋予了 admin
角色,那么组中的成员(比如 lxhuser
)会自动继承这个角色的权限到该域下的所有项目中。也就是说,lxhuser
在 lxh-domain
下的所有项目里都会拥有 admin
权限,而不需要再单独为每个项目分配角色。这样确实很方便,减少了重复操作,也更高效。
1 2 3 4 5 6 7 8 9 10 11 (overcloud) [stack@director ~]$ openstack group create lxhgroup --domain lxh-domain +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | | | domain_id | 750c06bbb1ca4179a41fc866eb48d13c | | id | b0e3aa43023d47bba6ae40e88892d73d | | name | lxhgroup | +-------------+----------------------------------+ (overcloud) [stack@director ~]$ openstack group add user --group-domain lxh-domain --user-domain lxh-domain lxhgroup lxhuser
看看人加进去没有
1 2 (overcloud) [stack@director ~]$ openstack group contains user lxhgroup lxhuser --group-domain lxh-domain --user-domain lxh-domain lxhuser in group lxhgroup
我们为组 lxhgroup 在 lxh-domain 域中赋予 admin 角色,并使其继承到该域下的所有项目
1 2 3 4 5 6 7 (overcloud) [stack@director ~]$ openstack role add --group lxhgroup --group-domain lxh-domain --project lxh-project1 --project-domain lxh-domain --inherited admin (overcloud) [stack@director ~]$ openstack role assignment list --group lxhgroup --group-domain lxh-domain --names +-------+------+---------------------+-------------------------+------------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +-------+------+---------------------+-------------------------+------------+--------+-----------+ | admin | | lxhgroup@lxh-domain | lxh-project1@lxh-domain | | | True |
自定义用户角色 除了标准的member和admin之类的,还可以自己创建角色,并关联到用户
自定义的角色没有权限,所以需要自己写策略,策略的规则部分可能更为复杂,并⽀持布尔运算符。此⽰例显⽰了多个条件的连接词,比如and 和 or
例子:
1 2 "<target>": "role:reader and system_scope:all" "<target>": "is_admin:True or project_id:%(project_id)s"
我们创建一个lxh-role的角色,然后再创建一个lxhuser2,并使其关联我们的角色,然后我们制定一些策略到我们的角色上,看看有没有效果
创建角色和用户 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 (overcloud) [stack@director ~]$ openstack role create role1 +-------------+----------------------------------+ | Field | Value | +-------------+----------------------------------+ | description | None | | domain_id | None | | id | bb2314902df4413bbf4bf55aa55cbb5a | | name | role1 | | options | {} | +-------------+----------------------------------+ (overcloud) [stack@director ~]$ openstack user create user1 --domain lxh-domain --password lxhpassword +---------------------+----------------------------------+ | Field | Value | +---------------------+----------------------------------+ | domain_id | 3cbf4e2f874b4662b689b69480362ae7 | | enabled | True | | id | 89bbca2e8b3f43638182a8976ddab838 | | name | user1 | | options | {} | | password_expires_at | None | +---------------------+----------------------------------+
关联角色到用户 1 2 3 4 5 6 7 (overcloud) [stack@director ~]$ openstack role add --user user1 --user-domain lxh-domain --project lxh-project1 --project-domain lxh-domain role1 (overcloud) [stack@director ~]$ openstack role assignment list --user user1 --user-domain lxh-domain --names +-------+------------------+-------+-------------------------+--------+--------+-----------+ | Role | User | Group | Project | Domain | System | Inherited | +-------+------------------+-------+-------------------------+--------+--------+-----------+ | role1 | user1@lxh-domain | | lxh-project1@lxh-domain | | | False | +-------+------------------+-------+-------------------------+--------+--------+-----------+
此时角色是空的,什么权限都没有,我们用这个角色来获取一下主机聚合
用超级用户可以获取
1 2 3 4 5 6 7 8 9 (overcloud) [stack@director ~]$ source overcloudrc (overcloud) [stack@director ~]$ openstack hypervisor list +--------------------------------------+-----------------------------------+-----------------+-------------+-------+ | ID | Hypervisor Hostname | Hypervisor Type | Host IP | State | +--------------------------------------+-----------------------------------+-----------------+-------------+-------+ | 4ae32d90-761d-4920-8b20-598f21c9d12e | compute1.overcloud.example.com | QEMU | 172.24.1.12 | up | | a54675fc-0ba3-4872-8b76-4fb094b41d30 | computehci0.overcloud.example.com | QEMU | 172.24.1.6 | up | | b506a957-3a44-4db6-b4bb-93e786b26356 | compute0.overcloud.example.com | QEMU | 172.24.1.2 | up | +--------------------------------------+-----------------------------------+-----------------+-------------+-------+
用我们自己的账号无法获取
先制作一个自己的rc文件,然后再get,根据实际情况修改用户、密码、域、项目啥的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 (overcloud) [stack@director ~]$ cp overcloudrc user1 (overcloud) [stack@director ~]$ vim user1 for key in $( set | awk '{FS="="} /^OS_/ {print $1}' ); do unset $key ; done export NOVA_VERSION=1.1export COMPUTE_API_VERSION=1.1export OS_USERNAME=user1export OS_PROJECT_NAME=lxh-project1export OS_USER_DOMAIN_NAME=lxh-domainexport OS_PROJECT_DOMAIN_NAME=lxh-domainexport OS_NO_CACHE=Trueexport OS_CLOUDNAME=overcloudexport no_proxy=,172.25.249.50,172.25.250.50export PYTHONWARNINGS='ignore:Certificate has no, ignore:A true SSLContext object is not available' export OS_AUTH_TYPE=passwordexport OS_PASSWORD=lxhpasswordexport OS_AUTH_URL=http://172.25.250.50:5000export OS_IDENTITY_API_VERSION=3export OS_COMPUTE_API_VERSION=2.latestexport OS_IMAGE_API_VERSION=2export OS_VOLUME_API_VERSION=3export OS_REGION_NAME=regionOneif [ -z "${CLOUDPROMPT_ENABLED:-} " ]; then export PS1=${PS1:-""} export PS1=\${OS_CLOUDNAME:+"(\$OS_CLOUDNAME)"} \ $PS1 export CLOUDPROMPT_ENABLED=1 fi
可以看到,我们没什么权限
1 2 3 4 5 (overcloud) [stack@director ~]$ source user1 (overcloud) [stack@director ~]$ openstack user list You are not authorized to perform the requested action: identity:list_users. (HTTP 403) (Request-ID: req-0c02ed30-5d0b-4ce4-8338-d8b55454d5c2) (overcloud) [stack@director ~]$ openstack hypervisor list Policy doesn't allow os_compute_api:os-hypervisors to be performed. (HTTP 403) (Request-ID: req-c441468a-18d0-4eb9-9c8a-f2beb08d568b)
创建角色策略 返回到管理员,分配策略到角色
先登录nova获取一些nova中的聚合主机策略怎么写,发现他需要admin_api的规则
1 2 3 4 [root@controller0 ~]# podman exec -it nova_api /bin/bash ()[root@controller0 /]# oslopolicy-policy-generator --namespace nova > nova.txt ()[root@controller0 /]# grep -i hyper nova.txt "os_compute_api:os-hypervisors" : "rule:admin_api"
再登录keystone看看用户列表策略怎么写,只能具有reader角色的才行
1 2 3 4 5 [root@controller0 ~]# podman exec -it keystone /bin/bash ()[root@controller0 /]# oslopolicy-policy-generator --namespace keystone > keystone.txt ()[root@controller0 /]# grep -i list_users keystone.txt "identity:list_users_in_group" : "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.group.domain_id)s)" "identity:list_users" : "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s)"
根据我们查到的内容,制作自己的nova和keystone策略,策略要放到具体服务的配置文件下,名称为policy.json
nova的部分,我们同时关联了我们的角色,创建了文件,可以验证一下,避免出问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@controller0 ~]# cd /var/lib/config-data/puppet-generated/ [root@controller0 puppet-generated]# cd nova/etc/nova/ [root@controller0 nova]# cat > policy.json <<-'EOF' { "os_compute_api:os-hypervisors" : "rule:admin_api or role:role1" } EOF [root@controller0 nova]# cat policy.json { "os_compute_api:os-hypervisors" : "rule:admin_api or role:role1" } [root@controller0 nova]# cat policy.json | python -m json.tool { "os_compute_api:os-hypervisors" : "rule:admin_api or role:role1" }
keystone的部分,我们同时关联了我们的角色,创建了文件,可以验证一下,避免出问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@controller0 ~]# cd /var/lib/config-data/puppet-generated/ [root@controller0 puppet-generated]# cd keystone/etc/keystone/ [root@controller0 keystone]# ls credential-keys domains domains-prebuild.bak fernet-keys keystone.conf [root@controller0 keystone]# cat > policy.json <<-'EOF' { "identity:list_users" : "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s) or role:role1" } EOF [root@controller0 keystone]# cat policy.json { "identity:list_users" : "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s) or role:role1" } [root@controller0 keystone]# cat policy.json | python -m json.tool { "identity:list_users" : "(role:reader and system_scope:all) or (role:reader and domain_id:%(target.domain_id)s) or role:role1" }
重启容器生效
1 2 [root@controller0 ~]# systemctl restart tripleo_keystone [root@controller0 ~]# systemctl restart tripleo_nova_api
验证策略 再次回到director看看是否有了权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 (overcloud) [stack@director ~]$ source user1 (overcloud) [stack@director ~]$ openstack user list +----------------------------------+-------+ | ID | Name | +----------------------------------+-------+ | 89bbca2e8b3f43638182a8976ddab838 | user1 | +----------------------------------+-------+ (overcloud) [stack@director ~]$ openstack hypervisor list +--------------------------------------+-----------------------------------+-----------------+-------------+-------+ | ID | Hypervisor Hostname | Hypervisor Type | Host IP | State | +--------------------------------------+-----------------------------------+-----------------+-------------+-------+ | 4ae32d90-761d-4920-8b20-598f21c9d12e | compute1.overcloud.example.com | QEMU | 172.24.1.12 | up | | a54675fc-0ba3-4872-8b76-4fb094b41d30 | computehci0.overcloud.example.com | QEMU | 172.24.1.6 | up | | b506a957-3a44-4db6-b4bb-93e786b26356 | compute0.overcloud.example.com | QEMU | 172.24.1.2 | up | +--------------------------------------+-----------------------------------+-----------------+-------------+-------+