首页 > 技术文章 > OpenStack核心组件-cinder存储服务

ajunyu 2019-07-04 14:24 原文

1. cinder 介绍

Block Storage

操作系统获得存储空间的方式一般有两种:

  1)     通过某种协议(SAS,SCSI,SAN,iSCSI 等)挂接裸硬盘,然后分区、格式化、创建文件系统;或者直接使用裸硬盘存储数据(数据库);

  2)     通过 NFS、CIFS 等 协议,mount 远程的文件系统。

  第一种裸硬盘的方式叫做 Block Storage(块存储),每个裸硬盘通常也称作 Volume(卷) 第二种叫做文件系统存储。NAS 和 NFS 服务器,以及各种分布式文件系统提供的都是这种存储。

 

Block Storage Service

  Block Storage Servicet 提供对 volume 从创建到删除整个生命周期的管理。从 instance 的角度看,挂载的每一个 Volume 都是一块硬盘。OpenStack 提供 Block Storage Service 的是 Cinder,其具体功能是:

  1)     提供 REST API 使用户能够查询和管理 volume、volume snapshot 以及 volume type;

  2)     提供 scheduler 调度 volume 创建请求,合理优化存储资源的分配;

  3)     通过 driver 架构支持多种 back-end(后端)存储方式,包括 LVM,NFS,Ceph 和其他诸如 EMC、IBM 等商业存储产品和方案。

 

Cinder 架构

下图是 cinder 的逻辑架构图

Cinder 包含如下几个组件:

Cinder-api

  接收 API 请求, 调用 cinder-volume 。是整个 Cinder 组件的门户,所有 cinder 的请求都首先由 cinder-api 处理。cinder-api 向外界暴露若干 HTTP REST API 接口。在 keystone 中我们可以查询 cinder-api 的 endponits。

  客户端可以将请求发送到 endponits 指定的地址,向 cinder-api 请求操作。 当然,作为最终用户的我们不会直接发送 Rest API 请求。OpenStack CLI,Dashboard 和其他需要跟 Cinder 交换的组件会使用这些 API。

 

cinder-api 对接收到的 HTTP API 请求会做如下处理:

  1)  检查客户端传人的参数是否合法有效;

  2)  调用 cinder 其他子服务的处理客户端请求;

  3)  将 cinder 其他子服务返回的结果序列号并返回给客户端。

  cinder-api 接受哪些请求呢?简单的说,只要是 Volume 生命周期相关的操作,cinder-api 都可以响应。大部分操作都可以在 Dashboard 上看到。

  

Cinder-volume

  管理 volume 的服务,与 volume provider 协调工作,管理 volume 的生命周期。运行 cinder-volume 服务的节点被称作为存储节点。

  cinder-volume 在存储节点上运行,OpenStack 对 Volume 的操作,最后都是交给 cinder-volume 来完成的。cinder-volume 自身并不管理真正的存储设备,存储设备是由 volume provider 管理的。cinder-volume 与 volume provider 一起实现 volume 生命周期的管理。

 

通过 Driver 架构支持多种 Volume Provider

  接着的问题是:现在市面上有这么多块存储产品和方案(volume provider),cinder-volume 如何与它们配合呢?

  通过的 Driver 架构。 cinder-volume 为这些 volume provider 定义了统一的接口,volume provider 只需要实现这些接口,就可以 Driver 的形式即插即用到 OpenStack 系统中。、

 

定期向 OpenStack 报告计算节点的状态

  cinder-volume 会定期向 Cinder 报告存储节点的空闲容量来做筛选启动volume

 

实现 volume 生命周期管理

  Cinder 对 volume 的生命周期的管理最终都是通过 cinder-volume 完成的,包括 volume 的 create、extend、attach、snapshot、delete 等。

 

cinder-scheduler

  scheduler 通过调度算法选择最合适的存储节点创建 volume。 创建 Volume 时,cinder-scheduler 会基于容量、Volume Type 等条件选择出最合适的存储节点,然后让其创建 Volume。

 

volume provider

  数据的存储设备,为 volume 提供物理存储空间。 cinder-volume 支持多种 volume provider,每种 volume provider 通过自己的 driver 与cinder-volume 协调工作。

 

Message Queue

  Cinder 各个子服务通过消息队列实现进程间通信和相互协作。因为有了消息队列,子服务之间实现了解耦,这种松散的结构也是分布式系统的重要特征。

 

Database Cinder 

  有一些数据需要存放到数据库中,一般使用 MySQL。数据库是安装在控制节点上的,比如在我们的实验环境中,可以访问名称为“cinder”的数据库。

 

