一、Keytone 基础

1、基础介绍

Keystone (OpenStack ldentityService)是OpenStack中的一个独立的提供安全认证的模块,主要负责openstack用户的身份认证、令牌管理、提供访问资源的服务目录(指引路径)、以及基于用户角色的访问控制。

Keystone类似一个服务总线,或者说是整个Openstack框架的注册表,其他服务通过keystone来注册其服务的Endpoint(服务访问的URL),任何服务之间相互的调用,需要经过Keystone的身份验证,来获得目标服务的Endpoint来找到目标服务。

2、功能

实际上所有的组件都依赖keystone(单点的),它集成了三个功能:

(1) 管理身份验证(managing authentication):验证用户身份。

(2) 授权(authorization):基于角色role的权限管理。

(3) 服务目录(catalog of services):提服务目录(ServiceCatalog:包括service和endpoint)服务,类似于UDDI服务的概念,用户(无论是Dashboard, APIClient)都需要访问Keystone获取服务列表,以及每个服务的地址(Openstack中称为Endpoint)。

3、Keystone概念说明

(1) user

使用Openstack组件的客户端可以是人、服务、系统,任何的客户端来访问openstack组件,都需要有一个用户名。

(2) Credentials

用于确认用户身份的凭证,说白了就是‘信物’,具体可以是:

a. 用户名和密码

b. 用户名和API key

c. 一个 Keystone 分配的身份token

(3) Authentication

验证用户身份的过程。Keystone 服务通过检查用户的 Credential 来确定用户的身份。

最开始,使用用户名/密码或者用户名/API key作为credential。当用户的credential被验证后,Kestone 会给用户分配一个 authentication token 供该用户后续的请求使用。

Keystone中通过Policy(访问规则)来做到基于用户角色(Role)的访问控制。

(4) Token

是一个数字字符串,访问资源时需要"亮出"你的令牌。在keystone中主要是引入令牌机制来保护用户对于资源的访问,同时引入PKI(公钥基础实施)对令牌加以保护。

Token包含了在指定范围和有效时间内可以被访问的资源。EG. 在Nova中一个tenant可以是一些虚拟机,在Swift和Glance中一个tenant可以是一些镜像存储,在Network中一个tenant可以是一些网络资源。

(5) Role

本质就是一堆ACL的集合,用于划分权限

可以通过给User指定Role,使User获得Role对应的操作权限。

Keystone返回给User的Token包含了Role列表,被访问的Services会判断访问它的User和User提供的Token中所包含的Role,及每个role访问资源或者进行操作的权限。

系统默认使用管理Role admin和成员Role user(过去的普通用户角色是:member) 。

user验证时必须带有Project(Tenant)

(6) Policy

对于Keystone service来说,Policy就是一个JSON文件,默认是/etc/keystone/policy.json。通过配置这个文件,Keystone实现了对User基于Role的权限管理。

OpenStack对User的验证除了OpenStack的身份验证以外,还需要鉴别User对某个Service是否有访问权限。Policy机制就是用来控制User对Project(Tenant)中资源的操作权限。

(7) Project(Tenant)

是一个人、或服务所拥有的资源集合。不同的Project之间资源是隔离的,资源可以设置配额。

在一个Project(Tenant)中可以包含多个User,每一个User都会根据权限的划分来使用Project(Tenant)中的资源。比如通过Nova创建虚拟机时要指定到某个Project中,在Cinder创建卷也要指定到某个Project中。

User访问Project的资源前,必须要与该Project关联,并且指定User在Project下的Role,一个assignment(关联)即:Project-User-Role

(8) service

Openstack中运行的各个组件服务。

(9) Endpoint

  1. 是一个可以通过网络来访问和定位某个Openstack service的地址,通常是一个URL
  2. 不同的region有不同的endpoint(我们可以通过endpoint的region属性去定义多个region)。
  3. 当Nova需要访问Glance服务去获取image 时,Nova通过访问Keystone拿到Glance的endpoint,然后通过访问该endpoint去获取Glance服务。
  4. Endpoint 分为三类:
  • admin url –> 给admin用户使用,Port:35357
  • internal url –> OpenStack内部服务使用来跟别的服务通信,Port:5000
  • public url –> 互联网用户可以访问的地址,Port:5000

(10) Catalog

用户和服务可以使用使用keystone管理的catalog,定位到其他的服务,catalog一个openstack部署的相关服务的集合,每个服务都有一个或者多个endpoint(即可以访问的url地址),即catalog=services+endpoint。每个endpoint可以分为三种类型:

