您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
分离+借助社区力量: OpenStack持续交付进阶
 
  来源;UnitedStack发布于 2016-6-14
   次浏览      
 

分离+借助社区力量:

OpenStack持续交付进阶

分离+借助社区力量:OpenStack持续交付进阶

此文由在UnitedStack运维团队负责人余兴超在3月21日OpenStack Meetup活动的部分演讲整理而成。在上一篇名为《OpenStack持续交付的六大挑战与四个统一》的文章中,余兴超讲述了OpenStack在实际服务运维工作中所遇到的具体挑战,以及统一运维的具体策略。而在统一的基础之上,我们还需要以整体的角度去观察整套OpenStack持续交付系统,对于系统的运维团队而言,还有很多细化的工作要做。

【欢迎大家关注UnitedStack官方微信,我们将会在第一时间与您分享UnitedStack的工程师们工作中的经验与心得。】

一个参数引发的故障

2014年,我曾写过一篇blog,题目为《一个purge参数引发的惨案——从线上hbase数据被删事故说起》。在写下这篇文字前,我的心情是如此的忐忑,虽然早就明白运维工作如履薄冰,但没有料到这么一个细小的疏漏竟会带来如此严重的灾难。

这个Puppet参数的“坑”我也遇到过,幸运的是当时是在开发环境中。这样的一个案例引发了我很多有关运维的思考。

这个故障本可以从多个层面上去避免:

1.部署逻辑的上线,需要经开发和测试环境的验证;

2.不应盲目使用第三方模块,使用前应充分阅读源码或者README文档;

3.上线流程做好权限分离,保证有合理的审批机制。

首先有一个观念需要矫正。有些人认为部署逻辑不属于开发范畴,往往编写后不经测试就直接上线。其实只要涉及到代码的变更,无论是业务逻辑还是部署逻辑,都需要通过开发环境和测试环境的验证。那么,到底应该如何避免类似故障的发生呢?

分离与解耦

分离是关键:合理的分离可以对复杂逻辑和环境进行解耦,可以设立明晰的安全边界,可以更好地细化工作。

1.环境的分离

环境涵盖了部署逻辑与业务逻辑的环境,它们分别被划分为dev、test、production三种环境;其中,生产环境又被进一步细分为pre_production(预发布)和production(正式)环境。

2.仓库的分离

仓库分离是源自于我们在软件包管理上所经历过的血和泪的教训:

首先,根据包的类型划分为3类仓库;

其次,每个仓库也需要根据环境划分为devel、test、products三个子仓库;

最后,每个集群拥有完全独立的软件仓库;

3.部署逻辑和数据分离

我们要对配置管理工作进行划分,目的是为了解耦,并降低维护成本。具体还说我们把配置管理工作划分为三类,具体如下:

部署逻辑管理: modules 软件和服务的配置管理代码集合;

部署数据管理: hieradata 涵盖了所有集群软件和服务的定制化数据;

节点角色管理: manifests 所有被管理的服务器的角色定义集合;

4.角色的分离

角色分离是为了实现OpenStack灵活的部署架构。因为我们前面已经提到,我们可以对OpenStack的部署架构进行随意的调整。目前,我们一共涵盖了49种元角色,可以根据需要进行自由组合。比方说,Controller = API + MySQL + MQ + MC;Comb = Compute + OSD + OVS。

5.权限分离

权限分离的目的是为了设立安全边界。

无论是部署逻辑、部署数据或变更脚本,都需要通过版本控制工具管理,其中部署数据项目只有少数员工拥有访问权限,因为其中包括了敏感的密码或者密钥信息;代码要进入仓库,必须通过项目负责人的人工审查,这与OpenStack社区的代码开发流程是相同的;要执行线上业务变更,根据变更的类型和级别,须通过相关负责人的审核;最后,我们为不同环境的集群提供统一入口,后端划分独立的配置管理服务器,每台服务器有不同的访问权限。

借助开源的力量

我们前面提到Openstack项目众多,即使我们做到了统一,做到了解耦,做到了隔离,这只能说我们把这个架子搭好了,还有那么多的模块需要投入精力去开发。而一个人的精力毕竟是有限的。我做了一个简单的统计,目前我们通过git submodule的方式管理了:85个puppet module、67698行的puppet代码、79868行ruby代码和19371行的yaml格式数据。那么关键点在于哪?是加班吗?

当然不是!我们需要借助开源的力量。Puppet-Openstack项目是OpenStack社区推出的一系列的puppet