物理部署方案

  Cinder 的服务会部署在两类节点上,控制节点和存储节点。我们来看看控制节点 controller 上都运行了哪些 cinder-* 子服务。

       cinder-api 和 cinder-scheduler 部署在控制节点上,这个很合理。

 

  至于 cinder-volume 也在控制节点上:cinder-volume 不是应该部署在存储节点上吗?

       OpenStack 是分布式系统,其每个子服务都可以部署在任何地方,只要网络能够连通。无论是哪个节点,只要上面运行了 cinder-volume,它就是一个存储节点,当然,该节点上也可以运行其他 OpenStack服务。

 

  cinder-volume 是一顶存储节点帽子,cinder-api 是一顶控制节点帽子。在我们的环境中,devstack-controller 同时戴上了这两顶帽子,所以它既是控制节点,又是存储节点。当然,我们也可以用一个专门的节点来运行 cinder-volume。

 

  这再一次展示了 OpenStack 分布式架构部署上的灵活性: 可以将所有服务都放在一台物理机上,用作一个 All-in-One 的测试环境;而在生产环境中可以将服务部署在多台物理机上,获得更好的性能和高可用。

 

  RabbitMQ 和 MySQL 通常放在控制节点上。另外,也可以用 cinder service list 查看 cinder-* 子服务都分布在哪些节点上

 

volume provider 放在那里?

  一般来讲,volume provider 是独立的。cinder-volume 使用 driver 与 volume provider 通信并协调工作。所以只需要将 driver 与 cinder-volume 放到一起就可以了。在 cinder-volume 的源代码目录下有很多 driver,支持不同的 volume provider。

  后面我们会以 LVM 和 NFS 这两种 volume provider 为例讨论 cinder-volume 的使用,其他 volume provider 可以查看 OpenStack 的 configuration 文档。

2. Cinder 的设计思想

从 volume 创建流程看 cinder-* 子服务如何协同工作

  对于 Cinder 学习来说,Volume 创建是一个非常好的场景,涉及各个 cinder-* 子服务,下面是流程图:

 

  • ž       客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(cinder-api)发送请求:“帮我创建一个 volume”
  • ž       API 对请求做一些必要处理后,向 Messaging(RabbitMQ)发送了一条消息:“让 Scheduler 创建一个 volume”
  • ž   Scheduler(cinder-scheduler)从 Messaging 获取到 API 发给它的消息,然后执行调度算法,从若干计存储点中选出节点 A
  • ž   Scheduler 向 Messaging 发送了一条消息:“让存储节点 A 创建这个 volume”
  • ž   存储节点 A 的 Volume(cinder-volume)从 Messaging 中获取到 Scheduler 发给它的消息,然后通过 driver 在 volume provider 上创建 volume。

 Cinder 的设计思想

  Cinder 延续了 Nova 的以及其他组件的设计思想。

API 前端服务

  cinder-api 作为 Cinder 组件对外的唯一窗口,向客户暴露 Cinder 能够提供的功能,当客户需要执行 volume 相关的操作,能且只能向 cinder-api 发送 REST 请求。这里的客户包括终端用户、命令行和 OpenStack 其他组件。

设计 API 前端服务的好处在于:

  • 1)      对外提供统一接口,隐藏实现细节;
  • 2)      API 提供 REST 标准调用服务,便于与第三方系统集成;
  • 3)      可以通过运行多个 API 服务实例轻松实现 API 的高可用,比如运行多个 cinder-api 进程。

Scheduler 调度服务

  Cinder 可以有多个存储节点,当需要创建 volume 时,cinder-scheduler 会根据存储节点的属性和资源使用情况选择一个最合适的节点来创建 volume。

  调度服务就好比是一个开发团队中的项目经理,当接到新的开发任务时,项目经理会根据任务的难度,每个团队成员目前的工作负荷和技能水平,将任务分配给最合适的开发人员。

 

Worker 工作服务

  调度服务只管分配任务,真正执行任务的是 Worker 工作服务。

  在 Cinder 中,这个 Worker 就是 cinder-volume 了。这种 Scheduler 和 Worker 之间职能上的划分使得 OpenStack 非常容易扩展:当存储资源不够时可以增加存储节点(增加 Worker)。 当客户的请求量太大调度不过来时,可以增加 Scheduler。

 

