如何在Ansible/Python中高效采集远程主机信息并降低资源消耗?
优化Ansible信息采集效率的实用方案
一、合并所有采集命令,减少SSH连接次数
每次调用shell模块都会建立一次SSH连接,55次连接的握手、认证开销是耗时的核心原因。把所有采集逻辑打包成一个脚本,通过Ansible的script模块一次性执行,只需要一次SSH连接就能完成所有采集。
示例合并后的采集脚本(collect_info.sh):
#!/bin/bash # 输出ip6tables服务启动状态 echo "ip6tables_startup: $(chkconfig --list ip6tables | awk '{$1=""; gsub(/\s+/, " "); print substr($0,2)}')" # 输出vm.swappiness参数值 echo "vm_swappiness: $(sysctl vm.swappiness | awk '{print $3}')" # 输出logrotate的rotate配置 echo "logrotate_rotate: $(awk '/^[Rr][Oo][Tt][Aa][Tt][Ee]/ {print $2}' /etc/logrotate.conf)" # 输出数据库监听地址和端口 echo "db_listener: $(lsnrctl status | grep -v 'Connecting' | grep -Po '(?<=HOST=)[^)]+|(?<=PORT=)\d+' | sed 'N;s/\n/:/')" # 其他采集命令依次追加...
在Playbook中调用这个脚本:
- name: 批量采集主机信息 script: collect_info.sh register: collect_result
二、用Ansible原生模块替代Shell命令
Ansible内置了很多专门用于信息采集的模块,这些模块经过优化,不仅执行效率更高,还能直接返回结构化数据,省去手动文本处理的麻烦:
- 服务状态采集:用
service_facts模块自动收集所有服务状态,无需调用chkconfig:
- name: 收集所有服务信息 service_facts: - name: 提取ip6tables服务状态 debug: msg: "{{ ansible_facts.services['ip6tables.service'].state }}"
- 内核参数采集:用
sysctl模块的info模式直接获取参数值:
- name: 获取vm.swappiness参数 sysctl: name: vm.swappiness state: info register: swappiness_result - name: 输出参数值 debug: msg: "{{ swappiness_result.value }}"
三、优化单条Shell命令的执行效率
尽量减少管道符的使用,用单个工具完成多步文本处理,避免重复创建进程消耗资源:
- 原ip6tables命令简化:
# 原命令 chkconfig --list ip6tables| awk '{$1=""; print $0}' | sed 's/\s\s*/ /g' # 优化后(用awk完成所有处理) chkconfig --list ip6tables | awk '{$1=""; gsub(/\s+/, " "); print substr($0,2)}' - 原logrotate命令简化:
# 原命令 cat /etc/logrotate.conf |grep -i '^rotate'|awk '{print $2}' # 优化后(直接用awk匹配并提取) awk '/^[Rr][Oo][Tt][Aa][Tt][Ee]/ {print $2}' /etc/logrotate.conf
四、调整Ansible配置,提升整体执行速度
- 开启SSH连接复用:在
ansible.cfg中添加以下配置,让Ansible复用已建立的SSH连接,避免重复认证:[ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=60s control_path = %(directory)s/%%h-%%r - 提高并行执行数:默认
forks为5,可根据控制机性能调高(比如20),同时处理更多主机:[defaults] forks = 20 - 精简Facts收集:如果不需要默认的系统Facts,在Playbook中关闭或只收集需要的子集:
- name: 采集信息任务 hosts: all gather_facts: yes gather_subset: - '!all' - '!min' - services - sysctl
五、异步执行(针对大量主机场景)
如果需要同时处理数十上百台主机,用Ansible的异步功能让任务后台执行,控制机无需等待单台完成后再处理下一台:
- name: 异步启动信息采集 script: collect_info.sh async: 300 poll: 0 register: async_collect - name: 等待所有采集任务完成 async_status: jid: "{{ async_collect.ansible_job_id }}" register: collect_result until: collect_result.finished retries: 10 delay: 10
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

