实验环境

VirtualBox 搭建 Ubuntu 18.04 虚拟机

  • 4 处理器
  • 8 GB 内存
  • 100 GB 硬盘

使用两块网卡

  • NAT 提供网络服务
  • Host-Only 提供宿主机 ssh 连接

安装依赖

设置 Python3 和 pip3

1
2
3
4
5
# python
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 1

# pip
sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

下载 Keystone 源码,指定 Victoria 版本

1
2
# 下载源码
git clone https://github.com/openstack/keystone.git -b stable/victoria --single-branch

Keystone 的各种依赖可以根据代码目录下提供的 bindep.txt 进行安装。 bindep 即 Binary dependency management ,通过 pip 安装 bindep

1
pip install bindep

进入 Keystone 目录安装相关依赖

1
2
3
4
5
# 进入目录
cd keystone

# 安装依赖
sudo apt install $(bindep -b) -y

因为 Keystone 使用 Flask 提供 WSGI 接口,依赖 Apache 驱动,所以还需要安装支持 python3 的 WSGI 模块

1
sudo apt install apache2 libapache2-mod-wsgi-py3

OpenStack 客户端用于和 Keystone 进行交互,使用 pip 安装

1
pip install python-openstackclient

部署 Keystone

上面的步骤做好了准备,接下来执行 Keystone 的部署。

源码目录中有两个依赖包文件(都安装),或直接用 -e 参数安装

1
2
3
4
# 安装依赖
pip install -r requirements.txt
pip install -r test-requirements.txt
pip install -e .

安装 tox 测试工具,生成配置文件,相关文件 tox.ini

1
2
3
# 安装 tox
pip install tox
tox -e genconfig

设置 MySQL 数据库 root 用户密码,这里设置为 mysql

1
2
3
4
5
# 设置密码
sudo mysql_secure_installation

# 登录 MySQL
sudo mysql -u root -p

创建数据库和 keystone 用户,并授予相关权限

1
2
3
4
5
6
--- 创建数据库
CREATE DATABASE keystone;

--- 授予权限
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'KEYSTONE_DBPASS';
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'KEYSTONE_DBPASS';

手动创建目录,将配置文件拷贝过去

1
2
3
4
5
6
7
8
# 创建目录
sudo mkdir /etc/keystone

# 拷贝配置文件
sudo cp etc/keystone.conf.sample /etc/keystone/keystone.conf

# 修改配置文件
sudo vim /etc/keystone/keystone.conf

[database] 小节中添加数据库连接配置

1
2
[database]
connection = mysql+pymysql://keystone:KEYSTONE_DBPASS@localhost/keystone

安装 Keystone,创建令牌时如果报错提示 /etc/keystone/fernet-keys 文件夹中已有文件,删除后再重新执行指令即可

1
2
3
4
5
6
7
8
9
10
# 安装 Keystone
sudo python setup.py install

# 填充数据库
keystone-manage db_sync

# 令牌
sudo mkdir -p /etc/keystone/fernet-keys
sudo keystone-manage fernet_setup --keystone-user jck --keystone-group jck
sudo keystone-manage credential_setup --keystone-user jck --keystone-group jck

启动 Keystone 服务,设置管理员密码

1
2
3
4
5
6
# 初始化
keystone-manage bootstrap --bootstrap-password ADMIN_PASS \
--bootstrap-admin-url http://127.0.0.1:5000/v3/ \
--bootstrap-internal-url http://127.0.0.1:5000/v3/ \
--bootstrap-public-url http://127.0.0.1:5000/v3/ \
--bootstrap-region-id RegionOne

配置 Apache 服务,拷贝 Keystone 源码目录下的配置文件到 Apache 文件夹中,修改 usergroup 字段为当前用户,启用该配置文件并重启 Apache 服务

1
2
3
4
5
6
7
8
9
10
11
# 拷贝
sudo cp httpd/wsgi-keystone.conf /etc/apache2/conf-available/wsgi-keystone.conf

# 修改
sudo vim /etc/apache2/conf-available/wsgi-keystone.conf

# 启用
sudo ln -s /etc/apache2/conf-available/wsgi-keystone.conf /etc/apache2/conf-enabled/wsgi-keystone.conf

# 重启 Apache
sudo service apache2 restart

重新部署只需要重新执行安装即可

1
sudo python setup.py install

测试

配置环境变量后可访问 Keystone 服务,使用管理员帐号,并指定认证使用的 url 和版本

1
2
3
4
5
6
7
8
# 环境变量
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://127.0.0.1:5000/v3
export OS_IDENTITY_API_VERSION=3

OpenStack Client

1
2
# 查询用户列表
openstack user list

OpenStack API

设置环境变量后才能正确执行以下命令行语句。

  1. 获取 API 信息
1
2
curl -s http://localhost:5000 \
| python -mjson.tool
  1. 获取 token ,指定 project/domain 范围
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
# Unscoped
curl -i "http://localhost:5000/v3/auth/tokens" \
-H "Content-Type: application/json" \
-d '
{ "auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "admin",
"domain": { "id": "default" },
"password": "ADMIN_PASS"
}
}
}
}
}'

