Ansible多主机复制/抓取文件时避免覆盖并按主机标识区分存储的方案咨询
Ansible多主机复制/抓取文件时避免覆盖并按主机标识区分存储的方案咨询
嗨,这个问题在Ansible批量管理多主机时太常见了——默认情况下不管用copy还是fetch,如果目标路径固定,新主机的内容肯定会覆盖之前的,好在我们可以利用Ansible内置的主机标识变量轻松解决这个问题,让每台主机的文件都能按专属标识存储,不会互相冲突。
首先得澄清一下:如果你的需求是把远程主机上的/data/logs/app拉取到控制机本地,其实更适合用fetch模块(copy模块默认是从控制机推送到远程,remote_src=true只是让它在远程主机内部复制,没法直接拉到本地)。下面分两种场景给你方案:
一、用fetch模块拉取远程文件到本地(推荐)
1. 按主机名创建单独目录存储
直接在dest路径里嵌入{{ inventory_hostname }}(这个变量是你inventory文件里定义的主机名),让每台主机的文件存在独立目录:
ansible aid -m fetch -a "src=/data/logs/app dest=./logs/{{ inventory_hostname }}/ flat=yes"
flat=yes:避免默认创建远程路径的完整层级(默认会生成./logs/主机名/data/logs/app),直接把文件放在./logs/主机名/下- 执行后,你会看到本地
logs目录下多出每个主机对应的子目录,各自存着对应主机的app文件
2. 给文件加上主机名后缀(同目录区分)
如果不想建太多子目录,只想给文件名加上主机标识后缀,可以这样写:
ansible aid -m fetch -a "src=/data/logs/app dest=./logs/app_{{ inventory_hostname }} flat=yes"
执行后,本地logs目录下会生成app_主机A、app_主机B这类命名的文件,完美避免覆盖。
二、如果需要用copy模块(远程主机内部复制)
如果你的场景是在远程主机内部复制文件,同时要区分不同主机的复制结果(比如每台主机复制后的文件带自己的标识),可以这样写:
ansible aid -m copy -a "src=/data/logs/app dest=/path/to/dest/app_{{ inventory_hostname }} remote_src=true"
这里同样用{{ inventory_hostname }}给目标文件名加上主机标识,确保每台主机的复制结果互不干扰。
进阶:用Playbook更高效管理多主机
如果经常要执行这个操作,写个Playbook会更方便(也更易维护):
- name: 按主机标识拉取/复制日志文件 hosts: aid tasks: # 拉取远程文件到本地按主机名目录存储 - name: 拉取app日志到本地专属目录 fetch: src: /data/logs/app dest: ./logs/{{ inventory_hostname }}/ flat: yes # 或者:远程主机内部复制带主机标识的文件 - name: 远程内部复制带主机标识的日志 copy: src: /data/logs/app dest: /remote/dest/app_{{ inventory_hostname }} remote_src: true
执行时只需运行ansible-playbook your_playbook.yml即可。
小提示
- 除了
{{ inventory_hostname }},还可以用{{ ansible_hostname }}(远程主机的系统主机名),但这个变量需要先收集主机facts才能用(执行命令时加-m setup,或者Playbook默认会收集) - 如果要复制的是目录,去掉
flat=yes即可,Ansible会自动把整个目录复制到对应的主机标识路径下
备注:内容来源于stack exchange,提问作者Tiina
相关产品推荐
相关产品推荐

