最近在配合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模式。