如何用Ansible高效将远程命令输出重定向至本地文件?
解决Ansible处理远程大输出脚本的内存溢出问题
常规的注册输出再写入本地的方法会把完整输出加载到控制节点内存,导致MemoryError,这里提供两种Ansible原生解决方案,无需借助sshpass:
方法一:用fetch模块(推荐,符合Ansible最佳实践)
先在远程把脚本输出写到临时文件,再拉取到本地,最后清理远程临时文件。fetch模块基于scp分块传输,不会把大输出一次性加载到内存。
- name: 拉取远程大输出到本地 hosts: 192.168.206.132 tasks: - name: 远程执行脚本并写入临时文件 command: ./script_that_produce_large_output /dev/stdout > /tmp/remote_temp_file args: chdir: /path/to/your/script # 替换成脚本实际所在目录 - name: 将远程临时文件拉到本地 fetch: src: /tmp/remote_temp_file dest: /tmp/local_file flat: yes # 直接覆盖本地目标文件,不自动创建主机名子目录 - name: 删除远程临时文件 file: path: /tmp/remote_temp_file state: absent
方法二:直接通过SSH管道流式传输到本地
和你手动用ssh root@host ... > /tmp/local_file原理一致,利用Ansible已配置的SSH密钥认证,在本地执行ssh命令直接把远程输出写到本地文件,全程流式处理,不占额外内存。
- name: 流式传输远程输出到本地 hosts: localhost tasks: - name: 执行远程脚本并保存到本地 shell: ssh root@192.168.206.132 './script_that_produce_large_output /dev/stdout' > /tmp/local_file
为什么常规方法会报错?
register: output会把命令的完整输出存入控制节点的内存变量,当输出体积超过可用内存时,就会触发MemoryError。上面两种方法都是分块/流式处理输出,不会一次性加载全部内容到内存。
内容的提问来源于stack exchange,提问作者Almog
相关产品推荐
相关产品推荐