Driver 框架

  OpenStack 作为开放的 Infrastracture as a Service 云操作系统,支持业界各种优秀的技术,这些技术可能是开源免费的,也可能是商业收费的。

  这种开放的架构使得 OpenStack 保持技术上的先进性,具有很强的竞争力,同时又不会造成厂商锁定(Lock-in)。 那 OpenStack 的这种开放性体现在哪里呢?一个重要的方面就是采用基于 Driver 的框架。

  以 Cinder 为例,存储节点支持多种 volume provider,包括 LVM, NFS, Ceph, GlusterFS,以及 EMC, IBM 等商业存储系统。 cinder-volume 为这些 volume provider 定义了统一的 driver 接口,volume provider 只需要实现这些接口,就可以 driver 的形式即插即用到 OpenStack 中。下面是 cinder driver 的架构示意图:

 

  在 cinder-volume 的配置文件 /etc/cinder/cinder.conf 中 volume_driver 配置项设置该存储节点使用哪种 volume provider 的 driver,下面的示例表示使用的是 LVM。

 

 

3. 部署cinder服务

3.1 部署控制节点

1> 创建数据库

[root@ajy6 ~]# mysql -uroot -p123
MariaDB [(none)]> CREATE DATABASE cinder;
MariaDB [(none)]>  GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' \
->   IDENTIFIED BY 'CINDER_DBPASS';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' \
->   IDENTIFIED BY 'CINDER_DBPASS';
MariaDB [(none)]> exit
Bye

2> 创建用户

[root@ajy6 ~]# openstack user create --domain default --password=cinder  cinder

3> 设置为管理员

[root@ajy6 ~]# openstack role add --project service --user cinder admin

4> 创建两个卷服务

[root@ajy6 ~]# openstack service create --name cinderv2 \
>   --description "OpenStack Block Storage" volumev2
[root@ajy6 ~]# openstack service create --name cinderv3 \
>   --description "OpenStack Block Storage" volumev3

5> 添加服务端点

[root@ajy6 ~]# openstack endpoint create --region RegionOne \
>   volumev2 public http://ajy6:8776/v2/%\(project_id\)s
[root@ajy6 ~]#  openstack endpoint create --region RegionOne \
>   volumev2 internal http://ajy6:8776/v2/%\(project_id\)s
[root@ajy6 ~]#  openstack endpoint create --region RegionOne \
>   volumev2 admin http://ajy6:8776/v2/%\(project_id\)s
[root@ajy6 ~]# openstack endpoint create --region RegionOne \
>   volumev3 public http://ajy6:8776/v3/%\(project_id\)s
[root@ajy6 ~]# openstack endpoint create --region RegionOne \
>   volumev3 internal http://ajy6:8776/v3/%\(project_id\)s
[root@ajy6 ~]# openstack endpoint create --region RegionOne \
>   volumev3 admin http://ajy6:8776/v3/%\(project_id\)s

6> 下载安装

[root@ajy6 ~]# yum install openstack-cinder -y

7> 编辑配置文件/etc/cinder/cinder.conf

[root@ajy6 ~]# cd /etc/cinder/
[root@ajy6 cinder]# ls
api-paste.ini  cinder.conf  policy.json  rootwrap.conf  rootwrap.d  volumes
[root@ajy6 cinder]# cp cinder.conf cinder.conf.bak
[root@ajy6 cinder]# vim cinder.conf
[DEFAULT]
my_ip = 192.168.16.66
#glance_api_servers = http://ajy6:9292
auth_strategy = keystone
#enabled_backends = lvm     #使用lvm的方式开启后端存储,存储节点使用           
transport_url = rabbit://openstack:123@ajy6

[backend]

[barbican]

[brcd_fabric_example]

[cisco_fabric_example]

[coordination]

[cors]

[cors.subdomain]

[database]
connection = mysql+pymysql://cinder:CINDER_DBPASS@ajy6/cinder

[fc-zone-manager]

[healthcheck]

[key_manager]

[keystone_authtoken]
auth_uri = http://ajy6:5000
auth_url = http://ajy6:35357
memcached_servers = ajy6:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = cinder
password = cinder

[matchmaker_redis]

[oslo_concurrency]
lock_path = /var/lib/cinder/tmp

[oslo_messaging_amqp]

[oslo_messaging_kafka]

[oslo_messaging_notifications]

[oslo_messaging_rabbit]

[oslo_messaging_zmq]

[oslo_middleware]

[oslo_policy]

[oslo_reports]

[oslo_versionedobjects]

[profiler]

[ssl]

