Hi,本周第一天没什么事,所以就先分享一下我研究自动化代码部署与回滚软件的经验。这个软件有什么用途?主要是解决自动进行代码的部署,避免手动部署时出现错误,节省时间,同时在出现问题的时候,能回滚到之前的版本(或者你指定的版本),我在gitlab里找到了这样的软件,名为capistrano。下面就先给大家介绍一下。
文章结构
一、介绍
二、要求的环境
三、安装
四、命令行测试
五、代码部署(结合git)
六、代码部署(结合svn)
七、代码回滚
八、总结
九、namespace
一、介绍
Capistrano是一种在多台服务器上运行脚本的开源工具,它主要用于部署web应用。它自动完成多台服务器上新版本的同步更新,包括数据库的改变。Capistrano最初由Jamis Buck用Ruby开发,并用RubyGems部署渠道部署。现在Capistrano不仅限于应用Ruby on Rails的 web应用框架,而且可以用于部署用其他框架的web应用程序,比如用PHP开发的。Capistran最初是用来应用于bash指令行。现在Ruby on Rails框架的用于也可以使用它的新特性,例如,对当前web应用部署改变使其更新版本,或者使其回滚到之前的旧版本。
二、要求的环境
1、Ruby一定要1.9.x;
2、server端与client端一定要进行ssh信任或者client端统一一个相同的密码;
三、安装
1
|
gem install capistrano
|
四、命令行测试
1
2
3
4
|
root@ubuntu:/tmp# cat capfile
task :du, :hosts =>
"ubuntu.hadoop.com"
do
run
"df -h"
end
|
在ubuntu.hadoop.com(本机)机器上运行df –h命令查看磁盘空间
1
2
3
4
5
6
7
8
9
10
11
12
13
|
root@ubuntu:/tmp# cap du
*
2013
-
06
-
25
13
:
34
:
48
executing `du'
* executing
"df -h"
servers: [
"ubuntu.hadoop.com"
]
[ubuntu.hadoop.com] executing command
** [out :: ubuntu.hadoop.com] Filesystem Size Used Avail Use% Mounted on
** [out :: ubuntu.hadoop.com] /dev/mapper/ubuntu-root 39G
3
.3G 33G
10
% /
** [out :: ubuntu.hadoop.com] udev 489M
4
.0K 489M
1
% /dev
** [out :: ubuntu.hadoop.com] tmpfs 199M 336K 199M
1
% /run
** [out :: ubuntu.hadoop.com] none
5
.0M
0
5
.0M
0
% /run/lock
** [out :: ubuntu.hadoop.com] none 498M
0
498M
0
% /run/shm
** [out :: ubuntu.hadoop.com] /dev/sda1 228M 51M 166M
24
% /boot
command finished
in
981ms
|
可以看到类似使用python的fabric,但capistrano比fabric多了一个代码回滚功能。
需要注意的是如果你的client机器的ssh端口不是默认22的话,你还想操作的话,需要添加
ssh_options[:port] = 50020#ssh port
如果不添加的话,就会出现connection failed for: ip (Errno::ECONNREFUSED: Connection refused - connect(2))
如果你在使用iptables的机器上使用capistrano,只需要开启ssh端口就可以正常的使用capistrano。
五、代码部署(结合git)
测试环境
1
2
3
|
主机名 ip 状态 ruby
ubuntu.hadoop.com
192.168
.
56.102
server
1.9
.
3
server.hadoo.com
192.168
.
56.101
client
1.9
.
3
|
1、进入tmp目录,然后创建capi目录
1
2
3
|
cd /tmp
mkdir capi
cd capi
|
2、capistrano部署我的应用
1
|
capify .
|
这将产生两个文件,一个是capfile,这个是Capistrano需要的主要文件,就像make自动产生makefile,rake自动产生Rakefile一样,Capistrano默认寻找并加载capfile文件,默认产生的rapfile非常小,它所做的事就是加载“config/deploy.rb";第二个文件是"config/deploy.rb",这个文件包含你的应用程序部署所需的设置。Ralis的所有设置文档都放在config目录下,通常,你不需要管capfile文件,只需要把精力放在config/deploy.rb的设置和优化上。如果你的Capistrano用于非Rails环境,你可能只有一个capfile文件,而没有config/deploy.rb这个文件。
3、修改config/deploy.rb文件
1
2
3
4
5
6
7
8
9
10
11
|
set
:application,
"test"
set
:scm, :git
set
:repository,
"ssh://git@192.168.1.250/data/gitrepo/jsonLib.git"
set
:deploy_to,
"/tmp/result"
set
:normalize_asset_timestamps,
false
#
set
:scm, :git # You can
set
:scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
role :web,
"192.168.56.101"
# Your HTTP server, Apache/etc
role :app,
"192.168.56.101"
# This may be the same
as
your `Web` server
role :db,
"192.168.56.101"
, :primary =>
true
# This
is
where Rails migrations will run
#role :db,
"your slave db-server here"
|
我的修改内容如上
主要是从192.168.1.250里获取git库,然后应用部署到192.168.56.102机器的/tmp/result目录。
1
|
set
:application,
"test"
|
是告诉Capistrano我们的应用程序被"调用"了
1
|
set
:scm, :git
|
默认启动svn,而不是git,如果使用的话,需要set :scm, :git开启。
1
|
set
:repository,
"ssh://git@192.168.1.250/data/gitrepo/jsonLib.git"
|
然后我们需要告诉Capistrano我们的源代码在哪里,这个地址你的本地主机和服务器都可以到达。
1
|
set
:deploy_to,
"/tmp/result"
|
我们需要告诉Capistran我们的应用放在服务器的哪里,如果不加的话,默认为"/u/apps/#{application}"。
1
|
set
:normalize_asset_timestamps,
false
|
如果不添加这句话,在deploy:update的时候会出现
1
2
3
4
|
*** [err ::
192.168
.
56.101
] find: `/tmp/result_svn/releases/
20130625071724
/
public
/images'
*** [err ::
192.168
.
56.101
] : No such file or directory
*** [err ::
192.168
.
56.101
] find: `/tmp/result_svn/releases/
20130625071724
/
public
/stylesheets': No such file or directory
*** [err ::
192.168
.
56.101
] find: `/tmp/result_svn/releases/
20130625071724
/
public
/javascripts': No such file or directory
|
原因是
1
2
3
|
Capistrano
default
behavior
is
to
'touch'
all assets files. (To make sure that any cache
get
the deployment date). Assets are images, stylesheets, etc.
If your PHP application
is
not using these directories, capistrano complains
in
such an ugly way.
To disable asset timestamps updates, simply add:
|
app,web,db是Capistrano需要的三种角色:
web:你的服务器软件运行的地方;
app:你的应用层运行的地方;
db:迁移运行的地方;
4、部署目录结构
1
|
cap deploy:setup
|
会在192.168.56.101创建/tmp/result目录,然后在这个目录里创建releases与shared目录
1
2
3
4
5
6
7
8
9
10
|
root@ubuntu:/tmp/capi# cap deploy:setup
*
2013
-
06
-
25
15
:
26
:
47
executing `deploy:setup'
* executing
"sudo -p 'sudo password: ' mkdir -p /tmp/result /tmp/result/releases /tmp/result/shared /tmp/result/shared/system /tmp/result/shared/log /tmp/result/shared/pids"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
781ms
* executing
"sudo -p 'sudo password: ' chmod g+w /tmp/result /tmp/result/releases /tmp/result/shared /tmp/result/shared/system /tmp/result/shared/log /tmp/result/shared/pids"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
40ms
|
5、检查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
root@ubuntu:/tmp/capi# cap deploy:check
*
2013
-
06
-
25
15
:
29
:
04
executing `deploy:check'
* executing
"test -d /tmp/result/releases"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
819ms
* executing
"test -w /tmp/result"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
25ms
* executing
"test -w /tmp/result/releases"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
26ms
* executing
"which git"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
26ms
You appear to have all necessary dependencies installed
|
没有问题继续下一步更新
还得注意,如果你使用ssh模式的git,你需要把客户端与服务端的ssh key都传到服务器里,否则更新失败。
6、更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
root@ubuntu:/tmp/capi# cap deploy:update
*
2013
-
06
-
25
15
:
29
:
22
executing `deploy:update'
** transaction: start
*
2013
-
06
-
25
15
:
29
:
22
executing `deploy:update_code'
executing locally:
"git ls-remote ssh://git@192.168.1.250/data/gitrepo/jsonLib.git HEAD"
command finished
in
219ms
* executing
"git clone -q ssh://git@192.168.1.250/data/gitrepo/jsonLib.git /tmp/result/releases/20130625072923 && cd /tmp/result/releases/20130625072923 && git checkout -q -b deploy ed8339e65d263fb9076b8f6168073765540bc4c4 && (echo ed8339e65d263fb9076b8f6168073765540bc4c4 > /tmp/result/releases/20130625072923/REVISION)"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
1151ms
*
2013
-
06
-
25
15
:
29
:
24
executing `deploy:finalize_update'
* executing
"chmod -R -- g+w /tmp/result/releases/20130625072923 && rm -rf -- /tmp/result/releases/20130625072923/public/system && mkdir -p -- /tmp/result/releases/20130625072923/public/ && ln -s -- /tmp/result/shared/system /tmp/result/releases/20130625072923/public/system && rm -rf -- /tmp/result/releases/20130625072923/log && ln -s -- /tmp/result/shared/log /tmp/result/releases/20130625072923/log && rm -rf -- /tmp/result/releases/20130625072923/tmp/pids && mkdir -p -- /tmp/result/releases/20130625072923/tmp/ && ln -s -- /tmp/result/shared/pids /tmp/result/releases/20130625072923/tmp/pids"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
41ms
*
2013
-
06
-
25
15
:
29
:
24
executing `deploy:create_symlink'
* executing
"sudo -p 'sudo password: ' rm -f /tmp/result/current && sudo -p 'sudo password: ' ln -s /tmp/result/releases/20130625072923 /tmp/result/current"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
60ms
** transaction: commit
|
没有错误,去192.167.56.101查看文件,确认都正常的复制过去了。
需要注意,服务端与客户端的ssh key都需要添加到git server里。
同时如果你的git有分支的话,你可以设置更新分支,设置需要在配置文件里设置,内容为
1
|
set
:branch,
"master"
|
这样就会更新master分支
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
root@server:/tmp/result# ll
total
16
drwxrwxr-x
4
root root
4096
Jun
25
15
:
29
./
drwxrwxrwt
32
root root
4096
Jun
25
15
:
30
../
lrwxrwxrwx
1
root root
35
Jun
25
15
:
29
current -> /tmp/result/releases/
20130625072923
/
drwxrwxr-x
3
root root
4096
Jun
25
15
:
29
releases/
drwxrwxr-x
5
root root
4096
Jun
25
15
:
26
shared/
root@server:/tmp/result# cd current
root@server:/tmp/result/current# ll
total
100
drwxrwxr-x
6
root root
4096
Jun
25
15
:
29
./
drwxrwxr-x
3
root root
4096
Jun
25
15
:
29
../
-rwxrwxr-x
1
root root
172
Jun
25
15
:
29
build_sh*
-rwxrwxr-x
1
root root
749
Jun
25
15
:
29
ckHashMap.h*
-rw-rw-r--
1
root root
1740
Jun
25
15
:
29
CStrUtils.cpp
-rw-rw-r--
1
root root
586
Jun
25
15
:
29
CStrUtils.h
drwxrwxr-x
8
root root
4096
Jun
25
15
:
29
.git/
lrwxrwxrwx
1
root root
22
Jun
25
15
:
29
log -> /tmp/result/shared/log/
drwxr-xr-x
2
root root
4096
Jun
25
15
:
29
public
/
-rw-rw-r--
1
root root
41
Jun
25
15
:
29
REVISION
drwxr-xr-x
2
root root
4096
Jun
25
15
:
29
tmp/
|
六、代码部署(结合svn)
测试环境
1
2
3
|
主机名 ip 状态 ruby
ubuntu.hadoop.com
192.168
.
56.102
server
1.9
.
3
server.hadoo.com
192.168
.
56.101
client
1.9
.
3
|
1、进入tmp目录,然后创建capi_svn
1
2
3
|
cd /tmp
mkdir capi_svn
cd capi_svn
|
2、capistrano部署我的应用
1
2
3
4
5
6
|
capify .
root@ubuntu:/tmp/capi_svn# capify .
[add] writing
'./Capfile'
[add] making directory
'./config'
[add] writing
'./config/deploy.rb'
[done] capified!
|
3、修改config/deploy.rb文件
1
2
3
4
5
6
7
8
9
10
11
12
|
set
:application,
"test_svn"
set
:scm, :subversion
set
:repository,
"https://192.168.1.56/svn/sgol/trunk/0-sgol_server"
set
:scm_username,
"denglei"
set
:scm_password,
"123456"
set
:deploy_to,
"/tmp/result_svn"
set
:normalize_asset_timestamps,
false
#
set
:scm, :git # You can
set
:scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
role :web,
"192.168.56.101"
# Your HTTP server, Apache/etc
role :app,
"192.168.56.101"
# This may ber
role :db,
"192.168.56.101"
, :primary =>
true
# This
is
where Rails migrations will run
#role :db,
"your slave db-server here"
|
4、部署目录结构
1
|
cap deploy:setup
|
会在192.168.56.101创建/tmp/result目录,然后在这个目录里创建releases与shared目录
1
2
3
4
5
6
7
8
9
10
|
root@ubuntu:/tmp/capi_svn# cap deploy:setup
*
2013
-
06
-
25
15
:
19
:
29
executing `deploy:setup'
* executing
"sudo -p 'sudo password: ' mkdir -p /tmp/result_svn /tmp/result_svn/releases /tmp/result_svn/shared /tmp/result_svn/shared/system /tmp/result_svn/shared/log /tmp/result_svn/shared/pids"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
783ms
* executing
"sudo -p 'sudo password: ' chmod g+w /tmp/result_svn /tmp/result_svn/releases /tmp/result_svn/shared /tmp/result_svn/shared/system /tmp/result_svn/shared/log /tmp/result_svn/shared/pids"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
36ms
|
5、环境检查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
root@ubuntu:/tmp/capi_svn# cap deploy:check
*
2013
-
06
-
25
15
:
21
:
03
executing `deploy:check'
* executing
"test -d /tmp/result_svn/releases"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
1050ms
* executing
"test -w /tmp/result_svn"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
21ms
* executing
"test -w /tmp/result_svn/releases"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
22ms
* executing
"which svn"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
28ms
You appear to have all necessary dependencies installed
|
没有问题
还有一个需要注意的,在进行更新前,需要在client里对svn先co一下,否则会出现
1
2
3
4
5
6
7
8
9
10
|
Error validating server certificate
for
'https://192.168.1.56:443'
:
- The certificate
is
not issued by a trusted authority. Use the
fingerprint to validate the certificate manually!
- The certificate hostname does not match.
Certificate information:
- Hostname: yx
- Valid: from Fri,
14
Jan
2011
12
:
31
:
10
GMT until Mon,
11
Jan
2021
12
:
31
:
10
GMT
- Issuer: yx
- Fingerprint: b2:b2:
26
:5d:5a:
76
:cd:d2:
46
:e4:a6:
31
:d9:dc:c7:2b:2a:3a:eb:
46
(R)eject, accept (t)emporarily or accept (p)ermanently?
|
错误,选择p然后yes,之后你的用户名与密码即可。
6、更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
root@ubuntu:/tmp/capi_svn# cap deploy:update
*
2013
-
06
-
25
15
:
21
:
38
executing `deploy:update'
** transaction: start
*
2013
-
06
-
25
15
:
21
:
38
executing `deploy:update_code'
executing locally:
"svn info https://192.168.1.56/svn/sgol/trunk/0-sgol_server --username denglei --password **** --no-auth-cache -rHEAD"
command finished
in
691ms
* executing
"svn checkout -q --username denglei --password **** o-auth-cache -r2446 https://192.168.1.56/svn/sgol/trunk/0-sgol_server /tmp/result_svn/releases/20130625072139 && (echo 2446 > /tmp/result_svn/releases/20130625072139/REVISION)"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
7259ms
*
2013
-
06
-
25
15
:
21
:
46
executing `deploy:finalize_update'
* executing
"chmod -R -- g+w /tmp/result_svn/releases/20130625072139 && rm -rf -- /tmp/result_svn/releases/20130625072139/public/system && mkdir -p -- /tmp/result_svn/releases/20130625072139/public/ && ln -s -- /tmp/result_svn/shared/system /tmp/result_svn/releases/20130625072139/public/system && rm -rf -- /tmp/result_svn/releases/20130625072139/log && ln -s -- /tmp/result_svn/shared/log /tmp/result_svn/releases/20130625072139/log && rm -rf -- /tmp/result_svn/releases/20130625072139/tmp/pids && mkdir -p -- /tmp/result_svn/releases/20130625072139/tmp/ && ln -s -- /tmp/result_svn/shared/pids /tmp/result_svn/releases/20130625072139/tmp/pids"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
100ms
*
2013
-
06
-
25
15
:
21
:
46
executing `deploy:create_symlink'
* executing
"sudo -p 'sudo password: ' rm -f /tmp/result_svn/current && sudo -p 'sudo password: ' ln -s /tmp/result_svn/releases/20130625072139 /tmp/result_svn/current"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
command finished
in
89ms
** transaction: commit
|
没有问题,192.168.56.101查看,文件都正常复制过去没有问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
root@server:/tmp/result_svn# pwd
/tmp/result_svn
root@server:/tmp/result_svn# ll
total
16
drwxrwxr-x
4
root root
4096
Jun
25
15
:
21
./
drwxrwxrwt
32
root root
4096
Jun
25
15
:
21
../
lrwxrwxrwx
1
root root
39
Jun
25
15
:
21
current -> /tmp/result_svn/releases/
20130625072139
/
drwxrwxr-x
3
root root
4096
Jun
25
15
:
21
releases/
drwxrwxr-x
5
root root
4096
Jun
25
15
:
19
shared/
root@server:/tmp/result_svn# cd current
root@server:/tmp/result_svn/current# ll
total
80
drwxrwxr-x
19
root root
4096
Jun
25
15
:
21
./
drwxrwxr-x
3
root root
4096
Jun
25
15
:
21
../
drwxrwxr-x
3
root root
4096
Jun
25
15
:
21
config/
drwxrwxr-x
4
root root
4096
Jun
25
15
:
21
controller/
drwxrwxr-x
7
root root
4096
Jun
25
15
:
21
data/
drwxrwxr-x
4
root root
4096
Jun
25
15
:
21
docs/
drwxrwxr-x
3
root root
4096
Jun
25
15
:
21
lib/
lrwxrwxrwx
1
root root
26
Jun
25
15
:
21
log -> /tmp/result_svn/shared/log/
drwxrwxr-x
17
root root
4096
Jun
25
15
:
21
logs/
drwxrwxr-x
3
root root
4096
Jun
25
15
:
21
model/
drwxrwxr-x
5
root root
4096
Jun
25
15
:
21
plugins/
drwxr-xr-x
2
root root
4096
Jun
25
15
:
21
public
/
-rw-rw-r--
1
root root
5
Jun
25
15
:
21
REVISION
drwxrwxr-x
3
root root
4096
Jun
25
15
:
21
server1001/
drwxrwxr-x
6
root root
4096
Jun
25
15
:
21
.svn/
|
在顺便说一下,如果你想要指定版本升级的话,可以使用cap -s revision=2449 deploy:update
revision后添加版本后即可
七、代码回滚
1、为了做测试,我新部署个应用,然后用本机测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
root@ubuntu:/tmp/check# ll
total
8
drwxrwxr-x
2
root root
4096
Jun
25
11
:
05
./
drwxrwxrwt
16
root root
4096
Jun
25
14
:
09
../
root@ubuntu:/tmp/check# capify .
[add] writing
'./Capfile'
[add] making directory
'./config'
[add] writing
'./config/deploy.rb'
[done] capified!
root@ubuntu:/tmp/check# cat config/deploy.rb
set
:application,
"test"
set
:repository,
"/tmp/svn"
set
:deploy_to,
"/tmp/result"
set
:normalize_asset_timestamps,
false
#
set
:scm, :git # You can
set
:scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
role :web,
"192.168.56.102"
# Your HTTP server, Apache/etc
role :app,
"192.168.56.102"
# This may be the same
as
your `Web` server
role :db,
"192.168.56.102"
, :primary =>
true
# This
is
where Rails migrations will run
#role :db,
"your slave db-server here"
|
2、然后在/tmp/svn(这个目录为上面config/deploy.rb里定义的)里创建个文件为1,内容也是1
1
2
3
|
root@ubuntu:/tmp/check# echo
"1"
>/tmp/svn/
1
root@ubuntu:/tmp/check# cat /tmp/svn/
1
1
|
3、然后先部署目录结构
1
2
3
4
5
6
7
8
9
10
|
root@ubuntu:/tmp/check# cap deploy:setup
*
2013
-
06
-
25
15
:
33
:
17
executing `deploy:setup'
* executing
"sudo -p 'sudo password: ' mkdir -p /tmp/result /tmp/result/releases /tmp/result/shared /tmp/result/shared/system /tmp/result/shared/log /tmp/result/shared/pids"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
997ms
* executing
"sudo -p 'sudo password: ' chmod g+w /tmp/result /tmp/result/releases /tmp/result/shared /tmp/result/shared/system /tmp/result/shared/log /tmp/result/shared/pids"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
45ms
|
查看/tmp/result目录里内容
1
2
3
4
5
6
|
root@ubuntu:/tmp/check# ll /tmp/result/
total
16
drwxrwxr-x
4
root root
4096
Jun
25
15
:
33
./
drwxrwxrwt
17
root root
4096
Jun
25
15
:
17
../
drwxrwxr-x
2
root root
4096
Jun
25
15
:
33
releases/
drwxrwxr-x
5
root root
4096
Jun
25
15
:
33
shared/
|
4、然后进行更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
root@ubuntu:/tmp/check# cap deploy:update
*
2013
-
06
-
25
15
:
35
:
01
executing `deploy:update'
** transaction: start
*
2013
-
06
-
25
15
:
35
:
01
executing `deploy:update_code'
* executing
"cp -R /tmp/svn /tmp/result/releases/20130625073501 && (echo > /tmp/result/releases/20130625073501/REVISION)"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
945ms
*
2013
-
06
-
25
15
:
35
:
02
executing `deploy:finalize_update'
* executing
"chmod -R -- g+w /tmp/result/releases/20130625073501 && rm -rf -- /tmp/result/releases/20130625073501/public/system && mkdir -p -- /tmp/result/releases/20130625073501/public/ && ln -s -- /tmp/result/shared/system /tmp/result/releases/20130625073501/public/system && rm -rf -- /tmp/result/releases/20130625073501/log && ln -s -- /tmp/result/shared/log /tmp/result/releases/20130625073501/log && rm -rf -- /tmp/result/releases/20130625073501/tmp/pids && mkdir -p -- /tmp/result/releases/20130625073501/tmp/ && ln -s -- /tmp/result/shared/pids /tmp/result/releases/20130625073501/tmp/pids"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
36ms
*
2013
-
06
-
25
15
:
35
:
02
executing `deploy:create_symlink'
* executing
"sudo -p 'sudo password: ' rm -f /tmp/result/current && sudo -p 'sudo password: ' ln -s /tmp/result/releases/20130625073501 /tmp/result/current"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
49ms
** transaction: commit
|
然后在查看更新情况
1
2
3
4
5
6
7
|
root@ubuntu:/tmp/check# ll /tmp/result/
total
16
drwxrwxr-x
4
root root
4096
Jun
25
15
:
35
./
drwxrwxrwt
17
root root
4096
Jun
25
15
:
17
../
lrwxrwxrwx
1
root root
35
Jun
25
15
:
35
current -> /tmp/result/releases/
20130625073501
/
drwxrwxr-x
3
root root
4096
Jun
25
15
:
35
releases/
drwxrwxr-x
5
root root
4096
Jun
25
15
:
34
shared/
|
可以看到已经有了一个current指向正确的版本了,然后看看里面都有什么内容
1
2
|
root@ubuntu:/tmp/check# cat /tmp/result/current/
1
1
|
可以看到已经有我之前追加到/tmp/svn/1里的内容了
5、再/tmp/svn/1里添加一个内容为2,需要覆盖修改
1
2
3
|
root@ubuntu:/tmp/result/current# echo
"2"
>/tmp/svn/
1
root@ubuntu:/tmp/result/current# cat /tmp/svn/
1
2
|
6、然后在更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
root@ubuntu:/tmp/check# cap deploy:update
*
2013
-
06
-
25
15
:
36
:
28
executing `deploy:update'
** transaction: start
*
2013
-
06
-
25
15
:
36
:
28
executing `deploy:update_code'
* executing
"cp -R /tmp/svn /tmp/result/releases/20130625073628 && (echo > /tmp/result/releases/20130625073628/REVISION)"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
1251ms
*
2013
-
06
-
25
15
:
36
:
29
executing `deploy:finalize_update'
* executing
"chmod -R -- g+w /tmp/result/releases/20130625073628 && rm -rf -- /tmp/result/releases/20130625073628/public/system && mkdir -p -- /tmp/result/releases/20130625073628/public/ && ln -s -- /tmp/result/shared/system /tmp/result/releases/20130625073628/public/system && rm -rf -- /tmp/result/releases/20130625073628/log && ln -s -- /tmp/result/shared/log /tmp/result/releases/20130625073628/log && rm -rf -- /tmp/result/releases/20130625073628/tmp/pids && mkdir -p -- /tmp/result/releases/20130625073628/tmp/ && ln -s -- /tmp/result/shared/pids /tmp/result/releases/20130625073628/tmp/pids"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
71ms
*
2013
-
06
-
25
15
:
36
:
30
executing `deploy:create_symlink'
* executing
"sudo -p 'sudo password: ' rm -f /tmp/result/current && sudo -p 'sudo password: ' ln -s /tmp/result/releases/20130625073628 /tmp/result/current"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
53ms
** transaction: commit
|
在查看一下/tmp/result里的最新版本里1的内容
1
2
|
root@ubuntu:/tmp/check# cat /tmp/result/current/
1
2
|
可以看到已经更新为2了
7、在继续对/tmp/svn/1里修改内容为3,覆盖修改(此步骤主要是想测试连续回滚的时候,恢复那个版本)
1
2
3
|
root@ubuntu:/tmp/check# echo
"3"
>/tmp/svn/
1
root@ubuntu:/tmp/check# cat /tmp/svn/
1
3
|
在继续更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
root@ubuntu:/tmp/check# cap deploy:update
*
2013
-
06
-
25
15
:
37
:
11
executing `deploy:update'
** transaction: start
*
2013
-
06
-
25
15
:
37
:
11
executing `deploy:update_code'
* executing
"cp -R /tmp/svn /tmp/result/releases/20130625073711 && (echo > /tmp/result/releases/20130625073711/REVISION)"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
890ms
*
2013
-
06
-
25
15
:
37
:
12
executing `deploy:finalize_update'
* executing
"chmod -R -- g+w /tmp/result/releases/20130625073711 && rm -rf -- /tmp/result/releases/20130625073711/public/system && mkdir -p -- /tmp/result/releases/20130625073711/public/ && ln -s -- /tmp/result/shared/system /tmp/result/releases/20130625073711/public/system && rm -rf -- /tmp/result/releases/20130625073711/log && ln -s -- /tmp/result/shared/log /tmp/result/releases/20130625073711/log && rm -rf -- /tmp/result/releases/20130625073711/tmp/pids && mkdir -p -- /tmp/result/releases/20130625073711/tmp/ && ln -s -- /tmp/result/shared/pids /tmp/result/releases/20130625073711/tmp/pids"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
42ms
*
2013
-
06
-
25
15
:
37
:
12
executing `deploy:create_symlink'
* executing
"sudo -p 'sudo password: ' rm -f /tmp/result/current && sudo -p 'sudo password: ' ln -s /tmp/result/releases/20130625073711 /tmp/result/current"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
56ms
** transaction: commit
|
查看结果
1
2
|
root@ubuntu:/tmp/check# cat /tmp/result/current/
1
3
|
也是正确的。
8、测试回滚
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
root@ubuntu:/tmp/check# cap deploy:rollback
*
2013
-
06
-
25
15
:
37
:
42
executing `deploy:rollback'
*
2013
-
06
-
25
15
:
37
:
42
executing `deploy:rollback:revision'
* executing
"sudo -p 'sudo password: ' ls -x /tmp/result/releases"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
980ms
* executing
"sudo -p 'sudo password: ' rm /tmp/result/current; sudo -p 'sudo password: ' ln -s /tmp/result/releases/20130625073628 /tmp/result/current"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
94ms
*
2013
-
06
-
25
15
:
37
:
43
executing `deploy:restart'
*
2013
-
06
-
25
15
:
37
:
43
executing `deploy:rollback:cleanup'
* executing
"if [ `readlink /tmp/result/current` != /tmp/result/releases/20130625073711 ]; then sudo -p 'sudo password: ' rm -rf /tmp/result/releases/20130625073711; fi"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
65ms
|
查看结果
1
2
|
root@ubuntu:/tmp/check# cat /tmp/result/current/
1
2
|
已经回滚到之前的版本
9、测试连续回滚
也就是说在回滚后继续回滚
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
root@ubuntu:/tmp/check# cap deploy:rollback
*
2013
-
06
-
25
15
:
38
:
09
executing `deploy:rollback'
*
2013
-
06
-
25
15
:
38
:
09
executing `deploy:rollback:revision'
* executing
"sudo -p 'sudo password: ' ls -x /tmp/result/releases"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
987ms
* executing
"sudo -p 'sudo password: ' rm /tmp/result/current; sudo -p 'sudo password: ' ln -s /tmp/result/releases/20130625073501 /tmp/result/current"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
49ms
*
2013
-
06
-
25
15
:
38
:
10
executing `deploy:restart'
*
2013
-
06
-
25
15
:
38
:
10
executing `deploy:rollback:cleanup'
* executing
"if [ `readlink /tmp/result/current` != /tmp/result/releases/20130625073628 ]; then sudo -p 'sudo password: ' rm -rf /tmp/result/releases/20130625073628; fi"
servers: [
"192.168.56.102"
]
[
192.168
.
56.102
] executing command
command finished
in
66ms
root@ubuntu:/tmp/check# cat /tmp/result/current/
1
1
|
可以从结果了解到,使用回滚的时候,默认都是按照更新的时间来回滚(比如你第一个更新为1,第二次更新为2,第三次更新为3的时候,想回滚,你只能使用rollback回滚到第二次,值为2的,不知直接回滚到第一次,值为1的,如果还想回滚到1,就在回滚一次,也就是在第3次,值为3的时候,连续回滚2次)
在深入一下,默认的回滚是到之前的版本,如果你想回滚到指定的版本,可以使用
cap -s previous_release=/tmp/result_svn/releases/20130627023154 deploy:rollback
其中previous_release为你在client里release的路径加上你想回滚的版本
八、总结
从上面的介绍与实例,大家可以很方便的理解capistrano的用途,可以配置crontab或者puppet实现自动化的部署更新代码,简化运维人员的工作量、减少部署错误、增加自己的时间。
九、namespace
在简单的讲一下namespace,就是同一个任务不同的规则,具体如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
root@server:~/capistrano# cat Capfile
namespace
:command
do
task :hostname, :hosts =>
"127.0.0.1"
do
run
"hostname"
end
task :ip, :hosts =>
"127.0.0.1"
do
run
"ifconfig"
end
end
root@server:~/capistrano# cap -vT
cap command:hostname #
cap command:ip #
cap invoke # Invoke a single command on the remote servers.
cap shell # Begin an interactive Capistrano session.
Extended help may be available
for
these tasks.
Type `cap -e taskname' to view it.
|
可以看到command任务有hostname与ip这2个不同的规则,下面分别运行一下看看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
root@server:~/capistrano# cap command:ip
*
2013
-
07
-
30
10
:
07
:
05
executing `command:ip'
* executing
"ifconfig"
servers: [
"127.0.0.1"
]
[
127.0
.
0.1
] executing command
** [out ::
127.0
.
0.1
] eth0 Link encap:Ethernet HWaddr
08
:
00
:
27
:
66
:7a:7a
** [out ::
127.0
.
0.1
] inet addr:
192.168
.
56.101
Bcast:
192.168
.
56.255
Mask:
255.255
.
255.0
** [out ::
127.0
.
0.1
] inet6 addr: fe80::a00:27ff:fe66:7a7a/
64
Scope:Link
** [out ::
127.0
.
0.1
] UP BROADCAST RUNNING MULTICAST MTU:
1500
Metric:
1
** [out ::
127.0
.
0.1
] RX packets:
2821
errors:
0
dropped:
0
overruns:
0
frame:
0
** [out ::
127.0
.
0.1
] TX packets:
1161
errors:
0
dropped:
0
overruns:
0
carrier:
0
** [out ::
127.0
.
0.1
] collisions:
0
txqueuelen:
1000
** [out ::
127.0
.
0.1
] RX bytes:
211437
(
211.4
KB) TX bytes:
183757
(
183.7
KB)
** [out ::
127.0
.
0.1
]
** [out ::
127.0
.
0.1
] eth1 Link encap:Ethernet HWaddr
08
:
00
:
27
:
29
:f6:9a
** [out ::
127.0
.
0.1
] inet6 addr: fe80::a00:27ff:fe29:f69a/
64
Scope:Link
** [out ::
127.0
.
0.1
] UP BROADCAST RUNNING MULTICAST MTU:
1500
Metric:
1
** [out ::
127.0
.
0.1
] RX packets:
28
errors:
0
dropped:
0
overruns:
0
frame:
0
** [out ::
127.0
.
0.1
] TX packets:
81
errors:
0
dropped:
0
overruns:
0
carrier:
0
** [out ::
127.0
.
0.1
] collisions:
0
txqueuelen:
1000
** [out ::
127.0
.
0.1
] RX bytes:
9576
(
9.5
KB) TX bytes:
26118
(
26.1
KB)
** [out ::
127.0
.
0.1
]
** [out ::
127.0
.
0.1
] lo Link encap:Local Loopback
** [out ::
127.0
.
0.1
] inet addr:
127.0
.
0.1
Mask:
255.0
.
0.0
** [out ::
127.0
.
0.1
] inet6 addr: ::
1
/
128
Scope:Host
** [out ::
127.0
.
0.1
] UP LOOPBACK RUNNING MTU:
16436
Metric:
1
** [out ::
127.0
.
0.1
] RX packets:
504
errors:
0
dropped:
0
overruns:
0
frame:
0
** [out ::
127.0
.
0.1
] TX packets:
504
errors:
0
dropped:
0
overruns:
0
carrier:
0
** [out ::
127.0
.
0.1
] collisions:
0
txqueuelen:
0
** [out ::
127.0
.
0.1
] RX bytes:
71762
(
71.7
KB) TX bytes:
71762
(
71.7
KB)
** [out ::
127.0
.
0.1
]
command finished
in
941ms
root@server:~/capistrano# cap command:hostname
*
2013
-
07
-
30
10
:
07
:
11
executing `command:hostname'
* executing
"hostname"
servers: [
"127.0.0.1"
]
[
127.0
.
0.1
] executing command
** [out ::
127.0
.
0.1
] server.hadoop.com
command finished
in
978ms
|
从结果可以看出namespace,就是把不同的规则都统一的挂到一个任务下。
在namespace里运行命令可以使用run与system,但这2个区别,可以从下面的结果看到
1
2
3
4
5
6
7
8
|
root@ubuntu:/tmp/caphub/test/config/deploy# cat ec2.rb
namespace
:world
do
task :hostname, :hosts =>
"192.168.56.101"
do
run
"hostname"
run
"ifconfig"
system(
"ifconfig"
)
end
end
|
运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
root@ubuntu:/tmp/caphub/test/config/deploy# cap ec2 world:hostname
triggering load callbacks
*
2013
-
07
-
30
11
:
59
:
23
11
:
59
:
23
== Currently executing `uptodate'
*
2013
-
07
-
30
11
:
59
:
23
11
:
59
:
23
== Currently executing `uptodate:git'
*
2013
-
07
-
30
11
:
59
:
23
11
:
59
:
23
== Currently executing `ec2'
triggering start callbacks
for
`world:hostname'
*
2013
-
07
-
30
11
:
59
:
23
11
:
59
:
23
== Currently executing `multiconfig:ensure'
*
2013
-
07
-
30
11
:
59
:
23
11
:
59
:
23
== Currently executing `world:hostname'
* executing
"hostname"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
** [out ::
192.168
.
56.101
] server.hadoop.com
command finished
in
975ms
* executing
"ifconfig"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
** [out ::
192.168
.
56.101
] eth0 Link encap:Ethernet HWaddr
08
:
00
:
27
:
66
:7a:7a
** [out ::
192.168
.
56.101
] inet addr:
192.168
.
56.101
Bcast:
192.168
.
56.255
Mask:
255.255
.
255.0
** [out ::
192.168
.
56.101
] inet6 addr: fe80::a00:27ff:fe66:7a7a/
64
Scope:Link
** [out ::
192.168
.
56.101
] UP BROADCAST RUNNING MULTICAST MTU:
1500
Metric:
1
** [out ::
192.168
.
56.101
] RX packets:
9888
errors:
0
dropped:
0
overruns:
0
frame:
0
** [out ::
192.168
.
56.101
] TX packets:
8763
errors:
0
dropped:
0
overruns:
0
carrier:
0
** [out ::
192.168
.
56.101
] collisions:
0
txqueuelen:
1000
** [out ::
192.168
.
56.101
] RX bytes:
830795
(
830.7
KB) TX bytes:
1496795
(
1.4
MB)
** [out ::
192.168
.
56.101
]
** [out ::
192.168
.
56.101
] eth1 Link encap:Ethernet HWaddr
08
:
00
:
27
:
29
:f6:9a
** [out ::
192.168
.
56.101
] inet addr:
192.168
.
8.229
Bcast:
192.168
.
8.255
Mask:
255.255
.
255.0
** [out ::
192.168
.
56.101
] inet6 addr: fe80::a00:27ff:fe29:f69a/
64
Scope:Link
** [out ::
192.168
.
56.101
] UP BROADCAST RUNNING MULTICAST MTU:
1500
Metric:
1
** [out ::
192.168
.
56.101
] RX packets:
94100
errors:
0
dropped:
0
overruns:
0
frame:
0
** [out ::
192.168
.
56.101
] TX packets:
18954
errors:
0
dropped:
0
overruns:
0
carrier:
0
** [out ::
192.168
.
56.101
] collisions:
0
txqueuelen:
1000
** [out ::
192.168
.
56.101
] RX bytes:
71655678
(
71.6
MB) TX bytes:
1413729
(
1.4
MB)
** [out ::
192.168
.
56.101
]
** [out ::
192.168
.
56.101
] lo Link encap:Local Loopback
** [out ::
192.168
.
56.101
] inet addr:
127.0
.
0.1
Mask:
255.0
.
0.0
** [out ::
192.168
.
56.101
] inet6 addr: ::
1
/
128
Scope:Host
** [out ::
192.168
.
56.101
] UP LOOPBACK RUNNING MTU:
16436
Metric:
1
** [out ::
192.168
.
56.101
] RX packets:
1355
errors:
0
dropped:
0
overruns:
0
frame:
0
** [out ::
192.168
.
56.101
] TX packets:
1355
errors:
0
dropped:
0
overruns:
0
carrier:
0
** [out ::
192.168
.
56.101
] collisions:
0
txqueuelen:
0
** [out ::
192.168
.
56.101
] RX bytes:
183369
(
183.3
KB) TX bytes:
183369
(
183.3
KB)
command finished
in
63ms
eth0 Link encap:Ethernet HWaddr
08
:
00
:
27
:dc:ff:
20
inet addr:
192.168
.
8.104
Bcast:
192.168
.
8.255
Mask:
255.255
.
255.0
inet6 addr: fe80::a00:27ff:fedc:ff20/
64
Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:
1500
Metric:
1
RX packets:
33300
errors:
0
dropped:
0
overruns:
0
frame:
0
TX packets:
535
errors:
0
dropped:
0
overruns:
0
carrier:
0
collisions:
0
txqueuelen:
1000
RX bytes:
3383618
(
3.3
MB) TX bytes:
106195
(
106.1
KB)
eth1 Link encap:Ethernet HWaddr
08
:
00
:
27
:af:1e:
13
inet addr:
192.168
.
56.102
Bcast:
192.168
.
56.255
Mask:
255.255
.
255.0
inet6 addr: fe80::a00:27ff:feaf:1e13/
64
Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:
1500
Metric:
1
RX packets:
10153
errors:
0
dropped:
0
overruns:
0
frame:
0
TX packets:
8767
errors:
0
dropped:
0
overruns:
0
carrier:
0
collisions:
0
txqueuelen:
1000
RX bytes:
935274
(
935.2
KB) TX bytes:
1437233
(
1.4
MB)
lo Link encap:Local Loopback
inet addr:
127.0
.
0.1
Mask:
255.0
.
0.0
inet6 addr: ::
1
/
128
Scope:Host
UP LOOPBACK RUNNING MTU:
16436
Metric:
1
RX packets:
440
errors:
0
dropped:
0
overruns:
0
frame:
0
TX packets:
440
errors:
0
dropped:
0
overruns:
0
carrier:
0
collisions:
0
txqueuelen:
0
RX bytes:
78000
(
78.0
KB) TX bytes:
78000
(
78.0
KB)
|
从上面可以看到使用system更符合我们的要求。
而且run不能调用 cap命令,比如使用run调用cap git deploy:check来进行git的检测
1
2
3
4
5
6
|
* executing
"cap git deploy:check"
servers: [
"192.168.56.101"
]
[
192.168
.
56.101
] executing command
*** [err ::
192.168
.
56.101
] sh:
1
: cap: not found
command finished
in
29ms
failed:
"sh -c 'cap git deploy:check'"
on
192.168
.
56.101
|
如果使用就会出现上面的结果,但使用system就没有问题。
本文转自 reinxu 51CTO博客,原文链接:http://blog.51cto.com/dl528888/1270670,如需转载请自行联系原作者