英文:
Ansible - synchronise files to remote hosts from local
问题
我有以下的库存:
mta:
hosts:
10.1.0.3:
10.1.0.2:
vars:
ansible_user: root
ansible_ssh_private_key_file: ~/.ssh/play
和以下任务
- name: 在委托主机上使用rsync协议同步(推送)
ansible.posix.synchronize:
src: "/home/play/tmp/"
dest: "ssh://{{ mta_servers }}/tmp"
loop: "{{ groups['mta'] }}"
loop_control:
loop_var: mta_servers
run_once: true
register: sync_files
当我运行它
TASK [local : 在委托主机上使用rsync协议同步(推送)] **********************************************************************************************************************************
failed: [10.1.0.4] (item=10.1.0.3) => {"ansible_loop_var": "mta_servers", "changed": false, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -i /home/play/.ssh/pwned -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /home/play/tmp/ root@10.1.0.4:ssh://10.1.0.3/tmp", "msg": "Warning: Permanently added '10.1.0.4' (ED25519) to the list of known hosts.\r\nrsync: [Receiver] mkdir \"/root/ssh://10.1.0.3/tmp\" failed: No such file or directory (2)\nrsync error: error in file IO (code 11) at main.c(783) [Receiver=3.2.3]\n", "mta_servers": "10.1.0.3", "rc": 11}
failed: [10.1.0.4] (item=10.1.0.2) => {"ansible_loop_var": "mta_servers", "changed": false, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -i /home/play/.ssh/pwned -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /home/play/tmp/ root@10.1.0.4:ssh://10.1.0.2/tmp", "msg": "Warning: Permanently added '10.1.0.4' (ED25519) to the list of known hosts.\r\nrsync: [Receiver] mkdir \"/root/ssh://10.1.0.2/tmp\" failed: No such file or directory (2)\nrsync error: error in file IO (code 11) at main.c(783) [Receiver=3.2.3]\n", "mta_servers": "10.1.0.2", "rc": 11}
需要知道的事实
我以用户play
身份在10.1.0.4上运行这个playbook,然后我以具有公钥的root身份连接到本地。
我这样做的原因是,最终我想要在本地生成Let's Encrypt证书,然后将它们同步到上述的服务器。
令我困扰的是,无论我选择作为目标的目录是什么(dest: "ssh://{{ mta_servers }}/tmp"
), 都会失败。
详细输出-vvv
failed: [10.1.0.4] (item=10.1.0.2) => {
"ansible_loop_var": "mta_servers",
"changed": false,
"cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -i /home/play/.ssh/pwned -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /home/play/tmp/ root@10.1.0.4:ssh://10.1.0.2/tmp",
"invocation": {
"module_args": {
"_local_rsync_password": null,
"_local_rsync_path": "rsync",
"_substitute_controller": false,
"archive": true,
"checksum": false,
"compress": true,
"copy_links": false,
"delay_updates": true,
"delete": false,
"dest": "root@10.1.0.4:ssh://10.1.0.2/tmp",
"dest_port": null,
"dirs": false,
"existing_only": false,
"group": null,
"link_dest": null,
"links": null,
"mode": "push",
"owner": null,
"partial": false,
"perms": null,
"private_key": "/home/play/.ssh/pwned",
"recursive": null,
"rsync_opts": [],
"rsync_path": null,
"rsync_timeout": 0,
"set_remote_user": true,
"src": "/home/play/tmp/",
<details>
<summary>英文:</summary>
I have the following inventory:
```yaml
mta:
hosts:
10.1.0.3:
10.1.0.2:
vars:
ansible_user: root
ansible_ssh_private_key_file: ~/.ssh/play
and the following task
- name: Synchronization using rsync protocol on delegate host (push)
ansible.posix.synchronize:
src: "/home/play/tmp/"
dest: "ssh://{{ mta_servers }}/tmp"
loop: "{{ groups['mta'] }}"
loop_control:
loop_var: mta_servers
run_once: true
register: sync_files
When I run it
TASK [local : Synchronization using rsync protocol on delegate host ( push )] **********************************************************************************************************************************
failed: [10.1.0.4] (item=10.1.0.3) => {"ansible_loop_var": "mta_servers", "changed": false, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -i /home/play/.ssh/pwned -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /home/play/tmp/ root@10.1.0.4:ssh://10.1.0.3/tmp", "msg": "Warning: Permanently added '10.1.0.4' (ED25519) to the list of known hosts.\r\nrsync: [Receiver] mkdir \"/root/ssh://10.1.0.3/tmp\" failed: No such file or directory (2)\nrsync error: error in file IO (code 11) at main.c(783) [Receiver=3.2.3]\n", "mta_servers": "10.1.0.3", "rc": 11}
failed: [10.1.0.4] (item=10.1.0.2) => {"ansible_loop_var": "mta_servers", "changed": false, "cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -i /home/play/.ssh/pwned -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /home/play/tmp/ root@10.1.0.4:ssh://10.1.0.2/tmp", "msg": "Warning: Permanently added '10.1.0.4' (ED25519) to the list of known hosts.\r\nrsync: [Receiver] mkdir \"/root/ssh://10.1.0.2/tmp\" failed: No such file or directory (2)\nrsync error: error in file IO (code 11) at main.c(783) [Receiver=3.2.3]\n", "mta_servers": "10.1.0.2", "rc": 11}
Facts to be known
I'm running the playbook on 10.1.0.4 as the user play
, then I'm connecting to local as root with a pubkey.
The reason I'm doing this, is because eventually I want to generate letsencrypt certificates on localhost and then sync them to the above servers.
What bugs me is that, whatever directory I choose as the target (dest: "ssh://{{ mta_servers }}/tmp"
), if would fail still.
detailed output -vvv
failed: [10.1.0.4] (item=10.1.0.2) => {
"ansible_loop_var": "mta_servers",
"changed": false,
"cmd": "/usr/bin/rsync --delay-updates -F --compress --archive --rsh='/usr/bin/ssh -S none -i /home/play/.ssh/pwned -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --out-format='<<CHANGED>>%i %n%L' /home/play/tmp/ root@10.1.0.4:ssh://10.1.0.2/tmp",
"invocation": {
"module_args": {
"_local_rsync_password": null,
"_local_rsync_path": "rsync",
"_substitute_controller": false,
"archive": true,
"checksum": false,
"compress": true,
"copy_links": false,
"delay_updates": true,
"delete": false,
"dest": "root@10.1.0.4:ssh://10.1.0.2/tmp",
"dest_port": null,
"dirs": false,
"existing_only": false,
"group": null,
"link_dest": null,
"links": null,
"mode": "push",
"owner": null,
"partial": false,
"perms": null,
"private_key": "/home/play/.ssh/pwned",
"recursive": null,
"rsync_opts": [],
"rsync_path": null,
"rsync_timeout": 0,
"set_remote_user": true,
"src": "/home/play/tmp/",
"ssh_args": null,
"ssh_connection_multiplexing": false,
"times": null,
"verify_host": false
}
},
"msg": "Warning: Permanently added '10.1.0.4' (ED25519) to the list of known hosts.\r\nrsync: [Receiver] mkdir \"/root/ssh://10.1.0.2/tmp\" failed: No such file or directory (2)\nrsync error: error in file IO (code 11) at main.c(783) [Receiver=3.2.3]\n",
"mta_servers": "10.1.0.2",
"rc": 11
}
[play@ans ansible]$ ansible --version
ansible [core 2.13.3]
config file = /home/play/ansible/ansible.cfg
configured module search path = ['/home/play/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.9/site-packages/ansible
ansible collection location = /home/play/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/bin/ansible
python version = 3.9.14 (main, Jan 9 2023, 00:00:00) [GCC 11.3.1 20220421 (Red Hat 11.3.1-2)]
jinja version = 3.1.2
libyaml = True
RHEL9
答案1
得分: 4
你把这个过于复杂化了,而且你的 dest
字符串不正确(无论是在你的问题中还是在你的评论中)。
你只需要在一个剧本中定位你的组,并使用这个自然循环来将文件同步到每个目标主机。
- name: 同步我的文件
hosts: mta
tasks:
- name: 使用 rsync 推送文件到目标
ansible.posix.synchronize:
src: "/home/play/tmp/"
dest: "/tmp/"
register: sync_files
英文:
You are making this overly complicated and your dest
string is not correct anyway (either the one in your question or in your comment).
All you need is to target your group in a play and use that natural loop to rsync to each target host.
- name: sync my files
hosts: mta
tasks:
- name: push files to target with rsync
ansible.posix.synchronize:
src: "/home/play/tmp/"
dest: "/tmp/"
register: sync_files
答案2
得分: 2
以下是翻译的内容:
例如,将本地主机的/tmp/foo/
同步到两个远程服务器test_12
和test_13
的/tmp/bar/
。给定以下目录结构:
shell> tree /tmp/foo
/tmp/foo
├── file1
└── file2
0 directories, 2 files
Playbook如下:
shell> cat pb.yml
- hosts: test_12,test_13
tasks:
- ansible.posix.synchronize:
src: /tmp/foo/
dest: /tmp/bar/
register: sync_files
- debug:
var: sync_files.stdout_lines
执行后的输出如下:
shell> ansible-playbook pb.yml
PLAY [test_12,test_13] ***********************************************************************
TASK [ansible.posix.synchronize] *************************************************************
changed: [test_12]
changed: [test_13]
TASK [debug] *********************************************************************************
ok: [test_12] =>
sync_files.stdout_lines:
- .d..t...... ./
- <f+++++++++ file1
- <f+++++++++ file2
ok: [test_13] =>
sync_files.stdout_lines:
- .d..t...... ./
- <f+++++++++ file1
- <f+++++++++ file2
PLAY RECAP ***********************************************************************************
test_12: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_13: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
查看远程主机上的文件:
shell> ssh admin@test_12 ls -1 /tmp/bar/
file1
file2
shell> ssh admin@test_13 ls -1 /tmp/bar/
file1
file2
注意:
-
您的标题说“从本地同步文件到远程主机”,但任务的名称说“在委派主机上使用rsync协议进行同步”。使用rsync协议进行推送需要在目标主机上运行rsync守护进程。请参阅Notes。
-
推送是mode的默认模式。
-
您不必在目标URL中指定ssh协议。查看已注册变量的cmd属性,例如:
cmd: /usr/bin/rsync --delay-updates -F --compress --dry-run --archive --rsh='/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --rsync-path='sudo -u root rsync' --out-format='<
>%i %n%L' /tmp/foo/ admin@test_12:/tmp/bar/ -
您不必委派给本地主机。控制器是默认的来源。
-
不要迭代主机。让它们并行运行既更简单又更快。
英文:
For example, synchronize localhost /tmp/foo/
to /tmp/bar/
on two remote servers test_12 and test_13. Given the tree
shell> tree /tmp/foo
/tmp/foo
├── file1
└── file2
0 directories, 2 files
the playbook
shell> cat pb.yml
- hosts: test_12,test_13
tasks:
- ansible.posix.synchronize:
src: /tmp/foo/
dest: /tmp/bar/
register: sync_files
- debug:
var: sync_files.stdout_lines
gives
shell> ansible-playbook pb.yml
PLAY [test_12,test_13] ***********************************************************************
TASK [ansible.posix.synchronize] *************************************************************
changed: [test_12]
changed: [test_13]
TASK [debug] *********************************************************************************
ok: [test_12] =>
sync_files.stdout_lines:
- .d..t...... ./
- <f+++++++++ file1
- <f+++++++++ file2
ok: [test_13] =>
sync_files.stdout_lines:
- .d..t...... ./
- <f+++++++++ file1
- <f+++++++++ file2
PLAY RECAP ***********************************************************************************
test_12: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
test_13: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Take a look at the files on the remote hosts
shell> ssh admin@test_12 ls -1 /tmp/bar/
file1
file2
shell> ssh admin@test_13 ls -1 /tmp/bar/
file1
file2
<hr>
Notes:
-
Your title says "Synchronise files to remote hosts from local" but the name of the task says "Synchronization using rsync protocol on delegate host (push)". Push using the rsync protocol requires running the rsync daemon on the destination. See the Notes.
-
Push is the default mode
-
You don't have to specify ssh protocol in the destination URL. See the cmd attribute of the registered variable, e.g.
> cmd: /usr/bin/rsync --delay-updates -F --compress --dry-run --archive --rsh='/usr/bin/ssh -S none -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' --rsync-path='sudo -u root rsync' --out-format='<<CHANGED>>%i %n%L' /tmp/foo/ admin@test_12:/tmp/bar/
-
You don't have to delegate to localhost. The controller is the default source.
-
Do not iterate the hosts. It's both simpler and faster to let them run in parallel.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论