最近在配合php开发人员开发salt自动化平台,我负责后台Python的自动化任务处理,另外一个同事负责前台页面和数据的下发。遇到了一点小小的问题,先总结下。
php
一、如何确保minion id 惟一前端
因为人为的去配置,可能致使mid重复,这样致使的结果是严重的。后来想了下,这个能够经过salt主动上报mid和ip的对应信息的。代码以下:python
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形成的错误。mysql
二、因为state.sls是串行的,就是说不能在同一个目标机上同时执行多个state.sls。web
举个简单的例子:redis
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队列。
sql
三、因为任务放到队列执行,每次的执行结果存储到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
四、最后一个问题就是salt 分布式架构的问题,因为网络问题,返回结果不稳定,怎么确保结果返回,这个就要自定以returner。这个我写了一个C/S结构的结果采集。master启用server,syndic启用client端,使用zmq socket。
centos
最后附上前端展现图,这里效仿了zabbix的web模式。网络