# Project-Scoped
curl -i "http://localhost:5000/v3/auth/tokens" \
-H "Content-Type: application/json" \
-d '
{ "auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "admin",
"domain": { "id": "default" },
"password": "ADMIN_PASS"
}
}
},
"scope": {
"project": {
"name": "admin",
"domain": { "id": "default" }
}
}
}
}'

# Domain-Scoped(前提:角色绑定到域上)
curl -i "http://localhost:5000/v3/auth/tokens" \
-H "Content-Type: application/json" \
-d '
{ "auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"name": "admin",
"domain": { "id": "default" },
"password": "ADMIN_PASS"
}
}
},
"scope": {
"domain": {
"id": "default"
}
}
}
}'
  1. 使用 token 获取新的 token
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# X-Subject-Token 字段就是 token
export OS_TOKEN=gAAAAABgdpLGBSoQy0KT68qlRT_i7BPdN67KVUg2To53yxPJFcSwNucacaNxVNT_Ca11ASIovOFsyw8OZfCkgLDC7YHA-h5--DvUZ8JX8cLv340-jE2mc1YFZmRmzocnNXS3i-TQ2X6Czk2CNSPeNqbpw7wWV3X3qg

curl -i "http://localhost:5000/v3/auth/tokens" \
-H "Content-Type: application/json" \
-d '
{ "auth": {
"identity": {
"methods": ["token"],
"token": {
"id": "'$OS_TOKEN'"
}
}
}
}'
  1. 删除 token(返回 204)
1
2
3
4
curl -i -X DELETE \
-H "X-Auth-Token: $OS_TOKEN" \
-H "X-Subject-Token: $OS_TOKEN" \
"http://localhost:5000/v3/auth/tokens"
  1. 列出 domain(项目范围的 token)
1
2
3
curl -s "http://localhost:5000/v3/domains"\
-H "X-Auth-Token: $OS_TOKEN" \
| python -mjson.tool
  1. 创建 domain
1
2
3
4
5
curl -s "http://localhost:5000/v3/domains" \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "domain": { "name": "newdomain" } }' \
| python -mjson.tool
  1. 更新 domain 状态
1
2
3
4
5
6
7
# domain_id
curl -s -X PATCH \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "domain": { "enabled": false } }' \
"http://localhost:5000/v3/domains/d94c8df6149146ae9fd3aa50544789b4" \
| python -mjson.tool
  1. 删除 domain(返回 204)
1
2
3
4
5
# domain_id
curl -i -X DELETE \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
"http://localhost:5000/v3/domains/d94c8df6149146ae9fd3aa50544789b4"
  1. 列出 project
1
2
3
curl -s "http://localhost:5000/v3/projects" \
-H "X-Auth-Token: $OS_TOKEN" \
| python -mjson.tool
  1. 创建 project
1
2
3
4
5
curl -s "http://localhost:5000/v3/projects" \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "project": { "name": "newproject" } }' \
| python -mjson.tool
  1. 禁用 project
1
2
3
4
5
6
7
# project_id
curl -s -X PATCH \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "project": { "enabled": false } }' \
"http://localhost:5000/v3/projects/7f926f22b2784dfba2687aad2e2d1283" \
| python -mjson.tool
  1. 删除 project(返回 204)
1
2
3
4
5
# project_id
curl -i -X DELETE \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
"http://localhost:5000/v3/projects/7f926f22b2784dfba2687aad2e2d1283"
  1. 列出服务
1
2
3
curl -s "http://localhost:5000/v3/services" \
-H "X-Auth-Token: $OS_TOKEN" \
| python -mjson.tool
  1. 列出端点
1
2
3
curl -s "http://localhost:5000/v3/endpoints"\
-H "X-Auth-Token: $OS_TOKEN" \
| python -mjson.tool
  1. 列出用户
1
2
3
curl -s "http://localhost:5000/v3/users" \
-H "X-Auth-Token: $OS_TOKEN" \
| python -mjson.tool
  1. 创建用户
1
2
3
4
5
curl -s "http://localhost:5000/v3/users" \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"user": {"name": "newuser", "password": "pwd"}}' \
| python -mjson.tool
  1. 查看用户信息
1
2
3
4
5
# user_id
curl -s \
-H "X-Auth-Token: $OS_TOKEN" \
"http://localhost:5000/v3/users/629169d123244d269d8b39538fc8f872" \
| python -mjson.tool
  1. 修改用户密码(返回 204)
1
2
3
4
5
6
# user_id
curl -i \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "user": {"password": "password", "original_password": "pwd"} }' \
"http://localhost:5000/v3/users/629169d123244d269d8b39538fc8f872/password"
  1. 更新用户
1
2
3
4
5
6
7
# user_id
curl -s -X PATCH \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "user": {"password": "pwd"} }' \
"http://localhost:5000/v3/users/629169d123244d269d8b39538fc8f872" \
| python -mjson.tool
  1. 删除用户(返回 204)
1
2
3
4
5
# user_id
curl -i -X DELETE \
-H "X-Auth-Token: $OS_TOKEN" \
-H "Content-Type: application/json" \
"http://localhost:5000/v3/users/629169d123244d269d8b39538fc8f872"

参阅