Skip to content

openstack cinder使用 #22

@tzing0013

Description

@tzing0013

Cinder

粘官网的一句话
The default OpenStack Block Storage service implementation is an iSCSI solution that
uses Logical Volume Manager (LVM) for Linux.

几种CLI创建volume的方式

1 参数含义

名称 作用
--size 指定volume的大小
--tyep 使用openstack volume type create命令创建 如共有私有所属project等 会有默认值
--snapshot snapshot是对示例或卷进行备份操作 记录了当前实例或卷的状态 用于还原
--image 创建的卷包含镜像 可作为启动盘
--source 指定源,克隆卷
--description 描述
--bootable 标记是否可用于启动 无镜像的卷设置后可作为启动盘 就是虚拟机连不上

--source和--snapshot不能同时使用,
--size和--snapshot谁大用谁
代码点openstackclient.volume.v2.volume.py::CreateVolume.take_action

        size = parsed_args.size

        snapshot = None
        if parsed_args.snapshot:
            snapshot_obj = utils.find_resource(
                volume_client.volume_snapshots,
                parsed_args.snapshot)
            snapshot = snapshot_obj.id
            # Cinder requires a value for size when creating a volume
            # even if creating from a snapshot. Cinder will create the
            # volume with at least the same size as the snapshot anyway,
            # so since we have the object here, just override the size
            # value if it's either not given or is smaller than the
            # snapshot size.
            size = max(size or 0, snapshot_obj.size)

--size和--source同时使用时--size不能小于--source的大小,否则会报错
报错代码点cinderclient.client.py::SessionClient.request # 请求返回码400以上
判断的代码点应该是在服务里,当前还没有看到

--type的默认值是从db中获取的 应该是安装cinder的时候创建的 未关注这个点
可以使用如下openstack命令或者到db里查询

# openstack volume type list  

# mysql -u root -p
MariaDB [(none)]> use cinder
MariaDB [cinder]> show tables;  # 查看table
MariaDB [cinder]> select * from volume_types;  # 查看volume_types表的所有属性
+---------------------+---------------------+------------+---------+--------------------------------------+-------------+--------------+-----------+---------------------+
| created_at          | updated_at          | deleted_at | deleted | id                                   | name        | qos_specs_id | is_public | description         |
+---------------------+---------------------+------------+---------+--------------------------------------+-------------+--------------+-----------+---------------------+
| 2024-01-01 00:00:00 | 2024-01-01 00:00:00 | NULL       |       0 | 125ad3d2-7755-41cc-b319-46929fcb310e | __DEFAULT__ | NULL         |         1 | Default Volume Type |
+---------------------+---------------------+------------+---------+--------------------------------------+-------------+--------------+-----------+---------------------+

2 创建volume

  • 创建大小100G的数据卷:
openstack volume create --size 100 vdata
  • 创建大小50G 包含镜像 可以作为启动盘的卷:
openstack volume create --size 50 --image my-image vboot
  • 使用快照创建卷:
    以下命令依次为
    1创建实例快照2创建卷快照3查看创建的快照4使用快照创建卷
openstack server image create --name my-image-snapshot my-server
openstack volume snapshot create --volume vdata vdata-snapshot
openstack volume snapshot list
openstack volume create --snapshot 'snapshot for my-image-snapshot' vboot2

创建卷快照时卷状态必须是available

  • 克隆卷:
    直接克隆某个卷 忽略卷状态
openstack volume create --source vboot vboot-source
  • 创建卷时使用type参数:
openstack volume type create --public --property provisioning:min_vol_size=89 --property volume_backend_name=range min89
openstack volume create --size 91 --image my-image --type min89 testv2

一开始以为这个type就是随便指定个类型,在看volume创建的流程时发现type参数可以限制volume的大小,
同时在使用--source或--snapshot参数时还会验证backend
调用及源码如下:

volume.api.py::API.create  
-> volume.volume_types.py::provision_filter_on_size  # 检查type规定的大小  
-> volume.api.py::API._retype_is_possible  # 使用--source或--snapshot参数时验证backend是否一致  
# 验证backend是否一致
        if snapshot and volume_type:
            if volume_type.id != snapshot.volume_type_id:
                if not self._retype_is_possible(context,
                                                snapshot.volume.volume_type,
                                                volume_type):
                    msg = _("Invalid volume_type provided: %s (requested "
                            "type is not compatible; recommend omitting "
                            "the type argument).") % volume_type.id
                    raise exception.InvalidInput(reason=msg)
