深刻SaltStack

对系统工程师来讲,配置管理已经向前跃进了一大步. 系统配置的自动化不只可预测,可重复, 还具备可管理性. 配置管理工具一般使用版本控制化的配置模板来描述基础设施的目标状态。凭借版本控制化的配置,能够将环境回滚(或前滚)到前面(或后序)状态;环境配置文件的自动化管理也是持续性交付管道的必要特性。node

CFEngine, Puppet和Chef(按年龄降序)是开源领域流行的配置管理工具。 我是一个Puppet的长期用户, 与自定义的配置脚本相比,它在系统自动化的组织性和可靠性方面带来了巨大的提高。(我是在2009年做出这一次飞跃,与此相比, 之前的日子简直是混乱不堪…).python

虽然配置管理工具精于描述并达到想要的状态, 但并不擅长动态地查询或设置状态. 这一点在状态资源尚未被归入配置管理时特别明显。Llinux系统管理员的传统解决办法是ssh循环登录节点列表并执行一堆命令。这不只容易出错, 且每一次循环都要打开新的ssh会话,效率低下。想像一下要在1000台机器上顺序执行命令!更不用说网络安全,ssh密钥和命令执行权限的问题。这固然是一种可行的办法,但缺乏一种可管理的框架。mysql

这就是命令编排工具产生的缘由。这些工具旨在大量的节点上并行执行命令和实时操做。CFEngine, Puppet和Chef各自用不一样的方法来解决命令编排问题。Puppet使用MCollective做为其武器,并将其集成到商业版中。linux

近来,我开始探索使用SaltStack来解决配置管理和命令编排这两个问题。SaltStack开始于2011年,是一个相对较新的项目,但在系统管理员和DevOps工程师中拥有愈来愈多的粉丝。我将在本文中探讨Salt做为前途光明的替代者,并与Puppet做比较以探索其特性。nginx

安装

创世之初,尽是空白和无序,黑暗笼罩着整个系统……而后神安装了配置管理器,因而阳光普照!惟一的麻烦是,咱们还须要安装依赖……而后配置管理器自己还得被配置……而且有时事情会有那么一点丑陋。git

Salt在Ubuntu和CentOS上的安装过程异常简单,我相信在有安装指南的别的系统也同样 (Arch Linux, Debian, Fedora, RedHat, CentOS, FreeBSD, Gentoo, Windows, Solaris). YMMV. 典型安装过程隐藏了没必要要的细节配置,除非你须要修改他们。首先安装salt master,而后安装salt minions, 将minions指向master,安装完成。若是salt master的主机名是"salt",都不须要将minions指向master,直接就能够运行。github

然而, 若是你不是使用上面提到的发行版或操做系统, 你极可能须要卷起袖子本身手动安装一些依赖。包括Python (>= 2.6 < 3.0), ZeroMQ, pyzmq, PyCrypto, msgpack-python和YAML的Python绑定.web

另外一方面, Puppet在多数基础安装时只依赖Ruby和Facter, 依赖带来的麻烦显著减小. 然而,Puppet的依赖列表能够进一步增长,包括augeas-libs, dmidecode, hiera, libselinux-ruby, pciutils, ruby-augeas, ruby-irb, ruby-rdoc, rubygem-json, ruby-shadow, rubygems. 这取决于Puppet的版本和你想要使用的功能。redis

我喜欢Salt包安装的简单明了。For the cases mentioned it is trivial to set up and get going. 若是你想亲自安装和配置的繁过程, 跟着安装指南作便可。sql

If you are like me though and you prefer your provisioning and configuration all in one gift wrapped package, que Vagrant to the rescue and download this project by elasticdog on github.

配置管理

配置状态

配置管理对Puppet来讲是小菜一叠,对Salt又如何呢。让我(高兴的)惊讶的是,这件事简单到使人发指。和Puppet同样,在Salt中能够描述系统的目标状态。. Salt将其称之为一个state, 配置模块是state模块。Salt的State模块文件用YAML写成,以.sls结尾。它们从功能上等同于Puppet模块的manifest文件,后者用Puppet DSL写成,以.pp结尾。

