实验环境

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
  2. 获取 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"
    }
    }
    }
    }'
  3. 使用 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'"
    }
    }
    }
    }'
  4. 删除 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"
  5. 列出 domain(项目范围的 token)

    1
    2
    3
    curl -s "http://localhost:5000/v3/domains"\
    -H "X-Auth-Token: $OS_TOKEN" \
    | python -mjson.tool
  6. 创建 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
  7. 更新 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
  8. 删除 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"
  9. 列出 project

    1
    2
    3
    curl -s "http://localhost:5000/v3/projects" \
    -H "X-Auth-Token: $OS_TOKEN" \
    | python -mjson.tool
  10. 创建 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
  11. 禁用 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
  12. 删除 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"
  13. 列出服务

    1
    2
    3
    curl -s "http://localhost:5000/v3/services" \
    -H "X-Auth-Token: $OS_TOKEN" \
    | python -mjson.tool
  14. 列出端点

    1
    2
    3
    curl -s "http://localhost:5000/v3/endpoints"\
    -H "X-Auth-Token: $OS_TOKEN" \
    | python -mjson.tool
  15. 列出用户

    1
    2
    3
    curl -s "http://localhost:5000/v3/users" \
    -H "X-Auth-Token: $OS_TOKEN" \
    | python -mjson.tool
  16. 创建用户

    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
  17. 查看用户信息

    1
    2
    3
    4
    5
    # user_id
    curl -s \
    -H "X-Auth-Token: $OS_TOKEN" \
    "http://localhost:5000/v3/users/629169d123244d269d8b39538fc8f872" \
    | python -mjson.tool
  18. 修改用户密码(返回 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"
  19. 更新用户

    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
  20. 删除用户(返回 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"

参阅