在云计算平台的实际部署中,认证服务是基石中的基石。无论是虚拟机、存储还是网络资源,所有操作都需要一个统一的身份验证和授权中心。OpenStack 作为主流的开源云平台,其认证服务 Keystone 的安装与配置,是每一位云平台运维和开发工程师必须掌握的技能。很多朋友在初次接触时,会被其复杂的配置项和多组件交互搞得晕头转向,网上教程又往往版本不一、步骤零散。
本文将为你提供一份从零开始的、手把手的 Keystone 安装与配置实战指南。我们将基于一个最小化的实验环境,详细拆解每一个步骤,解释每一个关键配置项的作用,并最终完成一个可用的 Keystone 服务。无论你是正在学习云计算的学生,还是需要搭建开发测试环境的工程师,都可以按照本文的步骤,一步步完成搭建,并理解其背后的原理。
1. 背景与核心概念:为什么需要 Keystone?
在深入动手之前,我们必须先理解 Keystone 在 OpenStack 生态中的角色。你可以把 OpenStack 想象成一个庞大的“云资源商城”,里面有计算(Nova)、存储(Cinder/Swift)、网络(Neutron)等各种“店铺”(服务)。而 Keystone 就是这个商城的“总服务台”和“安保中心”。
它的核心职责包括:
- 身份认证 (Authentication): 验证用户(或程序)的身份。就像进入商城需要出示会员卡或验证身份。
- 授权 (Authorization): 确认用户是否有权限进行某项操作。比如,普通会员可能无法进入VIP专区的店铺。
- 服务目录 (Service Catalog): 提供一个所有可用服务及其访问端点的清单。告诉用户“计算店铺在3楼A区,网络店铺在2楼B区”。
- 令牌 (Token): 发放一个有时效性的“临时通行证”(Token)。用户拿着这个 Token 去访问其他服务时,其他服务会向 Keystone 验证该 Token 是否有效且有权访问。
核心概念解析:
- User: 使用云资源的实体,可以是人、系统或服务。每个用户必须属于一个Domain(早期版本属于Tenant/Project)。
- Project (Tenant): 资源隔离的基本单元。一个项目下可以拥有虚拟机、网络、存储等资源。用户必须关联到至少一个项目才能使用资源。
- Role: 定义用户权限的标签,如
admin,member,reader。权限的具体含义由各个服务(如 Nova)来定义。 - Domain: 一个更高层次的命名空间,用于隔离项目、用户和组。在大型部署中非常有用,本文实验环境使用默认的
defaultDomain。 - Service & Endpoint: Service 指 OpenStack 的一个服务(如
nova,cinder)。Endpoint 是该服务的访问地址,通常分为public(公网)、internal(内网)、admin(管理)三种类型。
理解了这些,我们就知道安装 Keystone 的目标:建立一个能管理用户、项目、角色,并能发放和验证令牌的中心服务。
2. 环境准备与版本说明
我们的实验将在一个干净的环境中进行,这有助于排除干扰,理解核心流程。
实验环境说明:
- 操作系统: Ubuntu 22.04 LTS (Jammy Jellyfish)。这是目前 LTS 版本中较新且稳定的选择。其他发行版如 CentOS 7/8 步骤类似,但包管理命令(
yum/dnfvsapt)和部分配置文件路径不同。 - OpenStack 版本: Yoga (2022.2)。我们选择 Yoga 版本,因为它是一个成熟的长期支持版本,文档和社区资源丰富。后续安装其他组件时也请保持版本一致。
- 数据库: MariaDB 10.6。Keystone 需要后端数据库来存储其数据(用户、项目、令牌等)。
- 消息队列: RabbitMQ 3.10。用于服务内部通信(虽然 Keystone 本身对消息队列依赖不重,但为后续集成其他服务做准备)。
- Web 服务器: Apache2 +
mod_wsgi。Keystone 本身是一个 WSGI 应用,通常通过 Apache 来提供 HTTP 服务。 - 网络: 假设你有一台独立的服务器或虚拟机,我们将其称为“控制节点”。确保网络通畅,主机名设置正确(如
controller)。
重要前提:
- 系统为全新安装或已重置,避免端口冲突和配置残留。
- 拥有
root权限或sudo权限。 - 主机名已静态配置(
/etc/hosts)。编辑 hosts 文件,确保能解析自身:
添加一行(假设你的服务器 IP 是 192.168.1.100,主机名是 controller):sudo vim /etc/hosts192.168.1.100 controller - 确保系统时间准确,建议配置 NTP 服务。
3. 基础环境搭建:数据库与消息队列
Keystone 依赖于数据库和消息队列。我们先完成这些基础设施的安装与配置。
3.1 安装与配置 MariaDB 数据库
首先更新系统并安装 MariaDB 服务器和客户端:
sudo apt update sudo apt upgrade -y sudo apt install mariadb-server python3-pymysql -y安装完成后,需要进行安全配置。运行以下命令并按照提示操作,建议设置 root 密码并移除匿名用户、禁止远程 root 登录等:
sudo mysql_secure_installation接下来,我们需要为 Keystone 创建一个专用的数据库和用户。连接到 MariaDB:
sudo mysql -u root -p在 MariaDB 提示符下,执行以下 SQL 命令:
-- 创建 keystone 数据库 CREATE DATABASE keystone CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建 keystone 数据库用户,并授予权限 -- 请将 ‘KEYSTONE_DBPASS’ 替换为一个强密码,并记住它 GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'KEYSTONE_DBPASS'; GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'KEYSTONE_DBPASS'; -- 刷新权限 FLUSH PRIVILEGES; -- 退出 EXIT;关键解释:
utf8mb4字符集支持更广泛的字符(如 emoji),是当前推荐的选择。- 我们创建了从
localhost和任意主机 (%) 的访问权限,这为后续可能的远程管理或高可用部署留有余地。在生产环境中,应严格限制访问源。
3.2 安装与配置 RabbitMQ 消息队列
虽然 Keystone 的独立运行对 RabbitMQ 依赖不高,但它是 OpenStack 服务间通信的标准组件,提前安装好是标准做法。
sudo apt install rabbitmq-server -y启动服务并设置为开机自启:
sudo systemctl enable rabbitmq-server sudo systemctl start rabbitmq-server为 OpenStack 创建一个专用用户(例如openstack)并设置密码:
sudo rabbitmqctl add_user openstack RABBIT_PASS # 请将 RABBIT_PASS 替换为强密码授予该用户对所有虚拟主机的配置、读、写权限:
sudo rabbitmqctl set_permissions openstack ".*" ".*" ".*"验证用户是否添加成功:
sudo rabbitmqctl list_users你应该能看到openstack用户。
4. Keystone 服务安装与核心配置
基础环境就绪后,我们开始安装和配置 Keystone 本身。
4.1 安装 Keystone 及相关组件
Ubuntu 系统提供了 OpenStack 的云归档仓库,方便我们安装特定版本。首先添加仓库并安装 Keystone:
sudo apt install software-properties-common -y sudo add-apt-repository cloud-archive:yoga -y sudo apt update sudo apt install keystone apache2 libapache2-mod-wsgi-py3 python3-openstackclient -y安装包说明:
keystone: Keystone 服务本体。apache2和libapache2-mod-wsgi-py3: 用于通过 Apache 托管 Keystone 的 WSGI 应用。python3-openstackclient: OpenStack 命令行客户端,后续我们将用它来与 Keystone 交互。
4.2 配置 Keystone 数据库连接
Keystone 的主配置文件是/etc/keystone/keystone.conf。在修改前,建议先备份:
sudo cp /etc/keystone/keystone.conf /etc/keystone/keystone.conf.bak使用crudini工具(如果没有则安装:sudo apt install crudini -y)或直接编辑文件来修改配置。这里我们使用crudini,它更清晰:
# 配置数据库连接,使用上一步创建的密码 sudo crudini --set /etc/keystone/keystone.conf database connection mysql+pymysql://keystone:KEYSTONE_DBPASS@controller/keystone # 配置 Fernet 令牌提供者。Fernet 是一种对称加密令牌,无需持久化到数据库,性能更好。 sudo crudini --set /etc/keystone/keystone.conf token provider fernet关键解释:
connection字符串格式:mysql+pymysql://<用户名>:<密码>@<数据库主机>/<数据库名>。provider fernet:指定使用 Fernet 令牌。相比 UUID 令牌,Fernet 更安全、高效,是当前版本的默认推荐。
4.3 初始化 Keystone 数据库
现在,用我们刚才的配置来填充数据库表结构:
sudo su -s /bin/sh -c "keystone-manage db_sync" keystone这个命令以keystone系统用户的身份运行数据库同步。执行成功后,不会有太多输出。你可以通过登录 MariaDB 查看keystone数据库是否生成了许多表来验证。
4.4 初始化 Fernet 密钥仓库
Fernet 令牌需要加密密钥。我们需要初始化密钥仓库:
sudo keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone sudo keystone-manage credential_setup --keystone-user keystone --keystone-group keystone这些密钥文件通常位于/etc/keystone/fernet-keys/目录下。务必保护好这个目录。
4.5 引导 Keystone 服务(创建初始域、项目、用户、角色)
这是最关键的一步。我们将使用keystone-manage bootstrap命令来创建初始的管理员账户、项目、角色等。这个命令一次性完成多个操作,是 Yoga 及之后版本推荐的方式。
sudo 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参数详解:
--bootstrap-password ADMIN_PASS: 设置初始管理员用户admin的密码。请将ADMIN_PASS替换为一个非常强壮的密码并妥善保存!--bootstrap-*-url: 分别设置 Keystone 的管理、内部、公网访问端点。在实验环境中,我们通常使用同一个地址和端口(5000)。--bootstrap-region-id RegionOne: 指定区域名称。OpenStack 可以支持多区域,这里我们使用默认的RegionOne。
执行此命令后,它会自动创建:
default域(Domain)。admin项目(Project)。admin用户(User),并赋予其admin角色(Role)。- 在
admin项目上,为admin用户分配admin角色。 - 创建
service项目(用于部署其他 OpenStack 服务)。 - 注册
keystone服务,并创建对应的端点(Endpoint)。
5. 配置 Apache HTTP Server
Keystone 将通过 Apache 来提供服务。我们需要配置 Apache 来托管 Keystone 的 WSGI 应用。
5.1 配置 Apache 虚拟主机
编辑 Apache 的 Keystone 配置文件:
sudo vim /etc/apache2/sites-available/keystone.conf将以下配置内容粘贴进去(如果文件已有内容,请替换)。这里我们配置监听 5000 端口(Keystone 的主 API 端口)和 35357 端口(旧版管理端口,某些老客户端可能用到,Yoga 版本后主要用 5000):
Listen 5000 Listen 35357 <VirtualHost *:5000> WSGIDaemonProcess keystone-public processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP} WSGIProcessGroup keystone-public WSGIScriptAlias / /usr/bin/keystone-wsgi-public WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On ErrorLogFormat "%{cu}t %M" ErrorLog /var/log/apache2/keystone-error.log CustomLog /var/log/apache2/keystone-access.log combined <Directory /usr/bin> Require all granted </Directory> </VirtualHost> <VirtualHost *:35357> WSGIDaemonProcess keystone-admin processes=5 threads=1 user=keystone group=keystone display-name=%{GROUP} WSGIProcessGroup keystone-admin WSGIScriptAlias / /usr/bin/keystone-wsgi-admin WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On ErrorLogFormat "%{cu}t %M" ErrorLog /var/log/apache2/keystone-error.log CustomLog /var/log/apache2/keystone-access.log combined <Directory /usr/bin> Require all granted </Directory> </VirtualHost>配置解释:
WSGIDaemonProcess: 定义运行 WSGI 应用的进程/线程池,以keystone用户身份运行,提高安全性。WSGIScriptAlias: 将 URL 路径映射到实际的 WSGI 脚本。Keystone 安装后会在/usr/bin/下提供keystone-wsgi-public和keystone-wsgi-admin这两个脚本。ErrorLog和CustomLog: 定义日志位置,便于排查问题。
5.2 启用配置并重启 Apache
启用我们刚刚创建的站点配置,并禁用 Apache 的默认站点(避免冲突):
sudo a2ensite keystone sudo a2dissite 000-default重启 Apache 服务以使配置生效:
sudo systemctl restart apache2设置 Apache 开机自启:
sudo systemctl enable apache2检查 Apache 和 Keystone 服务状态:
sudo systemctl status apache2确保状态为active (running)。同时,检查 5000 和 35357 端口是否在监听:
sudo netstat -tnlp | grep -E ‘:(5000|35357)’你应该能看到 Apache 进程正在监听这两个端口。
6. 创建环境变量脚本与首次验证
为了方便后续使用命令行客户端,我们创建一个包含管理员凭证的环境变量脚本。
6.1 创建管理员 OpenRC 脚本
创建一个文件,例如admin-openrc.sh:
vim admin-openrc.sh加入以下内容,请根据你的实际密码和主机IP进行修改:
export OS_USERNAME=admin export OS_PASSWORD=ADMIN_PASS # 替换为 keystone-manage bootstrap 时设置的密码 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 export OS_REGION_NAME=RegionOne export OS_AUTH_TYPE=password然后加载这个脚本以设置环境变量:
source admin-openrc.sh为了安全,建议设置该脚本的权限为仅当前用户可读:
chmod 600 admin-openrc.sh6.2 验证 Keystone 安装
现在,使用 OpenStack 命令行客户端来验证我们的 Keystone 服务是否正常工作。
1. 获取令牌(Token):令牌是访问 OpenStack API 的凭证。我们尝试获取一个管理员令牌。
openstack token issue如果配置正确,你将看到类似以下的输出,其中包含一个长的id字段(即令牌),以及令牌的过期时间、所属用户和项目等信息。这证明认证流程是通的。
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Field | Value | +------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | expires | 2023-10-27T09:30:00+0000 | | id | gAAAAAB...(很长一串 Fernet 令牌) | | project_id | 8c4c5e3b1d7a4f19b5c6a8d2e3f4a1b7 | | user_id | 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p | +------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+2. 列出已有用户、项目、角色:我们可以用命令行列出当前已有的实体,验证bootstrap命令创建的默认数据。
# 列出用户 openstack user list # 列出项目 openstack project list # 列出角色 openstack role list # 列出服务目录 openstack catalog list你应该能看到admin用户、admin和service项目、admin角色,以及已注册的keystone服务及其端点。
3. 测试服务端点:直接使用curl命令测试 Keystone 的 API 端点是否可访问:
curl -i http://controller:5000/v3/你应该收到一个包含HTTP/1.1 300 Multiple Choices的响应,这表明 Keystone API 根路径可访问,并返回了可用的 API 版本信息。
7. 创建常规项目、用户与角色(实战演练)
仅仅有管理员账户还不够。在实际使用中,我们需要为不同的团队或用户创建普通项目、用户和角色。下面我们演示如何创建一个名为demo的项目、用户,并为其分配member角色。
7.1 创建demo项目
openstack project create --domain default --description “Demo Project” demo7.2 创建demo用户并设置密码
openstack user create --domain default --password-prompt demo执行命令后,会提示你输入并确认该用户的密码。
7.3 创建member角色(如果不存在)
通常admin角色是自带的,但member角色可能需要手动创建。先检查是否存在:
openstack role list | grep member如果不存在,则创建它:
openstack role create member7.4 将member角色授予demo用户在demo项目上
openstack role add --project demo --user demo member这条命令的含义是:在demo项目上,给demo用户添加member角色。
7.5 验证非管理员用户
现在,我们创建一个普通用户的 OpenRC 脚本来测试:
vim demo-openrc.sh内容如下(替换DEMO_PASS为你为demo用户设置的密码):
export OS_USERNAME=demo export OS_PASSWORD=DEMO_PASS export OS_PROJECT_NAME=demo 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 export OS_REGION_NAME=RegionOne export OS_AUTH_TYPE=password加载该脚本并尝试获取令牌:
source demo-openrc.sh openstack token issue这次,你获取到的令牌的project_id应该对应demo项目,user_id对应demo用户。尝试列出用户(openstack user list),你会收到一个403 Forbidden错误,因为demo用户只有member角色,默认没有查看所有用户的权限。这正好说明了基于角色的访问控制(RBAC)在起作用。
8. 常见问题与排查思路
在安装配置过程中,你可能会遇到一些问题。下面是一些常见问题及其解决方法。
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
openstack token issue返回401 Unauthorized | 1. 管理员密码错误。 2. 环境变量 OS_AUTH_URL设置错误。3. Apache 服务未运行或配置错误。 4. Keystone 数据库未正确初始化。 | 1. 检查admin-openrc.sh中的OS_PASSWORD。2. 确认 OS_AUTH_URL指向正确的控制器地址和端口(http://controller:5000/v3)。3. 运行 systemctl status apache2和sudo netstat -tnlp | grep :5000检查服务状态和端口。4. 查看 Apache 错误日志 /var/log/apache2/keystone-error.log。5. 确认已成功执行 keystone-manage db_sync和keystone-manage bootstrap。 |
keystone-manage db_sync失败 | 1. 数据库连接字符串配置错误。 2. 数据库用户 keystone权限不足。3. MariaDB 服务未启动。 | 1. 检查/etc/keystone/keystone.conf中[database]部分的connection参数,确保密码、主机名、数据库名正确。2. 登录 MariaDB,确认 keystone用户对keystone数据库有全部权限。3. 运行 systemctl status mariadb确保数据库服务已启动。 |
| Apache 无法启动或重启失败 | 1. 端口 5000 或 35357 被占用。 2. keystone.conf语法错误。3. WSGI 脚本路径错误。 | 1. 使用sudo netstat -tnlp | grep -E ‘:(5000|35357)’查看端口占用情况,杀死占用进程或修改监听端口。2. 运行 sudo apache2ctl configtest检查 Apache 配置语法。3. 确认 /usr/bin/keystone-wsgi-public和keystone-wsgi-admin文件存在。 |
能获取 Token 但openstack user list报 403 | 当前用户(如demo)缺少执行该操作的权限。 | 这是正常现象,说明 RBAC 生效。需要使用具有相应角色(如admin)的用户来执行管理操作。切换回admin用户环境变量即可。 |
| 服务端点(Endpoint)列表为空 | keystone-manage bootstrap可能未成功注册服务,或者后续操作误删了端点。 | 1. 使用openstack catalog list检查。2. 可以手动创建服务端点,但建议重新审视 bootstrap步骤,或使用openstack service create和openstack endpoint create命令手动创建。 |
通用排查命令:
- 查看日志:
sudo tail -f /var/log/apache2/keystone-error.log(Apache 错误日志)和sudo tail -f /var/log/keystone/keystone.log(Keystone 应用日志,如果启用)。 - 验证数据库:
sudo mysql -u keystone -p keystone -e “SHOW TABLES;”查看表是否存在。 - 验证网络连通性:
curl -v http://controller:5000/v3/查看详细请求响应。
9. 最佳实践与工程建议
在实验环境成功的基础上,如果你计划将其用于开发测试或更严肃的环境,请考虑以下最佳实践:
密码安全:
- 绝不使用弱密码:
ADMIN_PASS、KEYSTONE_DBPASS、RABBIT_PASS等必须使用高强度随机密码。 - 密码管理:使用安全的密码管理器存储这些密码,并将
admin-openrc.sh等脚本放在安全位置,或使用交互式输入密码的方式。 - 定期轮换:制定策略定期更换关键服务的密码和 Fernet 密钥。
- 绝不使用弱密码:
配置管理:
- 版本控制:将
/etc/keystone/keystone.conf、Apache 站点配置等关键配置文件纳入版本控制(如 Git)。 - 配置分离:敏感信息(如数据库密码)可以考虑使用
[DEFAULT]部分的config-dir选项从单独的安全文件中读取。 - 备份:定期备份 Keystone 数据库。虽然 Fernet 令牌不存于数据库,但用户、项目、角色关系等元数据都在数据库中。
- 版本控制:将
高可用与性能:
- 多节点部署:生产环境应在多个控制节点上部署 Keystone,并通过负载均衡器(如 HAProxy)对外提供服务,避免单点故障。
- 会话缓存:考虑配置 Memcached 或 Redis 作为令牌的缓存后端,可以极大提升验证性能。在
keystone.conf的[token]和[cache]部分进行配置。 - Fernet 密钥轮转:定期轮转 Fernet 密钥(
keystone-manage fernet_rotate),并确保所有 Keystone 节点同步。
安全加固:
- 使用 HTTPS:在生产环境中,必须通过 HTTPS(TLS/SSL)暴露 Keystone 端点,防止凭证和令牌在传输中被窃听。这需要配置 Apache 的 SSL 证书。
- 防火墙:严格限制对 5000 和 35357 端口的访问,只允许可信网络(如管理网络、计算节点网络)访问。
- 审计日志:启用并监控 Keystone 的审计日志,记录所有认证和授权事件。
后续集成:
- 安装完 Keystone 后,接下来通常会安装Glance(镜像服务)、Nova(计算服务)、Neutron(网络服务)等。每个服务都需要在 Keystone 中注册,并创建对应的服务用户和端点。
- 牢记流程:创建服务用户 -> 授权角色 -> 注册服务 -> 创建端点。本文的
bootstrap命令已经为keystone服务完成了这些步骤。
至此,你已经成功在 Ubuntu 22.04 上部署并配置了 OpenStack Yoga 版本的 Keystone 认证服务,完成了从环境准备、软件安装、数据库初始化、服务配置到最终验证的完整流程。你不仅拥有了一个可工作的认证中心,还创建了管理员和普通用户,并理解了用户-项目-角色的核心模型。
这个 Keystone 服务将成为你 OpenStack 云平台的“大脑”。在后续安装其他组件时,你都需要回到这里,为它们创建服务凭证,并让它们知道如何找到 Keystone 进行身份验证。建议你保存好本文中的环境变量脚本和关键命令,它们将是你在 OpenStack 世界中进行一切操作的起点。