Ansible - 将文件从一个远程节点获取到另一个远程节点

Ansible - 将文件从一个远程节点获取到另一个远程节点

我想使用 Ansible 将文件从本地工作站上传到 NAS 服务器。两者都通过 Ansible 进行管理。

到目前为止,我实现此功能的唯一方法是通过 NFS 将 NAS 文件共享安装为本地目录,并将复制任务委派给 Ansible 控制器:

  - name: Fetch files to NAS
    fetch:
      src: "{{ item.path }}"
      dest: "/NAS/Share/{{inventory_hostname}}/" #<local NFS mount
      flat: yes
      validate_checksum: yes
    with_items: "{{ found_files.files }}"

然而,该解决方案速度慢且容易出错。另外,我想开始使用 Ansible tower,但我认为这个解决方案根本不起作用。

通过 Ansible 自动化执行此任务是否可行?我能想到的唯一解决方案是将 NAS 安装到工作站并将其复制到本地 - 我宁愿避免这种情况。

任何指示将不胜感激。

谢谢!

编辑:感谢下面伟大的评论者!我设法按照建议使用synchronizeLinux 工作站上的模块。

不幸的是,某些工作站运行 Windows,该模块不可用。目前我可以采取的唯一可行的解​​决方案是使用pscp,我宁愿避免使用它来保持 Ansible-only。

我可以使用其他方法将文件从 Windows 工作站提取到 NAS 吗?

谢谢!

答案1

还有更多选择。例如,使用同步或者SCP

同步

使用模块同步如果可以的话:

  • 安装同步在 NAS 和工作站上。看笔记
  • 配置从 NAS 到工作站的无密码 ssh。

例如创建一个项目用于测试

shell> tree .
.
├── ansible.cfg
├── group_vars
│   └── all
│       └── nas.yml
├── hosts
└── pb.yml

2 directories, 4 files
shell> cat ansible.cfg 
[defaults]
gathering = explicit
collections_path = $HOME/.local/lib/python3.9/site-packages/
inventory = $PWD/hosts
roles_path = $PWD/roles
remote_tmp = ~/.ansible/tmp
retry_files_enabled = false
stdout_callback = yaml

声明并自定义变量

shell> cat group_vars/all/nas.yml 
---

# Customize below variables - - - - - - - - - - - - - - - - - - - - - -

# Resolvable host or IP
nas_host: "{{ hostvars[nas].ansible_host }}"

# Workstation user who can read the files
wrks_admin: admin

# NAS user who runs the upload script
nas_admin: admin

# Directory at controller keeps the public keys of nas_admin
nas_dir_pub_keys: /tmp/nas_pub_keys

# Directory at NAS to upload the files to
nas_dir_share: /tmp/ansible/share

# Script at NAS run by nas_admin to upload the files
nas_upload_script: /tmp/nas_upload_script.bash

# List of files to upload from the workstations to NAS
nas_upload:
  - /etc/passwd


# Do not change this - - - - - - - - - - - - - - - - - - - - - - - - -

# The variable wrks keeps the comma-separated list of
# worstations. Create a list of the workstations
nas_wrks: "{{ wrks.split(',') }}"

# Public key of nas_admin stored at controller
nas_key: "{{ nas_dir_pub_keys }}/{{ nas }}/home/{{ nas_admin }}/.ssh/id_rsa.pub"

创建 NAS 服务器和工作站的清单

shell> cat hosts 
[nas]
nas_4 ansible_host=10.1.0.74

