通过Rex管理所有的web服务器节点

2016-07-12 10:19:50来源:oschina作者:black_mud人点击

为什么要用到Rex,因为目前线上业务量越来越多,服务器数量也越来越多,维护的项目也越来越多,无论是安装软件,修改配置,优化,管理,升级等操作通过写一堆脚本来集中操作已经很难达到我的要求。这时候就需要将所有不同业务类型不同项目所对应的集群环境都统一起来,集中进行管理。


常用的集中管理软件有puppetsaltansible Rex等。在进行综合比对后,我选择了Rex。原因是Rex是基于SSH来进行集成管理的,不需要再各个服务节点安装客户端,简洁,轻量,是我选择Rex的一部分原因,当然其它的集成管理软件没有怎么研究过,不过Rex已经能满足我的所有要求了,模块Rex既可以做为一个库来调用,也可以作为一个集中管理平台来使用,通过rex命令来进行一切操作。我对perl非常熟练,对于一些特殊的应用场景我会结合把Rex当做一个普通的模块,通过在自己的脚本中调用Rex模块提供的一些方法来进行远程操作,灵活性,可用性都比较强。这也是我选择Rex的一个主要原因。


介绍一下我线上的环境:


我要管理7个项目,每个项目都有一个集群环境(平均都是4个节点左右),每个节点上的web服务都是用tomcat7.0+jdk1.7的环境;session共享使用的是两台memcache组成的集群环境,数据库采用的是二台高性能的物理机+一个iscsi的盘柜组成的RAC环境。四台代理服务器(都是采用的nginx),图片存储采用的drbd+heartbeat+nfs的形式,因为是商城网站图片量现在越来越多,访问量越来越多,nfs图片服务器很容易因为I/O问题变的非常不稳定,目前测试用Moosefs和fastDFS,准备将图片存储迁移到分布式存储。


我接手之后就是这么个环境,当然整体的网络结构设计的很糟糕,很差劲。无论是从安全性,稳定性,高可用性方面去看都存在缺陷。但是上头不愿意让我对架构进行改动,只好对现有的环境进行集中管理。(哎,做运维很难!!)

废话不多说,因为实验环境有限,我只能为7个项目准备7个节点,也就是一个项目对应的集群就是一个节点也就是它自己!(公司穷,没办法,内部测试用两台pc机加一个组装的盘柜搞了一个集群虚拟化,为了节约资源只能这样玩)


1,因为是内部测试,为了方便,每个节点对应的域名都在hosts文件中解析;


[root@localhost~]#cat/etc/hosts
127.0.0.1mail.weike.commxlocalhostlocalhost.localdomainlocalhost4localhost4.localdomain4
::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6
#192.168.0.128test1
#192.168.0.129test2
192.168.0.164shopwap
192.168.0.193gerenwap
192.168.0.196appwap
192.168.0.224geren
192.168.0.226chaoshi
192.168.0.228quanguo
192.168.0.215boss

则七个节点对应的域名为 shopwap gerenwap appwap geren chaoshi quanguo boss(实际上线上的项目远比这多,有的是单个tomcat节点跑多个实例)


2,安装Rex,在安装之前需要确定你已经安装了perl环境(如果没有就通过yum install perl cpan进行安装)


[root@localhostsrc]#perl-v
Thisisperl5,version16,subversion3(v5.16.3)builtforx86_64-linux-thread-multi
(with28registeredpatches,seeperl-Vformoredetail)
Copyright1987-2012,LarryWall

3,对于所有的perl模块安装我们都用cpanm命令来安装,到cpan或者metacpan 上去找一个叫App-cpanminus 的源码包,然后下载下来进行解压编译安装


