Cinder服务详解
# Cinder服务详解
Cinder是OpenStack中为虚拟机提供虚拟硬盘服务的组件,在早期也是Nova中的一个组件,但是从F版本开始被剥离出来作为单独的项目存在。在OpenStack里面,Nova组件和Cinder组件都可以创建存储卷,在之前搭建虚拟机的时候中我们也实际操作过,Nova组件和Cinder组件都使用本地的LVM存储卷来提供存储服务。
Nova组件通常是创建虚拟机的系统盘,单个系统盘容量一般比较小,通常在50-100G左右,整个大小是在创建实例规格的时候定义的。而实际提供数据存储的盘则由Cinder服务提供,一般会把Cinder对接多种后端,来提供不同性能水平的数据盘,通常是IOPS的大小差异,并发写入的带宽差异等。例如下面的公有云磁盘性能差异:
Cinder服务可以实现存储卷的创建、挂载、卸载、快照(snapshot)全生命周期管理。
# Cinder体系结构
Cinder的各个组件之间的体系架构如下图所示:
从上面图里可以看到,cinder-api负责接收用户请求,例如创建存储卷、获取存储卷信息、删除存储卷、创建快照等。然后调用后端不同的组件来完成用户请求,例如调用Cinder-scheduler来处理存储卷的创建、删除、扩缩容等操作。调用cinder-backup组件完成存储卷备份的管理工作,例如创建备份、备份恢复、备份删除这些基本操作,cinder-backup组件后端也是需要对接外部存储。
cinder-volume组件是用来管理本地硬盘资源或者网络存储资源到宿主机的映射,一般是安装在提供物理硬盘存储的计算节点或者专门的存储节点上。
cinder默认使用lvm作为后端存储,这样就可以直接使用存储节点上的物理磁盘,就像我们在之前第一章的计算节点上创建的lvm,先在物理磁盘上创建pv,然后创建vg,cinder在接收到存储盘创建请求的时候,到vg上去划分对应大小的空间创建lv,并在lv上创建虚拟机数据盘所需的文件系统, 例如ext4,xfs等,创建好后挂载到虚拟机上使用。如果使用的是网络存储,例如Ceph,它会通过Ceph集群的配置信息和认证文件,到Ceph集群上对应存储池中(通常是volumes)创建一个rbd文件,然后将这个rbd文件挂载为虚拟机所在宿主机上的物理磁盘,最后再把这个物理磁盘挂载到虚拟机里使用。
这两种存储各有各的优势,例如lvm存储可以直接利用物理磁盘,因此性能更加优异,对于一些需要高性能的需求来说,使用这种类型的存储比较合适。但是磁盘是固定在物理服务器上,当物理服务器宕机时,数据也不能即时取出。
使用Ceph存储,当物理服务器宕机的时候,我们只需要把rbd文件挂载到新的宿主机上,并在这个新的宿主机直接启动虚拟机,数据就回来了。 因此灵活性更好,但是相对lvm存储来说,性能就比不上了。对于云服务来说,数据安全性和灵活性一般比性能更重要,这也是为什么网络存储在云服务中使用这么广泛的原因。
# Cinder的调度策略
当使用lvm存储,cinder-scheduler这个组件就会根据实际的请求去选择合适的存储节点,它会经过过滤和权重两个流程选择出最合适的存储节点。基本流程像下面示例图演示的那样,对这个流程只需要了解即可,因为实际私有云部署中,使用lvm存储的情况比较少见,大部分还是以云存储居多。
# 过滤器和权重器
cinder选择合适的存储节点是通过过滤器(Filters)和权重器(weigher)两层工具来实现。首先使用过滤器从所有后端存储节点中选择出符合条件的多个节点,然后通过权重计算,依次计算出每个节点的权重值,最后选择权重最高的那个节点来创建存储卷。
在Cinder的配置文件中,默认的过滤器配置是:
scheduler_default_filters = AvailabilityZoneFilter,CapacityFilter,CapabilitiesFilter
即默认有3个过滤器,分别是
- 可用区过滤器,通过可用区来过滤;
- 容量过滤器,通过存储节点可用存储容量来过滤;
- 兼容性过滤器,存储类型是是否满足实例或存储卷的要求来过滤; 同样在配置文件中,默认的权重器配置是:
scheduler_default_weighers = CapacityWeigher
这个配置计算权重,是根据存储节点上剩余的磁盘空间容量来计算的,剩余的磁盘空间容量越大,权重值越高。
实际上Cinder的配置中还可以使用其他的过滤器和权重器,但是就像上面说的那样,现在的OpenStack集群在生产上部署时,以网络存储为主,基本上不使用本地存储,因此这两者我们不需要过多的去了解,当真正要用到的时候再去查看官方文档即可。
cinder-volume
在上面基本流程中说到,cinder-volume是存储节点上实际负责被调度的组件,它会对接后端的存储硬盘,并根据请求里的参数创建出对应大小的数据卷,并将这个数据卷映射到虚拟机上,给虚拟机使用。实际配置如下:
[lvm]
target_helper = lioadm
target_protocol = iscsi
target_ip_address = 192.168.31.193
volume_backend_name = LVM
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_group = cinder-volumes
volumes_dir = $state_path/volumes
2
3
4
5
6
7
8
其实从参数上我们就可以看到,它使用的是iSCSI协议,这个协议简单点说,就是把远程服务器上的存储设备映射到本地机器上作为一个块设备来使用。对于普通用户来说,映射过来的磁盘和本地直接安装的物理磁盘没什么区别。
在上面的配置中,我们依次指定了使用协议、提供磁盘的服务器IP地址、提供卷的后端名称、操作卷的驱动名称、卷组名称以及卷组路径。
# 网络存储映射流程
目前生产上的OpenStack集群后端对接的存储类型大部分都是各种分布式存储,例如我们经常提到的Ceph。Glance组件用它存储镜像文件,Nova用它存储系统盘文件,Cinder用它存储数据盘和镜像备份文件。这些组件使用的都是Ceph提供的块存储,也称为RBD存储,因为它使用rbd协议直接将Ceph存储池里的文件挂载到虚拟机上使用。使用rbd协议的块存储和使用iSCSI协议的LVM存储一样,都是把远程设备上的文件映射到本地作为一个块设备,提供给虚拟机使用。
对于LVM来说,它的映射结构如下所示:
对于Ceph来说,它的映射结构是:
# Cinder多存储卷配置
如果后端可以提供多种类型的存储卷,例如普通性能的SSD和高性能的SSD,像上面图中看到的,我们在公有云上购买虚拟机的时候,都会有这样的选项,而在OpenStack上我们自己配置的时候,也可以实现。
# 准备工作
先在存储节点上安装好ceph-common工具,因为nova需要利用这个工具里提供的命令来挂载ceph 存储到虚拟机上,安装命令是:
yum install ceph-common
然后在Ceph节点上获取cinder keyring文件的一个临时副本:
ceph auth get-key client.cinder | ssh {your-compute-node} tee client.cinder.key
这个命令会把这个副本密钥文件client.cinder.key发送到计算节点上。然后在存储节点上生成一个uuid,命令是:
uuidgen
生成的uuid如下所示:
f1ce6a51-d46b-4af0-88d2-593d45edd899
然后在计算节点上编译一个secret.yml文件,内容如下:
<secret ephemeral='no' private='no'>
<uuid>f1ce6a51-d46b-4af0-88d2-593d45edd899</uuid>
<usage type='ceph'>
<name>client.cinder secret</name>
</usage>
</secret>
2
3
4
5
6
然后定义一个secret,命令是:
sudo virsh secret-define --file secret.xml
它会提示创建成功了一个secret,并生成了一个secret uuid。
Secret f1ce6a51-d46b-4af0-88d2-593d45edd899 created
然后我们将它设置为一个固定的键值对:
sudo virsh secret-set-value --secret f1ce6a51-d46b-4af0-88d2-593d45edd899 \
--base64 $(cat client.cinder.key) && rm client.cinder.key secret.xml
2
设置成功后删除临时的keyring文件和secret.xml文件,这里的操作实际上就是把uuid和认证文件的key绑定到一起。
你在实际测试过程中的uuid值可能不一样,替换为你自己的uuid值即可。
假设后端的Ceph存储给我们提供了两种类型的存储池,第一种是基于普通的HDD磁盘,第二种是基于纯SSD构建,存储团队那边给我们提供了存储池的名称分别是volumes和volumes-ssd,那么在Cinder的配置文件里的配置就是:
[DEFAULT]
enabled_backends=lvm,volumes-hdd,volumes-ssd
[volumes-hdd]
volume_driver = cinder.volume.drivers.rbd.RBDDriver
volume_backend_name = volumes-hdd
rbd_pool = volumes
rbd_ceph_conf = /etc/ceph/ceph.conf
rados_connect_timeout = 5
rbd_keyring_conf = /etc/ceph/ceph.client.cinder.keyring
rbd_user = cinder
rbd_secret_uuid = f1ce6a51-d46b-4af0-88d2-593d45edd899
report_discard_supported = True
[volumes-ssd]
volume_driver = cinder.volume.drivers.rbd.RBDDriver
volume_backend_name = volumes-ssd
rbd_pool = volumes-ssd
rbd_ceph_conf = /etc/ceph/ceph.conf
rbd_keyring_conf = /etc/ceph/ceph.client.cinder2.keyring
rados_connect_timeout = 5
rbd_user = cinder
rbd_secret_uuid = f1ce6a51-d46b-4af0-88d2-593d45edd899
report_discard_supported = True
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
上面的配置中因为两个用户名都是一样的,如果后端是两个不一样的集群,那么对应的keyring文件名就要避免冲突。是由rbd_keyring_conf配置来分别指定不同的认证文件名称。配置好以后重启后端服务:
systemctl restart openstack-cinder-volume
然后我们需要手动创建一个这个卷类型,命令是:
openstack volume type create --public --description "ceph hdd rbd pool" ceph-hdd
openstack volume type set --property volume_backend_name="volumes-hdd" ceph-hdd
2
第二个命令把后端的存储池名称和卷类型绑定到一起,然后创建这种类型的数据卷时,就会自动到对应的存储池里创建卷文件。
创建一个示例卷演示。
# Cinder-Backup存储配置
在搭建Cinder服务的时候,我们有提到过Cinder-backup组件的后端只能对接网络存储服务,不支持本地存储,目前支持的网络存储有:
- Ceph
- Swift
- Glusterfs
- GCS 等等组件,因此在本节搭建好了Ceph存储以后,我们来尝试也把它对接到Ceph存储。
在计算节点上打开/etc/cinder/cinder.conf配置文件,添加下面的配置:
[DEFAULT]
backup_ceph_conf=/etc/ceph/ceph.conf
backup_ceph_user=cinder-backup
backup_ceph_chunk_size = 134217728
backup_ceph_pool=backups
backup_driver = cinder.backup.drivers.ceph.CephBackupDriver
backup_ceph_stripe_unit = 0
backup_ceph_stripe_count = 0
restore_discard_excess_bytes = true
2
3
4
5
6
7
8
9
对于部署cinder-backup服务的节点需要下面3个配置文件:
- /etc/ceph/ceph.conf
- /etc/cinder/ceph.client.cinder.keyring
- /etc/cinder/ceph.client.cinder-backup.keyring 而且需要把两个keyring文件的用户和群组都改为cinder,避免权限问题。添加好以后,重启cinder组件服务,命令是:
systemctl restart openstack-cinder-api openstack-cinder-scheduler openstack-cinder backup
重启完成以后,就可以来测试cinder-backup服务了。
首先显示存储卷:
openstack volume list
+--------------------------------------+----------+-----------+------+-------------+
| ID | Name | Status | Size | Attached to |
+--------------------------------------+----------+-----------+------+-------------+
| 60d95974-6f99-47a9-a7f2-1c29518185d1 | ceph-sdb | available | 5 | |
+--------------------------------------+----------+-----------+------+-------------+
2
3
4
5
6
7
为什么比cinder组件多一个keyring文件,原因是cinder-backup它需要到cinder组件的存储池去读取原来的文件,并写入到新的备份存储池中。
创建存储卷备份,命令是:
openstack volume backup create 60d95974-6f99-47a9-a7f2-1c29518185d1
命令最后是存储卷的ID,创建完成后,可以使用命令来查看:
openstack volume backup list
创建好的备份数据如下所示:
+--------------------------------------+------+-------------+-----------+------+
| ID | Name | Description | Status | Size |
+--------------------------------------+------+-------------+-----------+------+
| 4792d8ee-d3d9-4a54-805d-ed18cadcb37a | None | None | available | 5 |
+--------------------------------------+------+-------------+-----------+------+
2
3
4
5