基本概念
keystone
OpenStack 的 Keystone V3 中引入了 Domain 的概念
Domain,project,user,role,token 的概念和关系
简单来说,
- Domain - 表示 project 和 user 的集合,在公有云或者私有云中常常表示一个客户
- Group - 一个domain 中的部分用户的集合
- Project - IT基础设施资源的集合,比如虚机,卷,镜像等
- Role - 角色,表示一个 user 对一个 project resource 的权限
- Token - 一个 user 对于某个目标(project 或者 domain)的一个有限时间段内的身份令牌
它们之间的关系用一个不完整的图来表示:
说明:
- Domain 可以认为是 project,user,group 的 namespace。 一个 domain 内,这些元素的名称不可以重复,但是在两个不同的domain内,它们的名称可以重复。因此,在确定这些元素时,需要同时使用它们的名称和它们的 domain 的 id 或者 name。
- Group 是一个 domain 部分 user 的集合,其目的是为了方便分配 role。给一个 group 分配 role,结果会给 group 内的所有 users 分配这个 role。
- Role 是全局(global)的,因此在一个 keystone 管辖范围内其名称必须唯一。role 的名称没有意义,其意义在于 policy.json 文件根据 role 的名称所指定的允许进行的操作。
- 简单地,role 可以只有 admin 和 member 两个,前者表示管理员,后者表示普通用户。但是,结合 domain 和 project 的限定,admin 可以分为 cloud admin,domain admin 和 project admin。
- policy.json 文件中定义了 role 对某种类型的资源所能进行的操作,比如允许 cloud admin 创建 domain,允许所有用户创建卷等
- project 是资源的集合,其中有一类特殊的project 是 admin project。通过指定 admin_project_domain_name 和 admin_project_name 来确定一个 admin project,然后该project 中的 admin 用户即是 cloud admin。
- Token 具有 scope 的概念,分为 unscoped token,domain-scoped token 和 project-scoped token。下文有说明。
token
token即令牌,身份的凭证。在整个openstack项目中服务与服务之间的通信都需要token来进行身份认证,我们来举个例子:
如上图所示,一个用户需要创建一台虚拟机,用户首先要登入之后先拿到一个project_scope token 这个token包含了用户具有的角色以及服务列表,用户拿着这个令牌去请求nova服务,nova首先会去keystone认证该token是否有效,之后会向glance发送获取镜像的请求,glance接收请求后也会向之前的步骤一样去keystone认证token有效性,最终返回镜像给nova,nova再用镜像去给用户创建虚拟机。
另外需要说明的是token中包含用户所拥有的角色,nova和其他服务还会根据token中的role来判断用户是否有操作权限。token类型
unscope token
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 {
"token": {
"issued_at": "2016-11-30T03:50:49.277102Z",
"audit_ids": [
"AbSBE-XmTc-gacd4cxrZAQ"
],
"methods": [
"password"
],
"expires_at": "2016-12-01T03:50:49.277079Z",
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "fb7cdca584894c7ca3faa7388ee3a98f",
"name": "admin"
}
}
}如上所示为unscope token其中只包含了用户基本信息,以及创建/过期时间等基本信息。
scope token
在keystone中scope token主要有以下几种类型:
project-scoped token:该类型token表示用户对具体项目的访问权限,token信息主要包括用户可访问的服务目录、拥有的权限、以及项目信息。
domain-scoped token:该类型token表示用户在域范围具有的权限,例如如果用户对域内具有管理员权限,则该用户就能管理域内的所有项目以及用户。跟project-scoped token不同的是project-scoped token包含了可访问项目信息,而domain-scoped token则包含了具有操作权限的域信息。
trust-scoped token:当truster授予trustee一定的权限后,trustee可以使用该类型token来操作truster资源,该类型token信息包括truster的项目/域信息以及一系列权限,服务目录。
示例:
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 {
"token": {
"methods": [
"password"
],
"roles": [
{
"id": "eaee0b95f3dc4e2ca6476a41c2596de5",
"name": "admin"
}
],
"expires_at": "2016-12-01T03:15:43.057915Z",
"project": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "ed0596a674d84591940d6e3be10661a8",
"name": "admin"
},
"catalog": [
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:9696",
"region": "RegionOne",
"interface": "internal",
"id": "74f1c9d76070422cb6839a9090b2801e"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:9696",
"region": "RegionOne",
"interface": "public",
"id": "b7f77180541142d48c70a6bf63547ee2"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:9696",
"region": "RegionOne",
"interface": "admin",
"id": "fa44e5f5251a4cec8fe1044144d83a77"
}
],
"type": "network",
"id": "40c01df9e89a4d33bd97c140c0397c79",
"name": "neutron"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8004/v1/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "internal",
"id": "1986cb45bda74e779df52caf5445b61b"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8004/v1/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "admin",
"id": "c8626b60ef2a40a1ab30f97ac05e5052"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8004/v1/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "public",
"id": "effb9bba0ec34345b1f16f6616d41024"
}
],
"type": "orchestration",
"id": "4faf0d0323a1433b934008e2f371257f",
"name": "heat"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v2/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "admin",
"id": "3f6e61cceaea422fb884865fc8b93a15"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v2/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "public",
"id": "4ed6326d65a94401b5e1280134fd2d48"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v2/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "internal",
"id": "96e02eb9ebe345919ddac114e735c9af"
}
],
"type": "volumev2",
"id": "6b04d7f69edb4878910e5577e7203d99",
"name": "cinderv2"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v3/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "internal",
"id": "05c90aa6d91a4dd0a3b86b5ae7a3ec9f"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v3/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "public",
"id": "26d499a887874945b4296a153c5ffa36"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v3/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "admin",
"id": "6083327dec414ff7aee2578dc07be32a"
}
],
"type": "volumev3",
"id": "7ab5a6aa19d349e3b6f51d019708640b",
"name": "cinderv3"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:5000/v3",
"region": "RegionOne",
"interface": "public",
"id": "104f35e918ef4bc6b585680a1068759f"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:5000/v3",
"region": "RegionOne",
"interface": "internal",
"id": "1ae18bb03417491789758cb909f4e5a7"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:35357/v3",
"region": "RegionOne",
"interface": "admin",
"id": "81b5b166c3e44f569934032c030157f6"
}
],
"type": "identity",
"id": "94390d15efa54fb2b56f9c60eca92364",
"name": "keystone"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8000/v1",
"region": "RegionOne",
"interface": "internal",
"id": "59ce20e207ee442e8d34cc791a5074c3"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8000/v1",
"region": "RegionOne",
"interface": "public",
"id": "c02bc940384a49cabaf7e14be1862f66"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8000/v1",
"region": "RegionOne",
"interface": "admin",
"id": "cdaa6cedb47b4b26a3ffecfb208b8740"
}
],
"type": "cloudformation",
"id": "9952ffb22c6b4091be0e8d7104a9dc47",
"name": "heat-cfn"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v1/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "internal",
"id": "12ff0fbbfd4041dfa5baa2f398bc1743"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v1/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "public",
"id": "19b6c07105b049eaa6001a3236591a0a"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8776/v1/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "admin",
"id": "f968d4484e7648c888a1ee69e58f46f7"
}
],
"type": "volume",
"id": "aa9c81d5176f46238772fbd48d465a6e",
"name": "cinder"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8774/v2/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "public",
"id": "284c6e27ad36425abdb25ae4175dd3ea"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8774/v2/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "internal",
"id": "914f3f40ce8448df8817373779492abe"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:8774/v2/ed0596a674d84591940d6e3be10661a8",
"region": "RegionOne",
"interface": "admin",
"id": "b002db37826d47008149b5dd26ced405"
}
],
"type": "compute",
"id": "b606deae3b5042a3866fcca5abe203e9",
"name": "nova"
},
{
"endpoints": [
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:9292",
"region": "RegionOne",
"interface": "internal",
"id": "01e9dae6fd7246c0bc101abb112fcdb8"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:9292",
"region": "RegionOne",
"interface": "admin",
"id": "36013e038ffb473c9a377fffd63a86db"
},
{
"region_id": "RegionOne",
"url": "http://10.0.84.52:9292",
"region": "RegionOne",
"interface": "public",
"id": "e6f97873b7734743ba6eed52b789955b"
}
],
"type": "image",
"id": "e2d274d71113415399f3e24e187d165d",
"name": "glance"
}
],
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "fb7cdca584894c7ca3faa7388ee3a98f",
"name": "admin"
},
"audit_ids": [
"XgeY0-0cTbuvSuu58WlHLA"
],
"issued_at": "2016-11-30T03:15:43.057953Z"
}
}作者:爱吃土豆的程序猿
链接:https://www.jianshu.com/p/a8b6504fc3c6
调试
1. 查看endpoint
1 | openstack endpoint list |
2. 获取token
Curl方式
创建token-request.json
文件,作为HTTP消息的内容:
1 | { |
按照具体情况修改上面的json文件,向keystone请求token。-si
是返回消息头。token信息位于消息头的X-Subject-Token
字段
1 | # ipv4请求方式 |
从上面可以看到X-Subject-Token
,将其存放在USER_TOKEN的环境变量中:
1 | export USER_TOKEN=gAAAAABf13NKA1JVOP1pF6OYmtzgaiKXz17svZrXzsEX5_0klzwe9XPkHbxCn39Ri3y_2oglGHEAeWaKH1aycPENWJvPLGA63jk83fMBYwFFTpjvILcbjlKdDdG5hZwLGqdWR9VKYaEp07uIeGDJwQVFbf9tzt9x-uWytJeYyPJlORENLY6_6HQ |
OpenStack CLI方式
通过OpenStack CLI,获取token issue
1 | root@node01: ~ # openstack token issue |
将上述输出中的 id
对应的值,保存至环境变量USER_TOKEN中:
1 | export USER_TOKEN=gAAAAABgIQOadJ2W2Ado2IOaLipGG9dSveGEB1Nsm-PjpLia3OtswKRDMyxGs1sJjtlvkycDy31gPB6u2voamNb68wJFNSi37fuoby9X2TwdeKbvxuKOE9_a4HRRdesg6vhD-myvp8cGeZQIsZWyal0I0CF9Q5FcH42CB5O0047lgaNk4pBEJkM |
3. 访问OpenStack API接口
OpenStack API地址使用openstack endpoint list
中的对应地址
1 | USER_TOKEN=$(openstack token issue -c id -f value) |