[root@ceph-01 infra]# python3.6 -m venv /opt/python3.6/ve [root@ceph-01 infra]# source /opt/python3.6/ve/bin/activate (ve) [root@ceph-01 infra]# [root@ceph-01 ~]# echo "source /opt/python3.6/ve/bin/activate" >>/etc/profile [root@ceph-01 ~]# source /etc/profile (ve) [root@ceph-01 ~]#安装paramiko模块
(ve) [root@ceph-01 infra]# pip install -U pip
Cache entry deserialization failed, entry ignored
Collecting pip
Using cached https://files.pythonhosted.org/packages/90/a9/1ea3a69a51dcc679724e3512fc2aa1668999eed59976f749134eb02229c8/pip-21.3-py3-none-any.whl
Installing collected packages: pip
Found existing installation: pip 9.0.3
Uninstalling pip-9.0.3:
Successfully uninstalled pip-9.0.3
Successfully installed pip-21.3
(ve) [root@ceph-01 infra]# pip install -U paramiko
Collecting paramiko
Using cached paramiko-2.8.0-py2.py3-none-any.whl (206 kB)
Collecting pynacl>=1.0.1
Using cached PyNaCl-1.4.0-cp35-abi3-manylinux1_x86_64.whl (961 kB)
Collecting bcrypt>=3.1.3
Using cached bcrypt-3.2.0-cp36-abi3-manylinux2010_x86_64.whl (63 kB)
Collecting cryptography>=2.5
Using cached cryptography-35.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.7 MB)
Collecting six>=1.4.1
Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting cffi>=1.1
Downloading cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (405 kB)
|████████████████████████████████| 405 kB 241 kB/s
Collecting pycparser
Using cached pycparser-2.20-py2.py3-none-any.whl (112 kB)
Installing collected packages: pycparser, six, cffi, pynacl, cryptography, bcrypt, paramiko
Successfully installed bcrypt-3.2.0 cffi-1.15.0 cryptography-35.0.0 paramiko-2.8.0 pycparser-2.20 pynacl-1.4.0 six-1.16.0
代码
通过python结合shell判断远程主机上运行的docker容器
[root@ceph-01 infra]# cat docker_name.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
#import commands
import subprocess
import socket
import fcntl
import struct
CMD_HOSTS=''
CMD_HOST_NAME = 'hostname'
CMD_CONTAINER_NAME = 'docker ps --format "{{.Names}}"'
DICT={}
def get_container_name(CMD):
#return_code, output = commands.getstatusoutput(CMD)
return_code, output = subprocess.getstatusoutput(CMD)
container_list = output.split('n')
return container_list
def main():
docker_name = get_container_name(CMD_CONTAINER_NAME)
host_name = get_container_name(CMD_HOST_NAME)
#rel_netcard = [{item:get_ip_address(item)} for item in all_netcard_name if item not in vir_netcard_name]
#vir_netcard = [{item:get_ip_address(item)} for item in all_netcard_name if item in vir_netcard_name]
docker_name_str=','.join(docker_name)
host_name_str=''.join(host_name)
DICT[host_name_str]=docker_name_str
#print(docker_name)
#print(host_name)
print(DICT)
if __name__ == '__main__':
HOSTS=['ceph-01','ceph-02']
for i in HOSTS:
DICT={}
CMD_HOST_NAME = 'ssh %s hostname' %i
CMD_CONTAINER_NAME = 'ssh %s docker ps --format "{{.Names}}"' %i
main()
运行结果
(ve) [root@ceph-01 infra]# python docker_name.py
{'ceph-01': 'registry,redis-6379,redis-6380,redis-6381'}
{'ceph-02': 'redis-6380,redis-6379'}
自动填充配置
[root@ceph-01 infra]# cat auto_set_hosts.py
#!/usr/bin/env python
import configparser
service=['es','web','es2mysql','zs_power','bind','mysql','redis','zookeeper','kafka','ogg','mm2','jdbc_connect','hive_connect','kstream','zy','binary','connect','all_node','all_node_vars','all_vars']
hosts={'node64':'192.168.80.67','node65':'192.168.80.68','node66':'192.168.80.69'}
conf = configparser.ConfigParser()
conf.read(r'hosts',encoding='utf-8')
for host,ip in zip(hosts.keys(),hosts.values()):
print(host,ip)
for i in service:
#conf.set("code", "code", "6666") # 修改指定section 的option
#conf.set("code", "age", "123") # 增加指定section 的option
#conf.has_section("code")
#conf.has_option("code","age")
#conf.remove_section("test")
#conf.remove_option("test","haha")
if i not in conf.sections():
conf.add_section(i) # 增加section
conf.set(i, host, ip) # 给新增的section 写入option
file = open(r'hosts', 'w',encoding='utf-8')
conf.write(file)
file.close()
(ve) [root@ceph-01 infra]# python auto_set_hosts.py node64 192.168.80.67 node65 192.168.80.68 node66 192.168.80.69比较配置文件
[root@ceph-01 infra]# cat auto_read_hosts.py
#!/usr/bin/env python
import configparser
conf1 = configparser.ConfigParser()
conf1.read(r'hosts',encoding='utf-8')
conf2 = configparser.ConfigParser()
conf2.read(r'hosts2',encoding='utf-8')
sec1=conf1.sections()
sec2=conf2.sections()
diffsec1=[x for x in sec1 if x not in sec2]
diffsec2=[y for y in sec2 if y not in sec1]
if diffsec1:
print("hosts文件中存在sec %s,而hosts2中没有" % diffsec1)
else:
print("none")
if diffsec2:
print("hosts2文件中存在sec %s,而hosts中没有" % diffsec2)
else:
print("none")
#print(type(diffsec1))
#print(sec)
for i in sec2:
if i not in diffsec2:
host1=conf1.options(i)
value1=conf1.items(i)
host2=conf2.options(i)
diffhost1=[x for x in host1 if x not in host2]
diffhost2=[y for y in host2 if y not in host1]
if diffhost1:
print("hosts的 %s 存在 %s,而host2的 %s 没有"%(i,diffhost1,i))
#else:
# print("hosts的 %s 和 hosts2的 %s相同" %(i,i))
if diffhost2:
print("hosts2的 %s 存在 %s,而host的 %s 没有"%(i,diffhost2,i))
#else:
# print("hosts2的 %s 和 hosts的 %s相同" % (i,i))
#print("sec %s include %s" %(i,host1))
#print("sec %s dict %s" % (i,value1))
if i == "all:vars":
value1=dict(conf1.items(i))
value2=dict(conf2.items(i))
differ=set(value1.items()) ^ set(value2.items())
diffkey=set(value1.keys() ^ value2.keys())
diffkey2=set(value1.keys() - value2.keys())
diffkey3=set(value2.keys() - value1.keys())
#print(type(differ))
if diffkey:
print("hosts文件中和host2文件all:vars部分不共有的key为 %s" % diffkey)
else:
print("none")
if diffkey2:
print("hosts文件all:vars部分存在而host2文件all:vars部分不存在的key %s" % diffkey2)
else:
print("none")
if diffkey3:
print("hosts2文件all:vars部分存在而host文件all:vars部分不存在的key %s" % diffkey3)
else:
print("none")
def checkredis():
redis_num=len(conf2.options("redis"))
all_vars2=dict(conf2.items("all:vars"))
ha_redis=all_vars2["ha_redis"]
vip_redis=all_vars2["vip_redis"]
# print(type(vip_redis))
if redis_num == 2 and ha_redis == "1" and len(vip_redis) > 0:
print("redis配置正确")
def checkmysql():
mysql_num=len(conf2.options("mysql"))
all_vars2=dict(conf2.items("all:vars"))
slave_node=all_vars2["slave_node"]
if mysql_num == 2 and len(slave_node) > 0:
print("mysql高可用配置正确")
if mysql_num == 1 and len(slave_node) == 0:
print("mysql单点配置正确")
def checkogg():
ogg_num=len(conf2.options("ogg"))
ogg=conf2.items("ogg")
for i in ogg:
lst=list(i)
#str="".join(tuple(i))
print(lst)
#print(str)
#checkredis()
#checkmysql()
#checkogg()
运行结果
(ve) [root@ceph-01 infra]# cat hosts [mysql] ip=10.0.0.2 [es] ip=10.0.0.3 (ve) [root@ceph-01 infra]# cat hosts2 [openstack] ip=10.0.0.2 [es] ip=10.0.0.3 (ve) [root@ceph-01 infra]# python auto_read_hosts.py hosts文件中存在sec ['mysql'],而hosts2中没有 hosts2文件中存在sec ['openstack'],而hosts中没有python结合shell检测远程主机服务是否运行
判断核心逻辑:
1、如果对应的服务的配置文件存在且不为空就断定该服务在运行
[root@ceph-01 infra]# cat check_container.py
#!/usr/bin/env python3
import os
import subprocess
import paramiko
client=paramiko.SSHClient()
client.load_system_host_keys()
client.connect("10.0.0.3",username="root",password="word")
_,stdout,_=client.exec_command("[ -f /tmp ] && echo OK")
print(stdout.read())
client.close()
CMD_HOST_NAME = 'hostname'
def get_host_name(CMD):
#return_code, output = commands.getstatusoutput(CMD)
return_code, output = subprocess.getstatusoutput(CMD)
host_list = output.split('n')
return host_list
basedir="/home/zshield"
c_dict={'kstream':'%s/conf/kstream'% basedir,'mysql':'%s/conf/database' % basedir}
run_svc=[]
DICT={}
class Check:
def __init__(self,svc,dir):
self.svc=svc
self.dir=dir
def check_container(self):
empty_dir=[]
no_empty_dir=[]
if os.path.exists(self.dir):
if not os.listdir(dir):
#print("目录 %s 为空" % dir)
empty_dir.append(self.dir)
else:
#print("目录 %s 不为空" % dir)
no_empty_dir.append(self.dir)
else:
#print("目录 %s 不存在" % dir)
empty_dir.append(self.dir)
if self.dir in empty_dir:
print("服务%s未运行" % self.svc)
elif self.dir in no_empty_dir:
#print("服务%s运行" % self.svc)
run_svc.append(self.svc)
#print(run_svc)
host_name = get_host_name(CMD_HOST_NAME)
run_svc_str=''.join(str(run_svc))
host_name_str=''.join(host_name)
DICT[host_name_str]=run_svc_str
#print(docker_name)
#print(host_name)
#print(DICT)
for svc,dir in c_dict.items():
check=Check(svc,dir)
check.check_container()
print(DICT)
判断节点服务运行情况脚本
(ve) [root@ceph-01 infra]# cat check_container.py
#!/usr/bin/env python
import os
import subprocess
import paramiko
import configparser
file='/file/infra/check.ini'
conf = configparser.ConfigParser()
conf.read(file,encoding='utf-8')
#conf.read(file)
sec=conf.sections()
class Remote():
def __init__(self,host,port,user,passwd):
self.host = host
self.port = port
self.user = user
self.passwd = passwd
self.conn()
def conn(self):
self.myclient = paramiko.SSHClient()
self.myclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.myclient.connect(hostname = self.host,port = self.port,username = self.user,password = self.passwd)
def exec(self,command):
self.command = command
stdin,stdout,stderr = self.myclient.exec_command(self.command)
result = stdout.read()
self.myclient.close()
return result
def check_dir(dir,host,port,user,passwd):
c=Remote(host,port,user,passwd)
command = ("[ -d %s ] && ls -A %s|wc -w || echo 0" % (dir,dir))
result = c.exec(command)
if int(result) == 0:
return 0
else:
return 1
basedir="/home/zshield"
c_dict={'kstream':'%s/conf/kstream'% basedir,'mysql':'%s/conf/database' % basedir}
run_svc_dict = {}
not_run_svc_dict = {}
class Check:
def __init__(self,svc,dir,host,port,user,passwd):
self.svc=svc
self.dir=dir
self.host=host
self.port=port
self.user=user
self.passwd=passwd
def check_container(self):
empty_dir=[]
no_empty_dir=[]
if os.path.exists(self.dir):
if not os.listdir(dir):
empty_dir.append(self.dir)
else:
no_empty_dir.append(self.dir)
else:
empty_dir.append(self.dir)
if self.dir in empty_dir:
print("服务%s未运行" % self.svc)
elif self.dir in no_empty_dir:
run_svc.append(self.svc)
host_name = get_host_name(CMD_HOST_NAME)
run_svc_str=''.join(str(run_svc))
host_name_str=''.join(host_name)
DICT[self.host]=run_svc_str
class Check2:
#run_svc = []
#not_run_svc = []
def __init__(self,svc,dir,host,port,user,passwd):
self.svc=svc
self.dir=dir
self.host=host
self.port=port
self.user=user
self.passwd=passwd
def check_container(self):
empty_dir=[]
no_empty_dir=[]
status=check_dir(self.dir,self.host,self.port,self.user,self.passwd)
if status == 1:
#print("%s 节点服务 %s 运行" % (self.host,self.svc))
run_svc_dict.setdefault(self.host,[]).append(self.svc)
elif status == 0:
#print("%s 节点服务 %s 未运行" % (self.host,self.svc))
not_run_svc_dict.setdefault(self.host,[]).append(self.svc)
def main():
for i in sec:
value=dict(conf.items(i))
ip=str(value['ip'])
port=str(value['port'])
user=str(value['user'])
passwd=str(value['password'])
for svc,dir in c_dict.items():
try:
check=Check2(svc,dir,ip,port,user,passwd)
check.check_container()
except:
print ("获取节点 %s 服务运行信息失败" % ip)
main()
print("节点运行的服务详情 %s" % run_svc_dict)
print("节点未运行的服务详情 %s" % not_run_svc_dict)
结合配置文件
(ve) [root@ceph-01 infra]# cat check.ini [ceph-01] ip=10.0.0.2 port=22 user=root password=123456 [ceph-02] ip=10.0.0.3 port=22 user=root password=123456 [ceph-03] ip=10.0.0.4 port=222 user=root password=123456
运行结果
(ve) [root@ceph-01 infra]# python check_container.py
获取节点 10.0.0.4 服务运行信息失败
获取节点 10.0.0.4 服务运行信息失败
节点运行的服务详情 {'10.0.0.2': ['mysql']}
节点未运行的服务详情 {'10.0.0.2': ['kstream'], '10.0.0.3': ['kstream', 'mysql']}
这个脚本代码量有点大,是因为有些本来直接定义成函数就能解决的问题,定义成了类,更改后代码如下
(ve) [root@ceph-02 ~]# cat check_svc.py
#!/usr/bin/env python
#coding: utf-8
import os
import subprocess
import paramiko
import configparser
import _thread
import time
file='/root/check.ini'
conf = configparser.ConfigParser()
conf.read(file,encoding='utf-8')
#conf.read(file)
sec=conf.sections()
run_svc_dict = {}
not_run_svc_dict = {}
basedir="/home/zshield/"
c_dict={'kstream':'%s/conf/kstream' % basedir,'mysql':'%s/conf/database' % basedir,'binary':'%s/conf/supervisor_binary' % basedir,
'bind':'%s/conf/supervisor_bind' % basedir,'connect':'%s/conf/connect' % basedir,'diamond':'%s/conf/diamond' % basedir,
'es':'%s/conf/' % basedir,'es2mysql':'%s/conf/es2mysql' % basedir,'gosite':'%s/conf/powerservice' % basedir,
'hive_connect':'%s/conf/hive_connect/' % basedir,'jdbc_connect':'%s/conf/jdbc_connect' % basedir,
'kafka':'%s/conf/kafka/' % basedir,'keepalived':'%s/conf' % basedir,'kstream':'%sconf/kstream' % basedir,
'mm2':'%s/conf/mm2/' % basedir,'mysql':'%s/conf/database' % basedir,
'ntp':'/etc/','ogg_keepalived':'%s/bin/ogg_restart_keepalived.sh' % basedir,
'ogg':'%s/ogg/' % basedir,'redis':'%s/conf/redis.conf' % basedir,
'nginx':'%s/conf/nginx_conf/' % basedir,'logstash':'%s/conf/logstash' % basedir,'zy_merge':'%s/conf/supervisor_zy_merge' % basedir,
'zy_import':'%s/bin/zy_import.sh' % basedir,'zy_pp2':'%s/conf/supervisor_zy_pp2/' % basedir,
'zs_power':'%s/var/dumped_index' % basedir}
def conn(host,port,user,passwd,command):
myclient = paramiko.SSHClient()
myclient.set_missing_host_key_policy(paramiko.AutoAddPolicy())
myclient.connect(hostname = host,port = port,username = user,password = passwd)
stdin,stdout,stderr = myclient.exec_command(command)
result = stdout.read()
myclient.close()
return result
def check_dir(dir,svc,host,port,user,passwd):
#c=Remote(host,port,user,passwd)
command = ("[ -d %s ] && ls -A %s|wc -w || echo 0" % (dir,dir))
result = conn(host,port,user,passwd,command)
#result = c.exec(command)
if int(result) == 0:
#return 0
not_run_svc_dict.setdefault(host,[]).append(svc)
else:
#return 1
run_svc_dict.setdefault(host,[]).append(svc)
def main():
for i in sec:
start=time.clock()
value=dict(conf.items(i))
ip=str(value['ip'])
port=str(value['port'])
user=str(value['user'])
passwd=str(value['password'])
for svc,dir in c_dict.items():
try:
check_dir(dir,svc,ip,port,user,passwd)
#check=Check2(ip,port,user,passwd,dir,svc)
#check.check_container()
except:
print ("获取节点 %s 服务运行信息失败" % ip)
main()
print("节点运行的服务详情 %s" % run_svc_dict)
print("节点未运行的服务详情 %s" % not_run_svc_dict)
运行结果如下
(ve) [root@ceph-02 ~]# python check_svc.py
节点运行的服务详情 {'10.0.0.2': ['mysql', 'connect', 'es', 'gosite', 'kafka', 'keepalived', 'ntp', 'nginx', 'logstash', 'zy_merge', 'zy_pp2'], '10.0.0.3': ['es', 'keepalived', 'ntp'], '10.0.0.4': ['es', 'keepalived', 'ntp']}
节点未运行的服务详情 {'10.0.0.2': ['kstream', 'binary', 'bind', 'diamond', 'es2mysql', 'hive_connect', 'jdbc_connect', 'mm2', 'ogg_keepalived', 'ogg', 'redis', 'zy_import', 'zs_power'], '10.0.0.3': ['kstream', 'mysql', 'binary', 'bind', 'connect', 'diamond', 'es2mysql', 'gosite', 'hive_connect', 'jdbc_connect', 'kafka', 'mm2', 'ogg_keepalived', 'ogg', 'redis', 'nginx', 'logstash', 'zy_merge', 'zy_import', 'zy_pp2', 'zs_power'], '10.0.0.4': ['kstream', 'mysql', 'binary', 'bind', 'connect', 'diamond', 'es2mysql', 'gosite', 'hive_connect', 'jdbc_connect', 'kafka', 'mm2', 'ogg_keepalived', 'ogg', 'redis', 'nginx', 'logstash', 'zy_merge', 'zy_import', 'zy_pp2', 'zs_power']}