Salt在master的配置文件中指定"file roots", 相似于Puppet的"module path", 但同时包含了模块根目录和环境类型。举例来讲,在Salt中咱们能够分别指定development和test环境配置文件路径. 注意base环境是必须存在的。

1
2
3
4
5
6
7
file_roots:
   base:
     /srv/salt/
   dev:
     /srv/salt/dev
   prod:
     /srv/salt/prod

base环境必须包含Salt的入口top文件(叫作top.sls).base定义了一个或多个环境,用正则来匹配节点,而后引用相应的Salt states. top文件与Puppet的nodes文件类似。(Puppet入口点是site文件,在Salt中不须要).

假设有一个Salt master和两个minions (由Elasticdog github提供),我想要在两个minions上安装mongodb。若是在默认的软件仓库中有mongodb包,只须要3步便可。

一、在top.sls中指定节点:

1
2
3
dev:
   'minion*.example.com' :
     - mongodb

二、在dev/mongodb.sls中描述状态:

1
2
3
mongodb:
   pkg:
     - installed

三、传递状态到salt minions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# salt 'minion*' state.highstate -v
Executing job with jid 20121218102842533621
-------------------------------------------
minion1.example.com:
----------
State: - pkg
Name: mongodb
Function: installed
Result: True
Comment: Package mongodb installed
Changes: libicu: { 'new' '3.6-5.16.1' 'old' '' }
mongodb: { 'new' '1.6.4-1.el5' 'old' '' }
boost: { 'new' '1.33.1-15.el5' 'old' '' }
js: { 'new' '1.70-8.el5' 'old' '' }
minion2.example.com:
----------
State: - pkg
Name: mongodb
Function: installed
Result: True
Comment: Package mongodb installed
Changes: libicu: { 'new' '3.6-5.16.1' 'old' '' }
mongodb: { 'new' '1.6.4-1.el5' 'old' '' }
boost: { 'new' '1.33.1-15.el5' 'old' '' }
js: { 'new' '1.70-8.el5' 'old' '' }

配置描述文件与Puppet很是类似。但格式差异很大。这是由于Puppet使用本身的ruby-like DSL, 而Salt使用YAML. 正是因为这点不一样,造就了Salt state配置文件在视觉上的简洁性。YAML对人类可读也容易被映射到数据结构, 很是适合作配置管理中的资源描述。这不是说Puppet DSL不清晰或不结构化- it is neither - 但很难赛过YAML. YAML能够快速写成,在个人经验看,比Puppet DSL要容易生成.

注意: 配置管理社区关于声明配置的最佳方式一直存在争论。部分人青睐于利用编程语言(好比说Ruby)的灵活性。Chef是其中的表明。Puppet处于中间地段。当使用现成的功能时,Puppet DSL很是强大。但要给配置开发者更大的能力,就必须使用内部的Ruby DSL。在波谱的另外一端,Salt的简单YAML状态描述很是结构化。然而,Salt也支持渲染诸如JSON, Mako, Wempy和Jinja来扩展其能力, 在未来还会支持XML,原生Python及其余。

内置的state模块

我知道Salt是比Puppet新(注:原文为“近”字,在转载时以为不妥、进行了修正)的项目, 我彻底能够预料到不会有太多可用的内置模块。我错了: Salt有大量的内置模块,包含Puppet中的大部分必要模块好比 cron, exec (Salt是cmd), file, group, host, mount, package (Salt中是pkg), service, ssh_authorized_key (Salt是ssh_auth)和user。

尽管如此, Puppet仍然具备部分优点。好比, 我很是喜欢Puppet的Augeas模块。Augeas把内容看成value树,容许你修改(而不是覆盖)一个已存在的配置文件。

虽然Salt有一个Augeas execution模块,但很不幸貌似没有Augeas的state模块。虽然这样,Salt也有一些本身特有的东西,好比针对git, hg和svn的内置state模块.

模板

Puppet具备开盒即用的模板系统。Puppet有file资源和template资源的概念,这些资源分布在模块目录结构的不一样路径下。在Salt中, files和templates在同一个位置。经过为template指令指定type来区分是template仍是普通文件资源, type能够是jinja, mako或wempy。好处是能够很容易为file资源增长逻辑。state文件可能看起来像下面这样:

1
2
3
4
5
6
7
/etc/myapp .conf:
   file .managed:
     source : salt: //files/myapp .conf
     - mode: 644
     - owner: root
     - group: root
     - template: jinja

注意最后一行, 指明被管理的文件是一个jinja模板。

配置文件可使用jinja的语法来增长逻辑。举例来讲, 假设你的应用程序配置文件中用到了主机名。再假设在Ubuntuh 只须要短主机名(hostname),在CentOS须要FQDN。这能够很容易地在模板文件myapp.conf中指定:

1
2
3
4
5
{%  if  grains[ 'os' ] ==  'Ubuntu'  %}
host: {{ grains[ 'host' ] }}
{%  elif  grains[ 'os' ] ==  'CentOS'  %}
host: {{ grains[ 'fqdn' ] }}
{% endif %}

在CentOS节点minion1上结果文件/etc/myapp.conf将包含如下内容:

1
host: minion1.example.com

变量

Salt中的全局变量不能在使用时定义。在对变量的支持方面Puppet更加直观和灵活。在Salt中, 全部的变量保存在单独的位置。这样作不够灵活,但优点是更有秩序。用Salt的话讲,变量叫作"pillars"。pillars的位置在salt master的配置文件中指定:

1
2
3
pillar_roots:
   base:
     /srv/salt/pillar

和state文件同样, 首先建立一个top文件,在其中能够引用相关的pillar模块。

1
2
3
base:
   '*' :
     - packages

这个top文件引用了名为packages.sls的state文件, 其中包含将要安装的软件包的版本号的变量,以下所示:

1
2
mongodb: mongodb-1.6.4-1
httpd: httpd-2.2.3-65

声明了两个pillar, mongodb和httpd, 而后能够在state文件中用以下方式引用:

1
2
pillar[ 'mongodb' ]
pillar[ 'httpd' ]

模拟执行(Dry run)

管理系统有点像驾驶飞机。若是不当心谨慎,将会是高风险的事情。假设我是一个双翼飞机的驾驶员,将作一个危险的aerial manoeuvre, 我多半会但愿可以先模拟飞行。除非我像Red Baron同样无所畏惧。不管如何,还好在执行Salt以前能够先作测试。你须要作的仅仅是将Test设置为True。

1
2
3
4
5
6
7
8
9
10
11
12
# salt 'minion1.example.com' state.highstate -v test=True
 
minion1.example.com:
----------
State: -  file
Name:  /etc/myapp .conf
Function: managed
Result: None
Comment: The following values are  set  to be changed:
newfile:  /etc/myapp .conf
 
Changes:

总结

在配置管理方面,Salt在Puppet面前仍是可以站稳脚跟的。Salt安装很是简单,属于简单主义的开发风格, 功能丰富。总的来讲,不须要过多的操做就能够完成事情。我发现的惟一问题是salt-master和minion之间的链接有时会无端断掉。搜索一番后,我发现其余人在Salt 0.10.5这个版本上也遇到了一样的问题。但愿这个问题在下一个版本中获得解决。

命令编排和远程执行

MCollective

MCollective是 Puppet的命令编排解决方案。由R.I.Pienaar在PuppetLabs那帮人引发重视以前独立开发完成。MCollective使用message broker (好比ActiveMQ)经过pub-sub总线来传递消息, 能够并行通讯,这比用ssh快得多。这是一能够理解特定消息并产生响应的框架。Puppet和MCollective如今能够在同一个框架下工做,同时提供完成配置管理和命令编排的功能。

先无论MCollective的优点,有两个负担可以打击你的激情。第一,MCollective只是和Puppet松散集成,至少对社区版原本讲是这样 。MCollective有单独的安装包,独立的配置文件。另外你还须要安装配置broker(好比ActiveMQ),来与MCollective一块儿工做. 虽然不难,但很繁琐。最后,你还不得不本身解决生产环境中通讯渠道的安全问题。不幸的是,这个就有点困难。