[root@StorageServer1src]#ls-l|grep-iapp
-rw-r--r--1rootroot316814Sep1609:52App-cpanminus-1.7039.tar.gz
[root@StorageServer1src]#tarzxvfApp-cpanminus-1.7039.tar.gz
App-cpanminus-1.7039/
App-cpanminus-1.7039/bin/
App-cpanminus-1.7039/Changes
App-cpanminus-1.7039/cpanfile
App-cpanminus-1.7039/lib/
App-cpanminus-1.7039/LICENSE
App-cpanminus-1.7039/Makefile.PL
App-cpanminus-1.7039/MANIFEST
App-cpanminus-1.7039/MANIFEST.SKIP
App-cpanminus-1.7039/META.json
App-cpanminus-1.7039/META.yml
App-cpanminus-1.7039/README
App-cpanminus-1.7039/t/
App-cpanminus-1.7039/t/happy_cpantesters.t
App-cpanminus-1.7039/lib/App/
App-cpanminus-1.7039/lib/App/cpanminus/
App-cpanminus-1.7039/lib/App/cpanminus.pm
App-cpanminus-1.7039/lib/App/cpanminus/fatscript.pm
App-cpanminus-1.7039/bin/cpanm
[root@StorageServer1src]#cdApp-cpanminus-1.7039
[root@StorageServer1App-cpanminus-1.7039]#perlMakefile.PL&&make&&makeinstall
Checkingifyourkitiscomplete...
Looksgood
Warning:prerequisiteTest::More0notfound.
WritingMakefileforApp::cpanminus
cplib/App/cpanminus/fatscript.pmblib/lib/App/cpanminus/fatscript.pm
cplib/App/cpanminus.pmblib/lib/App/cpanminus.pm
cpbin/cpanmblib/script/cpanm
/usr/bin/perl-MExtUtils::MY-e'MY->fixin(shift)'--blib/script/cpanm
Manifyingblib/man1/cpanm.1
Manifyingblib/man3/App::cpanminus::fatscript.3pm
Manifyingblib/man3/App::cpanminus.3pm
Installing/usr/local/share/perl5/App/cpanminus.pm
Installing/usr/local/share/perl5/App/cpanminus/fatscript.pm
Installing/usr/local/share/man/man1/cpanm.1
Installing/usr/local/share/man/man3/App::cpanminus::fatscript.3pm
Installing/usr/local/share/man/man3/App::cpanminus.3pm
Installing/usr/local/bin/cpanm
Appendinginstallationinfoto/usr/lib64/perl5/perllocal.pod
[root@StorageServer1App-cpanminus-1.7039]#

3,安装完成现在可以使用cpanm来安装Rex了(因为源地址默认都是国外的一些站点,有可能会被屏蔽,所以用163提供的源地址),设置下环境变量:


[root@StorageServer1~]#cat.bashrc
#.bashrc
#Userspecificaliasesandfunctions
aliasvi='vim'
aliasrm='rm-i'
aliascp='cp-i'
aliasmv='mv-i'
aliascpanm='cpanm--mirrorhttp://mirrors.163.com/cpan--mirror-only'
#Sourceglobaldefinitions
if[-f/etc/bashrc];then
./etc/bashrc
fi
[root@StorageServer1~]#

4安装rex


root@StorageServer1~]#cpanmRex
-->WorkingonRex
Fetchinghttp://www.cpan.org/authors/id/F/FE/FERKI/Rex-1.3.3.tar.gz...OK
==>Founddependencies:ExtUtils::MakeMaker

安装过程中它自己会解决模块相关的依赖关系,可能会有一些底层的库需要手动去安装,比如我在安装过程中就失败了


! Installing the dependencies failed: Module 'XML::LibXML' is not installed, Module 'XML::Simple' is not installed


! Bailing out the installation for Rex-1.3.3.


提示有个XML::LibXML相关的模块安装不成功,这个和它依赖的相关的底层xml库有关系,所以我将libxml相关的底层库都安装一下就行了。


[root@StorageServer1~]#yuminstalllibxml*

然后再安装rex


root@StorageServer1~]#cpanmRex
-->WorkingonRex
Fetchinghttp://www.cpan.org/authors/id/F/FE/FERKI/Rex-1.3.3.tar.gz...OK
==>Founddependencies:ExtUtils::MakeMaker

5,安装完成后现在就开始进行管理。


用户:管理用户我用tomcat(因为root权限不能给测试人员使用);


模块:建立7个模块,每个模块对应一个不同的项目;


模板:建立两个模板模块,将对所有项目节点的统一操作都写进模板里,比如批量更新软件,设置时间,删除软件等等。


主机名配置文件:以ini形式保存所有项目的主机名。七个项目建立七个组,每个组中包含的主机名就是属于该项目集群环境中的几点服务器的主机名(因为集群就一个节点所以只有一个主机名)


Rexfile:配置文件,rex命令所有的操作都是读取该文件,所有类似于全局设置的选项都保存在该文件里。

第一步:建立模板:两个模板对应的名称为:


