如何使用Rex管理你的服務(wù)器?
譯文Rex是一款服務(wù)器協(xié)調(diào)和配置管理工具。有了Rex,你可以通過(guò)配置管理和軟件部署的完整流程,由集中點(diǎn)來(lái)管理所有服務(wù)器。
簡(jiǎn)而言之,Rex就好比Make命令。有一個(gè)集中式Rexfile,你可以在其中定義任務(wù)。這些任務(wù)通過(guò)SSH在遠(yuǎn)程機(jī)器上執(zhí)行。任務(wù)采用普通perl編寫而成。
你可以從網(wǎng)站http://rexify.org/獲得Rex。
前言
在本文中,我將使用Subversion來(lái)管理所有任務(wù)。你也可以使用其他任何軟件配置管理(SCM)系統(tǒng),只要它支持類似Subversion的外部命令的命令。我使用Ubuntu 12.04,但你也可以使用其他發(fā)行版。
我不會(huì)在每一個(gè)命令后面加上后綴“sudo”;必要的話,請(qǐng)使用“sudo”。
在本文中,我將建立兩個(gè)示例項(xiàng)目。一個(gè)項(xiàng)目名為“website”,另一個(gè)項(xiàng)目名為“database”,因?yàn)樵诖蠊局校到y(tǒng)管理員和數(shù)據(jù)庫(kù)管理員常常是分開設(shè)立的。這兩個(gè)項(xiàng)目都將使用可以由中央操作團(tuán)隊(duì)來(lái)管理的“常見任務(wù)”(common tasks)。
我將使用多個(gè)服務(wù)器:
•Subversion服務(wù)器,svn01
•數(shù)據(jù)庫(kù)服務(wù)器,db01
•Web服務(wù)器,web01
•工作站,wks01
#p# 創(chuàng)建版本庫(kù)
首先,你得安裝全部所需的軟件包。在Subversion服務(wù)器上執(zhí)行這個(gè)命令。
svn01# apt-get install libapache2-svn subversion apache2-mpm-prefork
現(xiàn)在,編輯文件/etc/apache2/mods-enabled/dav_svn.conf,把下列代碼粘貼到該文件中(更換現(xiàn)有的內(nèi)容)。
DAV svn
SVNParentPath /var/lib/svn
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/dav_svn.passwd
Require valid-user
現(xiàn)在,創(chuàng)建目錄/var/lib/svn和所有所需的版本庫(kù)。我會(huì)在后面描述版本庫(kù)的內(nèi)容。
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:
我們創(chuàng)建了版本庫(kù)后,需要為apache建立驗(yàn)證機(jī)制。
svn01# htpasswd -c /etc/apache2/dav_svn.passwd your-user-name
現(xiàn)在,可以重新啟動(dòng) apache了。
svn01# service apache2 restart
恭喜你!你的Subversion服務(wù)器現(xiàn)在準(zhǔn)備就緒了。不妨直奔你的工作站,檢出版本庫(kù)。
#p# 編寫任務(wù)
到了工作站,現(xiàn)在你可以檢出版本庫(kù)。
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
首先,我們添加一個(gè)常見任務(wù)來(lái)建立NTP。之后你可以添加其他常見任務(wù)。所以,更換到Common目錄,建立一個(gè)名為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;
這建立了一個(gè)名為“prepare”的任務(wù)。該任務(wù)登記在“Namespace”NTP中。如果軟件包“ntp”之前還沒(méi)有安裝,該任務(wù)將安裝該軟件包,并將配置文件上傳至服務(wù)器。要是文件的內(nèi)容發(fā)生變化,它會(huì)重新啟動(dòng)ntp服務(wù)。現(xiàn)在,你需要?jiǎng)?chuàng)建ntp.conf文件。
bash Common# mkdir files
把上面這行粘貼到文件files/ntp.conf中。這是一個(gè)簡(jiǎn)單的默認(rèn)ntp.conf文件。當(dāng)然,你可以更改該文件以滿足自己的要求。
# /etc/ntp.conf,由rex來(lái)管理。
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服務(wù)器作為應(yīng)急后備機(jī)制。
server ntp.ubuntu.com
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery
# 本地用戶可能更密切地詢問(wèn)ntp服務(wù)器。
restrict 127.0.0.1
restrict ::1
就開始而言,這足夠了。所以,現(xiàn)在你可以把新文件添加到版本庫(kù)。
wks01 Common# svn add NTP.pm files
wks01 Common# svn ci -m "added NTP task"
現(xiàn)在,我們將為服務(wù)庫(kù)添加內(nèi)容。
wks01 Common# cd ../Service
wks01 Service# touch Apache.pm MySQL.pm
現(xiàn)在,把下列代碼粘貼到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;
并創(chuàng)建由該模塊使用的模板。
wks01 Service# mkdir -p templates/apache2/conf.d
templates/apache2/apache2.conf.tpl的內(nèi)容如下。我已去掉了所有注釋。
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的內(nèi)容如下。我已去掉了所有注釋。
ServerTokens
ServerSignature
TraceEnable
現(xiàn)在我們繼續(xù)使用MySQL模塊。打開文件MySQL.pm,添加下列內(nèi)容。
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;
另外創(chuàng)建文件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/
現(xiàn)在,添加所有文件到版本庫(kù)。
wks01 Service# svn add *
wks01 Service# svn ci -m "inital commit of apache and mysql service"
好了,現(xiàn)在你已有了第一批常見模塊。現(xiàn)在,可以為數(shù)據(jù)庫(kù)項(xiàng)目創(chuàng)建任務(wù)了。
#p# 創(chuàng)建數(shù)據(jù)庫(kù)任務(wù)
更換到數(shù)據(jù)庫(kù)版本庫(kù)。
wks01 Service# cd ../database
wks01 database# touch Rexfile
現(xiàn)在,我們將把2個(gè)常見版本庫(kù)作為一個(gè)外部版本庫(kù)來(lái)添加。
wks01 database# svn propedit svn:externals .
添加下列幾行到編輯器中,保存并關(guān)閉。
lib/Common http://svn01/svn/common
lib/Service http://svn01/svn/service
在建好外部版本庫(kù)之后,運(yùn)行更新,提交新的設(shè)置。
wks01 database# svn up
wks01 database# svn ci -m "added external repositories"
svn up命令現(xiàn)在檢查兩個(gè)外部版本庫(kù),檢查有無(wú)更新。所以,要是有人往這其中一個(gè)版本庫(kù)添加了新服務(wù),你在執(zhí)行svn up命令后獲得新服務(wù)。現(xiàn)在,你可以開始創(chuàng)建Rexfile,以建立數(shù)據(jù)庫(kù)服務(wù)器。
set user => "root";
set password => "f00b4r";
include qw/
Common::NTP
Service::MySQL
/;
set group => srvdb => "db01";
task "prepare", group => "srvdb", sub {
# 運(yùn)行常見ntp任務(wù)“prepare”
Common::NTP::prepare();
# 安裝mysql
Service::MySQL::prepare();
# 配置mysql
Service::MySQL::configure({
key_buffer => "32M",
max_allowed_packet => "32M",
});
# 重新啟動(dòng)mysql
service mysql => "restart";
};
首先(在第1行和第2行),我們?cè)O(shè)立了針對(duì)目標(biāo)主機(jī)(db01)所用的驗(yàn)證機(jī)制。這里,你還可以使用密鑰驗(yàn)證(欲知詳情,請(qǐng)參閱http://rexify.org/howtos/start.html)。然后,我們添加了Common::NTP和Service::MySQL模塊,那樣我們可以從這些模塊來(lái)使用服務(wù)。每個(gè)任務(wù)還登記為一個(gè)perl函數(shù)。所以,我們完全可以像調(diào)用其余任何perl函數(shù)那樣來(lái)調(diào)用它們。我們添加了所需的模塊后,定義了一個(gè)新的服務(wù)器組,名為“srvdb”,并為其添加了主機(jī)“db01”。可以為一個(gè)服務(wù)器組添加多個(gè)主機(jī)。比如:
set group => srvdb => "db01", "db02", "db03";
set group => srvdb => "db[01..03]";
在第2行中,我們定義了第一個(gè)任務(wù),名為“prepare”。該任務(wù)在服務(wù)器組“srvdb”中的所有服務(wù)器上執(zhí)行。該任務(wù)調(diào)用Common::NTP和Service::MySQL模塊的“prepare”任務(wù)。創(chuàng)建工作完畢后,我們?cè)诘?0行配置了mysql服務(wù)器,在第26行重新啟動(dòng)了mysql服務(wù)。就這樣。這將安裝、配置和啟動(dòng)MySQL服務(wù)器。現(xiàn)在,你可以把一切重新提交到版本庫(kù)。
wks01 database# svn add Rexfile
wks01 database# svn ci -m "inital commit of Rexfile"
為了創(chuàng)建數(shù)據(jù)庫(kù)服務(wù)器,你可以輸入下列命令:
wks01 database# rex prepare
如果你想列出Rexfile里面的任務(wù),可以使用下列命令。
wks01 database# rex -T
我們的數(shù)據(jù)庫(kù)運(yùn)行后,現(xiàn)在可以為website項(xiàng)目創(chuàng)建任務(wù)。
#p# 創(chuàng)建Website任務(wù)
首先,更換到website項(xiàng)目目錄。
wks01 database# cd ../website
wks01 website# touch Rexfile
首先,我們同樣需要在此定義外部版本庫(kù)。
wks01 website# svn propedit svn:externals .
把下列幾行添加到編輯器中,保存并關(guān)閉。
lib/Common http://svn01/svn/common
lib/Service http://svn01/svn/service
在建好外部版本庫(kù)之后,運(yùn)行更新,提交新的設(shè)置。
wks01 database# svn up
wks01 database# svn ci -m "added external repositories"
svn up命令現(xiàn)在檢查兩個(gè)外部版本庫(kù),檢查有無(wú)更新。所以,如果有人往這其中一個(gè)版本庫(kù)添加了新服務(wù),你在執(zhí)行svn up命令后獲得新服務(wù)。現(xiàn)在,你可以開始創(chuàng)建Rexfile,建立web服務(wù)器。
# Rexfile
set user => "root";
set password => "test";
include qw/
Common::NTP
Service::Apache
/;
set group => srvweb => "web01";
task "prepare", group => "srvweb", sub {
# 運(yùn)行常見ntp任務(wù)“prepare”
Common::NTP::prepare();
# 安裝apache
Service::Apache::prepare();
# 配置apache
Service::Apache::configure({
timeout => 60,
});
#重新啟動(dòng)apache
service apache2 => "restart";
};
保存文件,并保存到版本庫(kù)。
wks01 website# svn add Rexfile
wks01 website# svn ci -m "initial Rexfile"
現(xiàn)在,你可以準(zhǔn)備用下列命令來(lái)創(chuàng)建web服務(wù)器了。
wks01 website# rex prepare
你創(chuàng)建好了數(shù)據(jù)庫(kù)和web服務(wù)器后,就可以準(zhǔn)備部署應(yīng)用程序了。比如說(shuō),如果你從開發(fā)團(tuán)隊(duì)獲得了一個(gè)ZIP或TAR壓縮文檔,可以往Rexfile添加第二個(gè)任務(wù),以此部署應(yīng)用程序。
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