MCollective的第二个问题是相对来说缺乏一些自带的功能。有不少现成的插件能够下载安装(https://github.com/puppetlabs/mcollective-plugins), 用Ruby写本身的插件也不是很复杂-不过想要当即使用的话,障碍比想像得要大。Nevertheless, given that the framework is solid and extensible, dabbling in Ruby plugins soon makes the real power of MCollective apparent.

Salt

另外一方面,Salt生来就有命令编排的功能。最早设想的就是远程执行技术,而后才添加的配置管理管理。Salt使用轻量的ZeroMQ来处理消息。结果就是不须要单独的安装。装好Salt后,配置管理和命令编排就能够工做了。绝不惊奇,Salt state模块和execution模块的命令在语法上相似,因此很直观。再看Puppet和MCollective组合,各自使用不一样的工具和语法结构,须要额外的时间去学习。

Salt远程执行功能的可用性使人印象深入。当前的在线文档列出了超过100个不一样的内置excution模块-包括augeas!(因此augeas成为state模块只是时间上的问题).

举个简单的例子,看看通用的"cmd.run"模块和指令。这在你知道想要执行的命令却又没有现成的模块可用时很是有用,- 或者你仅仅想要快速地远程执行命令。假设我想在全部节点上检查运行的内核版本号:

1
2
3
4
[root@salt salt] # salt '*' cmd.run "uname -r"
minion1.example.com: 2.6.18-274.18.1.el5
minion2.example.com: 2.6.18-274.18.1.el5
salt.example.com: 2.6.18-274.18.1.el5

或者我想看看磁盘使用状况:

1
salt  '*'  cmd.run  "df -h"

顺便说一下, Salt有一个模块用来查看磁盘用量以及其余磁盘相关的查询:

1
salt  '*'  disk.usage

使用内置模块而不用cmd.run发送shell命令的好处是,模块一般返回固定结构的数据。可以以编程的方式用在自动化处理上。

有不少现成的execution模块来知足通用的管理任务,好比apt, at, cp, cron, disk, extfs, file, hosts, iptables, mount, network, pam, parted, pkg, ps, selinux, shadow, ssh, and test. 也有大量的模块用于指定的软件包和应用程序,好比apache, cassandra, djangomod, git, mongodb, mysql, nginx, nova, postgres, solr, sqlite3, 和tomcat.

甚至支持执行Puppet程序。

总结

毫无疑问,Salt远程执行比Puppet加MCollective更优雅,附带可用的功能更多。支持动态查询和大规模的服务编排。要查看完整的功能,请参考salt execution模块的文档。

附加功能

Dashboard

uppet使用Puppet dashboard. Salt目前没有图形化的界面。我知道,咱们都大爱命令行。不过,有时看到满屏幕的绿色或是点点按钮也是很惬意的。 认真的讲,dashboard是得到你所管理的节点网络state概览的好工具。Salt的路线图中没有图形界面,但愿最终会出现。

Returners

Returners是minion返回数据到达后被调用的模块。不将返回数据传递给salt master,而是调用Returner模块来将数据发给其余服务,一般是数据库。Salt目前支持的returner,能够链接cassandra, mongo, redis和mysql. 也能够很容易的用Python脚本为其余服务写一个returner。

Salt Syndic

Salt文档将Salt Syndic描述为"一个能够构建Salt命令拓扑的强大工具“。实际意义上,Salt Syndic可让一个运行Syndic服务的Salt master链接到更高层的master。

假设你有多个不一样的Salt环境,每一个环境都有一个master。这些环境多是特的云或是有防火墙的网络。假设你想同时控制这几个环境中的minions。你能够在想要控制的master主机上安装Salt Syndic。Salt Syndic建立了传输接口,在最顶层的master看来,就像是控制了不少的minion,但配置状态其实是传递给了多个master。能够将其想像为军队的命令传递系统。

集成测试

有两个采用现有测试框架的项目给Puppet增长测试功能,名字是cucumber-puppet (使用 Cucumber框架)和rspec-puppet (使用RSpec).

Salt采起的作法是经过一系列的集成类提供对集成测试的支持,roadmap中提到将来会使用Unittest2和pytest作单元测试。

自动化集成测试是持续性交付管道被忽视的领域,能有一些内建的支持是很是好的。这也是之后的博文中将探讨的有趣领域

若是想深刻体验LINUX系统的新手,也能够先下载一个方德Linux软件中心试用一下。

免费下载地址:http://www.nfs-cloud.cn:81/appCenter/open/softcente

相关文章
相关标签/搜索