Perl集群配置管理系统Rex简明手册
Rex是Perl编写的基于SSH链接的集群配置管理系统,语法上类似PuppetDSL。官网中文版见http://rex.perl-china.com。本文仅为本人在部门Wiki上编写的简介性文档。
常用命令参数
rex命令参数很多,不过因为我们的环境是krb认证的,所以有些参数只能写在Rexfile里。所以一般固定在存放了Rexfile的/etc/puppet/webui下执行命令,很多配置就自动加载了。那么还需要用到的命令参数基本就只有下面几个:
-Tv:查看当前Rexfile里定义了哪些Task任务,以及服务器组。
-H:指定Task将在哪些Host上执行。这里比较方便的地方是支持10.5.16.[95..110]这样的写法。
-G:指定Task将在哪些Group上执行。Group的定义方式很多,Rex默认支持的有直接在Rexfile里通过group指令指定,通过ini配置文件设定等等。目前我是实现了一个groups_db指令,来从我们的sqlite里获取。groups_db('cdnbj::nginx')就会自动生成一个名叫‘cdnbj::nginx'的服务器组,包括cdnbj里所有部署了nginx的服务器。
-e:指定一个临时任务。通常是'sayrun“ipconfig”‘这样的简单命令形式。如果需要复杂逻辑,还是在Rexfile里书写Task。
-q:指定运行日志级别,有-q和-qq。
-d:指定运行日志级别,有-d和-dd。
Rexfile介绍
参数设置部分:
setconnection=>"OpenSSH"; user"root"; krb5_auth; parallelism10;
这四行指定采用kerberos认证,并发10个进程执行ssh命令。
desc"installpuppetagent"; task"puppet_install",sub{ } before"puppet_install",sub{ } after"puppet_install",sub{ }
这几行就是Rexfile的任务定义主体格式。task指令定义任务,任务会在具体的-H或者-G服务器上执行。其他都是可选项,desc内容会在-Tv的时候显示;before和after定义的任务会在执行对应task之前或之后,在'''rex命令执行处,即10.4.1.21本地'''执行。
常用指令介绍
run
运行命令。如果有回调函数,那么会把stdout和stderr传给回调函数;如果没有,直接把stdout作为返回值。
比如:
sayrun"uptime"; run"nginx-v",sub{my($out,$err)=@_;say$err};
file
分发文件。语法类似Puppet的file。支持source、template、ensure、on_change等操作。注意:rex是顺序执行Rexfile的,所以不用设置Puppet的require指令。
比如:
file"/etc/yum.repos.d/xiaonei-private.repo", source=>"repos/xiaonei-private.repo"; file"/etc/nginx/nginx.conf", content=>template("templates/etc/nginx/nginx.conf.tpl"), owner =>"nginx", group =>"nginx", mode =>644, ensure=>'file', on_change=>sub{servicenginx=>"restart";}; file"/etc/nginx/conf.d", ensure=>"directory",
pkg
安装软件包,在早期版本命令写作installpackage=>"nginx",最近改成pkg了,更像Puppet语法了。
也支持传递数组作为pkg内容。另外,rex还提供了一个update_package_db指令,用于执行yumcleanall或者apt-getupdate操作。这点是Puppet欠缺的。
比如:
update_package_db(); my$packages=caseoperating_system, Debian=>["apache2","libphp5-apache2"], CentOS=>["httpd","php5"], pkg$packages, ensure=>"present";
ensure也支持present、absent、latest等几种含义。同Puppet。
account
用户管理原先用create_user和create_group指令,最近把create_user更新为account指令。
比如:
create_group'puppet'; account"puppet", ensure =>"present", uid =>509, home =>'/home/puppet', comment =>'PuppetAccount', expire =>'2015-05-30', groups =>['puppet'], password=>'puppet', system =>1, no_create_home=>TRUE, ssh_key =>"ssh-rsaAAAAB3NzaC1yc2EAAAADAQABAAABAQChUw...";
tail
用来同时观测多台主机的日志的最新追加情况。应该是比较有用的一个小功能。代码如下:
tail"/var/log/syslog",sub{ my($data)=@_; my$server=Rex->get_current_connection()->{'server'}; print"$server>>$data\n"; };
远程主机详情相关变量
Puppet有专门的Facts变量来判定远程主机的详情。Rex因为走SSH连接,不会在远程主机上跑一个agent来收集这些信息,所以还是通过远程执行命令的方式来提供相关内容。目前常用的几个函数(也可以认为是变量)有:
is_redhat
这个用来判断操作系统是否是RedHat系列。之前因为有一批Debian的机器,所以Rexfile里一直有这么个操作逻辑:
if(is_debian){ }elsif(is_redhat){ }else{ }
operating_system_version
这个用来判断具体的操作系统版本号。比如CentOS5跟CentOS6应该应用的操作就不一样,甚至CentOS6.5和CentOS6.2也有可能不一致。
比如Rexfile里的1w10任务:
if(is_redhatandoperating_system_version>=64) }
route
rex可以收集的信息比puppet要多很多,比如网络相关、sysctl相关等等。Rexfile里的1w10任务用到了route信息来获取默认网关和网卡接口。
my($default_route)=grep{ $_->{"flags"}=~m/UG/&&( $_->{"destination"}eq"0.0.0.0"|| $_->{"destination"}eq"default") }route; if($default_route){ my$default_gw=$default_route->{"gateway"}; my$default_if=$default_route->{"iface"}; run"iproutechangedefaultvia${default_gw}dev${default_if}initcwnd10initrwnd10"; };
connection
在多台主机执行任务的时候,大多希望在输出的时候看到某条结果是哪个主机返回的。前面tail任务就用到了,不过写起来非常复杂的样子。其实rex提供给更简洁一点的写法。就是connection->server。
task'tellmewhoyouare',sub{ sayconnection->server; }
当前连接的服务器的整个信息,也可以通过get_system_information指令来获取,这两个指令其实是等同的。不过根据字面意思一般用来不同语境下。
这些信息如果要完整查看,可以通过dump_system_information指令来查看。这个命令跟printDumperget_system_information()不一样的是,会把每个键作为单独变量。而这些变量就是可以直接用于rex的template里的内嵌变量。比如:
listen<%=$eth0_ip%>:80; visible_hostname<%=$hostname%>
不在dump_system_information清单里的变量,也想在template里使用的,就必须显式传递。这点和Puppet不一致,puppet在template里可以通过scope.lookupvar()指令获取任意pp类里设定的变量,这一点完全无视词法作用域的存在==!
比如:
file'/etc/elasticsearch/elasticsearch.yml', content=>template('files/es.yml.tmpl',conf=>{ clustername=>'logstash' });
对应的es.yml.tmpl里写作:
clustername:<%=$conf->{'clustername'}%>
这样才行。