admin,internal,public,在生产环境中,不同endpoint类型位于不同的网络来为不同的用户使用(提高安全性),比如:

public API:对整个互联网可见,这样客户就可以方便的管理自己的云了。

admin API:应该严格限定只有管理云基础设施的组织内的运营商,才能使用该API

internel API:应该被限定只有那些安装有OpenStack服务的主机,才能使用该API

(11) Service与Endpoint关系介绍

在openstack中,每一个service都有三种endpoint. Admin, public, internal(创建完service后需要为其创建API EndPoint. )

Admin是用作管理用途的,如它能够修改user/tenant(project)。

public 是让客户调用的,比如可以部署在外网上让客户可以管理自己的云。

internal是openstack内部调用的。

三种endpoints 在网络上开放的权限一般也不同。Admin通常只能对内网开放,public通常可以对外网开放,internal通常只能对安装有openstack对服务的机器开放。

(12) Regions

openstack支持多个可扩展的regions,OpenStack的支持可扩展的多个区域。为简单起见,一般使用管理网络ip地址作为所有endpoint类型(三种api)的ip,且所有的endpoint类型(三种api)都使用一个区域,即regionone区。

每个你部署的openstack服务都需要绑定endpoint(存储在keystone中)来提供服一个服务的入口,因而我们第一需要部署的组件就是keystone。

二、Keystone 安装部署

1、 创建数据库

1
2
3
4
5
6
7
8
9
10
# 如果之前mysql数据库没有设置密码,则可以输入 mysql 回车进入。
[root@controller ~]# mysql -u root -p

MariaDB [(none)]> CREATE DATABASE keystone;

MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'KEYSTONE_DBPASS';

MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'KEYSTONE_DBPASS';

MariaDB [(none)]> quit

2、安装keystore软件包

1
2
[root@controller ~]# yum install openstack-keystone httpd mod_wsgi -y
# 注:CentOS 8使用 dnf -y install python3-mod_wsgi 安装mod_wsgi

3、修改 /etc/keystone/keystone.conf 配置文件

1
2
3
4
5
6
7
8
9
[root@controller ~]# vi /etc/keystone/keystone.conf

# 1. 在 [database] 部分,配置数据库访问
[database]
connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone

# 2. 在 [token] 部分,配置 Fernet 令牌提供程序
[token]
provider = fernet

也可以通过以下步骤进行操作,和上述步骤是一致的。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#修改配置文件
[root@controller ~]# cp /etc/keystone/keystone.conf /etc/keystone/keystone.conf.bak
[root@controller ~]# grep -Ev "^#|^$" /etc/keystone/keystone.conf.bak > /etc/keystone/keystone.conf
[root@controller ~]# vi /etc/keystone/keystone.conf
[DEFAULT]
[application_credential]
[assignment]
[auth]
[cache]
[catalog]
[cors]
[credential]
[database]
connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone
[domain_config]
[endpoint_filter]
[endpoint_policy]
[eventlet_server]
[federation]
[fernet_receipts]
[fernet_tokens]
[healthcheck]
[identity]
[identity_mapping]
[jwt_tokens]
[ldap]
[memcache]
[oauth1]
[oslo_messaging_amqp]
[oslo_messaging_kafka]
[oslo_messaging_notifications]
[oslo_messaging_rabbit]
[oslo_middleware]
[oslo_policy]
[policy]
[profiler]
[receipt]
[resource]
[revoke]
[role]
[saml]
[security_compliance]
[shadow_users]
[token]
provider = fernet
[tokenless_auth]
[totp]
[trust]
[unified_limit]
[wsgi]

### 4、同步数据库
1
[root@controller ~]# su -s /bin/sh -c "keystone-manage db_sync" keystone

5、配置初始化

1
2
3
4
5
6
7
8
9
10
# 初始化数据库
[root@controller ~]# keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
[root@controller ~]# keystone-manage credential_setup --keystone-user keystone --keystone-group keystone

# 初始化keystone
[root@controller ~]# keystone-manage bootstrap --bootstrap-password ADMIN_PASS \
--bootstrap-admin-url http://controller:5000/v3/ \
--bootstrap-internal-url http://controller:5000/v3/ \
--bootstrap-public-url http://controller:5000/v3/ \
--bootstrap-region-id RegionOne

6、配置httpd

1
2
[root@controller ~]# echo "ServerName controller" >>/etc/httpd/conf/httpd.conf
[root@controller ~]# ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/

7、启动httpd

1
2
[root@controller ~]# systemctl start httpd
[root@controller ~]# systemctl enable httpd

