多线程自动化运维linux的尝试
自动化操作多主机,省时,省力
动力:
日常工作对各个服务器的操作都是一样的,免不了重复工作.
思路:
1.通过一个管道向所有服务器发出同样指令并查看处理结果
2.利用多线程减少处理时间
构思:
1. 创建主机清单和命令清单
2.通过paramiko 登录到目标服务器,借助线程实现并发处理,
3.并且结果输入到日志文件.
问题: 如何批量在在不同的主机处理不同的命令
以下是清单及代码
1. 系统主机清单 文件:vmhost
host1
host2
host3
host4
host5
host6
host7
host8
host9
2. 批处理任务清单 文件: command.txt
hostname -f date uname cat /etc/security/limits.conf|grep -v ^#|grep -v ^$ cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$ cat /etc/sysctl.conf|grep -v ^#|grep -v ^$ rpm -ivh /mnt/hgfs/RPM/compat-libcap1-1.10-7.el7.x86_64.rpm rpm -ivh /mnt/hgfs/RPM/ksh-20120801-139.el7.x86_64.rpm rpm -ivh /mnt/hgfs/RPM/libaio-devel-0.3.109-13.el7.x86_64.rpm rpm -ivh /mnt/hgfs/RPM/compat-libstdc++-33-3.2.3-72.el7.x86_64.rpm
3. 多线程并发执行
前提:有统一的系统管理员密码
import paramiko import threading import sys import time import logging import getpass hostname="" def hostnamelist(): """ :return: hostname list """ global result,hosttoal try: hosts = open("vmhost", "r", encoding='utf-8') hostnames = hosts.readlines() hosts.seek(0) hosttoal = len(open("vmhost", "r", encoding='utf-8').readlines()) print("There are %d target host " % (hosttoal)) hosts.close() return hostnames except (FileNotFoundError,LookupError,UnicodeDecodeError) as e: print('can't open file reason is !',e) finally: if hosts: hosts.close() class Remoteserver(object): """ Container class for SSH functionality. Needs to be used in a with statement. """ def __init__(self): ssh_client = None user = None password = None self.ssh_client = paramiko.SSHClient() self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) def __setattr__(self, key, value): self.__dict__[key]=value def __exit__(self, exc_type, exc_val, exc_tb): try: if self.ssh_client is not None: logging.warning('will exit remote server %s' %(self.server)) self.ssh_client.close() except: print ("received an exception closing the ssh connection.") finally: self.ssh_client = None def connect(self, server, user, password,port=22): try: print("connect to server %s "%(server)) self.ssh_client.connect(server, 22,self.user, self.password) print("connect to server %s Successfully" % (server)) except paramiko.AuthenticationException: print ("you entered an incorrect username or password. Please try again") logging.warning('username or password error') try: self.ssh_client.connect(server,22, username=self.user, password=self.password) except: print ("you entered an incorrect username or password a second time. Exiting") sys.exit(1) except: logging.warning('connect to remote server %s failed' %(self.server)) print("Unexpected error:", sys.exc_info()[0]) now = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) with open(self.server + "_" + now + "ERROR.txt", "w+", encoding="utf+8") as output: print("result is write to log file %s_%sERROR.txt" % (self.server, now)) output.write("fail to login remote server %s"%(self.server)) exit() def execute(self, command, sudo=False): self.connect(self.server, self.user, self.password) out='' out = out + ("------------------------Start on %s -------------------------------\n\n" % (self.server)) for m in command: m=m.strip("\n") now = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) out=out+m+" :\t" try: print("Start execute command %s in %s at %s " %(m,self.server,now)) stdin, stdout, stderr = self.ssh_client.exec_command(m) out = out + "\n\n" + str(stdout.read().decode(encoding='utf-8')) + "\n" except paramiko.SSHException: out = out + "\n\n"+ str(stderr.read().decode(encoding='utf-8'))+"\n" out = out + ('%s\t\tOK\n' % (targethost)) out = out + ("----------------------End of server %s------------------------------\n\n" % (self.server)) if sudo: stdin.write(self.password + '\n') stdin.flush() with open(self.server+"_"+now+"SUCCESS.txt","w+",encoding="utf+8") as output: print("result is write to log file %s_%sSUCCESS.txt" %(self.server,now)) output.write(out) logging.info('will exit remote server %s' % (self.server)) print('will exit remote server %s' % (self.server)) self.ssh_client.close() if __name__ == '__main__': cmd="" with open("command.txt",'r',encoding='utf-8') as batch: command = batch.readlines() username = input("Please Input Username :") # 用户名 password = getpass.getpass('please type password of %s :' %username) print("........................................Batch Process Begin........................................") for targethost in hostnamelist(): targethost=targethost.strip("\n") sshhost=Remoteserver() sshhost.server=targethost sshhost.port=22 sshhost.user=username sshhost.password=password start_Batch = threading.Thread(sshhost.execute(command=command)) start_Batch.start() print("........................................Batch Process End........................................")
执行结果如下:
Please Input Username :root Input user root's password:XXXXXXX ........................................Batch Process Begin........................................ There are 5 target host connect to server host1 connect to server host1 Successfully Start execute command hostname -f in host1 at 20191201193114 Start execute command date in host1 at 20191201193114 Start execute command uname in host1 at 20191201193114 Start execute command cat /etc/security/limits.conf|grep -v ^#|grep -v ^$ in host1 at 20191201193114 Start execute command cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$ in host1 at 20191201193114 Start execute command cat /etc/sysctl.conf|grep -v ^#|grep -v ^$ in host1 at 20191201193114 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libcap1-1.10-7.el7.x86_64.rpm in host1 at 20191201193114 Start execute command rpm -ivh /mnt/hgfs/RPM/ksh-20120801-139.el7.x86_64.rpm in host1 at 20191201193114 Start execute command rpm -ivh /mnt/hgfs/RPM/libaio-devel-0.3.109-13.el7.x86_64.rpm in host1 at 20191201193114 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libstdc++-33-3.2.3-72.el7.x86_64.rpm in host1 at 20191201193114 result is write to log file host1_20191201193114SUCCESS.txt will exit remote server host1 connect to server host2 connect to server host2 Successfully Start execute command hostname -f in host2 at 20191201193114 Start execute command date in host2 at 20191201193115 Start execute command uname in host2 at 20191201193115 Start execute command cat /etc/security/limits.conf|grep -v ^#|grep -v ^$ in host2 at 20191201193115 Start execute command cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$ in host2 at 20191201193115 Start execute command cat /etc/sysctl.conf|grep -v ^#|grep -v ^$ in host2 at 20191201193115 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libcap1-1.10-7.el7.x86_64.rpm in host2 at 20191201193115 Start execute command rpm -ivh /mnt/hgfs/RPM/ksh-20120801-139.el7.x86_64.rpm in host2 at 20191201193115 Start execute command rpm -ivh /mnt/hgfs/RPM/libaio-devel-0.3.109-13.el7.x86_64.rpm in host2 at 20191201193115 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libstdc++-33-3.2.3-72.el7.x86_64.rpm in host2 at 20191201193115 result is write to log file host2_20191201193115SUCCESS.txt will exit remote server host2 connect to server host3 connect to server host3 Successfully Start execute command hostname -f in host3 at 20191201193115 Start execute command date in host3 at 20191201193115 Start execute command uname in host3 at 20191201193115 Start execute command cat /etc/security/limits.conf|grep -v ^#|grep -v ^$ in host3 at 20191201193116 Start execute command cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$ in host3 at 20191201193116 Start execute command cat /etc/sysctl.conf|grep -v ^#|grep -v ^$ in host3 at 20191201193116 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libcap1-1.10-7.el7.x86_64.rpm in host3 at 20191201193116 Start execute command rpm -ivh /mnt/hgfs/RPM/ksh-20120801-139.el7.x86_64.rpm in host3 at 20191201193116 Start execute command rpm -ivh /mnt/hgfs/RPM/libaio-devel-0.3.109-13.el7.x86_64.rpm in host3 at 20191201193116 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libstdc++-33-3.2.3-72.el7.x86_64.rpm in host3 at 20191201193116 result is write to log file host3_20191201193116SUCCESS.txt will exit remote server host3 connect to server host4 connect to server host4 Successfully Start execute command hostname -f in host4 at 20191201193116 Start execute command date in host4 at 20191201193116 Start execute command uname in host4 at 20191201193116 Start execute command cat /etc/security/limits.conf|grep -v ^#|grep -v ^$ in host4 at 20191201193116 Start execute command cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$ in host4 at 20191201193117 Start execute command cat /etc/sysctl.conf|grep -v ^#|grep -v ^$ in host4 at 20191201193117 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libcap1-1.10-7.el7.x86_64.rpm in host4 at 20191201193117 Start execute command rpm -ivh /mnt/hgfs/RPM/ksh-20120801-139.el7.x86_64.rpm in host4 at 20191201193117 Start execute command rpm -ivh /mnt/hgfs/RPM/libaio-devel-0.3.109-13.el7.x86_64.rpm in host4 at 20191201193117 Start execute command rpm -ivh /mnt/hgfs/RPM/compat-libstdc++-33-3.2.3-72.el7.x86_64.rpm in host4 at 20191201193117 result is write to log file host4_20191201193117SUCCESS.txt will exit remote server host4 connect to server host5 Unexpected error: <class 'socket.gaierror'> WARNING:root:connect to remote server host5 failed result is write to log file host5_20191201193118ERROR.txt Process finished with exit code 0
输出文件日志:
host1_20191201074036SUCCESS.txt
host2_20191201074037ERROR.txt
host3_20191201074036SUCCESS.txt
host4_20191201074037SUCCESS.txt
host5_20191201074037SUCCESS.txt
日志内容:
------------------------Start on host1 ------------------------------- hostname -f : host1 date : Sun Dec 1 19:31:14 CST 2019 uname : Linux cat /etc/security/limits.conf|grep -v ^#|grep -v ^$ : * soft core 65536 * hard rss 65536 * hard nproc 65536 * soft nproc 65536 oradu8 soft nproc 65536 oradu8 hard nproc 65536 oradu8 soft nofile 65536 oradu8 hard nofile 65536 oradu8 soft stack 65536 oradu8 hard stack 32768 oradu8 hard memlock 8000000 oradu8 soft memlock 8000000 oracle soft nproc 65536 oracle hard nproc 65536 oracle soft nofile 65536 oracle hard nofile 65536 oracle soft stack 65536 oracle hard stack 32768 oracle hard memlock 8000000 oracle soft memlock 8000000 @sapsys hard nofile 32800 @sapsys soft nofile 32800 @dba hard nofile 32800 @dba soft nofile 32800 cat /etc/security/limits.d/20-nproc.conf |grep -v ^#|grep -v ^$ : * soft nproc unlimited root soft nproc unlimited cat /etc/sysctl.conf|grep -v ^#|grep -v ^$ : fs.aio-max-nr = 1048576 fs.file-max = 6815744 kernel.sem = 250 32000 100 128 net.ipv4.ip_local_port_range = 9000 65500 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 1048586 kernel.msgmni=1024 kernel.panic_on_oops = 1 kernel.sem = 1250 256000 100 1024 kernel.shmmax = 214748364800 kernel.shmall = 52428800 kernel.shmmni = 4096 vm.nr_hugepages = 2500 vm.max_map_count=2000000 rpm -ivh /mnt/hgfs/RPM/compat-libcap1-1.10-7.el7.x86_64.rpm : Preparing... ######################################## rpm -ivh /mnt/hgfs/RPM/ksh-20120801-139.el7.x86_64.rpm : Preparing... ######################################## rpm -ivh /mnt/hgfs/RPM/libaio-devel-0.3.109-13.el7.x86_64.rpm : Preparing... ######################################## rpm -ivh /mnt/hgfs/RPM/compat-libstdc++-33-3.2.3-72.el7.x86_64.rpm : Preparing... ######################################## host1 OK ----------------------End of server host1------------------------------
每天进步一点点,多思考,多总结
版权声明:本文为CNblog博主「zaituzhong」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。