- 自动化运维工具:ansible
- 多进程调用ansible api的应用场景: 应用系统检查
- 一个应用系统可能具有20—50台服务器的集群,初步的系统层面检查可以用一个统一的playbook来检查,比如(df -h这种命令)。但是深入到应用层的话,就有些个性化的应用了,比如有2台http服务器,有20台中间件服务器在加4台数据库服务器等等,检查项都是不同的。如果现在还要进行批量的系统检查,就不能用同一个playbook了。另外,如果顺序执行的话,等待时间就会非常长,而且没有必要,因为中间件的检查和数据库的检查没有必然的先后顺序的要求,可以同步执行。
- 所以因为上述的场景需求,导致我们需要多进程调用ansible api来动态生成Inventory并执行不同的playbook。
- 实现步骤
- 基于ansible python api 2.0 二次开发,封装接口
- 创建多个ansible 对象,不同的inventory 不同的playbook
- 创建多进程,执行程序
- 注意事项
- ansible api2.0 相较于1.0复杂了许多,也更加灵活。这个需要去阅读原代码,需要多花点时间和耐心
- 在用多进程之前,我尝试使用多线程,这块好像ansible不支持threading ,所以就用multiprocessing代替
- 代码
AnsibleAPI.py
1 #!/usr/bin/env python 2 # coding=utf-8 3 import json 4 import logging 5 from ansible.parsing.dataloader import DataLoader 6 from ansible.vars import VariableManager 7 from ansible.inventory import Inventory 8 from ansible.playbook.play import Play 9 from ansible.executor.task_queue_manager import TaskQueueManager 10 from ansible.executor.playbook_executor import PlaybookExecutor 11 from ansible.plugins.callback import CallbackBase 12 from collections import namedtuple 13 from ansible import constants as C 14 import ansible.executor.task_result 15 import multiprocessing 16 17 18 class ResultsCollector(CallbackBase): 19 20 def v2_runner_on_ok(self, result): 21 host = result._host 22 logging.warning(‘===v2_runner_on_ok====host=%s===result=%s‘ % (host, result._result)) 23 24 25 def v2_runner_on_failed(self, result, ignore_errors=False): 26 host = result._host 27 logging.warning(‘===v2_runner_on_failed====host=%s===result=%s‘ % (host, result._result)) 28 29 def v2_runner_on_unreachable(self, result): 30 host = result._host 31 logging.warning(‘===v2_runner_on_unreachable====host=%s===result=%s‘ % (host, result._result)) 32 33 34 class AnsibleAPI(object): 35 def __init__(self, hostlist, playbooks, *args, **kwargs): 36 self.hostlist = hostlist 37 self.playbooks = playbooks 38 self.passwords = None 39 self.callback = None 40 Options = namedtuple(‘Options‘, [‘connection‘, ‘remote_user‘, ‘ask_sudo_pass‘, ‘verbosity‘, ‘ack_pass‘, 41 ‘module_path‘, ‘forks‘, ‘become‘, ‘become_method‘, ‘become_user‘, 42 ‘check‘, ‘listhosts‘, ‘listtasks‘, ‘listtags‘, ‘syntax‘, 43 ‘sudo_user‘, ‘sudo‘, ‘display_skipped_hosts‘]) 44 45 self.options = Options(connection=‘smart‘, remote_user=‘root‘, ack_pass=None, sudo_user=‘root‘, 46 forks=200, sudo=‘yes‘, ask_sudo_pass=False, verbosity=5, module_path=None, 47 become=True, become_method=‘su‘, become_user=‘root‘, check=None, listhosts=False, 48 listtasks=False, listtags=None, syntax=None, display_skipped_hosts=False) 49 self.loader = DataLoader() 50 self.variable_manager = VariableManager() 51 self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, 52 host_list=self.hostlist) 53 self.variable_manager.set_inventory(self.inventory) 54 self.variable_manager.extra_vars = {"ansible_ssh_user": "root"} # 额外参数,包括playbook参数 key:value 55 56 def runplaybook(self): 57 playbook = PlaybookExecutor( 58 playbooks=self.playbooks, 59 inventory=self.inventory, 60 variable_manager=self.variable_manager, 61 loader=self.loader, 62 options=self.options, 63 passwords=None) 64 playbook._tqm._stdout_callback = ResultsCollector() 65 playbook.run() 66 67 if __name__ == ‘__main__‘: 68 #创建对象 69 anl = AnsibleAPI([‘10.26.222.216‘], [‘/root/ansibleInventory_cl/df.yml‘]) 70 an2 = AnsibleAPI([‘10.26.222.210‘, ‘10.26.222.213‘], [‘/root/ansibleInventory_cl/ifconfig.yml‘]) 71 #多进程 72 processes = [] 73 p1 = multiprocessing.Process(name=‘process_one‘, target=anl.runplaybook) 74 p2 = multiprocessing.Process(name=‘process_two‘, target=an2.runplaybook) 75 processes.append(p1) 76 processes.append(p2) 77 for p in processes: 78 p.start() 79 80 print(‘tasks completed‘)
时间: 2024-11-09 06:24:22