8、配置环境变量

1
2
3
4
5
6
7
8
9
#定义环境变量
[root@controller ~]# vi admin-openrc
export OS_USERNAME=admin
export OS_PASSWORD=ADMIN_PASS
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://controller:5000/v3
export OS_IDENTITY_API_VERSION=3
1
2
#加载环境变量
[root@controller ~]# source admin-openrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#开机自动加载环境变量,配置 .bashrc , 最下面添加 source admin-openrc
[root@controller ~]# cat .bashrc
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
source admin-openrc

9、创建Keystone对象实例

Keystone为每个 OpenStack 服务提供身份验证服务。身份验证服务使用域、项目、用户和角色的组合。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#创建域
[root@controller ~]# openstack domain create --description "An Example Domain" example
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | An Example Domain |
| enabled | True |
| id | 00c198ac769d4424a842692c2f06111b |
| name | example |
| options | {} |
| tags | [] |
+-------------+----------------------------------+

#创建项目
[root@controller ~]# openstack project create --domain default --description "Demo Project" myproject
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | Demo Project |
| domain_id | default |
| enabled | True |
| id | a04121c96e3b4e978f41515e4d788168 |
| is_domain | False |
| name | myproject |
| options | {} |
| parent_id | default |
| tags | [] |
+-------------+----------------------------------+

#创建用户
[root@controller ~]# openstack user create --domain default --password-prompt myuser
User Password:
Repeat User Password:
No password was supplied, authentication will fail when a user does not have a password.
+---------------------+----------------------------------+
| Field | Value |
+---------------------+----------------------------------+
| domain_id | default |
| enabled | True |
| id | c4f4a104dea0425ca5e3ad3966e8809c |
| name | myuser |
| options | {} |
| password_expires_at | None |
+---------------------+----------------------------------+

#创建角色
[root@controller ~]# openstack role create myrole
+-------------+----------------------------------+
| Field | Value |
+-------------+----------------------------------+
| description | None |
| domain_id | None |
| id | 7f71ee008de940b3afa5164f437f8d40 |
| name | myrole |
| options | {} |
+-------------+----------------------------------+

#将角色添加到项目和用户
openstack role add --project myproject --user myuser myrole


# 检查添加结果
[root@controller ~]# openstack project list
+----------------------------------+-----------+
| ID | Name |
+----------------------------------+-----------+
| 37297436d3384cf18dde714da386d2af | admin |
| 7efc773eda9648e8b041821a6a29d93c | service |
| a04121c96e3b4e978f41515e4d788168 | myproject |
+----------------------------------+-----------+
[root@controller ~]# openstack domain list
+----------------------------------+---------+---------+--------------------+
| ID | Name | Enabled | Description |
+----------------------------------+---------+---------+--------------------+
| 00c198ac769d4424a842692c2f06111b | example | True | An Example Domain |
| default | Default | True | The default domain |
+----------------------------------+---------+---------+--------------------+
[root@controller ~]# openstack user list
+----------------------------------+--------+
| ID | Name |
+----------------------------------+--------+
| 49a25f94cf88430d889a9dee6e7f27a4 | admin |
| c4f4a104dea0425ca5e3ad3966e8809c | myuser |
+----------------------------------+--------+
[root@controller ~]# openstack role list
+----------------------------------+--------+
| ID | Name |
+----------------------------------+--------+
| 0285a6213e8441adb5b6fc9c75b46359 | admin |
| 147dbdf7503c4241b2661f251724c0b9 | member |
| 7f71ee008de940b3afa5164f437f8d40 | myrole |
| fb396571f9714c3faf0007ccc04566e5 | reader |
+----------------------------------+--------+

10、验证Keystone服务是否正常

1
2
3
4
5
6
7
8
9
10
11
#获取token测试,输出token信息则正常。

[root@controller ~]# openstack token issue
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Field | Value |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| expires | 2021-08-20T04:01:26+0000 |
| id | gAAAAABhHxsGDuAaeHeYrA6Sxon7jtqrEPMQMQUXF9rtRgJrr1_BNhxjpg2SfwFYxM3a8Ax8AoncDSHOzXujKM3zgnuhmotI6WECyemd7KvML_s4m5SGTbiui-6iIt45meeR8sJjVjjPLGCONAsFfFSC41lpX1neZmo7UiCbPlJd9Pz5128u2lM |
| project_id | 37297436d3384cf18dde714da386d2af |
| user_id | 49a25f94cf88430d889a9dee6e7f27a4 |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+