有很多開源的批量部署的工具可以使用,比如puppet, ansible , saltstack , chef 。
但這些工具都有自己的一套語法規則,你得按照他的語法來編寫程序,然後批量執行。
那有沒有方法可以直接寫bash 或者Python腳本,然後批量執行呢?
方法當然是有的,需要自己寫程序來傳輸腳本,拷貝文件,再複雜點,可以自定義腳本式同步還是異步執行,自定義要執行的主機組,等等,需要根據自己的業務需要來想。
這裏只是拋磚引玉,我採用建立socket(TCP)連接來批量執行腳本。
服務端腳本,cat server.py
#!/usr/bin/env python
# This script is used to as server , which could transfer script to agents , copy files to agents
import os
import socket
import threading
HostList = {
'10.1.214.10':10001,
'10.1.214.105':10001,
'10.1.214.106':10001
}
class LoadScript(object):
def __init__(self):
pass
def get_input(self):
input_str = raw_input('Please input the script(Absolute Path ) :')
return input_str
def check_input(self):
while 1:
input_str = self.get_input()
if input_str is None or os.path.isfile(input_str) is False:
print "Wrong Path for script!\n"
else:
print "Your script is %s" % input_str
return input_str
def read_script(self):
script = self.check_input()
try:
f = open(script, 'r')
content = f.readlines()
content_str = ''.join(content)
return content_str
except:
print "Open script %s Error!" % script
sys.exit(1)
class SocketServer(object):
def __init__(self, host, port):
self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
self.host = host
self.port = port
def connect(self):
self.sock.connect((self.host, self.port))
def send(self, content):
#content = LoadScript().read_script()
print "content:", content
self.sock.send(content)
def receive(self):
result = self.sock.recv(10000)
print result
def close(self):
self.sock.close()
def run(self, content):
self.connect()
self.send(content)
self.receive()
self.close()
content = LoadScript().read_script()
print content
for key in HostList.keys():
server = SocketServer(key, HostList[key])
t = threading.Thread(target = server.run, args = (str(content)))
t.start()
客戶端腳本,cat agent.py
#!/usr/bin/env python
# This script is used to as server , which could transfer script to agents , copy files to agents
import socket
import subprocess
import os
class SocketAgent(object):
def __init__(self, port):
self.port = port;
self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
self.sock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
self.sock.bind( ("", port) )
self.sock.listen( 5 )
def listen(self):
pass
def receive(self):
self.clisock, (remote_host, remote_port) = self.sock.accept()
content = self.clisock.recv(10000)
#clisock.close()
return content
def set_file(self, file = "/var/tmp/script"):
return file
def convert_to_script(self):
content = self.receive()
script = self.set_file()
f = open(script, 'w')
f.write("#!/usr/bin/bash\n" + content + "\n")
f.close()
def execute(self):
script = self.set_file()
cmd = 'bash %s' % str(script)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
out, err = p.communicate()
print "output:", out
print "err:", err
return err
def response(self):
if self.execute() is None:
self.clisock.send("Script run successfully")
else:
self.clisock.send("Script run failed")
agent = SocketAgent(10001)
agent.convert_to_script()
agent.execute()
agent.response()
先運行客戶端腳本,在執行服務端腳本,在服務端指定要執行的腳本。
考慮到用建立socket連接的方法不是很方便,後續會考慮改成其他協議,比如ftp等。
若大家有什麼想法,歡迎隨時留言溝通。