我想使用 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 安装到工作站并将其复制到本地 - 我宁愿避免这种情况。
任何指示将不胜感激。
谢谢!
编辑:感谢下面伟大的评论者!我设法按照建议使用synchronize
Linux 工作站上的模块。
不幸的是,某些工作站运行 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