# 检查type规定的大小
def provision_filter_on_size(context, volume_type, size):
    if volume_type:
        size_int = int(size)
        extra_specs = volume_type.get('extra_specs', {})
        min_size = extra_specs.get(MIN_SIZE_KEY)
        if min_size and size_int < int(min_size):
            msg = _("Specified volume size of '%(req_size)d' is less "
                    "than the minimum required size of '%(min_size)s' "
                    "for volume type '%(vol_type)s'.") % {
                'req_size': size_int, 'min_size': min_size,
                'vol_type': volume_type['name']
            }
            raise exception.InvalidInput(reason=msg)

        max_size = extra_specs.get(MAX_SIZE_KEY)
        if max_size and size_int > int(max_size):
            msg = _("Specified volume size of '%(req_size)d' is "
                    "greater than the maximum allowable size of "
                    "'%(max_size)s' for volume type '%(vol_type)s'."
                    ) % {
                'req_size': size_int, 'max_size': max_size,
                'vol_type': volume_type['name']}
            raise exception.InvalidInput(reason=msg)

根据代码反推出openstack volume type create命令--property参数的格式,但是按照以上命令创建volume会发现命令可以成功执行,volume却无法创建成功,
在scheduler.log可以看到错误原因是
No valid backend was found. No weighed backends available
再去网上搜一搜发现backend是要配置

  • 使用volume创建虚拟机
    以下命令依次为
    1创建100G数据卷vdata
    2创建50G启动卷vboot
    3使用vboot创建虚拟机
    4给虚拟及添加数据卷
openstack volume create --size 100 vdata
openstack volume create --size 50 --image my-image vboot
openstack server create --flavor my-flavor --volume vboot --network public-network --key-name keypair my-server
openstack server add volume my-server vdata

连接虚拟机并查看块设备,可看到vda 50G,vdb 100G

# ssh cirros@10.100.100.234 -i /root/tzing/tmp/tmp_private_key
$ lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vda     252:0    0   50G  0 disk 
|-vda1  252:1    0   50G  0 part /
`-vda15 252:15   0    8M  0 part 
vdb     252:16   0  100G  0 disk 

配置back-end选择方式

简单翻译总结下官网话的几句话,使用back-end的原因(自己的理解 可能不准确)
1.通过设置filter和weighting,可以选择更好的back-end
2.默认的filter使用的原则是free capacity
3.有多个块设备时,单个设备总空间的占用率达到75%会导致性能下降

back-end的名字可以随意起,比如我上面的命令中就叫的range,可以通过cinder.conf中配置
filter和weighing来过滤选择合适的back-end
以filter为例,在cinder.conf文件中新增如下配置

[DEFAULT]
# 新增rng
enabled_backends = lvm, rng
scheduler_default_filters = DriverFilter

[rng]
volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver
volume_backend_name = range
filter_function = "volume.size < 10"

添加完以上配置后重启cinder所有服务,
再使用之前的命令创建携带type参数的volume成功

其他配置细节可参考官网文档链接

当前没理解这个工作原理,按功能理解应该是多个backend上配置,
然后根据配置的filter选择通过哪个backend来创建volume,
当前资源有限,后续再验证这个猜测

设置cinder的log级别为DEBUG

1 找到cinder服务使用的config文件
一般默认是/etc/cinder/cinder.conf
也可以ps -ef|grep cinder命令查询,部分结果如下,可看到cinder-api使用的config-file

# ps -ef|grep cinder
cinder   1065511       1  0 09:04 ?        00:00:11 /usr/bin/python3 /usr/bin/cinder-api --config-file /etc/cinder/cinder.conf --logfile /var/log/cinder/api.log

具体配置方法可在官网Cinder Service Configuration章节提供的cindr.conf.sample中找到
修改配置文件如下并重启cinder服务后即可在日志中显式DEBUG级别的日志

[DEFAULT]
debug = true

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions