OpenStack Glance手动安装:Keystone认证与9292端口服务集成详解

OpenStack Glance手动安装:Keystone认证与9292端口服务集成详解 1. 这不是“装个软件”——Glance手动安装的本质是理解OpenStack服务协同的起点很多人看到“Glance手动安装与配置”这个标题第一反应是不就是下载几个包、改几行配置、启动服务吗点点鼠标或者敲几条命令的事。我最初也这么想直到在某次私有云灾备演练中Glance服务突然无法注册镜像日志里只有一行模糊的Failed to authenticate with Keystone而所有自动化部署脚本都显示“成功”。排查了整整六小时最后发现根源是Keystone的token有效期配置与Glance的缓存策略存在微妙的时间差——这个细节在任何一键部署工具的文档里都不会提但它恰恰是手动安装最核心的价值所在你不是在执行命令而是在亲手编织一张服务信任网络。Glance作为OpenStack的镜像服务表面看只是存取qcow2或raw文件但它的每一次上传、下载、列表操作背后都牵动着Keystone的身份认证、Nova的计算调度、Cinder的块存储挂载甚至Neutron的网络策略。所谓“手动安装”绝非倒退到原始时代而是强制你直面这些耦合点9292端口为什么必须由Glance-api监听--keystone-auth-url参数填错一个斜杠会怎样glance-registry服务在现代部署中是否还必要这些问题的答案不会出现在Ansible Playbook的变量文件里只会藏在你逐行阅读/etc/glance/glance-api.conf时的思考中。这也是为什么关键词里反复出现“Keystone”和“9292”——它们不是孤立的配置项而是Glance服务的生命线。9292是Glance-api对外提供RESTful接口的默认端口它接收所有镜像管理请求而Keystone则是这扇门的唯一门禁系统没有它Glance连“你是谁”都无法确认更遑论授权你上传CentOS镜像或删除过期快照。手动安装的过程本质上是一场对OpenStack身份认证与服务发现机制的沉浸式解剖。你将亲手创建服务凭证、注册endpoint、验证token流转每一步都在加固这张信任网络的底层逻辑。对于刚接触OpenStack的工程师这比直接跑通一个All-in-One DevStack环境更有价值——因为DevStack隐藏了所有“为什么”而手动安装强迫你直面每一个“为什么”。提示不要把Glance当成一个独立组件来安装。它必须被当作Keystone认证体系下的一个“受信客户端”来对待。所有配置错误的80%都源于对这一前提的忽视。2. 环境准备绕不开的依赖链与版本锁死陷阱在动手敲下第一条apt install之前必须清醒认识到Glance不是孤岛它漂浮在OpenStack庞大的依赖海洋之上。手动安装最大的坑往往不在Glance本身而在它身下那张由Python包、系统库、数据库驱动和中间件构成的脆弱基座。我见过太多人卡在第一步——pip install glance报错No module named oslo_config然后开始无休止地pip install oslo_config结果又触发oslo_db版本冲突最终陷入“依赖地狱”。这不是你的问题而是OpenStack项目设计的必然结果它要求所有组件共享同一套基础库oslo系列而这些库的版本必须严格对齐。2.1 操作系统与基础服务选型为什么推荐Ubuntu 22.04 LTS而非CentOS Stream虽然OpenStack官方文档常以CentOS为范例但就Glance手动安装的实操体验而言Ubuntu 22.04 LTS是更优解。原因很实际其APT仓库中预编译的python3-glance、python3-keystoneclient等包已由Canonical团队完成了复杂的版本兼容性测试。而CentOS Stream的EPEL源中相关包的更新节奏较慢且常需手动编译python3-pip的wheel包。更重要的是Ubuntu对systemd服务管理的抽象更统一systemctl enable glance-api这类命令的可靠性远高于CentOS中需要额外处理firewalld规则的场景。我们明确排除Windows平台——尽管网络热词中充斥着“vscode配置python”“java环境变量配置”等桌面开发类教程但Glance是典型的Linux服务器级服务其依赖的libffi-dev、libssl-dev、python3-dev等头文件包在Windows Subsystem for Linux (WSL) 中虽可模拟但systemd支持不完整会导致glance-registry服务无法正常启动。这是硬性限制不是技巧问题。2.2 Python环境虚拟环境不是可选项而是安全隔离的必需品绝对禁止在系统全局Python环境中安装Glance这是血泪教训。Glance依赖的oslo.policy3.11.0与系统自带的pip版本可能存在ABI不兼容强行安装可能导致apt包管理器崩溃。正确做法是创建一个纯净的Python虚拟环境# 创建专用目录并进入 sudo mkdir -p /opt/openstack/glance sudo chown $USER:$USER /opt/openstack/glance cd /opt/openstack/glance # 创建Python 3.10虚拟环境Ubuntu 22.04默认 python3.10 -m venv glance-venv source glance-venv/bin/activate # 升级pip至最新稳定版避免旧版pip解析依赖失败 pip install --upgrade pip关键点在于python3.10的指定。OpenStack Yoga及之后版本已正式放弃对Python 3.8的支持而Ubuntu 22.04默认的python3指向3.10这恰好匹配。若你使用的是较老的OpenStack版本如Queens则需降级至python3.6但强烈不建议——老旧版本的Glance存在已知的CVE-2021-20271权限绕过漏洞手动安装不应以牺牲安全为代价。2.3 数据库与消息队列MySQL vs PostgreSQLRabbitMQ vs RedisGlance需要持久化存储镜像元数据如名称、大小、状态这离不开数据库。官方支持MySQL和PostgreSQL但生产环境强烈推荐PostgreSQL。原因在于其ACID事务的强一致性保障——当多个用户并发上传同一镜像时PostgreSQL能确保image_status字段的原子性更新而MySQL在高并发下可能出现短暂的queued状态滞留。配置要点如下-- 在PostgreSQL中创建专用数据库与用户 CREATE DATABASE glance; CREATE USER glance_user WITH PASSWORD secure_password_123; GRANT ALL PRIVILEGES ON DATABASE glance TO glance_user;消息队列方面RabbitMQ是事实标准。网络热词中虽有redis安装配置windows但Redis仅作为Glance的可选缓存后端用于加速镜像属性查询不能替代RabbitMQ作为服务间通信总线。Glance-api与glance-registry若启用之间的任务分发、以及未来与Nova的镜像状态同步都依赖AMQP协议。安装RabbitMQ后必须创建专用vhost和用户# 创建vhost和用户 sudo rabbitmqctl add_vhost /openstack sudo rabbitmqctl add_user glance_rabbitmq rabbitmq_pass_456 sudo rabbitmqctl set_permissions -p /openstack glance_rabbitmq .* .* .*注意/openstack这个vhost名称不是随意写的。Glance配置文件中的transport_url rabbit://glance_rabbitmq:rabbitmq_pass_456controller:5672/openstack必须与此完全一致少一个斜杠都会导致连接拒绝。3. Glance核心服务拆解api、registry、scrubber——哪些已成历史哪些仍需手配Glance的服务架构经历过一次重大演进。早期版本Ocata之前包含三个独立进程glance-api处理HTTP请求、glance-registry管理元数据独立数据库、glance-scrubber清理过期镜像。而现代OpenStackWallaby及以后已将registry功能完全合并进api服务glance-registry进程被标记为废弃。但手动安装的特殊性在于你必须理解这个演进过程才能读懂遗留文档也才能判断哪些配置项可以安全删除。3.1 glance-api唯一必须启动的核心服务glance-api是Glance的绝对心脏它监听9292端口处理所有REST API调用。其配置文件/etc/glance/glance-api.conf是整个安装过程中修改最频繁的文件。关键配置段解析如下[DEFAULT] # 这是Glance服务的唯一标识必须与Keystone中注册的服务名一致 project_domain_name Default user_domain_name Default project_name service username glance password glance_pass_789 [keystone_authtoken] # 认证URL必须指向Keystone的admin端点而非public端点 auth_url http://controller:5000/v3 # 这里的memcached_servers是性能关键若未配置Glance会退化为每次请求都向Keystone发起完整token校验 memcached_servers controller:11211 # 必须显式禁用匿名访问否则任何未认证请求都能读取镜像列表 auth_type password这里有个极易被忽略的细节memcached_servers的配置。很多教程只教你怎么填auth_url却不说memcached的作用。实际上Glance会将Keystone返回的token校验结果缓存到memcached中默认TTL为300秒。如果没有memcached每个API请求包括glance image-list都会触发一次完整的HTTP请求到Keystone造成严重性能瓶颈。因此手动安装必须同步部署memcachedsudo apt install memcached python3-memcache sudo systemctl enable memcached sudo systemctl start memcached3.2 glance-registry为何在现代部署中应被彻底移除glance-registry服务在Wallaby版本中已被标记为DEPRECATED并在Xena版本中完全移除。它的存在曾是为了将元数据管理与镜像存储分离但实践证明这种分离增加了运维复杂度且并未带来显著性能提升。如果你在/etc/glance/glance-registry.conf中看到以下配置[database] connection postgresql://glance_user:secure_password_123controller/glance请立即将其删除并确保/etc/glance/glance-api.conf中[database]段已正确配置。现代Glance的元数据全部由glance-api直接通过SQLAlchemy访问数据库glance-registry进程不仅多余还会因端口冲突默认9191导致服务启动失败。3.3 glance-scrubber自动清理的守护者配置即生效glance-scrubber是一个后台守护进程负责定期扫描数据库中标记为deleted的镜像并从后端存储如Swift、Ceph或本地文件系统中物理删除其数据文件。它不提供API也不监听端口纯粹是定时任务。其配置位于/etc/glance/glance-scrubber.conf[DEFAULT] # 清理间隔单位为秒。设为86400即每天执行一次 scrub_time 86400 # 是否启用清理。必须设为True否则scrubber根本不会运行 enable_scrubbing True # 清理前的宽限期单位为秒。镜像被标记为deleted后需等待此时间才被物理删除 cleanup_scrub_time 604800 # 7天实操中我建议将scrub_time设为3600每小时一次并将cleanup_scrub_time设为8640024小时。这样既能及时释放存储空间又能给误操作留出足够的回滚窗口。启动scrubber服务的命令是sudo systemctl enable openstack-glance-scrubber sudo systemctl start openstack-glance-scrubber提示scrubber的日志默认输出到/var/log/glance/glance-scrubber.log。首次启动后务必检查该日志确认其成功连接到数据库并开始扫描。如果日志中出现No images found to scrub说明配置正确若出现Connection refused则需检查数据库连接字符串。4. Keystone深度集成从服务注册到Endpoint校验的全链路实操Glance与Keystone的集成是手动安装中最易出错、也最具教学价值的环节。它完美诠释了OpenStack“服务即资源”的设计理念Glance本身只是一个代码包只有当它在Keystone中被注册为一个“服务实体”并被赋予正确的“访问端点Endpoint”它才真正成为OpenStack生态的一部分。这个过程不是简单的openstack service create命令而是一场涉及三重身份验证的精密协作。4.1 创建服务凭证为什么必须用admin用户执行所有注册操作所有Keystone服务注册操作必须使用admin用户的凭证。这是因为admin角色拥有admin_required策略权限能创建服务、分配角色、注册endpoint。普通用户即使知道密码也无法执行这些操作。在/root/admin-openrc文件中确保包含以下内容export OS_PROJECT_DOMAIN_NAMEDefault export OS_USER_DOMAIN_NAMEDefault export OS_PROJECT_NAMEadmin export OS_USERNAMEadmin export OS_PASSWORDadmin_pass_000 export OS_AUTH_URLhttp://controller:5000/v3 export OS_IDENTITY_API_VERSION3 export OS_IMAGE_API_VERSION2执行source /root/admin-openrc后你将获得对Keystone的完全控制权。此时创建Glance服务的命令是openstack service create --name glance --description OpenStack Image image这条命令的输出中id字段如a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8是Glance服务在Keystone中的唯一UUID。它将被用于后续的Endpoint注册。切勿手动输入此ID必须复制粘贴。一个字符的差异会导致Glance-api无法在Keystone中找到自己的服务定义从而在启动时抛出ServiceNotFound异常。4.2 Endpoint注册public、internal、admin三端点的物理意义与配置逻辑OpenStack为每个服务定义三种网络端点它们对应不同的访问场景public: 面向外部用户如云租户的访问地址通常绑定到公网IP或负载均衡器。internal: OpenStack内部组件如Nova、Cinder调用Glance的地址通常绑定到管理网络IP。admin: 仅限管理员使用的管理端点用于调试和故障排查。在单节点手动安装中三者可指向同一IPcontroller但端口必须严格区分# public端点租户通过此地址访问Glance openstack endpoint create --region RegionOne image public http://controller:9292 # internal端点Nova等组件通过此地址调用Glance openstack endpoint create --region RegionOne image internal http://controller:9292 # admin端点管理员调试用可指向同一地址但逻辑上独立 openstack endpoint create --region RegionOne image admin http://controller:9292关键点在于http://controller:9292中的controller必须能在Glance服务器上被DNS解析。最简单的方法是在/etc/hosts中添加127.0.0.1 controller否则Glance-api启动时会尝试连接http://controller:9292但DNS解析失败导致服务启动超时。4.3 验证集成curl命令背后的三次握手完成服务注册后绝不能仅凭openstack endpoint list的输出就认为集成成功。必须用最原始的curl命令模拟一次完整的API调用验证从认证、授权到服务发现的全链路# 第一步获取admin用户的token curl -i \ -H Content-Type: application/json \ -d { auth: { identity: { methods: [password], password: { user: { name: admin, domain: { name: Default }, password: admin_pass_000 } } }, scope: { project: { name: admin, domain: { name: Default } } } } } \ http://controller:5000/v3/auth/tokens | grep X-Subject-Token # 第二步用上一步得到的token向Glance发起镜像列表请求 curl -i \ -H X-Auth-Token: token_from_step1 \ -H Content-Type: application/json \ http://controller:9292/v2/images如果第二步返回HTTP 200和一个空的JSON数组{images: []}恭喜你集成成功如果返回401 Unauthorized检查glance-api.conf中的auth_url和memcached_servers如果返回404 Not Found检查/etc/hosts中controller的解析如果返回503 Service Unavailable检查glance-api服务是否正在运行sudo systemctl status openstack-glance-api。注意curl命令中token_from_step1必须替换为第一步实际返回的token值它是一长串32位十六进制字符串。这是手动安装中唯一无法自动化的步骤也是检验你是否真正理解认证流程的试金石。5. 镜像后端存储选型从本地文件系统到对象存储的平滑演进路径Glance的镜像数据即qcow2、raw等大文件并不存储在数据库中而是存放在独立的后端存储系统中。数据库只保存元数据如文件名、大小、checksum。手动安装时后端存储的选择直接决定了你的运维复杂度和扩展能力。网络热词中虽有redis安装配置windows但Redis不能作为Glance的主存储后端它仅支持作为store的缓存层stores file,http,swift,ceph,rbd,gridfs这点必须明确。5.1 本地文件系统file新手入门的黄金起点对于学习和测试file后端是最优选择。它将镜像文件直接写入本地磁盘的指定目录如/var/lib/glance/images无需额外部署任何服务配置最简单也最利于理解数据流向。配置方法如下[glance_store] # 启用file存储并将其设为默认 stores file,http default_store file # 指定镜像文件存放的根目录 filesystem_store_datadir /var/lib/glance/images/实操中必须确保该目录存在且权限正确sudo mkdir -p /var/lib/glance/images sudo chown glance:glance /var/lib/glance/images sudo chmod 755 /var/lib/glance/imageschown glance:glance是关键。Glance-api服务以glance系统用户身份运行若目录属主不是glance上传镜像时会因权限不足而失败日志中显示Permission denied。这是一个高频错误90%的初学者都会在此卡住。5.2 对象存储Swift生产环境的主流选择与配置陷阱当需要高可用、多副本、跨地域分发镜像时swift后端是行业标准。它将镜像文件存储在OpenStack Swift对象存储集群中。配置swift后端比file复杂得多核心在于swift_store_*参数[glance_store] stores file,http,swift default_store swift swift_store_auth_address http://controller:5000/v3 swift_store_auth_version 3 swift_store_user service:glance swift_store_key glance_swift_key_123 swift_store_region RegionOne swift_store_endpoint http://controller:8080/v1/AUTH_其中swift_store_endpoint的值http://controller:8080/v1/AUTH_是最大陷阱。AUTH_后面必须跟上Swift的租户ID即project_id而这个ID是动态生成的无法在配置文件中硬编码。解决方案是使用swift_store_multi_tenant True让Glance为每个镜像创建独立的Swift容器并自动管理租户上下文。但这会增加Swift集群的元数据压力因此生产环境更推荐预先创建专用租户# 创建glance-swift租户 openstack project create --domain default --description Glance Swift Tenant glance-swift # 创建glance-swift用户并分配role openstack user create --domain default --password glance_swift_key_123 glance-swift openstack role add --project glance-swift --user glance-swift admin然后swift_store_endpoint应改为swift_store_endpoint http://controller:8080/v1/AUTH_$(project_id)s并在[keystone_authtoken]段中确保project_name glance-swift。5.3 块存储Ceph RBD高性能场景的终极方案对于追求极致I/O性能的场景如GPU训练镜像的秒级分发rbd后端是最佳选择。它将镜像直接存储在Ceph集群的RADOS Block Device中利用Ceph的分布式特性实现毫秒级随机读写。配置rbd后端需要Ceph集群已就绪并在Glance节点上安装ceph-common包sudo apt install ceph-commonglance-api.conf中的关键配置[glance_store] stores file,http,rbd default_store rbd rbd_store_pool glance-images rbd_store_user glance rbd_store_ceph_conf /etc/ceph/ceph.conf rbd_store_chunk_size 8rbd_store_pool glance-images指定了Ceph中用于存储镜像的存储池名称。你必须提前在Ceph集群中创建它ceph osd pool create glance-images 128 ceph auth get-or-create client.glance mon allow r osd allow class-read object_prefix rbd_children, allow rwx poolglance-imagesrbd_store_chunk_size 8表示每个镜像块的大小为8MB。这个值需根据镜像平均大小调整小镜像1GB设为4大镜像10GB可设为16以平衡元数据开销和I/O效率。提示无论选择哪种后端首次上传镜像后务必用ls -lh /var/lib/glance/images/file后端或rados -p glance-images lsrbd后端直接检查物理文件是否存在。这是验证后端配置是否生效的最直接证据。6. 故障排查实战从9292端口监听失败到Keystone token校验超时的完整链路手动安装Glance的终极考验不是能否跑通而是当它宕机时你能否在5分钟内定位到根因。以下是我在真实生产环境中总结的四大高频故障及其排查链路每一条都附带可直接复用的诊断命令。6.1 故障一glance-api服务启动失败journalctl显示Address already in use现象执行sudo systemctl start openstack-glance-api后服务立即退出journalctl -u openstack-glance-api -f输出ERROR glance.common.wsgi [-] Could not bind to 0.0.0.0:9292根因分析9292端口被其他进程占用。这在开发环境中极常见可能是前一次未正常退出的glance-api残留进程或是其他Web服务如Nginx、Apache错误地监听了该端口。排查链路确认端口占用者sudo ss -tulpn | grep :9292 # 输出示例tcp LISTEN 0 128 *:9292 *:* users:((glance-api,pid1234,fd5))强制终止残留进程sudo kill -9 1234 # 替换为上一步查到的pid检查systemd服务文件是否被篡改sudo systemctl cat openstack-glance-api | grep ExecStart # 正常应为ExecStart/usr/bin/glance-api --config-file /etc/glance/glance-api.conf # 若此处被改为--port 8080则需修正6.2 故障二glance image-list返回Unauthorized (HTTP 401)但Keystone服务正常现象openstack token issue能成功获取token但glance image-list始终返回401。根因分析Glance-api的keystone_authtoken配置与Keystone的实际部署不匹配。最常见的原因是auth_url指向了http://controller:5000/v3但Keystone的admin端点实际监听在https://controller:5000/v3启用了TLS。排查链路验证Keystone admin端点是否可达curl -k https://controller:5000/v3 # -k忽略SSL证书错误 # 应返回JSON格式的Keystone版本信息检查Glance配置中的auth_url协议grep auth_url /etc/glance/glance-api.conf # 若输出为 auth_url http://controller:5000/v3而Keystone实际是HTTPS则必须改为https检查memcached服务状态sudo systemctl status memcached # 若为inactive则Glance会退化为每次请求都做完整token校验极易超时6.3 故障三镜像上传成功但glance image-show id返回Image not found现象glance image-create返回201glance image-list能看到新镜像但glance image-show却报错。根因分析镜像元数据已写入数据库但镜像文件未成功写入后端存储。这通常发生在file后端因目录权限错误或磁盘空间不足。排查链路检查数据库中镜像状态sudo -u postgres psql -d glance -c SELECT id, status, location FROM images WHERE namemy-centos; # status应为activelocation应为类似file:///var/lib/glance/images/uuid的路径检查location路径下的文件是否存在ls -lh /var/lib/glance/images/uuid # 若文件不存在则是存储写入失败检查Glance日志中的存储错误sudo tail -50 /var/log/glance/api.log | grep -i error\|fail # 常见错误OSError: [Errno 13] Permission denied6.4 故障四glance image-list响应极慢30秒但单个镜像查询很快现象列出所有镜像耗时漫长但glance image-show id瞬间返回。根因分析Glance在image-list时会对每个镜像执行一次完整的get_image_location操作以填充location字段。若后端存储如Swift响应慢或memcached未命中就会导致累积延迟。排查链路禁用location字段以验证glance image-list --limit 10 --sort-key name --sort-dir asc --fields id,name,status,size # 若此命令变快则证实是location字段拖慢了速度检查glance-api.conf中是否启用了show_image_direct_url[DEFAULT] show_image_direct_url False # 必须为False否则会强制查询每个镜像的物理位置优化memcached配置# 编辑/etc/memcached.conf增大内存和连接数 -m 512 # 内存从默认64M提升到512M -c 1024 # 最大连接数从1024提升到2048 sudo systemctl restart memcached最后分享一个个人心得每次修改glance-api.conf后不要直接systemctl restart而是先用glance-api --config-file /etc/glance/glance-api.conf --debug --verbose前台运行。它会实时打印所有加载的配置项和初始化日志让你一眼看出哪个参数没生效比在systemd日志里大海捞针高效十倍。这是我踩过二十多次坑后总结出的最省时排错法。