原文链接
自从入了贵圈,每天需要强大的内心来维护混乱的线上,每天都是用浆糊一样的shell /python在糊墙补窟窿啊,感觉每天都是在和if else打交道啊,每次花牛鼻子劲写的脚本,下次来点新需求,能重用的部分居然少到不想再重用,很绝望啊,有木有?批量运行工具还是在lhck lhcp,每次一长串命令,各种转义各种烦躁啊,有木有?转义也就罢了,还时不时被信任关系之类的bulabula,爷是root?这是啥root啊!
![](http://noops.me/wp-content/uploads/2014/03/1.jpeg)
番二、 ansible vs puppet vs saltstack
你一定不会屈服的,实际上很多人已经揭竿而起投笔从戎写出各种IT Automation Management Tool/System(ITAMS),甚至有人还遍尝百草,把经验写成了书(佩服!),我们要搞一个进来也是大势所趋,你真的不想扩容扩到睡着了。
![](http://noops.me/wp-content/uploads/2014/03/2.png)
你也一定听过很多ITAMS,那么你看好哪一个呢?所谓萝卜青菜各有所爱,呐,我来放一下我的选择理由:
首先,没有一个工具是能满足大家所有需求的,所以开发是more or less的事了,在选择的时候,我们的标准是:
1. 可作为批量执行工具
2. 可支持playbook,模块化
3. 容易上手,开发扩展容易
4. 在权限控制方面能很好的与目前的登陆授权管理系统结合
5. 社区活跃,有问题能查到解决办法
就playbook和模块化来说,puppet,saltstack和ansible半斤八两,就不细比了。
puppet有产品线已经在用,优点是历史悠久,比较成熟,在可远程可本地,功能强劲,不过这厮批量执行功能没得,为了批量执行个命令写个配置文件,好像有点大刀砍蚊子腿的感觉了,而且有客户端在,和授权系统结合比较麻烦。
saltstack和ansible都是python流的,而且就功能上来讲,两者也极为相似,不同之处是salt stack是有客户端的,并且execution模块还用0MQ实现了pub-sub,命令和执行结果因此可以高效并行传输,不过成也萧何败也萧何,第一个sub阶段(将querystring下发到所有机器,然后收集机器响应的阶段)太依赖与客户端返回了,如果客户端未能及时返回或未响应的话,playbook执行阶段可能会直接漏掉这部分机器而没有任何提示,这对于运维来说是不可接受的,要改造这个就得推掉saltstack的现有架构…算了吧。
与前两者比起来,ansible在特性上似乎并不抢眼,配置管理方面(playbook)绝对比不过老大哥puppet,批量执行方面也只是多线程,不像saltstack那么高大上,不过ansible搜索热度高出saltstack三倍多,显然靠的不是吹牛,至少,ansible至少不会悄悄的丢机器,这给了我们一个定心丸,而且仅依赖ssh,与登录授权管理系统天然集成,简单即有效,没有比这更美妙的事情了。
So, 让我们来尝尝Ansible吧!
番三、Ansible的说明书
三番一话 ansible
ansible是一个python package,是个完全的unpack and play软件,对客户端唯一的要求是有ssh有python,并且装了python-simplejson包,部署上简单到发指。
安装完成后,ansible套装里会有几个可执行命令,我们重点讲两个
ansible 是一个批量执行工具,可以理解为一个已经插件化的lh工具。
一个最简单的运行实例如下:
![](http://noops.me/wp-content/uploads/2014/03/3.png)
ansible 从hosts.txt中读取机器列表,并匹配其中机器名符合正则xcache06的机器,在其上执行date命令
再看一个:
![](http://noops.me/wp-content/uploads/2014/03/4.png)
和上一个相比,有一些变化。
· 首先,这个例子中,机器列表是从系统配置里自动得到的;
· 然后还多了个-m,指明了我们是在调用yum模块,实际上第一个例子中,module也是有的,只不过是默认的shell,我们可以不写而已;
· 最后 -a参数也有些特别,需要理解这些参数不难,执行ansible-doc yum就可以获得帮助:
![](http://noops.me/wp-content/uploads/2014/03/5.png)
三番二话 host-pattern
在上面的示例中,大家可能注意到了第一个参数,这个参数被称为host-pattern,主要用来从全量机器/分组列表中筛选出符合要求的机器列表。
之所以单独放出来讲,是因为在ansible命令中,host-pattern参数算是比较需要耗费记忆力的地方,并且我们也做了一点修改,大体介绍下:
”plain-example” 机器名或组名等于plain-example的机器
”~regex-excmple” 机器名或组名正则匹配regex-excmple的机器
”~regex-array[1-3]” 机器名或组名正则匹配regex-array[1-3]的机器【与官方版本有差异,官方版本有bug,查看网络文档时请关注】
”~regex-array[2]” 机器名或组名正则匹配regex-array的机器list中的第3个【为啥是[2]?程序员从零开始数….依赖hosts脚本返回,不要使用!!】
”~regex-array[1:2]” 机器名或组名正则匹配regex-array的机器list中的第2个【为啥是第2个?左闭右开+程序员从0开始….依赖hosts脚本返回,不要使用!!】
”pdl.relation;pdl.bmw” 获取pdl.relation和pdl.bmw的并集,逻辑”或“
”pdl.relation;&pdl.bmw” 获取pdl.relation和pdl.bmw的交集,逻辑”与“
”pdl.relation;!pdl.bmw” 获取属于pdl.relation但不属于pdl.bmw的机器集合,逻辑”非”
逻辑”或与非“可以与普通或正则规则一起使用,比如:
![](http://noops.me/wp-content/uploads/2014/03/6.png)
但是,需要注意的是,ansible的“逻辑操作”并不遵守典型的逻辑运算法则,处理的过程是:按分号切分 — 所有“非”组成排除集 — 所有“与”组成交集, — 所有“或”组成最终结果
官方程序支持从脚本获取机器和分组信息,我们利用此特性与公司内的运维管理系统进行了集成,小米的机器用一组tag来维护,对于每一个tag,我们都在cache中建立了对应的组,查询时请按照上述规则组装即可
比如,tagstr pdl.bmw_sbs.fe_srv.nginx 可以写成pdl.bmw;&sbs.fe;&srv.nginx ,关于这个脚本的书写方法和小米机器管理系统的相关介绍,可以参见“
如何写出自己的host脚本”一文。
更多ansible相关命令,请查看ansible -h
三番三话 ansible-shell
每次敲ansible xxx ,敲得多了,是不是也有些烦躁了?来试试ansible-shell吧!这个shell来自github,我们对他做了一些修改完善,美化输出,增加了后台日志,机器数实时显示,step by等实用功能,所有更改目前已merge进主干,来看看吧:
![](http://noops.me/wp-content/uploads/2014/03/7.png)
支持cd 确定操作集,支持内置模块命令和参数补全,是不是方便多了?
CentOS 默认没有装pip,运行自然失败,装一个吧:
![](http://noops.me/wp-content/uploads/2014/03/8.png)
等等,权限?没问题,加参数!
![](http://noops.me/wp-content/uploads/2014/03/9.png)
下载失败这事吧。。,算了,下一个话题!
呐,能不能切换到其它账号?
![](http://noops.me/wp-content/uploads/2014/03/10.png)
这个没解决是不好意思给大家用的。
作为一名SRE,手中自有千钧之力,一回车reboot一票机器,岂不是成千古恨?加个-p参数吧,每次run之前都确认下,是不是安全感多了好多?
![](http://noops.me/wp-content/uploads/2014/03/11.png)
敢不看清楚就回车的,都是真勇士,大家在y前还是先确认下参数好一些。
有人就烦了,说你截图太多了,到现在我还没明白基础使用呢。先系统讲讲呗!
行!
ansible-shell内置的命令主要有四个:
cd : 切换到指定的组/表达式筛选的机器集合上list: 显示目前的机器集合,list groups 可以列出所有的组(对我们可能没啥用)serial:运行时的并发度,默认是20help: 顾名思义,他能生成简单的模块帮助信息,方便即时查询
![](http://noops.me/wp-content/uploads/2014/03/12.png)
![](http://noops.me/wp-content/uploads/2014/03/13.png)
不过上面大家显然看到了更多的命令,这些命令是怎么个用法呢,我打了一行参数进去,到底是谁去执行了 ?
是这样的:ansible-shell在启动时将所有的内置命令/ansible模块和参数列表等都加入自动补全中,在你敲完每个命令回车后,它会拿第一个参数判断你输入的是不是一个内置命令(cd/list/serial),是则执行;否则看他是不是一个ansible模块,是则运行ansible模块;否则,认为他是一个shell命令,举例来说,当你输入hostname -i的时候,你会发现他会报错,原因是有个ansible模块就叫hostname,如果你一定想运行shell的那个hostname,在前面加个!就可以了
![](http://noops.me/wp-content/uploads/2014/03/13.1.png)
那,我就想运行shell怎么办? 前面加个!就好
![](http://noops.me/wp-content/uploads/2014/03/13.2.png)
进可攻退可守啊,会用了没?
![](http://noops.me/wp-content/uploads/2014/03/14.png)
麻麻再也不用担心我的批量操作了
![](http://noops.me/wp-content/uploads/2014/03/15.jpeg)
收队!下面我们迅速带过剩下的部分吧!
三番末
ansible套件中的其他工具:
ansible-doc 模块文档查看器,很有用,使用ansible -l 显示所有module列表,使用 ansible-doc <module_x>来查看module_x的详细文档,这里不做太多介绍
ansible-playbook 传说中的配置管理工具,如果你用过puppet或者saltstack,这个可以不用介绍了,如果你没用过,也没关系,花费20分钟看下
官方的Video。 掌握一件事情最好的办法就是使用它,你可以下载
官方的example来学习
ansible-galaxy 和三星没关系,你可以把他理解成ansible的pip,可以从galaxy.ansible.com下载官方收录的playbooks
ansible-pull 支持直接从git下载playbook执行,需要遵循其规定的目录格式,用处不是特别大,可以不关注
ansible-vault 如果你的配置文件中含有敏感信息,你可能并不希望他能被人看到,vault可以帮你加密/解密这个配置文件,高级用法,请参照
http://blog.ansibleworks.com/2014/02/19/ansible-vault/
如果希望了解更多,请访问官方wiki主页和博客:
我想开发!
欢迎!
本人github上的地址为htps://github.com/iambocai,欢迎您共享和交流
为了方便大家快速了解代码结构,我以执行流程作为切入点给大家讲下代码结构。
ansible执行过程大体过程如下图,其中暖色调的代表已经模块化。
![](http://noops.me/wp-content/uploads/2014/03/16.png)
代码结构就是这个样子,对哪一块不满意,一起来改造吧!
![](http://noops.me/wp-content/uploads/2014/03/17.png)