如何使用可视化在两个节点之间复制文件

我需要复制文件形式的机器 A 到机器 B,而我的控制机器从那里我运行所有可能的任务是机器 C (本地机器)

I have tried the following:

在可视化的 shell 模块中使用 scp 命令

hosts: machine2
user: user2
tasks:
- name: Copy file from machine1 to machine2
shell: scp user1@machine1:/path-of-file/file1 /home/user2/file1

这种方法永远不会结束。

使用提取和复制模块

hosts: machine1
user: user1
tasks:
- name: copy file from machine1 to local
fetch: src=/path-of-file/file1 dest=/path-of-file/file1


hosts: machine2
user: user2
tasks:
- name: copy file from local to machine2
copy: src=/path-of-file/file1 dest=/path-of-file/file1

这种方法给我出了一个错误,如下所示:

error while accessing the file /Users/<myusername>/.ansible/cp/ansible-ssh-machine2-22-<myusername>, error was: [Errno 102] Operation not supported on socket: u'/Users/<myusername>/.ansible/cp/ansible-ssh-machine2-22-<myusername>'

任何建议都会有帮助。

186781 次浏览

我能够使用 local _ action to scp 解决这个问题,将文件从 machineA 复制到 machineC,然后将文件复制到 machineB。

要复制远程到远程的文件,可以使用带有“ delegate_to: source-server”关键字的 同步模块:

- hosts: serverB
tasks:
- name: Copy Remote-To-Remote (from serverA to serverB)
synchronize: src=/copy/from_serverA dest=/copy/to_serverB
delegate_to: serverA

This playbook can run from your machineC.

正如 ant31已经指出的,您可以使用 synchronize模块来实现这一点。默认情况下,模块在控制计算机和当前远程主机(inventory_host)之间传输文件,但是可以使用任务的 delegate_to参数进行更改(注意这是 任务的参数,而不是模块的参数,这一点很重要)。

您可以将任务放置在 ServerAServerB上,但是您必须相应地调整传输的方向(使用 synchronizemode参数)。

Placing the task on ServerB

- hosts: ServerB
tasks:
- name: Transfer file from ServerA to ServerB
synchronize:
src: /path/on/server_a
dest: /path/on/server_b
delegate_to: ServerA

This uses the default mode: push, so the file gets transferred from the delegate (ServerA) to the current remote (ServerB).

This might sound like strange, since the task has been placed on ServerB (via hosts: ServerB). However, one has to keep in mind that the task is actually 在委托的主机上执行, which in this case is ServerA. So pushing (from ServerA to ServerB) is indeed the correct direction. Also remember that we cannot simply choose not to delegate at all, since that would mean that the transfer happens between the 控制机 and ServerB.

将任务放在 ServerA

- hosts: ServerA
tasks:
- name: Transfer file from ServerA to ServerB
synchronize:
src: /path/on/server_a
dest: /path/on/server_b
mode: pull
delegate_to: ServerB

这使用 mode: pull来反转传输方向。同样,请记住任务实际上是在 ServerB上执行的,因此拉是正确的选择。

If you need to sync files between two remote nodes via ansible you can use this:

- name: synchronize between nodes
environment:
RSYNC_PASSWORD: "\{\{ input_user_password_if_needed }}"
synchronize:
src: rsync://user@remote_server:/module/
dest: /destination/directory/
// if needed
rsync_opts:
- "--include=what_needed"
- "--exclude=**/**"
mode: pull
delegate_to: "\{\{ inventory_hostname }}"

当你在 remote_server上需要启动 rsync 时,使用守护进程模式。简单的例子:

pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log
port = port


[module]
path = /path/to/needed/directory/
uid = nobody
gid = nobody
read only = yes
list = yes
auth users = user
secrets file = /path/to/secret/file

使用复制模块将文件从一个服务器传输到另一个服务器的简单方法

这是战术手册

---
- hosts: machine1 {from here file will be transferred to another remote machine}
tasks:
- name: transfer data from machine1 to machine2


copy:
src=/path/of/machine1


dest=/path/of/machine2


delegate_to: machine2 {file/data receiver machine}

If you want to do rsync and use custom user and custom ssh key, you need to write this key in rsync options.

---
- name: rsync
hosts: serverA,serverB,serverC,serverD,serverE,serverF
gather_facts: no
vars:
ansible_user: oracle
ansible_ssh_private_key_file: ./mykey
src_file: "/path/to/file.txt"
tasks:
- name: Copy Remote-To-Remote from serverA to server{B..F}
synchronize:
src:  "\{\{ src_file }}"
dest: "\{\{ src_file }}"
rsync_opts:
- "-e ssh -i /remote/path/to/mykey"
delegate_to: serverA

You can use deletgate with scp too:

- name: Copy file to another server
become: true
shell: "scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null admin@\{\{ inventory_hostname }}:/tmp/file.yml /tmp/file.yml"
delegate_to: other.example.com

由于 delegate的存在,该命令在另一台服务器上运行,并且 scp是该服务器的文件。

在2021年,你应该安装包装器:

ansible-galaxy collection install ansible.posix

和使用

- name: Synchronize two directories on one remote host.
ansible.posix.synchronize:
src: /first/absolute/path
dest: /second/absolute/path
delegate_to: "\{\{ inventory_hostname }}"

延伸阅读:

Https://docs.ansible.com/ansible/latest/collections/ansible/posix/synchronize_module.html

检查:

ansible --version
ansible 2.10.5
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/daniel/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.9/site-packages/ansible
executable location = /sbin/ansible
python version = 3.9.1 (default, Dec 13 2020, 11:55:53) [GCC 10.2.0]

当把系统机密从机器1传输到机器2时,你可能无法在它们之间进行直接访问,所以涉及到 delegate_to的解决方案将会失败。当您将您的私钥保留在您的可视控制节点上,并将您的公钥保留在 machine1和 machine2的可视用户帐户上的 ~/.ssh/authorized_keys中时,就会发生这种情况。相反,你可以通过 ssh 将一个文件或目录从一台机器传输到另一台机器,使用无密码的 sudo 进行远程权限提升:

-name "Copy /etc/secrets directory from machine1 and machine2"
delegate_to: localhost
shell: |
ssh machine1 sudo tar -C / -cpf - etc/secrets | ssh machine2 sudo tar -C / -xpf -

例如,要使用 MUNGE 守护进程设置 临时的计算集群进行身份验证,可以使用以下方法将凭据从头节点复制到 worker。

setup_worker.yml

- name: "Install worker packages"
apt:
name: "\{\{ packages }}"
vars:
packages:
- munge
# ...and other worker packages...
become: true
- name: "Copy MUNGE credentials from head to \{\{ host }}"
delegate_to: localhost
shell:
ssh head.domain.name sudo tar -C / -cpf - etc/munge | ssh \{\{ ansible_facts["nodename"] }} sudo tar -C / -xpf -
become: false
when: ansible_facts["nodename"] != "head.domain.name"
- name: "Restart MUNGE"
shell: |
systemctl restart munge
become: true

这是作为 ansible-playbook -e host=machine1 setup_worker.yml运行。 由于有敏感性的用户没有特权,所以远程系统任务需要 become: true。复制任务不需要权限提升,因为控制器只用于设置管道,权限提升通过 ssh 命令中的 sudo 发生。变量 host包含在命令行上使用的主机模式,而不是正在初始化的 worker。而是使用 ansible_facts["nodename"],它将是当前 worker 的完全限定域名(假设 worker 配置正确)。when子句阻止我们尝试将目录从头节点复制到它自己。