modules,旨在提供OpensStack各服务的配置管理。(https://wiki.openstack.org/wiki/Puppet-openstack)

stackforge/puppet-openstacklib

stackforge/puppet-openstack-specs

stackforge/puppet-openstack_extras

这些是Puppet的公共库以及Blue Print Collection项目,在Havana Desigin Summit上,我们决定开始把一些公共的代码抽取出来,作为Puppet-Openstack基础模块的公共库,提高代码的复用率。

在这里我想强调,一个开源项目的成功与否,关键在于它的用户数和活跃度。那么我们就来看看Puppet项目的用户。Mirantis Fuel和RedHat Packstack是目前主流的OpenStack部署工具。其中,Mirantis Fuel 的部署逻辑使用了Puppet-Openstack 模块,当然Mirantis 进行了一些定制化的修改,主要在HA方面,同时它提供了灵活多变的部署方式。RedHat Packstack则直接使用了upstream的Puppet-Openstack模块。

这是在Juno Operator Puppet Session上做的一个统计,我们可以看到思科、欧洲原子能、Godaddy、甲骨文、时代华纳等公司都在使用这个项目。当然,通过这张表我惊奇地发现大家更喜欢用Ubuntu。

这张图来自Openstack社区的官方用户调查,关于部署工具占有率的最新数据统计。可以看到,在所有规模的Openstack集群部署调研中,Puppet的占有率排名第一。

UnitedStack如何参与社区?

参与社区的目的是什么,每个人都会有自己的答案。我从自己的角度来回答主要有三点:首先,能够更加深入地理解源代码;第二,能够掌握项目的发展动态;第三,能够有效提升项目的代码质量。

UnitedStack在社区做了不少的工作,就拿最近一个比较重要的变更来说,是关于配置管理的改进和变迁的。事实上,社区在如何改善配置文件的管理上,持续投入了大量的精力。我们在2014年提交的数个Patch让配置参数的管理变得更加灵活。

配置文件管理的终极目标是有效、灵活和低成本。在早期,配置文件的管理是“模板统治一切”的时代。要管理nova.conf中的libvirt_type选项,首先在nova模块的templates文件夹下的nova.conf.erb文件,使用ERB语法在里面添加以下一行代码:

然后,在nova模块init.pp中,使用file resource来管理nova.conf配置文件。

然而,通过模板来管理配置文件是非常复杂和繁琐的,以nova.conf为例,算上注释文件,代码超过1700多行。这个庞大的模板文件是非常难于维护的。

后来,社区中出现了拼接(Concat)的方法来取代模板,它把一个模板拆分为多个子模板进行管理,然后再进行拼接。OpenStack的配置文件是标准的INI格式,每个配置文件由多个section组成。例如,在swift的proxy-server.conf中有[default]、[pipeline:main]、[app:proxy-server]等。

concat模块将配置拆分成了子模板,然后使用concat::fragment define把这些Template拼接起来。使用方式和file

resource来渲染template类似,唯一的区别就是order参数,指明这片(fragment)配置在目标配置文件中的顺序,升序排列。

事实上,拼接方法的出现只是提高了代码的可维护性,并没有带来实质的变化。

使用模板进行配置文件管理的最主要缺点就是繁琐:每次添加一个新变量,都需要修改三个不同的代码文件。

在template文件里添加上这个新变量:

<%= @new_variable %>

在class文件中添加这个变量:

$new_vairable = ‘hello’

最后在hieradata文件中对其赋值:

xxx::new_vairable:: ‘hey’

对于一个成熟的项目来说,配置变更并不频繁,使用模板是理所当然的。但是对于快速迭代、频繁变更的Openstack项目来说,模板将成为一个梦魇。PTL曾经做了一个统计,在G版前的过半提交都是和配置选项有关的。

因此,在模板之后,社区使用Ruby扩展了一种自定义的资源类型,来管理配置选项。新方式的成本是,新增一个配置选项需要修改两个配置文件。以nova为例,社区开发了nova_config custom resource type。在管理libvirt_type = ‘kvm’选项时,无需在模板里定义,直接在class中定义:

nova_config { ‘default/libvirt_type': value => $libvirt_type;}

但是一个新的问题产生了: 新增一个配置选项 = 在两个配置文件中各添加一行代码。

懒是程序员的天性。有没有一种办法不需要事先定义,并且只需要声明一次就能添加一个配置参数的呢?比方说,某些plugin或者driver的配置选项缺失了,例如cinder的solidfire,neutron的ibm plugin等等;还有一定自定义参数。 例如,我们针对Neutron、Nova、Ceilometer、Keystone做了定制化修改,添加了大量的自定义选项。

驱使我这样去做的动力是UnitedStack活力十足的网络组同事。这些同事每天都会在协作平台上给我分上一堆非常有趣的任务,其中和配置相关的任务我大致分成了一下三类。

a. 在测试环境中,在abc配置文件中添加参数x

b. 把参数x的值修改为y

c. 删除参数x

被折腾了两个多月后,我终于厌倦这样烦躁的重复劳动了,开始思考人生。我曾经和iweb的Mathieu(社区的一位核心开发者)对此也进行过讨论和尝试,因为他也饱受相同的痛苦。

我们在2014年6月提出了一个关于灵活管理自定义参数的BP,它的代码其实很简洁,核心在于create_resouces函数所做的迭代,类似于编程语言中的for循环。Puppet 3.5之前还不支持这种语法的迭代(虽然有trick可以做到)。create_resources接受两个参数,第一个是resource name,第二个是带有多组键值的hash数据。

下面是一个调用的用例(不需要在Puppet代码中预先定义,直接调用即可):

nova::config class:用于管理自定义参数

nova::config的调用用例

   
次浏览       
 
相关文章

云计算的架构
对云计算服务模型
云计算核心技术剖析
了解云计算的漏洞
 
相关文档

云计算简介
云计算简介与云安全
下一代网络计算--云计算
软浅析云计算
 
相关课程

云计算原理与应用
云计算应用与开发
CMMI体系与实践
基于CMMI标准的软件质量保证
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件的思考
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS
更多...   
相关培训课程

云计算原理与应用
Windows Azure 云计算应用

摩托罗拉 云平台的构建与应用
通用公司GE Docker原理与实践
某研发中心 Openstack实践
知名电子公司 云平台架构与应用
某电力行业 基于云平台构建云服务
云计算与Windows Azure培训
北京 云计算原理与应用