指挥千军万马

我心目中优秀的程序员就是早上十点半来到公司,刷刷微博,看看新闻。然后花三四个小时写代码,在大约六点钟回家打游戏机的人。很可惜事与愿违,在我每天工作了十多个小时以后,我认识到因为自己多么的不牛逼,导致出现这样可悲的结果。

后来由于一些更奇怪的原因,我实际上成为了一个做着SA工作号称程序员,大家却以为是网管(没错,就是网吧那种)的人。面对每天数十次的线上部署操作和越来越多的机器,我开始庆幸,我其实是个python程序员。

153639u9xymr8uhcz9guce

 

同时管理大规模的服务器,会让人有一种指挥千军万马的快感。隐藏在一排排坚固铁柜中,看似冰冷、复杂、有狰狞的黑色界面,吞吐奇怪字符和热风的服务器。在管理员面前,像士兵一样驯服。指挥它们的管理员,胸中像藏有百万雄兵的大将,从容不迫。大将手中的虎符,是自动化的服务器管理系统。

所谓自动化管理服务器早就不是什么新鲜的事了。批量的操作只是自动管理的入门而已。面对一堆新上线的服务器,想要批量的操作它们,该怎么办呢。

fabric 可以批量操作服务器,它使用SSH登陆服务器进行远程的操作。比如,我们现在需要对某些机器添加一个账户 tom 。我们新建一个 user.py

from fabric.api import sudo

def add():
    sudo('useradd -m tom')

然后通过fab命令执行

fab -f user.py -u root -H 192.168.1.1,192.168.1.2 add

当然了,这只是fabric最简单的用法,它的功能也不止于此。如果你有很多的机器,在 env.hosts 指定这些机器,fabric就可以操纵很多很多的机器。虽然fabric还有很多其他功能,但是它的作用仅限于此:是一个批量执行任务的工具。他解决了操作大量机器的问题,但离管理好大量服务器的目标还很远。

我喜欢用管理大量服务器,而不是运维来形容我的工作。同样的,我的目标是大量的管理服务器,而不是运维很多的机器。管理大量的服务器,而不仅仅是操作它们,需要让这些服务器的状态是可以描述的,并且它们之间的关系和依赖也是可以描述的。我们对任意的节点进行操作的时候,与它一切相关的依赖和关系,也要能够处在或者到达我们预期状态。这有点像测试驱动开发所做的事情:100%测试用例覆盖,保证程序的任何重构都不改变系统的功能。

所以,无论是fabric,expect还是其他的远程批量执行工具,并不能实现大量管理服务器这个目标。

配置管理工具puppet现在越来越流行,但是我并不喜欢它。我选择了基于python的配置管理工具salt 。 一个公司如果对于python语言有大量的投资、雇佣了很多的python程序员,以python构建服务器管理系统,salt是一个更好的选择,而不是puppet。并不是因为语言的宗教战争,而是有更现实的原因:通过我们现有的技术力量,很容易就能通过对salt的扩展,大大增强我们对服务器的管理能力。因为开发自定义的salt模块是如此的简单,就像在写配置文件一样。

salt可以配置管理,描述服务器的状态,也可以批量的操作服务器,甚至可以用来监控服务器。最令人喜欢的是,它十分的简单。基本上,一个不是太菜的linux用户,一甚至几分钟就能正确配置完成,一两天就能熟练的使用salt对服务器进行管理。

它有十分简单的安装方法

wget -O - http://bootstrap.saltstack.org | sudo sh

这个脚本在下面的系统中经过测试:
Ubuntu 10.x/11.x/12.x
Debian 6.x
CentOS 6.3
Fedora
Arch
FreeBSD 9.0

我们可以通过fabric批量安装它

from fabric.api import sudo

def install_salt():
    sudo('wget -O - http://bootstrap.saltstack.org | sudo sh')

在生产环境中,我还是建议通过系统的包管理工具去安装它:比如 apt-get 或者 yum 。

salt的配置文件是YAML,实际上是经过jinja模板渲染的YAML。相比于puppet的DSL,学习成本极低,灵活程度高出甚多。

salt中配置管理是通过称为state的模块完成的,下面是一个关于用户的state

fred:
  user.present
:
    - fullname
: Fred Jones
    - shell
: /bin/zsh
    - home
: /home/fred
    - uid
: 4000
    - gid
: 4000

salt的批量执行功能也非常棒。我们批量给机器添加用户

salt '*' user.add name <uid> <gid> <groups> <home> <shell>

在salt长长的内置模块中,发现了对openstack模块的支持,nova、glance、keystone模块都有提供,将来和openstack的结合是一个看点。

salt也有令人不爽的地方,salt的master在和各个客户端通讯的时候使用的是私有的协议。在这一点上我比较认同puppet基于http的连接,这让puppet很容易通过常规的http集群的方式进行扩容。另外salt现在还处于非常年轻的状态,当前的稳定版本是0.1.3。对于配置文件的校验,和出错的处理上比较原始。由于我们当前部署的规模不算太大,尚不知在超大规模下salt性能如何。

批量执行和配置管理只是大规模服务器管理的必要条件。面对数十上百,或更大数量级的产品线,每个产品线又包含若干种组件,它们之间的关系混乱又复杂,看起来令人生厌。解决这样的问题,才会有指挥千军万马的快感吧。