最近在配合php开发人员开发salt自动化平台,我负责后台Python的自动化任务处理,另一个同事负责前台页面和数据的下发。遇到了一点小小的问题,先总结下。
1、如何确保minion id 唯一
由于人为的去配置,可能导致mid重复,这样导致的结果是严重的。后来想了下,这个可以通过salt主动上报mid和ip的对应信息的。代码如下:
class CheckMid(object):
def __init__(self):
self.db = MySQL()
self.tbname = 't_ip_mid_map'
self.local = salt.client.LocalClient()
def check_mid(self):
for data in self.local.cmd_iter('*','grains.get',['ipv4']):
for key in data:
if data[key].has_key('ret'):
iplist = data[key]['ret']
if '127.0.0.1' in iplist:
iplist.remove('127.0.0.1')
iplist.sort()
ips = ','.join(iplist)
self.insert_mid(key,ips)
def insert_mid(self,mid,ips):
try:
task_num = self.db.query("select * from %s where mid = '%s'" % (self.tbname,mid))
except Exception,e:
LOG.error_log(e)
if not task_num:
try:
self.db.insert(self.tbname,{'mid':mid,'ip':ips})
except Exception,e:
LOG.error_log(e)
这段代码主要是将mid和ip对应关系上报到数据库的一张表中,字段mid是主键。前端页面就负责展示,当新增机器和以前的机器mid重复了,在前端页面可以知道这个机器不可用(资产表和mid/ip表比较产生的),此时就要修改mid了。这个还能避免人为填写mid造成的错误。
2、由于state.sls是串行的,就是说不能在同一个目标机上同时执行多个state.sls。
举个简单的例子:
salt 'salt-centos' state.sls redis.stop &
salt 'salt-centos' state.sls mysql.stop
此时就会报错:
The function "state.sls" is running as PID 31693 .... with jid 20141016052159481497
这样的话,最简单的方法就是将任务放到队列中执行,采用python的Queue队列。
3、由于任务放到队列执行,每次的执行结果存储到redis。采用一个死循环根据jid去匹配redis的结果,匹配到结果则退出循环,然后可以执行下个任务了。但是如果minion端挂了,就没有返回结果,此时就会堵塞在循环上,后面的任务无法执行。于是我加了个判断,就是每次执行任务时,去test.ping。代码如下:
try:
for i in range(10):
if self.salt.ping(self.mid): # 返回为真就下发任务
jid = self.salt.state_run(self.mid, self.act)
break
else:
jid = 0
raise Exception,'{0} salt has problem,not return'.format(self.mid)
except Exception,e:
LOG.error_log(e)
pass
4、最后一个问题就是salt 分布式架构的问题,由于网络问题,返回结果不稳定,怎么确保结果返回,这个就要自定以returner。这个我写了一个C/S结构的结果采集。master启用server,syndic启用client端,使用zmq socket。
最后附上前端展示图,这里效仿了zabbix的web模式。
转载于:https://blog.51cto.com/liuping0906/1564910