[lvm]                                         #lvm驱动。存储节点使用
#volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
#volume_group = cinder-vg
#volumes_dir = $state_path/volumes
#iscsi_protocol = iscsi
#iscsi_helper = lioadm
#iscsi_ip_address = 192.168.16.66

 8> 同步数据库

[root@ajy6 cinder]# su -s /bin/sh -c "cinder-manage db sync" cinder

9> 配置计算节点使用后端存储

[root@ajy6 cinder]# vim /etc/nova/nova.conf
.........
[cinder]
os_region_name = RegionOne
........
[root@ajy8 ~]# vim  /etc/nova/nova.conf
........
[cinder]
os_region_name = RegionOne
..........

10> 重启nova服务

[root@ajy6 cinder]# systemctl restart openstack-nova-api.service

11> 启动存储服务

[root@ajy6 cinder]# systemctl start openstack-cinder-api.service openstack-cinder-scheduler.service
[root@ajy6 cinder]# systemctl enable openstack-cinder-api.service openstack-cinder-scheduler.service

启动后用cinder自己的命令查看服务

[root@ajy6 ~]# cinder service-list
+------------------+------+------+---------+-------+----------------------------+-----------------+
| Binary           | Host | Zone | Status  | State | Updated_at                 | Disabled Reason |
+------------------+------+------+---------+-------+----------------------------+-----------------+
| cinder-scheduler | ajy6 | nova | enabled | up    | 2019-07-03T06:18:44.000000 | -               |
+------------------+------+------+---------+-------+----------------------------+-----------------+

3.2 部署存储节点

       存储节点部署在主机192.168.16.69上。

1> 下载lvm2,开启lvm服务

存储节点使用lvm存储。

[root@ajy9 ~]# yum install lvm2 -y
[root@ajy9 ~]# systemctl start lvm2-lvmetad.service        #高版本centos开启的
[root@ajy9 ~]# systemctl enable lvm2-lvmetad.service
[root@ajy9 ~]# systemctl status lvm2-lvmetad.service

2> 使用添加的硬盘创建lvm卷组

查看新添加的硬盘

[root@ajy9 ~]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   35G  0 disk
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   34G  0 part
  ├─centos-root 253:0    0   32G  0 lvm  /
  └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
sdb               8:16   0   16G  0 disk
sr0              11:0    1  4.3G  0 rom

创建物理卷

[root@ajy9 ~]#  pvcreate /dev/sdb
  Physical volume "/dev/sdb" successfully created.

创建卷组

[root@ajy9 ~]# vgcreate cinder-volumes /dev/sdb
  Volume group "cinder-volumes" successfully created

查看vg组

[root@ajy9 ~]# vgdisplay
  --- Volume group ---
  VG Name               cinder-volumes
  System ID            
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               <16.00 GiB
  PE Size               4.00 MiB
  Total PE              4095
  Alloc PE / Size       0 / 0  
  Free  PE / Size       4095 / <16.00 GiB
  VG UUID               ylcUZi-HS8R-dglA-ysSu-nLNG-AL9j-BE5x9t

  --- Volume group ---
  VG Name               centos
  System ID            
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               <34.00 GiB
  PE Size               4.00 MiB
  Total PE              8703
  Alloc PE / Size       8702 / 33.99 GiB
  Free  PE / Size       1 / 4.00 MiB
  VG UUID               HheSxU-d8g6-sq3e-HxeF-T6iV-fWeG-v9L5ev

3> 编辑配置文件/etc/lvm/lvm.conf,将创建的vg组写入

[root@ajy9 ~]# vim /etc/lvm/lvm.conf
devices {
...........
        allow_changes_with_duplicate_pvs = 1
        filter = [ "a/sdb/", "r/.*/"]
}

4> 下载安装

[root@ajy9 ~]# yum install openstack-cinder targetcli python-keystone -y

 5> 修改配置文件/etc/cinder/cinder.conf

[root@ajy9 ~]# cd /etc/cinder/
[root@ajy9 cinder]# ls
api-paste.ini  cinder.conf  policy.json  rootwrap.conf  rootwrap.d  volumes
[root@ajy9 cinder]# cp cinder.conf cinder.conf.bak
[root@ajy9 cinder]# vim cinder.conf
[DEFAULT]
my_ip = 192.168.16.69
glance_api_servers = http://ajy6:9292
auth_strategy = keystone
enabled_backends = lvm                               #开启lvm存储
transport_url = rabbit://openstack:123@ajy6

[backend]

[barbican]

[brcd_fabric_example]

[cisco_fabric_example]

[coordination]

[cors]

[cors.subdomain]

