美文网首页
Openstack基础组件概览(1)

Openstack基础组件概览(1)

作者: VienFu | 来源:发表于2019-10-24 17:27 被阅读0次

    熟悉Openstack的童鞋都清楚:Openstack下的大多数项目比如Nova、Keystone、Cinder、Glance、Neutron、Ceilometer等这些项目在开发时都会用到一个叫做oslo的基础公共库,如下就一些最常见的Openstack基础共用库简单展开聊聊他们各自的用途和基本用法。

    1. oslo.config

    该组件功能为Openstack解析配置文件,使用起来也比较容易,如下举一个简单的例子:

    from oslo_config import cfg
    
    CONF = cfg.CONF
    
    options = [
      cfg.BoolOpt('source_is_ipv6',
                    default=False,
                    help='Source is ipv6'),
      cfg.StrOpt('cert',
                   default='self.pem',
                   help='SSL certificate file'),
    ]
    
    CONF.register_opts(options)  # 默认放在default组下面,如果是其他组的配置,则可以使用CONF.register_opts(options, group=group)
    
    # 然后就可以直接操作对应的配置参数,比如:
    def test_func():
      print(CONF.cert)
    

    Openstack配置文件使用INI文件格式,具体配置都会以键值对的形式呈现,并且可以分配到不同的group(默认是DEFAULT)下面,另外#开始的行是注释说明,针对上面的配置具体到文件里应该是如下样式:

    [DEFAULT]
    # Source is ipv6
    # (boolean value)
    source_is_ipv6 = True
    
    # SSL certificate file
    # (string value)
    # cert = self.pem
    

    对于设置了默认值的参数项,如果配置文件中没有配置则实际取默认值;参数项支持多种参数类型比如布尔型(BoolOpt)、字符串型(StrOpt)、浮点型(FloatOpt)、字典(DictOpt)、列表(ListOpt)、整型(IntOpt)、IP类型(IPOpt)、多值类型(MultiStrOpt)等;实际配置中可以对前面已经定义的参数项进行引用,具体方式跟bash引用变量类似,在key前加上$即可,而如果$有实际意义则用$$;另外如果实际的参数值包含空格,则需要把整个字符串值放在引号里。

    使用

    实际使用中,Openstack很多服务都需要基于配置文件来启动,只需在服务启动的命令后加上--config-file <config_path>即可。

    oslo-config-generator

    oslo-config-generator能够生成一个完整的配置文件的样本(默认格式是INI),实际使用时只需根据实际场景对这个配置文件更新即可,但在使用这个工具生成配置之前,需要定义配置的发现入口:

    # 1. 设置setup.cfg
    [entry_points]
    oslo.config.opts = 
      oslo.messaging = oslo.messaging.opts:list_opts
      umha.conf = umha.opts.list_opts
    
    # 2. 增加opts.py文件定义list_opts函数,比如增加umha/opts.py:
    def list_opts():
      return [
            ('DEFAULT', utils.cfg.common_opts),
            ('time', utils.cfg.time_opts),
            ('db', [utils.cfg.db_opt]),
            ('auth', utils.cfg.auth_opts),
            ('email', utils.cfg.email_opts),
            ('valve', utils.cfg.valve_opts),
        ]
    

    如此就可以通过命令:
    oslo-config-generator --namespace umha.conf --namespace oslo.messaging > /etc/umha/umha.conf
    生成所需的配置文件样本了。

    2. oslo.cache

    该组件为Openstack提供缓存功能,把一些常用的数据比如keystone token信息等放进缓存,降低数据库的压力提高查询效率。oslo.cache是通过dogpile.cache库为Openstack各个服务组件提供一个适用多种缓存后端的缓存接口,目前已经实现多种缓存后端的缓存设计比如Memcache、etcd、MongoDB等,其中Memcache最常用,因此本文仅就Nova项目(其他项目使用都类似)中的Memcache使用做展开。

    Nova项目跟缓存相关的最核心的文件:./nova/cache_utils.py
    这个文件主要实现了两大块:

    • 类CacheClient:定义缓存的各种操作比如查增删等;
    • 函数get_client():用来获取缓存client,其实质是类CacheClient的实例化,而实现的方式通常是基于oslo.config的配置来创建和配置region(dogpile.cache.region.CacheRegion类实例),之后基于这个region来生成一个CacheClient实例;

    类CacheClient实现代码:

    class CacheClient(object):
        def __init__(self, region):
            self.region = region
    
        def get(self, key):
            value = self.region.get(key)
            if value == cache.NO_VALUE:
                return None
            return value
    
        def get_or_create(self, key, creator):
            return self.region.get_or_create(key, creator)
    
        def set(self, key, value):
            return self.region.set(key, value)
    
        def add(self, key, value):
            return self.region.get_or_create(key, lambda: value)
    
        def delete(self, key):
            return self.region.delete(key)
    
        def get_multi(self, keys):
            values = self.region.get_multi(keys)
            return [None if value is cache.NO_VALUE else value for value in
                    values]
    
        def delete_multi(self, keys):
            return self.region.delete_multi(keys)
    

    函数get_client()代码实现:

    def get_client(expiration_time=0):
        if CONF.memcached_servers:
            return CacheClient(
                     _get_custom_cache_region(expiration_time=expiration_time,
                                             backend='dogpile.cache.memcached',
                                             url=CONF.memcached_servers))
        elif CONF.cache.enabled:
            return CacheClient(
                     _get_default_cache_region(expiration_time=expiration_time))
        
        return CacheClient(
                 _get_custom_cache_region(expiration_time=expiration_time,
                                         backend='oslo_cache.dict'))
    

    其实上面所述的CacheClient中缓存各种操作的实现都是基于region(具体可参见dogpile.cache.region.pydogpile.cache.backends.memcached.py)来的,至于实现细节可阅读dogpile库的源码
    来进一步深入。

    3. oslo.messaging

    此处不再展开,请参考我的另一篇博文Openstack基础组件之oslo.messaging即可。

    4. oslo.service

    该组件提供了一个框架,用于为Openstack应用定义长时间运行的服务,库的名称是oslo_service,在oslo.service的实现中,依赖于oslo_service.service的两个最核心的类:Service类和Launcher类。

    • Service类:基于抽象基类oslo_service.service.ServiceBase,它定义了一个服务对象以及管理整个服务生命周期的方法,包括reset、start、stop、wait,另外,在对服务对象实例化时可以传进一个threads的参数创建一个包含threads个线程的线程组ThreadGroup对象,用来管理服务中的所有线程。还有一个叫做Services的类,用来管理一组服务。
    • Launcher类:主要用来启动一个或多个服务并等待其完成。其定义了launcher_service(service, workers)、stop()、wait()、restart()方法管理Launcher对象中所有服务的生命周期,并且基于workers的数量又有两种实现机制:ServiceLauncher类和ProcessLauncher类。

    实际使用场景下,我们在创建Service时会对oslo_service.service.Service进一步封装,比如下面这样:

    from oslo_sevice import service
    from oslo_config import cfg
    
    CONF = cfg.CONF
    class TestService(service.Service):
      def __init__(self, *args, **kwargs):
        pass
    
      def start(self):
        # do something
        pass
    
      def stop(self):
        pass
    
      def reset(self):
        pass
    
    if __name__ == '__main__':
      service.launch(CONF, TestService()).wait()
    

    相关文章

      网友评论

          本文标题:Openstack基础组件概览(1)

          本文链接:https://www.haomeiwen.com/subject/nlntvctx.html