Rex是一款服务器协调和配置管理工具。有了Rex,你可以通过配置管理和软件部署的完整流程,由集中点来管理所有服务器。
简而言之,Rex就好比Make命令。有一个集中式Rexfile,你可以在其中定义任务。这些任务通过SSH在远程机器上执行。任务采用普通perl编写而成。
你可以从网站http://rexify.org/获得Rex。
前言
在本文中,我将使用Subversion来管理所有任务。你也可以使用其他任何软件配置管理(SCM)系统,只要它支持类似Subversion的外部命令的命令。我使用Ubuntu 12.04,但你也可以使用其他发行版。
我不会在每一个命令后面加上后缀“sudo”;必要的话,请使用“sudo”。
在本文中,我将建立两个示例项目。一个项目名为“website”,另一个项目名为“database”,因为在大公司中,系统管理员和数据库管理员常常是分开设立的。这两个项目都将使用可以由中央操作团队来管理的“常见任务”(common tasks)。
我将使用多个服务器:
•Subversion服务器,svn01
•数据库服务器,db01
•Web服务器,web01
•工作站,wks01
#p# 创建版本库
首先,你得安装全部所需的软件包。在Subversion服务器上执行这个命令。
svn01# apt-get install libapache2-svn subversion apache2-mpm-prefork
现在,编辑文件/etc/apache2/mods-enabled/dav_svn.conf,把下列代码粘贴到该文件中(更换现有的内容)。
DAV svn
SVNParentPath /var/lib/svn
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/dav_svn.passwd
Require valid-user
现在,创建目录/var/lib/svn和所有所需的版本库。我会在后面描述版本库的内容。
svn01# mkdir /var/lib/svn
svn01# cd /var/lib/svn
svn01 /var/lib/svn# svnadmin create common
svn01 /var/lib/svn# svnadmin create service
svn01 /var/lib/svn# svnadmin create database
svn01 /var/lib/svn# svnadmin create website
svn01 /var/lib/svn# chown -R www-data:
我们创建了版本库后,需要为apache建立验证机制。
svn01# htpasswd -c /etc/apache2/dav_svn.passwd your-user-name
现在,可以重新启动 apache了。
svn01# service apache2 restart
恭喜你!你的Subversion服务器现在准备就绪了。不妨直奔你的工作站,检出版本库。
#p# 编写任务
到了工作站,现在你可以检出版本库。
wks01# svn co http://svn01/svn/common Common
wks01# svn co http://svn01/svn/service Service
wks01# svn co http://svn01/svn/database
wks01# svn co http://svn01/svn/website
首先,我们添加一个常见任务来建立NTP。之后你可以添加其他常见任务。所以,更换到Common目录,建立一个名为NTP.pm的文件。
wks01# cd Common
# Common/NTP.pm
package Common::NTP;
use Rex -base;
task prepare => sub {
install "ntp";
file "/etc/ntp.conf",
source => "files/ntp.conf",
on_change => sub {
service ntp => "restart";
};
};
1;
这建立了一个名为“prepare”的任务。该任务登记在“Namespace”NTP中。如果软件包“ntp”之前还没有安装,该任务将安装该软件包,并将配置文件上传至服务器。要是文件的内容发生变化,它会重新启动ntp服务。现在,你需要创建ntp.conf文件。
bash Common# mkdir files
把上面这行粘贴到文件files/ntp.conf中。这是一个简单的默认ntp.conf文件。当然,你可以更改该文件以满足自己的要求。
# /etc/ntp.conf,由rex来管理。
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server 0.ubuntu.pool.ntp.org
server 1.ubuntu.pool.ntp.org
server 2.ubuntu.pool.ntp.org
server 3.ubuntu.pool.ntp.org
# 使用Ubuntu的ntp服务器作为应急后备机制。
server ntp.ubuntu.com
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery
# 本地用户可能更密切地询问ntp服务器。
restrict 127.0.0.1
restrict ::1
就开始而言,这足够了。所以,现在你可以把新文件添加到版本库。
wks01 Common# svn add NTP.pm files
wks01 Common# svn ci -m "added NTP task"
现在,我们将为服务库添加内容。
wks01 Common# cd ../Service
wks01 Service# touch Apache.pm MySQL.pm
现在,把下列代码粘贴到Apache.pm模块。
package Service::Apache;
use Rex -base;
task prepare => sub {
install "apache2";
};
task configure => sub {
my $param = shift;
file "/etc/apache2/apache2.conf",
owner => "root",
mode => 644,
content => template("templates/apache2/apache2.conf.tpl", %{ $param });
file "/etc/apache2/conf.d/security",
owner => "root",
mode => 644,
content => template("templates/apache2/conf.d/security.tpl", %{ $param });
};
1;
并创建由该模块使用的模板。
wks01 Service# mkdir -p templates/apache2/conf.d
templates/apache2/apache2.conf.tpl的内容如下。我已去掉了所有注释。
LockFile /var/run/apache2/accept.lock
PidFile /var/run/apache2.pid
Timeout
KeepAlive
MaxKeepAliveRequests
KeepAliveTimeout
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxClients 150
MaxRequestsPerChild 0
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxClients 150
MaxRequestsPerChild 0
User
Group
AccessFileName .htaccess
Order allow,deny
Deny from all
Satisfy all
DefaultType None
HostnameLookups
ErrorLog
LogLevel
Include mods-enabled/*.load
Include mods-enabled/*.conf
Include httpd.conf
Include ports.conf
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
Include conf.d/
Include sites-enabled/
templates/apache2/conf.d/security.tpl的内容如下。我已去掉了所有注释。
ServerTokens
ServerSignature
TraceEnable
现在我们继续使用MySQL模块。打开文件MySQL.pm,添加下列内容。
package Service::MySQL;
use Rex -base;
task prepare => sub {
install "mysql-server";
};
task configure => sub {
my $param = shift;
file "/etc/mysql/my.cnf",
owner => "root",
mode => 644,
content => template("templates/mysql/my.cnf.tpl", %{ $param });
};
1;
另外创建文件templates/mysql/my.cnf.tpl。
[mysqld]
user =
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port =
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address =
key_buffer =
max_allowed_packet =
thread_stack =
thread_cache_size =
myisam-recover = BACKUP
query_cache_limit =
query_cache_size =
expire_logs_days =
max_binlog_size =
[mysqldump]
quick
quote-names
max_allowed_packet =
[mysql]
[isamchk]
key_buffer =
!includedir /etc/mysql/conf.d/
现在,添加所有文件到版本库。
wks01 Service# svn add *
wks01 Service# svn ci -m "inital commit of apache and mysql service"
好了,现在你已有了第一批常见模块。现在,可以为数据库项目创建任务了。
#p# 创建数据库任务
更换到数据库版本库。
wks01 Service# cd ../database
wks01 database# touch Rexfile
现在,我们将把2个常见版本库作为一个外部版本库来添加。
wks01 database# svn propedit svn:externals .
添加下列几行到编辑器中,保存并关闭。
lib/Common http://svn01/svn/common
lib/Service http://svn01/svn/service
在建好外部版本库之后,运行更新,提交新的设置。
wks01 database# svn up
wks01 database# svn ci -m "added external repositories"
svn up命令现在检查两个外部版本库,检查有无更新。所以,要是有人往这其中一个版本库添加了新服务,你在执行svn up命令后获得新服务。现在,你可以开始创建Rexfile,以建立数据库服务器。
set user => "root";
set password => "f00b4r";
include qw/
Common::NTP
Service::MySQL
/;
set group => srvdb => "db01";
task "prepare", group => "srvdb", sub {
# 运行常见ntp任务“prepare”
Common::NTP::prepare();
# 安装mysql
Service::MySQL::prepare();
# 配置mysql
Service::MySQL::configure({
key_buffer => "32M",
max_allowed_packet => "32M",
});
# 重新启动mysql
service mysql => "restart";
};
首先(在第1行和第2行),我们设立了针对目标主机(db01)所用的验证机制。这里,你还可以使用密钥验证(欲知详情,请参阅http://rexify.org/howtos/start.html)。然后,我们添加了Common::NTP和Service::MySQL模块,那样我们可以从这些模块来使用服务。每个任务还登记为一个perl函数。所以,我们完全可以像调用其余任何perl函数那样来调用它们。我们添加了所需的模块后,定义了一个新的服务器组,名为“srvdb”,并为其添加了主机“db01”。可以为一个服务器组添加多个主机。比如:
set group => srvdb => "db01", "db02", "db03";
set group => srvdb => "db[01..03]";
在第2行中,我们定义了第一个任务,名为“prepare”。该任务在服务器组“srvdb”中的所有服务器上执行。该任务调用Common::NTP和Service::MySQL模块的“prepare”任务。创建工作完毕后,我们在第20行配置了mysql服务器,在第26行重新启动了mysql服务。就这样。这将安装、配置和启动MySQL服务器。现在,你可以把一切重新提交到版本库。
wks01 database# svn add Rexfile
wks01 database# svn ci -m "inital commit of Rexfile"
为了创建数据库服务器,你可以输入下列命令:
wks01 database# rex prepare
如果你想列出Rexfile里面的任务,可以使用下列命令。
wks01 database# rex -T
我们的数据库运行后,现在可以为website项目创建任务。
#p# 创建Website任务
首先,更换到website项目目录。
wks01 database# cd ../website
wks01 website# touch Rexfile
首先,我们同样需要在此定义外部版本库。
wks01 website# svn propedit svn:externals .
把下列几行添加到编辑器中,保存并关闭。
lib/Common http://svn01/svn/common
lib/Service http://svn01/svn/service
在建好外部版本库之后,运行更新,提交新的设置。
wks01 database# svn up
wks01 database# svn ci -m "added external repositories"
svn up命令现在检查两个外部版本库,检查有无更新。所以,如果有人往这其中一个版本库添加了新服务,你在执行svn up命令后获得新服务。现在,你可以开始创建Rexfile,建立web服务器。
# Rexfile
set user => "root";
set password => "test";
include qw/
Common::NTP
Service::Apache
/;
set group => srvweb => "web01";
task "prepare", group => "srvweb", sub {
# 运行常见ntp任务“prepare”
Common::NTP::prepare();
# 安装apache
Service::Apache::prepare();
# 配置apache
Service::Apache::configure({
timeout => 60,
});
#重新启动apache
service apache2 => "restart";
};
保存文件,并保存到版本库。
wks01 website# svn add Rexfile
wks01 website# svn ci -m "initial Rexfile"
现在,你可以准备用下列命令来创建web服务器了。
wks01 website# rex prepare
你创建好了数据库和web服务器后,就可以准备部署应用程序了。比如说,如果你从开发团队获得了一个ZIP或TAR压缩文档,可以往Rexfile添加第二个任务,以此部署应用程序。
task "deploy", group => "srvweb", sub {
upload "your-web-application.tar.gz", "/tmp";
extract "/tmp/your-web-application.tar.gz",
owner => "www-data",
group => "www-data",
to => "/var/www";
rm "/tmp/your-web-application.tar.gz";
};
原文链接: http://www.howtoforge.com/how-to-manage-your-servers-with-rex-best-practice