Template::Service :该模板主要存放服务等相关的操作比如操作tomcat,启动 关闭 等


Template::File: 该模块主要发布项目和一些文件,包括文件内容同步等相关工作


建立tomcat用户并切换到tomcat目录下,然后创建rex目录,进入rex目录在创建两个模板;如下:


[


tomcat@StorageServer1~]$pwd
/home/tomcat
[tomcat@StorageServer1~]$mkdirrex
[tomcat@StorageServer1~]$cdrex
[tomcat@StorageServer1rex]$rexifyTemplate::Service--create-module
CreatingmoduleTemplate::Service...
mkdirTemplate/Service
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinTemplate/Service.
[tomcat@StorageServer1rex]$rexifyTemplate::File--create-module
CreatingmoduleTemplate::File...
mkdirTemplate/File
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinTemplate/File.
[tomcat@StorageServer1rex]$ls
Template
[tomcat@StorageServer1rex]$ls-ldTemplate/*
drwxr-xr-x2tomcattomcat4096Sep1612:18Template/File
drwxr-xr-x2tomcattomcat4096Sep1612:18Template/Service

第二步:在rex目录下建立file.ini文件 里面存放的主要是操作的主机组如下


[tomcat@StorageServer1rex]$ls
file.iniTemplate
[tomcat@StorageServer1rex]$catfile.ini
[quanguo_servers]
quanguo
[chaoshi_servers]
chaoshi
[geren_servers]
geren
[boss_servers]
boss
[shopwap_servers]
shopwap
[appwap_servers]
appwap
[gerenwap_servers]
gerenwap
[all_servers]
@quanguo_servers
@chaoshi_servers
@geren_servers
@boss_servers
@shopwap_servers
@appwap_servers
@gerenwap_servers
[tomcat@StorageServer1rex]$

主机名所对应的ip可以查看hosts文件


第三步:在rex目录下建立模块,总共七个项目,我需要建立七个模块;


[tomcat@StorageServer1rex]$rexifyServers::Appwap--create-module
CreatingmoduleServers::Appwap...
mkdirServers/Appwap
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinServers/Appwap.
[tomcat@StorageServer1rex]$rexifyServers::Boss--create-module
CreatingmoduleServers::Boss...
mkdirServers/Boss
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinServers/Boss.
[tomcat@StorageServer1rex]$rexifyServers::Chaoshi--create-module
CreatingmoduleServers::Chaoshi...
mkdirServers/Chaoshi
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinServers/Chaoshi.
[tomcat@StorageServer1rex]$rexifyServers::Geren--create-module
CreatingmoduleServers::Geren...
mkdirServers/Geren
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinServers/Geren.
[tomcat@StorageServer1rex]$rexifyServers::Gerenwap--create-module
CreatingmoduleServers::Gerenwap...
mkdirServers/Gerenwap
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinServers/Gerenwap.
[tomcat@StorageServer1rex]$rexifyServers::Quanguo--create-module
CreatingmoduleServers::Quanguo...
mkdirServers/Quanguo
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinServers/Quanguo.
[tomcat@StorageServer1rex]$rexifyServers::Shopwap--create-module
CreatingmoduleServers::Shopwap...
mkdirServers/Shopwap
Creatingtemplatefile:__module__.pm
Creatingtemplatefile:meta.yml
YourmodulehasbeencreatedinServers/Shopwap.
[tomcat@StorageServer1rex]$

查看创建的七个模块


[tomcat@StorageServer1rex]$lsServers/-l
total28
drwxr-xr-x2tomcattomcat4096Sep1612:27Appwap
drwxr-xr-x2tomcattomcat4096Sep1612:27Boss
drwxr-xr-x2tomcattomcat4096Sep1612:27Chaoshi
drwxr-xr-x2tomcattomcat4096Sep1612:27Geren
drwxr-xr-x2tomcattomcat4096Sep1612:28Gerenwap
drwxr-xr-x2tomcattomcat4096Sep1612:28Quanguo
drwxr-xr-x2tomcattomcat4096Sep1612:28Shopwap
[tomcat@StorageServer1rex]$ls
file.iniServersTemplate
[tomcat@StorageServer1rex]$

第五步:在rex目录下创建Rexfile主配置文件


[tomcat@StorageServer1rex]$ls
file.iniRexfileServersTemplate

稍后会讲Rexfile中的内容是什么意思(现在可以忽略Rexfie中的内容只需要创建个Rexfile文件就行);


因为我所有项目都是部署的tomcat7.0+jdk1.7 所以我可以将重启 关闭 启动等服务操作写到Template::Sevice模块中如下:


[tomcat@StorageServer1rex]$catTemplate/Service/__module__.pm
packageTemplate::Service;
usev5.10;
usewarnings;
useRex-base;
task"shutdown_tomcat",group=>"all_servers",sub{
my$server=Rex::get_current_connection()->{server};
formy$proc(ps()){
if($proc->{"command"}=~/java.*?tomcat/i){
run"./shutdown.sh",
cwd=>"/usr/local/tomcat/bin",
only_if=>"pgrepjava";
say"[$server]:tomcat服务关闭完成";
last;
}else{
next;
}
}
given($server){
when(//bchaoshi/b/i){
file"/usr/local/tomcat/webapps/osms",ensure=>"absent";
file"/usr/local/tomcat/work/Catalina",ensure=>"absent";
file"/usr/local/tomcat/webapps/ROOT",ensure=>"absent";
say"[$server:缓存清理完成]";
break;}
when(//bquanguo/b/i){
file"/usr/local/tomcat/webapps/olsm",ensure=>"absent";
file"/usr/local/tomcat/work/Catalina",ensure=>"absent";
file"/usr/local/tomcat/webapps/ROOT",ensure=>"absent";
say"[$server:缓存清理完成]";
break;}
when(//bgeren/b/i){
file"/usr/local/tomcat/webapps/imss",ensure=>"absent";
file"/usr/local/tomcat/work/Catalina",ensure=>"absent";
file"/usr/local/tomcat/webapps/ROOT",ensure=>"absent";
say"[$server:缓存清理完成]";
break;}
when(//bboss/b/i){
file"/usr/local/tomcat/webapps/boss",ensure=>"absent";
file"/usr/local/tomcat/work/Catalina",ensure=>"absent";
file"/usr/local/tomcat/webapps/ROOT",ensure=>"absent";
say"[$server:缓存清理完成]";
break;}
when(//bshopwap/b/i){
file"/usr/local/tomcat/webapps/shopwap",ensure=>"absent";
file"/usr/local/tomcat/work/Catalina",ensure=>"absent";
file"/usr/local/tomcat/webapps/ROOT",ensure=>"absent";
say"[$server:缓存清理完成]";
break;}
when(//bappwap/b/i){
file"/usr/local/tomcat/webapps/moser",ensure=>"absent";
file"/usr/local/tomcat/work/Catalina",ensure=>"absent";
file"/usr/local/tomcat/webapps/ROOT",ensure=>"absent";
say"[$server:缓存清理完成]";
break;}
when(//bgerenwap/b/i){
file"/usr/local/tomcat/webapps/imsswap",ensure=>"absent";
file"/usr/local/tomcat/work/Catalina",ensure=>"absent";
file"/usr/local/tomcat/webapps/ROOT",ensure=>"absent";
say"[$server:缓存清理完成]";
break;}
default{say"没有该服务";}
}
say"[$server]:服务已经关闭";
};
task"start_tomcat",group=>"all_servers",sub{
my$server=Rex::get_current_connection()->{server};
if(is_file("/usr/local/tomcat/bin/startup.sh")){
run"./startup.sh",sub{
my($stdout,$stderr)=@_;
say"[$server]:$stdout";
},
cwd=>"/usr/local/tomcat/bin",
unless=>"pgrepjava";
}else{
say"[$server]:没有正确安装tomcat,请认真检查服务状态";
exit0;
}
formy$proc(ps()){
if($proc->{"command"}=~/java.*tomcat/i){
say"[$server]:tomcat已经启动,进程pid:".$proc->{"pid"};
last;
}else{
next;
}
}
};
task"restart_tomcat",group=>"all_servers",sub{
my$server=Rex::get_current_connection()->{server};
needs'shutdown_tomcat';
sleep5;
needs'start_tomcat';
say"[$server]:服务重启完成";
};
task"show_time",group=>"all_servers",sub{
sayrun"date";
};
1;

里面定义了四个任务,分别为tomcat的启动,关闭,重启,和系统当前时间


第四步:调用该模板,查看当前任务,我们讲过所有的操作都是通过rex命令来完成的,rex必须要在有Rexfile的目录下执行并且读取Rexfile中的代码;因此我要通过在Rexfile写代码调用这个模板。如下所示


[tomcat@StorageServer1rex]$catRexfile
useRex-feature=>['1.3'];
usestrict;
usewarnings;
useRex::Group::Lookup::INI;
#useData::Dumper;
#加载模版
requireTemplate::Service;
requireTemplate::File;
#设置并发连接数,默认是1
parallelism'max';
#将服务器分组并以文件的形式来保存主机名
groups_file"file.ini";
#将定义好的方法,属性,以及变量都保存在改模版中(此模板也是一个模块)
authfor=>"all_servers"=>
user=>"tomcat",
private_key=>"/home/tomcat/.ssh/id_rsa",
public_key=>"/home/tomcat/.ssh/id_rsa.pub";
desc"启动所有web服务";
task"web_start",group=>"all_servers",sub{
Template::start_tomcat();
};
desc"关闭所有web服务";
task"web_stop",group=>"all_servers",sub{
Template::shutdown_tomcat();
};
desc"重启所有web服务";
task"web_restart",group=>"all_servers",sub{
Template::Service::restart_tomcat();
};
desc"查看所有服务器节点时间";
task"show_times",group=>"all_servers",sub{
Template::show_time();
};

通过rex -T来查看当前的任务 如下


[tomcat@StorageServer1rex]$rex-T
Tasks
show_times查看所有服务器节点时间
web_restart重启所有web服务
web_start启动所有web服务
web_stop关闭所有web服务
ServerGroups
all_serversappwap,boss,chaoshi,geren,gerenwap,quanguo,shopwap
appwap_serversappwap
boss_serversboss
chaoshi_serverschaoshi
geren_serversgeren
gerenwap_serversgerenwap
quanguo_serversquanguo
shopwap_serversshopwap
[tomcat@StorageServer1rex]$

比如我现在要重启所有项目的web服务 我只需要通过rex+任务名就行了,


在执行之前我要说明下:因为rex是通过ssh来进行集成管理的,所以我需要用到账户和密码,ssh登陆可以通过口令登陆


也可以通过公钥认证的方式,我这里使用的是公钥认证的方式,需要将本地生成的公钥传输到各个节点上,不然登陆的话会提示让你输入密码等交互操作


为了解决这个问题,我写了个脚本名为login.pl执行以下就行了 操作如下


首先生成key


[tomcat@StorageServer1rex]$ssh-keygen-trsa
Generatingpublic/privatersakeypair.
Enterfileinwhichtosavethekey(/home/tomcat/.ssh/id_rsa):
Createddirectory'/home/tomcat/.ssh'.
Enterpassphrase(emptyfornopassphrase):
Entersamepassphraseagain:
Youridentificationhasbeensavedin/home/tomcat/.ssh/id_rsa.
Yourpublickeyhasbeensavedin/home/tomcat/.ssh/id_rsa.pub.
Thekeyfingerprintis:
2b:15:90:70:0a:06:99:a6:2d:e1:5f:28:99:11:31:a9tomcat@StorageServer1
Thekey'srandomartimageis:
+--[RSA2048]----+
|.B*..o.|
|+=..o..|
|=o+o.|
|E=....|
|.o.S|
|...|
|..|
|.|
||
+-----------------+

然后在写个login.pl脚本 赋予执行权限 在执行(因为用到了Expect模块如果没安装的话用cpanm安装下就行了)


[tomcat@StorageServer1rex]$vilogin.pl
#!/usr/bin/perl
usev5.16;
usewarnings;
useExpect;
my@serversqw(quanguochaoshigerenbossshopwapappwapimsswap);
formy$host(@servers){
my$exp=Expect->new();
$exp->spawn("ssh-copy-id-i/home/tomcat/.ssh/id_rsa.pub$host");
$exp->exp_internal(1);
$exp->log_stdout(0);
$exp->debug(3);
$exp->expect(2,[qr/connecting/(yes//no/)/?/i,sub{
my$self=shift;
$self->send("yes/n");
exp_continue;}],
[qr/password:/i,sub{
my$self=shift;
$self->send("tomcat12300./n");
exp_continue;}]
);
[tomcat@StorageServer1rex]$chmoda+xlogin.pl
[tomcat@StorageServer1rex]$./login.pl

重启所有tomcat服务


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台