给虚拟机加一块「永不丢数据」的盘,靠的是 Cinder。这篇按一条主线走:存储类型怎么分 → Cinder 到底是什么 → 五个组件怎么分工 → 一块卷从创建到挂进虚拟机经过哪几站 → 实验环境的 LVM 后端长什么样。全部内容对着一套
192.168.108.10(controller + compute)的 packstack 环境核实过,配置行、报错、卷组名都能直接对号入座。文中命令名均标注英文全称,完整清单见文末《附:命令英文全称速查表》。
本文概要:
| 项目 | 内容 |
|---|---|
| 文章主题 | Cinder 的定位、五组件架构、创建卷与挂卷全流程、LVM 后端落地 |
| 所属类别 | 云计算 → 私有云平台 → OpenStack 块存储管理 |
| 知识关键字 | Cinder·cinder-api·cinder-scheduler·cinder-volume·Filter/Weigher·cinder-volumes·LVM·iSCSI |
主线的因果只有一条:Cinder 自己不是存储,它只是「逻辑存储卷」这一层抽象;真正存数据的永远是它身后的 LVM、Ceph、SAN 这些后端。所以先把「谁管哪类存储」摆正,再看组件怎么分工,最后跟着一块卷走完创建和挂载的全程。
一、先摆正存储类型:临时存储与持久存储
从数据保存时间的角度,OpenStack 的存储分两类:
| 类型 | 谁提供 | 数据命运 | 典型例子 |
|---|---|---|---|
| 临时存储 Ephemeral | Nova | 实例关机、重启、删除后数据即丢失 | 实例里第一块 10 GB 系统盘 |
| 持久存储 Persistent | Cinder / Manila / Swift | 生命周期独立于实例,实例终止数据还在 | 云硬盘、镜像、备份 |
三个关键点:
- 只部署 Nova 时,默认分配给虚拟机的磁盘就是临时的——虚拟机终止,存储空间跟着释放;
- 临时存储默认以文件形式放在计算节点的本地磁盘上;
- 持久存储三兄弟按「速度 / 容量」背口径:块存储(Cinder)快而小、文件存储(Manila)中等、对象存储(Swift)慢而海量——对应跑车、卡车、货轮。文件存储的访问协议是NFS / CIFS;对象存储直接用REST API访问,对象名就是一个域名地址。
⚠️注意:三种存储的归属是高频考点——块存储是 Cinder,不是 Swift;文件存储是 Manila,别答成 Swift。Swift 存的是对象(虚拟机镜像、图片、备份归档这类静态数据)。
二、Cinder 的定位:抽象层,不是存储技术
Cinder 首次出现在 OpenStack 的Folsom版本,依赖Keystone认证服务。它的定位三句话:
- 在虚拟机与具体存储设备之间引入了一层「逻辑存储卷」的抽象——Cinder 本身不是一种存储技术,并没有实现对块设备的实际管理和服务;
- 它只提供中间抽象层,为后端不同的存储技术提供统一的接口;
- 不同的块设备厂商(华为、EMC、NetApp、Ceph……)在 Cinder 中以驱动(driver)的形式实现这套接口,从而被 OpenStack 整合管理。
和其他服务的交互关系也很简单:Nova创建虚拟机时,Cinder 给实例提供持久化块存储;Cinder 创建的卷备份可以存到Swift;所有操作都先过Keystone认证。
三、架构五组件:谁收请求、谁挑后端、谁真正落盘
| 组件 | 一句话职责 | 展开说 |
|---|---|---|
| cinder-api | 对外提供 REST API,解析操作需求 | 卷的增删改查(含从源卷、镜像、快照创建)、快照增删改查、备份、volume type 管理、挂载/卸载(由 Nova 调用) |
| cinder-scheduler | 收集后端上报的容量与能力信息,完成卷到 cinder-volume 的调度 | 与 nova-scheduler 同款思路:Filter 筛选 + Weigher 权重 |
| cinder-volume | 多节点部署,调 Driver 在后端真正执行卷操作 | 使用不同配置文件接入不同后端;用 Driver 返回的模型更新数据库 |
| cinder-backup | 把卷的数据备份到其他存储介质 | 目前Swift / Ceph / TSM提供了驱动 |
| SQL DB | 存卷、快照、备份、service 等数据 | 支持 MySQL、PG、MSSQL 等 |
配置文件与日志的位置也要记:
[root@controller ~]# ls /etc/cinder # cinder 的配置文件目录api-paste.ini cinder.conf resource_filters.json rootwrap.conf rootwrap.d volumes[root@controller ~]# systemctl status openstack-cinder-api.service● openstack-cinder-api.service - OpenStack Cinder API Server Active: active(running)...# 中文:服务运行中[root@controller ~]# ps -e | grep cinder # 中文:列出进程并过滤 cinder1746? 00:00:03 cinder-schedule1748? 00:00:04 cinder-api1772? 00:00:03 cinder-backup1791? 00:00:04 cinder-volume控制节点上 api、scheduler、volume、backup 四个进程同时在跑;排查问题先看
/var/log/cinder/下对应组件的日志。
四、创建卷全流程:api 查参数 → scheduler 挑后端 → volume 落盘
4.1 cinder-api:四件事
- 检查参数合法性——用户输入、权限、资源是否存在;
- 准备创建的参数字典,预留和提交配额;
- 在数据库中创建对应的数据记录;
- 通过消息队列把请求和参数发给 Scheduler。
4.2 cinder-scheduler:filter 过滤 + weigher 权重
调度分两步,和 nova-scheduler 一脉相承:
| Filter(过滤) | 干什么 |
|---|---|
AvailabilityZoneFilter | 不属于指定可用分区(AZ)的后端直接刷掉 |
CapacityFilter | 存储空间满足不了卷大小的后端刷掉 |
CapabilitiesFilter | 不支持卷类型所需特性(如 thin provision)的后端刷掉 |
Affinity_filter | 同后端亲和(SameBackendFilter)/ 反亲和(DifferentBackendFilter) |
| Weigher(权重) | 干什么 |
|---|---|
CapacityWeigher/AllocatedCapacityWeigher | 按容量/已分配容量打分(默认) |
ChanceWeigher | 随机打分 |
GoodnessWeigher | 按优良度打分 |
默认配置(/etc/cinder/cinder.conf)里这三行就是开关:
#scheduler_default_filters = AvailabilityZoneFilter,CapacityFilter,CapabilitiesFilter # 默认启用的过滤器(注释状态) #scheduler_default_weighers = CapacityWeigher # 默认权重算法(注释状态) #scheduler_driver = cinder.scheduler.filter_scheduler.FilterScheduler # 默认调度器(注释状态)选中最优后端后,Scheduler 再经消息队列把请求发给对应的 cinder-volume。
4.3 cinder-volume:三件事 + 一件长期任务
- 提取接收到的请求参数;
- 调用对应的 Driver 在后端创建实际的卷;
- 使用 Driver 返回的模型更新数据库中的记录。
长期任务是第 4 件:定期收集后端的容量、能力信息上报,让 Scheduler 内存里的 Backend 信息保持新鲜——这是后面所有调度判断的数据来源。
4.4 AZ 实验:一条报错看懂 AvailabilityZoneFilter
把存储节点的 AZ 改成az1后建卷,三种写法三种命:
[root@controller ~(keystone_admin)]# openstack volume create --size 1 volume1Availability zone'nova'is invalid.(HTTP400)# 中文:可用域 nova 无效——cinder.conf 里 default_availability_zone=nova,# 建卷不指定 AZ 就落到 nova,而节点在 az1,被 AvailabilityZoneFilter 拦下[root@controller ~(keystone_admin)]# openstack volume create --size 1 --availability-zone az2 volume1Availability zone'az2'is invalid.(HTTP400)# 中文:可用域 az2 无效——没有任何后端在 az2,同样被过滤[root@controller ~(keystone_admin)]# openstack volume create --size 1 --availability-zone az1 volume1+-------------------+--------------------------------------+|Field|Value|+-------------------+--------------------------------------+|availability_zone|az1||size|1||status|creating||type|iscsi|+-------------------+--------------------------------------+# 中文:指定 az1 才创建成功;type 显示 iscsi 是由卷类型的扩展规格决定的相关配置两行:
storage_availability_zone=az1 # 该存储节点所属的 AZ default_availability_zone=nova # 建卷不指定 AZ 时默认落到的 AZ改完记得systemctl restart openstack-cinder*重启生效。
五、挂卷流程:Nova 和 Cinder 打配合
挂卷的本质:把远端的卷连接到虚拟机所在的 Host 节点,再由虚拟机管理程序映射进虚拟机。六步:
- Nova 调用 Cinder API(attach),传递主机信息——hostname、iSCSI initiator name、FC WWPNs;
- Cinder API 把信息传给Cinder Volume;
- Cinder Volume 按建卷时保存的 host 信息找到对应的 Cinder Driver;
- Cinder Driver 通知存储放行该主机访问该卷,并返回连接信息——如 iSCSI iqn、portal,FC Target WWPN,NFS path;
- Nova 调用识别磁盘的代码(Cinder 提供 brick 模块作参考),在主机上识别出磁盘或文件设备;
- Nova 通知 Cinder 已挂载,再把主机设备信息交给hypervisor映射进虚拟机——虚拟机里出现
/dev/vdb这样的块设备,状态从 available 变in-use。
以 iSCSI 为例串一遍底层视角:计算节点是iSCSI initiator(发起端),存储端是iSCSI target(目标端),卷数据经 Storage Controller 交给 KVM。Cinder 支持 FC、NFS 等多种协议,流程骨架不变。
六、实验环境的后端:LVM 与 cinder-volumes 卷组
Cinder 默认使用LVM(Logical Volume Manager,逻辑卷管理)作为后端存储。LVM 的思路是把物理卷(PV,如磁盘分区)组成卷组(VG),再从卷组里切出**逻辑卷(LV)**挂文件系统——这正是「逻辑存储卷」抽象的最朴素实现。除 LVM 外,Cinder 已以驱动形式支持 SAN、Ceph、Sheepdog 及华为、EMC 等厂商设备。
实验环境的后端是安装时定死的,answers.txt里留了案底:
CONFIG_CINDER_BACKEND=lvm # 后端选了 lvm CONFIG_CINDER_VOLUMES_CREATE=y # 安装时自动创建卷组 CONFIG_CINDER_VOLUME_NAME=cinder-volumes # 卷组名 CONFIG_CINDER_VOLUMES_SIZE=20G # 卷组大小验收就一条命令:
[root@controller ~]# vgdisplay cinder-volumes # 中文:查看卷组 cinder-volumes 的信息--- Volume group --- VG Name cinder-volumes VG Size<20.60GiB Alloc PE / Size5020/<19.61GiB Free PE / Size253/1012.00MiB而[lvm]段的完整定义在/etc/cinder/cinder.conf尾部:
[lvm] volume_backend_name=lvm # 后端名字,卷类型靠它认后端 volume_driver=cinder.volume.drivers.lvm.LVMVolumeDriver # 驱动类 target_ip_address=192.168.108.10 # iSCSI target 地址 target_helper=lioadm # target 管理工具 volume_group=cinder-volumes # 用的卷组 volumes_dir=/var/lib/cinder/volumes # 卷信息目录⚠️注意:卷类型(volume type)与后端的绑定靠扩展规格里的
volume_backend_name——建卷时指定卷类型 iscsi,实际落到的就是volume_backend_name=lvm的这个后端。「卷类型指定 iscsi 为什么用的是 LVM」的答案就这一句:由卷类型的扩展规格决定。多后端(比如再加 NFS)的接法见姊妹篇《OpenStack 存储管理实操:卷类型 QoS、卷全生命周期与 NFS 第二后端》。
附:命令英文全称速查表
| 命令 | 英文全称 | 含义 |
|---|---|---|
cinder | Cinder | 块存储服务名(本文主角) |
openstack volume create | volume / create | 卷 / 创建 |
--size | size | 卷大小(GiB) |
--availability-zone | availability zone | 可用分区 |
ps -e | process status / every | 进程状态 / 所有进程 |
grep | global regular expression print | 全局正则匹配过滤 |
systemctl status | system control / status | 系统服务管理 / 查看状态 |
vgdisplay | volume group display | 显示 LVM 卷组信息 |
LVM | Logical Volume Manager | 逻辑卷管理 |
PV / VG / LV | Physical / Volume Group / Logical Volume | 物理卷 / 卷组 / 逻辑卷 |
iSCSI | Internet Small Computer System Interface | 基于 IP 的 SCSI 传输协议 |
initiator / target | 发起端 / 目标端 | iSCSI 两端角色 |
REST | Representational State Transfer | 表述性状态转移(API 风格) |
MQ | Message Queue | 消息队列 |