Cara menyalin file antara dua node menggunakan ansible

97

Saya perlu menyalin file dari mesin A ke mesin B sedangkan mesin kontrol saya dari mana saya menjalankan semua tugas yang mungkin saya adalah mesin C (mesin lokal)

Saya telah mencoba yang berikut ini:

Gunakan perintah scp dalam modul shell dari ansible

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

Pendekatan ini terus berjalan dan tidak pernah berakhir.

gunakan modul ambil & salin

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

Pendekatan ini memberi saya kesalahan sebagai berikut:

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>'

Setiap saran akan membantu.

pengguna3228188
sumber
1. Ini adalah fitur yang berguna untuk menyimpan akses jaringan, ketika mesin kontrol mungkin lebih jauh; 2. Harus diperbaiki sekarang per github.com/ansible/ansible/pull/16756 jctanner menggabungkan komit 0d94d39 menjadi ansible: dikembangkan pada 23 Sep 2016
AnneTheAgile

Jawaban:

101

Untuk menyalin file dari jarak jauh, Anda dapat menggunakan modul sinkronisasi dengan delegate_to: source-serverkata kunci ' ':

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

Playbook ini dapat dijalankan dari mesin AndaC.

ant31
sumber
jawaban yang bagus! Sayangnya saya tidak membuatnya berfungsi di lingkungan gelandangan dengan multi VM. Sepertinya Vagrant melakukan sesuatu yang spesial di sana.
therealmarv
Ini menggunakan rsync, apakah Anda sudah menginstalnya di vm?
ant31
1
Dimulai dengan Vagrant 1.7.x, ia menggunakan kunci pribadi yang berbeda tergantung pada mesin. Lihat masalah github.com/mitchellh/vagrant/issues/4967 Masukkan baris berikut ke dalam Vagrantfile config.ssh.insert_key = falseuntuk memaksa Vagrant menggunakan SATU insecure_key untuk mengakses semua mesin. Tapi sekarang saya bahkan tidak mendapatkan pesan kesalahan (menunggu selamanya). Juga bug github.com/ansible/ansible/issues/7250 mengatakan bahwa tidak mungkin menyalin dari jarak jauh ke jarak jauh.
therealmarv
9
Ini sebenarnya menyalin file dari serverB ke serverA. Jika Anda ingin menyalinnya dari serverA ke serverB, gunakan mode=push(atau delegate_to: serverB, tetapi tidak keduanya).
Marius Gedminas
2
@MariusGedminas Anda sudah benar, mode=pushharus digunakan, tetapi dalam situasi delegate_to: serverBini tidak dapat digunakan, karena itu akan membuat serverBsumber dan tujuan.
Strahinja Kustudic
95

Seperti yang telah ditunjukkan oleh ant31, Anda dapat menggunakan synchronizemodul untuk ini. Secara default, modul mentransfer file antara mesin kontrol dan host jarak jauh saat ini ( inventory_host), namun hal itu dapat diubah menggunakan delegate_toparameter tugas (penting untuk diperhatikan bahwa ini adalah parameter tugas , bukan modul).

Anda dapat menempatkan tugas di salah satu ServerAatau ServerB, tetapi Anda harus menyesuaikan arah transfer yang sesuai (menggunakan modeparameter synchronize).

Menempatkan tugas di 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

Ini menggunakan default mode: push, sehingga file ditransfer dari delegate ( ServerA) ke remote ( ServerB) saat ini.

Ini mungkin terdengar aneh, karena tugas telah ditempatkan pada ServerB(melalui hosts: ServerB). Namun, harus diingat bahwa tugas sebenarnya dijalankan pada host yang didelegasikan , yang dalam hal ini adalah ServerA. Jadi mendorong (dari ServerAke ServerB) memang arah yang benar. Juga ingat bahwa kita tidak bisa begitu saja memilih untuk tidak mendelegasikan sama sekali, karena itu berarti transfer terjadi antara mesin kontrol dan ServerB.

Menempatkan tugas di 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

Ini digunakan mode: pulluntuk membalikkan arah transfer. Sekali lagi, perlu diingat bahwa tugas sebenarnya dijalankan ServerB, jadi menarik adalah pilihan yang tepat.

Florian Brucker
sumber
8
Ini adalah jawaban yang bagus sehingga harus menjadi bagian dari dokumentasi Ansible . Tak satu pun dari contoh di sana menjelaskan hal ini dengan cara yang begitu jelas. Terima kasih!
ssc
2
Saya telah mencoba ini dengan berbagai cara, namun gagal Warning: Identity file /Users/myuser/.ssh/id_servers not accessible.
orotemo
@orotemo: Tanpa informasi lebih lanjut, saya hanya bisa menebak, tapi sepertinya ada masalah dalam penyiapan SSH Anda. Harap periksa apakah Anda telah mengkonfigurasi SSH atau Ansible untuk menggunakan file identitas yang diberikan dalam pesan kesalahan dan apakah file itu ada dan memiliki izin yang tepat.
Florian Brucker
2
@WilliamTurrell Saya telah memperbarui jawaban saya untuk menjelaskan arah transfer secara lebih rinci. Modulnya memang agak membingungkan.
Florian Brucker
1
Terima kasih. Bagi siapa pun yang memiliki masalah @ orotemo, solusi yang mungkin adalah Anda hanya tidak memiliki akses kunci publik antara server A dan B, atau seperti yang saya temukan, Anda telah mengaturnya untuk hanya bekerja dalam satu arah - yang salah. Jika tidak ada keypair apa pun di direktori .ssh Anda di server A, kemungkinan upaya untuk menggunakan direktori home mesin lokal Anda (yang tidak akan ada jika itu, katakanlah, Mac, dan mungkin memiliki nama akun yang berbeda.)
William Turrell
2

Saya dapat menyelesaikan ini menggunakan local_action ke scp ke file dari machineA ke machineC dan kemudian menyalin file ke machineB.

pengguna3228188
sumber
2

Jika Anda perlu menyinkronkan file antara dua node jarak jauh melalui ansible, Anda dapat menggunakan ini:

- 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 }}"

saat di remote_serverAnda perlu memulai rsync dengan mode daemon. Contoh sederhana:

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
CrusaderX
sumber
1

Cara sederhana untuk menggunakan modul salin untuk mentransfer file dari satu server ke server lain

Ini playbook

---
- 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}
Aliabbas Kothawala
sumber
Ini mengambang selama sesi hari ini, tetapi tak satu pun dari kami dapat meniru ini menggunakan 2.6.4. Menempatkan tugas ini ke dalam pedoman dengan membuat file di mesin1 terlebih dahulu dan mencantumkan direktori setelahnya gagal dengan "Tidak dapat menemukan atau mengakses '/ tmp / source-49731914' di Ansible Controller." Membuat file kosong pada mesin host memecahkannya, tetapi melakukan copy host> machine2. Mungkinkah ada perilaku buggy di beberapa versi?
Stephan B
0

Jika Anda ingin melakukan rsync dan menggunakan pengguna kustom dan kunci ssh kustom, Anda perlu menulis kunci ini di opsi rsync.

---
 - 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
Sasha Golikov
sumber
0

Anda juga dapat menggunakan deletgatedengan scp:

- 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

Karena delegateperintah dijalankan di server lain dan itu scpadalah file itu sendiri.

Keris
sumber