[database]
connection = mysql+pymysql://cinder:CINDER_DBPASS@ajy6/cinder

[fc-zone-manager]

[healthcheck]
[key_manager] [key_manager] [keystone_authtoken] auth_uri
= http://ajy6:5000 auth_url = http://ajy6:35357 memcached_servers = ajy6:11211 auth_type = password project_domain_name = default user_domain_name = default project_name = service username = cinder password = cinder
[matchmaker_redis] [oslo_concurrency] lock_path
= /var/lib/cinder/tmp [oslo_messaging_amqp] [oslo_messaging_kafka] [oslo_messaging_notifications] [oslo_messaging_rabbit] [oslo_messaging_zmq] [oslo_middleware] [oslo_policy] [oslo_reports] [oslo_versionedobjects] [profiler] [ssl] [lvm] volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver #驱动 volume_group = cinder-volumes #vg组 volumes_dir = $state_path/volumes #volumes卷挂载路径 iscsi_protocol = iscsi #iscsi协议 iscsi_helper = lioadm #io管理方式 iscsi_ip_address = 192.168.16.69 #lvm服务器地址

6> 启动存储节点服务

[root@ajy9 cinder]# systemctl start openstack-cinder-volume.service target.service
[root@ajy9 cinder]# systemctl enable openstack-cinder-volume.service target.service
[root@ajy9 cinder]# systemctl status openstack-cinder-volume.service target.service

7> 在控制节点使用cinder命令行查看cinder服务(有问题,要改)

[root@ajy6 ~]# cinder service-list
+------------------+----------+------+---------+-------+----------------------------+-----------------+
| Binary           | Host     | Zone | Status  | State | Updated_at                 | Disabled Reason |
+------------------+----------+------+---------+-------+----------------------------+-----------------+
| cinder-scheduler | ajy6     | nova | enabled | up    | 2019-07-03T07:28:49.000000 | -               |
| cinder-volume    | ajy9@lvm | nova | enabled | down  | 2019-07-03T15:29:19.000000 | -               |
+------------------+----------+------+---------+-------+----------------------------+-----------------+

3.3 创建卷

  cinder部署好后就可以创建卷了。由于选择部署cinder在新加的sdb上面,因此创建的卷全部在磁盘sdb上。

再在存储节点查看块设备,块设备下已创建了卷

[root@ajy9 cinder]# lsblk
NAME                                        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda                                           8:0    0   35G  0 disk
├─sda1                                        8:1    0    1G  0 part /boot
└─sda2                                        8:2    0   34G  0 part
  ├─centos-root                           253:0    0   32G  0 lvm  /
  └─centos-swap                           253:1    0    2G  0 lvm  [SWAP]
sdb                                           8:16   0   16G  0 disk
└─cinder--volumes-volume--ea80fbbd--4b1d--4f9b--9fa7--c26083ad7cf4
                                            253:2    0    1G  0 lvm 

控制节点查看cinder

[root@ajy6 ~]# cinder list
+--------------------------------------+-----------+-------------+------+-------------+----------+-------------+
| ID                                   | Status    | Name        | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+-------------+------+-------------+----------+-------------+
| ea80fbbd-4b1d-4f9b-9fa7-c26083ad7cf4 | available | volume-test | 1    | -           | false    |             |
+--------------------------------------+-----------+-------------+------+-------------+----------+-------------+

删除创建的卷用cinder del ID

[root@ajy6 ~]# cinder delete ea80fbbd-4b1d-4f9b-9fa7-c26083ad7cf4
[root@ajy6 ~]# cinder list
+----+--------+------+------+-------------+----------+-------------+
| ID | Status | Name | Size | Volume Type | Bootable | Attached to |
+----+--------+------+------+-------------+----------+-------------+
+----+--------+------+------+-------------+----------+-------------+
[root@ajy9 cinder]# lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   35G  0 disk
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   34G  0 part
  ├─centos-root 253:0    0   32G  0 lvm  /
  └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
sdb               8:16   0   16G  0 disk

4. web界面创建虚拟机

       新建虚拟机要创建其镜像、配置、网络。

1> 镜像

 

2> 配置(实例对象)

标配:

实际环境配置要高,高配:

3> 网络(交换机)

查看创建的网络

网络拓扑图:

图表:

4> 实例(虚拟机)

  选择源时,如果选择创建新卷,则虚拟机的磁盘会落在存储节点的sdb上,如果选择不创建新卷,则disk磁盘会选择落在计算节点上。先创建一个落在计算节点上的虚拟机。

 

推荐阅读