python加shell快速部署集群
时间:2015-05-02 22:06 来源:51cto.com 作者:admin
最近痛感在集群里逐台部署ganglia, cacti这些监控的东西很麻烦,就写了个小程序去批量自动部署。原理是通过python的pexpect用ssh去复制文件和执行系统命令,我用它来部署ganglia等,但是其他的东西也可以通过这个脚本来批量部署,只要自己编写部署脚本就可以了。主要是提出一个解决思路,看对大家是否有所帮助。
先约定一个概念,我们把放置python和脚本的服务器叫做主控节点或者server,把需要安装的节点叫做受控节点或者client。以下均以server和client代称。
首先是配置文件,我需要先定义一个配置文件,来约定server的一些路径,和client具体信息。
1
2
3
4
5
6
7
8
9
10
#-*-coding:UTF-8 -*-
log_dir
=
'./logs/'
#定义日志路径,不过我还没写,打算用log4py来做
client_tmp_dir
=
'/tmp/'
#定义client端存放脚本路径
ssh_port
=
'22'
#SSH端口
script_dir
=
'./shells/'
#server端脚本存放路径
node_list
=
[
{
'ip'
:
'192.168.1.1'
,
'user'
:
'root'
,
'passwd'
:
'123456'
,
'cmd'
:
'sh /tmp/dpkg_client_ubuntu_x.x86_64.sh'
},
#cmd为在client端执行的命令,别的不解释
{
'ip'
:
'192.168.1.2'
,
'user'
:
'root'
,
'passwd'
:
'123456'
,
'cmd'
:
'sh /tmp/dpkg_client_ubuntu_x.x86_64.sh'
},
]
接下来是主程序
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python
#-*-coding:UTF-8 -*-
import
os
import
sys
import
platform
#用import方式引入conf.py
import
conf
import
subprocess
'''
判断server(本机)操作系统类型和版本的类
'''
class
System:
def
GetBranch(
self
):
Branch
=
platform.dist()[
0
]
return
Branch
def
GetRelease(
self
):
Release
=
platform.dist()[
1
]
return
Release
def
GetInstaller(
self
):
if
self
.GetBranch()
in
[
'Ubuntu'
,
'debian'
]:
installer
=
'apt-get'
elif
self
.GetBranch()
in
[
'redhat'
,
'fedora'
,
'centos'
]:
installer
=
'yum'
elif
self
.GetBranch()
in
[
'SuSE'
]:
installer
=
'zypper'
else
:
installer
=
'unknown'
return
installer
'''
以操作系统版本为依据获取相应的pexpect包并尝试引入,因pexpect非默认操作系统安装,这部分支持RH,Ubuntu,Debian,SuSE
'''
try
:
import
pexpect
except
ImportError:
installer
=
System()
inst
=
install.GetInstaller()
if
(inst
=
=
'apt-get'
)
or
(inst
=
=
'zypper'
):
cmd
=
'%s install python-pexpect'
%
(inst)
elif
inst
=
=
'yum'
:
cmd
=
'$s install pexpect'
%
(inst)
else
:
cmd
=
'echo "Not support yet:)"'
;
try
:
fd
=
subprocess.Popen( cmd, shell
=
True
, stdin
=
subprocess.PIPE, stdout
=
subprocess.PIPE, stderr
=
subprocess.PIPE )
out
=
fd.stdout.readlines()
err
=
fd.stderr.readlines()
all
=
out
+
err
all
=
"".join(
all
)
except
OSError,e:
all
=
"Cannot run command, Exception:"
+
e
+
os.linesep
import
pexpect
#print all
'''
pexpect执行类,分两个方法,ssh和scp,自动判断是否首次连接,并自动完成yes或输入密码的应答。
'''
class
Expect:
#定义ssh方法,入口变量包括ip, port,username,password,执行命令
def
ssh(
self
, ip, port, user, passwd, cmd):
#创建连接子进程对象
ssh
=
pexpect.spawn(
'ssh -p %s %s@%s "%s"'
%
(port, user, ip, cmd))
r
=
''
try
:
#判断是否首次连接,如果是首次,则回答yes并输入密码,否则直接输入密码
i
=
ssh.expect([
'password:'
,
'continue connecting (yes/no)?'
], timeout
=
5
)
if
i
=
=
0
:
ssh.sendline(passwd)
elif
i
=
=
1
:
ssh.sendline(
'yes'
)
ssh.expect(
'password:'
)
ssh.sendline(passwd)
except
pexpect.EOF:
ssh.close()
else
:
r
=
ssh.read()
ssh.expect(pexpect.EOF)
ssh.close()
return
r
#定义scp方法,入口变量包括ip,port,username,password,需要复制到client的文件名,复制到client的路径
def
scp(
self
, ip, port, user, passwd, srcfile
=
"index.html"
, distpath):
#创建连接子进程对象
ssh
=
pexpect.spawn(
'scp -P %s %s %s@%s:%s '
%
(port,
file
, user, ip, distpath))
r
=
''
try
:
#判断是否首次连接,如果是首次,则回答yes并输入密码,否则直接输入密码
i
=
ssh.expect([
'password:'
,
'continue connecting (yes/no)?'
], timeout
=
5
)
if
i
=
=
0
:
ssh.sendline(passwd)
elif
i
=
=
1
:
ssh.senline(
'yes'
)
ssh.expect(
'password:'
)
ssh.sendline(passwd)
except
pexpect.EOF:
ssh.close()
else
:
r
=
ssh.read()
ssh.expect(pexpect.EOF)
ssh.close()
return
r
#创建conf中的对象,只是为了写起来方便。不创建直接用也行
packages
=
conf.package_dir
logs
=
conf.log_dir
c_tmp
=
conf.client_tmp_dir
port
=
conf.ssh_port
scripts
=
conf.script_dir
nodes
=
conf.node_list
expect
=
Expect()
#在本机执行server端脚本。该脚本会安装Ganglia gmetad,gmond,cacti,nagios,gangliaweb,mysql,apache等等
os.system(
"sh "
+
scripts
+
"dpkg_server_ubuntu_x.x86_64.sh"
)
#循环列出conf的列表中配置的主机,用户名,密码,执行命令
for
i
in
range
(
len
(nodes)):
ip
=
nodes[i][
'ip'
]
user
=
nodes[i][
'user'
]
passwd
=
nodes[i][
'passwd'
]
cmd
=
nodes[i][
'cmd'
]
#将本机的client执行脚本复制到client端的conf.py中定义的路径client_tmp_dir
r
=
expect.scp(ip, port, user, passwd, scripts
+
'dpkg_client_ubuntu_x.x86_64.sh'
, c_tmp)
print
r
#在client端执行刚复制过去的脚本,脚本中包含gmond,nagios-client,snmpd等等
r
=
expect.ssh(ip, port, user, passwd, cmd)
print
r
我还没写按自动判断client端操作系统安装不同脚本的逻辑,有兴趣的可以自己改改,其实本身脚本并不难,核心都是在pexpect,我主要是不想用puppet,不想用puppet的主要原因是不想学ruby和他那复杂的配置文件。不光是部署监控,自己写shell脚本,随便部署什么都可以。nginx,php,反正能用脚本完成的事都可以干。
(责任编辑:IT)
最近痛感在集群里逐台部署ganglia, cacti这些监控的东西很麻烦,就写了个小程序去批量自动部署。原理是通过python的pexpect用ssh去复制文件和执行系统命令,我用它来部署ganglia等,但是其他的东西也可以通过这个脚本来批量部署,只要自己编写部署脚本就可以了。主要是提出一个解决思路,看对大家是否有所帮助。
先约定一个概念,我们把放置python和脚本的服务器叫做主控节点或者server,把需要安装的节点叫做受控节点或者client。以下均以server和client代称。
首先是配置文件,我需要先定义一个配置文件,来约定server的一些路径,和client具体信息。
接下来是主程序
我还没写按自动判断client端操作系统安装不同脚本的逻辑,有兴趣的可以自己改改,其实本身脚本并不难,核心都是在pexpect,我主要是不想用puppet,不想用puppet的主要原因是不想学ruby和他那复杂的配置文件。不光是部署监控,自己写shell脚本,随便部署什么都可以。nginx,php,反正能用脚本完成的事都可以干。 (责任编辑:IT) |