检测openstack云平台是否存在脑裂的虚拟机,加入zabbix告警
2017-10-11 21:03
501 查看
在openstack运维中,有时会遇到虚拟机热迁移,evacuate等操作中,发生虚拟机脑裂的情况,即同一个虚拟机同时在两个hypervisor上面运行,在使用ceph等共享存储时,十有八九会造成虚拟机文件系统损伤,运气好的情况下能修复文件系统错误,重则数据混乱,虚拟机无法启动.为此,我写了一个Python脚本,用于检测openstack的hypervisor(KVM)是否存在脑裂虚拟机,其原理是通过libvirt的API,获取hypervisor上面的虚拟机的名字,比较是否不同的hypervisor上面有相同的虚拟机名字.脚本需要在控制节点运行(需要openrc的环境变量文件),且该控制节点与计算节点打通了ssh秘钥验证,/etc/hosts解析所有hypervisor的主机名.笔者测试在liberty版本和Mitika能正常运行.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : VMSplitCheck.py
import re
import os
import sys
import libvirt
from novaclient import client
from multiprocessing import Pool,Queue
from collections import Counter,defaultdict
import pdb
q=Queue()
EnvFile='/root/openrc'
# 获取nova的认证token
def get_nova_creds():
d={}
try:
pattern_save=re.compile(r'^export.*=.*')
pattern_split=re.compile(r'=')
with open(EnvFile,'r') as f:
for i in f.readlines():
match=pattern_save.search(i)
if match:
temp_str = match.group(0).strip("export").strip()
environ_value_dic = pattern_split.split(temp_str)
os.environ[environ_value_dic[0]] = environ_value_dic[1].strip("'")
d['username'] = os.environ['OS_USERNAME']
d['api_key'] = os.environ['OS_PASSWORD']
d['auth_url'] = os.environ['OS_AUTH_URL']
d['project_id'] = os.environ['OS_TENANT_NAME']
d['region_name']= os.environ['OS_REGION_NAME']
return d
except:
print "error"
sys.exit(5)
#通过调用novaclient获取hypervisor,笔者环境hypervisor主机名都为node-xxx.domain.tld
def getHypervisor():
HypervisorHostname = []
pattern = re.compile(r'node-\d\.domain.tld')
creds = get_nova_creds()
nova = client.Client('2', **creds)
for i in nova.hypervisors.list():
match = pattern.search(i.hypervisor_hostname)
if match:
HypervisorHostname.append(match.group())
return HypervisorHostname
#获取各个hypervisor上面的虚拟机的名字,放入队列
def getVM(node):
try:
virtcon=libvirt.open("qemu+ssh://%s/system" %node)
except libvirtError,e:
print "wrong to connect"
for id in virtcon.listDomainsID():
vminfo=virtcon.lookupByID(id)
q.put((node,vminfo.name()))
# 获取所有运行的虚拟机名字的的列表,和以各个hypervisor的主机名为key,
ae61
上面运行虚拟机为value的字典
def getVMList():
InstanceNameList=[]
# a=getHypervisor()
# HyperDict = {}.fromkeys(a, [])
HyperDict=defaultdict(list)
while not q.empty():
node,vm=q.get()
InstanceNameList.append(vm)
HyperDict[node].append(vm)
return InstanceNameList,HyperDict
# 检测是否有脑裂虚拟机,如果存在,获取此脑裂虚拟机运行在哪些hypervisor上面.
def VMSplitCheck(instancelist,nodedict):
SplitList=[]
SplitDict=defaultdict(list)
c=Counter(instancelist)
for k,v in c.iteritems():
if v>=2:
SplitList.append(k)
if len(SplitList)==0:
print "no split vm"
else:
for i in SplitList:
for k,v in nodedict.iteritems():
if i in v:
SplitDict[i].append(k)
return SplitDict
# 主函数
def main():
hypername=getHypervisor()
# pdb.set_trace()
# print hypername
p=Pool()
for i in hypername:
p.apply_async(getVM,args=(i,))
p.close()
p.join()
inslist,hydict=getVMList()
# print inslist,hydict
vmsplit=VMSplitCheck(inslist,hydict)
print len(vmsplit)
if __name__ =="__main__":
main()
笔者测试如下:
如下图,有2台虚拟机同时在node-4和node-6运行
运行脚本后,返回以脑裂虚拟机名字为key,同时运行的hypervisor主机名为value的字典.
2 增加zabbix报警设置
zabbix-agent增加item
zabbix-dashboard操作
测试item能否正常
增加一个触发器
表达式:{node-1.domain.tld:vm.split.status.last(0)}>0
参考:
https://www.ibm.com/developerworks/cn/cloud/library/cl-openstack-pythonapis/ http://blog.csdn.net/gzhouc/article/details/52915822
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @File : VMSplitCheck.py
import re
import os
import sys
import libvirt
from novaclient import client
from multiprocessing import Pool,Queue
from collections import Counter,defaultdict
import pdb
q=Queue()
EnvFile='/root/openrc'
# 获取nova的认证token
def get_nova_creds():
d={}
try:
pattern_save=re.compile(r'^export.*=.*')
pattern_split=re.compile(r'=')
with open(EnvFile,'r') as f:
for i in f.readlines():
match=pattern_save.search(i)
if match:
temp_str = match.group(0).strip("export").strip()
environ_value_dic = pattern_split.split(temp_str)
os.environ[environ_value_dic[0]] = environ_value_dic[1].strip("'")
d['username'] = os.environ['OS_USERNAME']
d['api_key'] = os.environ['OS_PASSWORD']
d['auth_url'] = os.environ['OS_AUTH_URL']
d['project_id'] = os.environ['OS_TENANT_NAME']
d['region_name']= os.environ['OS_REGION_NAME']
return d
except:
print "error"
sys.exit(5)
#通过调用novaclient获取hypervisor,笔者环境hypervisor主机名都为node-xxx.domain.tld
def getHypervisor():
HypervisorHostname = []
pattern = re.compile(r'node-\d\.domain.tld')
creds = get_nova_creds()
nova = client.Client('2', **creds)
for i in nova.hypervisors.list():
match = pattern.search(i.hypervisor_hostname)
if match:
HypervisorHostname.append(match.group())
return HypervisorHostname
#获取各个hypervisor上面的虚拟机的名字,放入队列
def getVM(node):
try:
virtcon=libvirt.open("qemu+ssh://%s/system" %node)
except libvirtError,e:
print "wrong to connect"
for id in virtcon.listDomainsID():
vminfo=virtcon.lookupByID(id)
q.put((node,vminfo.name()))
# 获取所有运行的虚拟机名字的的列表,和以各个hypervisor的主机名为key,
ae61
上面运行虚拟机为value的字典
def getVMList():
InstanceNameList=[]
# a=getHypervisor()
# HyperDict = {}.fromkeys(a, [])
HyperDict=defaultdict(list)
while not q.empty():
node,vm=q.get()
InstanceNameList.append(vm)
HyperDict[node].append(vm)
return InstanceNameList,HyperDict
# 检测是否有脑裂虚拟机,如果存在,获取此脑裂虚拟机运行在哪些hypervisor上面.
def VMSplitCheck(instancelist,nodedict):
SplitList=[]
SplitDict=defaultdict(list)
c=Counter(instancelist)
for k,v in c.iteritems():
if v>=2:
SplitList.append(k)
if len(SplitList)==0:
print "no split vm"
else:
for i in SplitList:
for k,v in nodedict.iteritems():
if i in v:
SplitDict[i].append(k)
return SplitDict
# 主函数
def main():
hypername=getHypervisor()
# pdb.set_trace()
# print hypername
p=Pool()
for i in hypername:
p.apply_async(getVM,args=(i,))
p.close()
p.join()
inslist,hydict=getVMList()
# print inslist,hydict
vmsplit=VMSplitCheck(inslist,hydict)
print len(vmsplit)
if __name__ =="__main__":
main()
笔者测试如下:
如下图,有2台虚拟机同时在node-4和node-6运行
运行脚本后,返回以脑裂虚拟机名字为key,同时运行的hypervisor主机名为value的字典.
2 增加zabbix报警设置
zabbix-agent增加item
zabbix-dashboard操作
测试item能否正常
增加一个触发器
表达式:{node-1.domain.tld:vm.split.status.last(0)}>0
参考:
https://www.ibm.com/developerworks/cn/cloud/library/cl-openstack-pythonapis/ http://blog.csdn.net/gzhouc/article/details/52915822
相关文章推荐
- 自动化测试:k8s环境下,通过检测文件是否存在来自动启停tomcatapp的方法_20160316_七侠镇莫尛貝
- linux 检测进程是否存在,并统计进程数的有用的方法和脚本
- 检测远程URL是否存在的三种方法
- 检测 邮箱地址 是否存在[C#]
- 检测单向链表是否存在环
- 用3种方法检测远程URL是否存在
- PHP检测链接是否存在的代码实例分享
- 夸浏览器检测flash是否存在
- Oracle检测数据表是否存在
- 检测一个目录或文件是否存在
- SQL Server 2000/2005检测存储过程名是否存在,存在删除
- 通过对URL判断,检测引用的文件是否存在
- 利用certmgr生成测试证书,利用C#检测证书是否存在
- 常用Javascript检测函数:检测对像,函数,ID是否存在
- 检测远程URL是否存在的三种方法
- 检测变量是否存在的方法
- zabbix微信告警(虚拟机脚本测试成功,zabbix上收不到信息)
- OpenStack基于Libvirt的虚拟化平台调度实现----Nova虚拟机启动源码实现(3)
- jquery ajax 检测用户注册时用户名是否存在
- javascript - 检测对象中是否存在某个属性