OpenStack Glance镜像服务详解
Glance是OpenStack的镜像服务核心组件,提供虚拟机镜像的发现、注册、检索和交付能力。采用元数据与数据分离的架构设计,通过可插拔的 glance_store 适配层实现后端存储的灵活切换。📸
一、Glance核心架构概览
组件全景图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ┌──────────┐ │ Keystone │ └────┬─────┘ │ AUTH ┌────▼─────┐ USER ──REST API──► GLANCE-API│ └────┬─────┘ │ ┌─────────▼──────────┐ │ GLANCE.STORE │ ◄── 存储抽象层 ├────────────────────┤ │ 元数据 → SQL DB │ ◄── MySQL(镜像元信息) │ 镜像数据 → 后端 │ ◄── 可插拔后端存储 └────────────────────┘ │ ┌────────────────┼────────────────┐ ▼ ▼ ▼ FILE存储 SWIFT CEPH RBD (本地磁盘) (对象存储) (分布式存储)
|
核心组件一览表
| 组件 |
职责 |
说明 |
| glance-api |
RESTful API入口 |
处理镜像查询/上传/删除等所有请求,对接Keystone认证 |
| glance-registry |
元数据存储服务 |
Newton版本后为可选组件,旧版负责镜像元数据读写 |
| glance.db |
元数据库(MySQL) |
存储镜像ID、名称、格式、checksum、location等元信息 |
| glance.store |
存储后端适配层 |
核心抽象层,实现镜像数据与后端存储的解耦 |
架构设计哲学 — 元数据与数据分离
1 2 3 4 5 6 7 8 9 10 11 12 13
| 镜像 = 镜像元数据 (Metadata) + 镜像数据 (Data)
元数据 → 存储在 glance.db (MySQL) ├── id, name, disk_format, container_format ├── size, status, visibility ├── checksum (MD5), os_hash_value (SHA512) ├── properties (自定义属性) └── locations (指向后端存储的 URI)
镜像数据 → 存储在后端存储中 ├── file:///var/lib/glance/images/<UUID> ├── swift://account/container/<UUID> └── rbd://pool/image/<UUID>
|
关键设计理念: Nova 启动虚拟机时根据 location 直接从后端存储读取数据,不经 glance-api 中转,避免额外网络跳转和数据拷贝。🚀
二、镜像格式详解 🗂️
Glance 支持多种镜像格式,覆盖主流虚拟化平台:
| 格式 |
扩展名 |
特性 |
适用场景 |
| QCOW2 |
.qcow2 |
QEMU原生格式,稀疏文件(按需分配)、快照链、写时复制 |
最常用,KVM/QEMU 虚拟化首选 |
| RAW |
.raw |
无格式裸磁盘镜像,性能最优 |
高性能计算、数据库等I/O密集型场景 |
| VMDK |
.vmdk |
VMware虚拟磁盘格式 |
VMware 虚拟机迁移到 OpenStack |
| VHD/VHDX |
.vhd |
Microsoft Hyper-V 格式 |
与 Hyper-V 平台互操作 |
| ISO |
.iso |
光盘归档格式 |
安装介质注入(如 cloud-init) |
| AKI/ARI/AMI |
- |
Amazon kernel/ramdisk/image |
AWS 镜像兼容 |
| Ploop |
- |
Virtuozzo/Parallels 格式 |
容器化虚拟化场景 |
| Docker |
- |
Docker 容器格式 |
(已逐步淘汰) |
QCOW2 vs RAW 深度对比 ⚡
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| QCOW2: ├── 创建时仅占用实际使用的空间(稀疏文件) ├── 支持快照链(snapshot chain) ├── 支持写时复制(copy-on-write, COW) ├── 支持 AES 加密(不推荐生产使用) ├── 支持压缩(qemu-img convert -c) └── 有小幅性能开销(约 5-10%)
RAW: ├── 创建时即分配全部空间 ├── 无格式转换开销,I/O 性能最高 ├── QEMU/KVM 直通效率最高 ├── 可通过 qemu-img 转换为任意格式 └── 占用磁盘空间较大
|
经验建议: 日常虚拟机用 QCOW2(节省空间、支持快照),高性能数据库类用 RAW,VMware 对接用 VMDK。✅
三、镜像上传与下载 📥📤
上传镜像
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
| openstack image create "cirros-0.6.2" \ --file cirros-0.6.2-x86_64-disk.img \ --disk-format qcow2 \ --container-format bare \ --public
openstack image create "ubuntu-22.04" \ --location https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img \ --disk-format qcow2 \ --container-format bare \ --public
openstack image create "centos-stream-raw" \ --file CentOS-Stream-8-x86_64.raw \ --disk-format raw \ --container-format bare
openstack image create "windows-server-iso" \ --file windows-server-2022.iso \ --disk-format iso \ --container-format bare
|
create 参数详解:
| 参数 |
说明 |
可选值 |
--DISK-FORMAT |
磁盘格式 |
qcow2 / raw / vmdk / vhd / iso |
--CONTAINER-FORMAT |
容器封装格式 |
bare / ovf / aki / ari / ami / docker |
--PUBLIC |
公开可见 |
所有项目可访问 |
--PRIVATE |
私有镜像 |
仅本项目和被共享项目可见 |
--PROTECTED |
保护模式 |
禁止删除(需取消保护后方可删除) |
--PROPERTY |
自定义属性 |
如 --property architecture=x86_64 |
--STORE |
指定存储后端 |
多后端环境下指定目标后端(Stein+) |
--MIN-DISK |
最小磁盘要求 |
启动该镜像所需的最小磁盘 GB |
--MIN-RAM |
最小内存要求 |
启动该镜像所需的最小内存 MB |
--SIGNATURE |
签名文件 |
镜像完整性签名 |
--TAG |
Glance元数据标签 |
与元定义配合实现镜像分类 |
下载镜像
1 2 3 4 5 6 7 8 9 10 11 12
| openstack image list
openstack image show <IMAGE_ID_OR_NAME>
openstack image save --file myimage.qcow2 <IMAGE_ID>
|
镜像格式转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| qemu-img convert -f qcow2 -O raw source.qcow2 target.raw
qemu-img convert -f vmdk -O qcow2 source.vmdk target.qcow2
qemu-img convert -f raw -O qcow2 -c source.raw target.qcow2
qemu-img info image.qcow2
|
四、镜像共享 👥
4.1 项目间共享
Glance 提供细粒度的镜像共享机制,支持三种可见性级别:
| 级别 |
权限要求 |
行为 |
| public |
admin |
所有项目自动可见 |
| private |
镜像所有者 |
仅本项目和显式共享的项目可见 |
| shared |
镜像所有者 |
通过 member 机制授予特定项目访问 |
4.2 CLI 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| openstack image set --share --project <TARGET_PROJECT_ID> <IMAGE_ID>
openstack image add project <IMAGE_ID> <TARGET_PROJECT_ID>
openstack image member list <IMAGE_ID>
openstack image set --accept <IMAGE_ID>
openstack image remove project <IMAGE_ID> <TARGET_PROJECT_ID>
openstack image member list --image <IMAGE_ID>
|
4.3 社区镜像共享最佳实践
- 基础公共镜像(如 Ubuntu Cloud、Cirros)设为 public
- 自定义业务镜像设为 private,通过 member 精确控制
- 使用
--PROTECTED 防止关键镜像被误删 🛡️
五、后端存储架构 💾
5.1 解耦设计 — glance.store 适配层
Glance 的核心架构优势在于 镜像存储与镜像管理解耦,通过 glance.store 实现插拔式后端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ┌─────────────────────────────────────────────────┐ │ 用户 / Nova(REST API) │ ├─────────────────────────────────────────────────┤ │ glance-api │ ├─────────────────────────────────────────────────┤ │ glance.store 抽象层 │ │ ┌───────────┬───────────┬───────────┬────────┐ │ │ │ FILE │ SWIFT │ CEPH RBD │ 其它 │ │ │ │ 本地文件 │ 对象存储 │ 分布式存储 │ NFS.. │ │ │ └───────────┴───────────┴───────────┴────────┘ │ ├─────────────────────────────────────────────────┤ │ glance.db (MySQL) │ │ 存储镜像元数据 + locations │ └─────────────────────────────────────────────────┘
|
5.2 后端存储配置
配置位于 /etc/glance/glance-api.conf:
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
| [glance_store]
default_backend = file
enabled_backends = file:file, swift:swift, ceph:rbd
[file] filesystem_store_datadir = /var/lib/glance/images/ filesystem_store_file_perm = 1
[swift] swift_store_container = glance swift_store_create_container_on_put = True swift_store_auth_address = http://controller:5000/v3 swift_store_user = service:glance swift_store_key = <PASSWORD> swift_store_endpoint_type = internalURL
[rbd] rbd_store_pool = images rbd_store_user = glance rbd_store_ceph_conf = /etc/ceph/ceph.conf rbd_store_chunk_size = 8 rados_connect_timeout = 30
|
5.3 各后端对比
| 特性 |
本地 File |
Swift |
Ceph RBD |
| 高可用 |
❌ 单点 |
✅ 多副本 |
✅ 多副本/EC |
| 分布式 |
❌ |
✅ |
✅ |
| 性能 |
⭐⭐⭐⭐ |
⭐⭐⭐ |
⭐⭐⭐⭐⭐ |
| 扩展性 |
单机磁盘限制 |
水平扩展 |
水平扩展 |
| 支持克隆 |
❌ |
❌ |
✅ (RBD clone) |
| 运维复杂度 |
⭐(简单) |
⭐⭐⭐ |
⭐⭐⭐ |
| 典型规模 |
测试/小规模 |
中规模 |
大规模生产 |
| 数据路径优化 |
Nova本地读取 |
Nova从Swift拉取 |
Nova RBD clone零拷贝 |
生产推荐: ✅ Ceph RBD > Swift > 本地文件
5.4 多后端存储(Stein+)
Stein 版本开始支持多后端存储,不同镜像可选不同后端:
1 2 3 4 5 6 7 8 9 10 11
| [glance_store] enabled_backends = fast:ssd, standard:sata, archive:nfs
[ssd] filesystem_store_datadir = /var/lib/glance/fast_images/
[sata] filesystem_store_datadir = /var/lib/glance/standard_images/
[nfs] filesystem_store_datadir = /mnt/nfs/glance_images/
|
创建镜像时指定后端:
1 2 3 4 5
| openstack image create "fast-io-image" \ --file high_perf.qcow2 \ --store ssd \ --disk-format qcow2 \ --container-format bare
|
5.5 Location 机制 — 解耦的关键 🔑
Glance 在数据库中记录镜像数据的 存储位置 URI,Nova 根据该 URI 直接访问:
1 2 3 4 5 6 7
| 1. 用户上传镜像 → glance-api 接收数据流 2. glance_store 根据配置写入后端存储 3. 数据库记录 location 和 checksum 4. Nova 启动 VM 时: - 从 glance 获取镜像元数据(ID, location, checksum) - 根据 location 直接从后端存储读取数据 - 不需要经过 glance-api 中转(直接访问)
|
核心优势: Glance 不参与数据路径 — 虚机启动时 Nova 直接从 Ceph/Swift 拉取镜像数据,这是大规模 OpenStack 部署的关键性能优化。⚡
六、Ceph RBD 与 Glance 深度集成 🔗
6.1 RBD 零拷贝克隆
使用 Ceph RBD 后端时,Nova 可以直接从 Ceph 克隆镜像生成虚拟机磁盘:
1 2 3 4 5 6 7 8
| GLANCE: images pool (rbd) │ ├── image-a (template) │ └── NOVA: rbd clone ──→ vms pool (rbd) ├── vm-1-disk (COW snapshot of image-a) ├── vm-2-disk (COW snapshot of image-a) └── vm-3-disk (COW snapshot of image-a)
|
这意味着:
- 无需实际拷贝镜像数据,创建虚机秒级完成 🚀
- 写时复制技术,存储空间按需分配
- 百台虚机从同一镜像启动仅占一份全量空间
6.2 Ceph 配置步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ceph osd pool create images 128 ceph osd pool application enable images rbd
ceph auth get-or-create client.glance \ mon 'allow r' \ osd 'allow class-read object_prefix rbd_children, allow rwx pool=images' \ -o /etc/ceph/ceph.client.glance.keyring
ceph auth get-or-create client.glance | \ tee /etc/ceph/ceph.client.glance.keyring
|
6.3 Ceph 场景性能优势
| 指标 |
本地文件 |
Swift |
Ceph RBD |
| 100台VM启动时间 |
~30min |
~15min |
~30s |
| 镜像存量占用 |
100% |
100% |
~1%(COW) |
| Nova读取路径 |
NFS/CIFS远程挂载 |
HTTP拉取 |
RBD kernel直接读 |
| 快照支持 |
❌ |
❌ |
✅ RBD快照 |
七、镜像缓存策略 📦
7.1 glance-cache 机制
Glance 提供缓存层,将常用镜像缓存到本地磁盘,加速部署:
1 2 3 4 5 6 7 8 9 10 11 12
| glance-cache-manage --host=controller list-cached
glance-cache-manage --host=controller queue-image <IMAGE_ID>
glance-cache-manage --host=controller delete-cached-images
glance-cache-manage --host=controller fetch-all
|
7.2 缓存配置
1 2 3 4 5 6
| [ DEFAULT] image_cache_dir = /var/lib/glance/image-cache image_cache_driver = sqlite image_cache_max_size = 10737418240
|
八、镜像签名与安全验证 🔒
8.1 镜像签名
OpenStack Mitaka 版本开始支持镜像签名验证:
1 2 3 4 5 6 7 8 9 10 11 12
| openssl dgst -sha512 -sign private_key.pem \ -out image.signature image.qcow2
openstack image create "signed-image" \ --file image.qcow2 \ --sign-key-url http://keyserver/signing-key.pem \ --sign-cert-url http://keyserver/certificate.pem \ --signature image.signature \ --disk-format qcow2 \ --container-format bare
|
8.2 镜像完整性校验
1 2 3 4 5 6
| openstack image show <IMAGE_ID> -c checksum -c os_hash_algo -c os_hash_value
sha512sum downloaded-image.qcow2
|
九、镜像生命周期管理 📋
vm_image 状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| ┌──────────┐ │ queued │ ── 镜像元数据已创建,数据未上传 └────┬─────┘ │ ┌────▼─────┐ │ saving │ ── 正在上传镜像数据 └────┬─────┘ │ ┌────▼─────┐ ┌─────► active │ ── 镜像可用 │ └────┬─────┘ │ │ ┌────▼───┐ ┌──▼──────┐ │ deactivated│ │pending_delete│── 软删除 └──────────┘ └─────────┘ │ ┌────▼─────┐ │ deleted │ ── 已删除(不可恢复) └──────────┘
|
常用管理命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| openstack image list
openstack image set --name NEW_NAME \ --property architecture=arm64 \ --property hypervisor_type=kvm \ <IMAGE_ID>
openstack image delete <IMAGE_ID_OR_NAME>
openstack image deactivate <IMAGE_ID> openstack image reactivate <IMAGE_ID>
openstack server list --image <IMAGE_ID>
|
十、生产部署最佳实践 ✅
| 实践 |
说明 |
| 生产用 Ceph RBD |
避免本地文件存储的单点故障,利用 COW 提升性能 |
| 上传前校验格式 |
qemu-img info 确认格式正确,避免启动失败 |
| 使用 SHA512 校验 |
镜像完整性验证,防止数据损坏 |
| 设置 protected |
防止关键镜像被误删 🛡️ |
| 细粒度共享 |
敏感镜像设为 private + member 精确赋权 |
| 镜像签名 |
对关键镜像启用签名验证 |
| 清理未使用镜像 |
定期清理废弃镜像,释放存储空间 |
| 监控 glance 日志 |
/var/log/glance/api.log 关注上传/下载错误 |
| 多后端策略 |
高频镜像放 SSD,归档镜像放 HDD/NFS |
| 启用镜像缓存 |
多计算节点场景显著加速部署 |
十一、版本演进趋势 🚀
| 版本 |
核心变化 |
| Newton |
引入 glance_store 架构,registry 变为可选 |
| Ocata |
新增镜像去激活功能(deactivate/reactivate) |
| Pike |
支持多后端存储 |
| Queens |
镜像导入/导出流程标准化 |
| Stein |
多后端正式稳定,image import API 成熟 |
| Train |
镜像签名验证增强 |
| Wallaby |
支持镜像加密(使用 Barbican) |
| 2025.1 Epoxy |
强化镜像加密与签名校验 |
| 2026.1 Gazpacho |
持续优化 Ceph 集成与性能提升 |
💡 技术解析
- 术语: glance_store — Glance 的存储抽象层,独立的 oslo 库(
glance_store),所有后端存储通过该插件化接口接入。这是实现镜像与后端存储解耦的关键架构组件。所有后端实现只需实现核心 CRUD 接口即可无缝集成。
- 术语: QCOW2 — QEMU Copy-On-Write v2,支持稀疏文件(仅分配实际写入的块)、内部快照链(snapshot chain)、写时复制克隆(backing file)、AES 加密和 zlib 压缩。相较于 QCOW(v1),QCOW2 支持快照和更大的虚拟磁盘。
- 术语: Copy-on-Write (COW) — 写时复制技术,克隆时不复制源数据,仅写入新数据时才按需分配空间。Glance + Ceph 场景的核心性能保障,秒级创建百台虚机。
- 术语: RBD Clone — Ceph RBD 的快照克隆机制,基于 COW 技术从镜像快照直接创生虚拟机磁盘,无需拷贝源数据,是 Nova 与 Glance 协同优化的核心亮点。
- 术语: Location (存储位置) — glance.db 中记录镜像数据实际存储位置的 URI 字段(如
rbd://pool/image/uuid),Nova 根据该 URI 直接从后端读取镜像数据,实现 Glance 不参与数据路径。
- 术语: Container Format — 镜像的容器封装格式,
bare 表示无封装(裸镜像),ovf 表示 OVF 标准封装;aki/ari/ami 对应 AWS 内核/ramdisk/机器镜像。
- 术语: Multibackend (多后端) — Stein+ 版本功能,
enabled_backends 配置多个存储后端,创建镜像时通过 --STORE 参数指定目标后端,实现不同存储策略(SSD 高性能 / SATA 大容量 / NFS 归档)。
- 术语: Glance Cache — 将远端存储的热门镜像缓存到本地磁盘的加速机制,通过
glance-cache-manage 管理,适用于 Swift 后端的多计算节点场景。Yoga 版本后已标记废弃,推荐使用 Ceph RBD 替代。
- 命令:
openstack image create — 创建并上传镜像,--FILE 指定本地路径,--DISK-FORMAT 指定 qcow2/raw/vmdk/iso,--CONTAINER-FORMAT 指定 bare/ovf,--PUBLIC/--PRIVATE 控制可见性,--PROPERTY 添加自定义元数据。
- 命令:
openstack image save — 将远程镜像下载到本地,--FILE 指定保存路径。注意大镜像需确保本地磁盘空间充足,且下载路径不宜跨网络(建议在计算节点或 controller 节点直接操作)。
- 命令:
openstack image set --share — 跨项目共享镜像,--PROJECT 指定目标项目 ID,目标项目需 openstack image set --accept 接受后方可使用。
- 命令:
qemu-img convert — 磁盘镜像格式转换工具,-f 指定源格式,-O 指定目标格式,-c 启用压缩(仅目标为 qcow2 时有效)。支持的格式对:qcow2↔raw↔vmdk↔vhd↔qed。