cinder volume启动流程解析

本文详细解析了Cinder Volume服务在OpenStack中的启动流程,特别是如何使用Ceph RBD作为后端存储驱动。文章介绍了Cinder Volume服务的主要组件及其职责,强调了Green Thread的概念以及避免服务阻塞的重要性。通过对cinder-volume服务的启动过程分析,展示了VolumeManager的创建和VolumeDriver的关联。Ceph RBD Driver是基于ceph的python-rbd和python-rados接口定制的,处理rbd的管理操作。文章还讨论了在处理长时间运行的操作时,如何通过tpool和eventlet结合来解决服务阻塞问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于openstack stable queens版本阅读解析
基于 centos7.5 的linux系统

架构

如下所示,为cinder的官方架构说明:
这里写图片描述

各个组件介绍如下:
- DB: sql database for data storage. Used by all components.
- Web Dashboard: potential external component that talks to the api.
- api: component that receives http requests, converts commands and communicates with other components via the queue or http.
- Auth Manager: component responsible for users/projects/and roles. Can backend to DB or LDAP. This is not a separate binary, but rather a python class that is used by most components in the system.
- scheduler: decides which host gets each volume.
- volume: manages dynamically attachable block devices.
- backup: manages backups of block storage devices.

本文档主要基于volume这组件进行解析,来描述cinder如何使用后端存储,而其提供的api和scheduler问题,可能会少量涉及。

代码可以直接通过github获取:git clone https://git.openstack.org/openstack/cinder.git

cinder主要的实现代码在cinder目录下,其service组件的入口位置均在cinder/cmd/{service}.py,{service}为cinder的各个service组件,如api、scheduler、volume等等。由于都是python代码,可读性比较强,知道main函数后,后面的一步步追踪就好了。

cinder volume service

cinder-volume服务是Cinder最关键的服务,负责对接后端存储驱动,管理volume数据卷生命周期。
在openstack中,所有服务组件都是使用eventlet和greenlet库实现非阻塞的任务线程切换处理,以实现服务的并发功能,该线程模型被openstack称为Green Thread,也就是协程。Green Thread 的上下文切换只会发生在eventlet或者greenlet库调用的时候(比如sleep, certain I/O calls)。

from eventlet import greenthread
...
greenthread.sleep(0)

也就是说,从OS的角度来看,openstack service只有一个运行线程。如果某个green thread运行task时被阻塞了,即task调用的接口是阻塞,从而阻塞了thread,那么,service就会一直等待该线程执行结束,其它服务线程就无法进行切换。这会造成一个问题:cinder-volume服务会定时向数据库上报自己的状态,此时,如果volume服务调用比如ceph接口执行flatten操作(flatten操作时间可能会很长,是阻塞操作),导致thread一直阻塞,那么volume就不能及时上报自己的状态,导致集群认为volume服务挂了,执行HA的服务切换。基于此,需要确保volume的所有调用都是非阻塞的接口,即是(green)绿色安全接口,如果是阻塞性的接口,需要与tpool库一起使用。

cinder-volume启动流程

其main函数如下:

@@ file: cinder/cmd/volume.py

def main():
    objects.register_all()    # import cinder/objects目录下的所有模块
    gmr_opts.set_defaults(CONF)    # oslo_reports模块,用于生成错误报告,如内存泄漏等
    CONF(sys.argv[1:], project='cinder',
         version=version.version_string())
    logging.setup(CONF, "cinder")
    python_logging.captureWarnings(True)
    priv_context.init(root_helper=shlex.split(utils.get_root_helper()))    # oslo_privsep,service的执行权限设置
    utils.monkey_patch()    # monkey-patch,替换库比如socket、thread等,不改变import的行为,改变的是操作的指向函数
    gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
    global LOG
    LOG = logging.getLogger(__name__)

    ...
    # 基于系统类型启动服务
    if os.name == 'nt':
        # We cannot use oslo.service to spawn multiple services on Windows.
        # It relies on forking, which is not available on Windows.
        # Furthermore, service objects are unmarshallable objects that are
        # passed to subprocesses.
        _launch_services_win32()
    else:
        _launch_services_posix()

什么是monkey-patch? monkey-patch指的是在执行时动态替换模块,而且通常是在startup的时候做,一般用于改变函数行为但不影响调用方式,比如在测试用例打桩调用过程、使用gevent时替换某些标准库使函数变成非阻塞等等。
举一个简单的例子,有两个模块 A 和 B,它们功能相同,但是B使用了另一种实现方式,使之性能要远远优于A模块。但是某个项目大量使用了模块A,如果要完全使用B来替换A的话,需要花费大量的精力。这时,monkey-patch就排上用场了。此时,可以在服务初始化时执行 monkey-patch如下:

    def monkey_patch(m_source, m_decorator):
        a = __import__(m_source)
        b = __import__(m_decorator)
        a.func = b
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值