[nas:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=true
ansible_python_interpreter=/bin/python3.6

[wrks]
wrks_1 ansible_host=10.1.0.61
wrks_2 ansible_host=10.1.0.17
wrks_3 ansible_host=10.1.0.63

[wrks:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=true
ansible_python_interpreter=/usr/local/bin/python3.8
ansible_perl_interpreter=/usr/local/bin/perl

创建剧本

shell> cat pb.yml 
---

# Mandatory variables:
#
#   nas ... NAS server
#   wrks .. Workstations; comma-separated list

- name: NAS ready
  hosts: "{{ nas }}"
  tasks:
    - fetch:
        src: "/home/{{ nas_admin }}/.ssh/id_rsa.pub"
        dest: "{{ nas_dir_pub_keys }}"
    - file:
        state: directory
        path: "{{ nas_dir_share }}/{{ item }}"
        owner: "{{ nas_admin }}"
      loop: "{{ nas_wrks }}"
    - copy:
        dest: "{{ nas_upload_script }}"
        content: |
          {{ '#' }}!/usr/bin/bash
          {% for host in nas_wrks %}
          {% set wrks_host = hostvars[host].ansible_host %}
          {% for file in nas_upload %}
          scp {{ wrks_admin }}@{{ wrks_host }}:{{ file }} {{ nas_dir_share }}/{{ host }}
          {% endfor %}
          {% endfor %}
        owner: "{{ nas_admin }}"
        mode: "u+x"

- name: Workstations ready
  hosts: "{{ wrks }}"
  tasks:
    - authorized_key:
        user: "{{ wrks_admin }}"
        key: "{{ lookup('file', nas_key) }}"

- name: Workstations upload files to NAS
  hosts: "{{ wrks }}"
  tasks:
    - synchronize:
        mode: pull
        src: "{{ item }}"
        dest: "{{ nas_dir_share }}/{{ inventory_hostname }}"
        checksum: true
      delegate_to: "{{ nas }}"
      loop: "{{ nas_upload }}"
      register: out
      become_user: "{{ nas_admin }}"
    - debug:
        var: out
      when: debug|d(false)|bool

使用额外变量运行剧本

shell> ansible-playbook pb.yml -e nas=nas_4 -e wrks=wrks_2,wrks_3

在第一部剧中NAS ready:

  • 的公钥NAS管理员纳斯存储在控制器上
shell> tree -a /tmp/nas_pub_keys/
/tmp/nas_pub_keys/
└── nas_4
    └── home
        └── admin
            └── .ssh
                └── id_rsa.pub

4 directories, 1 file
  • 目录nas_dir_share适用于所有工作站沃克斯创建于纳斯
nas_4> ssh [email protected] tree /tmp/ansible/share
tmp/ansible/share/
├── wrks_2
└── wrks_3
2 directories, 0 files
  • 或者,创建一个脚本以从 NAS 上的命令行上传文件。

在第二部剧中Workstations ready:

  • 添加公钥NAS管理员纳斯授权密钥wrks_管理员在所有工作站上沃克斯

在第三部剧中Workstations upload files to NAS:

  • 拉取列表中的文件nas_上传从工作站到纳斯
  • (可选)显示注册结果。

运行剧本

shell> ansible-playbook pb.yml -e nas=nas_4 -e wrks=wrks_2,wrks_3

PLAY [NAS ready] *****************************************************************************

TASK [fetch] *********************************************************************************
changed: [nas_4]

TASK [file] **********************************************************************************
changed: [nas_4] => (item=wrks_2)
changed: [nas_4] => (item=wrks_3)

TASK [copy] **********************************************************************************
ok: [nas_4]

PLAY [Workstations ready] ********************************************************************

TASK [authorized_key] ************************************************************************
ok: [wrks_3]
ok: [wrks_2]

PLAY [Workstations upload files to NAS] ******************************************************

TASK [synchronize] ***************************************************************************
changed: [wrks_2 -> nas_4(10.1.0.74)] => (item=/etc/passwd)
changed: [wrks_3 -> nas_4(10.1.0.74)] => (item=/etc/passwd)

TASK [debug] *********************************************************************************
skipping: [wrks_2]
skipping: [wrks_3]

PLAY RECAP ***********************************************************************************
nas_4: ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
wrks_2: ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
wrks_3: ok=2    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

列表中的文件nas_上传是从工作站复制的沃克斯nas_dir_share纳斯

nas_4> tree /tmp/ansible/share/
/tmp/ansible/share/
├── wrks_2
│   └── passwd
└── wrks_3
    └── passwd

2 directories, 2 files

SCP

使用脚本nas_上传_脚本如果你:

  • 无法在 NAS 和工作站上安装 rsync。但是你
  • 可以配置从 NAS 到工作站的无密码 ssh。
admin@nas_4> cat /tmp/nas_upload_script.bash 
#!/usr/bin/bash
scp [email protected]:/etc/passwd /tmp/ansible/share/wrks_2
scp [email protected]:/etc/passwd /tmp/ansible/share/wrks_3

跳过第三次播放并运行脚本纳斯从命令行

admin@nas_4> /tmp/nas_upload_script.bash 
passwd                                  100% 2958   595.8KB/s   00:00    
passwd                                  100% 1708   375.5KB/s   00:00

笔记:

  • 如果您可以在 NAS 上安装 Ansible,那么简单的选择就是在那里运行游戏

  • 也可以创建一个脚本来同步来自 NAS 上命令行的文件

  • 的价值观NAS管理员wrks_管理员可能不同于ansible_用户

  • 任务复制在第一场比赛中是可选的。如果不需要该脚本,可以将其删除。

答案2

可以使用 Ansible 同步模块来进行 rsync 操作。如果存在未更新的文件,则可能会加快复制速度,因此它们不会被传输。
https://docs.ansible.com/ansible/latest/collections/ansible/posix/synchronize_module.html

相关内容