Jak kopiować pliki między dwoma węzłami za pomocą ansible

97

Muszę skopiować plik z komputera A na komputer B, podczas gdy moją maszyną sterującą, z której uruchamiam wszystkie moje zadania ansible, jest komputer C (komputer lokalny)

Próbowałem następujących rzeczy:

Użyj polecenia scp w module powłoki ansibla

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

To podejście po prostu trwa i nigdy się nie kończy.

użyj modułów pobierania i kopiowania

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

Takie podejście generuje następujący błąd:

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

Wszelkie sugestie byłyby pomocne.

user3228188
źródło
1. Jest to przydatna funkcja umożliwiająca zapisywanie dostępu do sieci, gdy maszyna sterująca może być dalej; 2. Powinno zostać naprawione teraz na github.com/ansible/ansible/pull/16756 jctanner, połączone zatwierdzenie 0d94d39 w ansible: devel, 23 września 2016 r.
AnneTheAgile

Odpowiedzi:

101

Aby skopiować pliki zdalne na zdalne, możesz użyć modułu synchronizacji ze delegate_to: source-serversłowem kluczowym „ ”:

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

Ten podręcznik można uruchomić z poziomu komputera C.

ant31
źródło
dobra odpowiedź! Niestety nie udało mi się go uruchomić w środowisku Vagrant z wieloma maszynami wirtualnymi. Wygląda na to, że Vagrant robi tam coś specjalnego.
therealmarv
Używa rsync, czy masz go zainstalowanego na vm?
ant31
1
Począwszy od wersji Vagrant 1.7.x używa różnych kluczy prywatnych w zależności od komputera. Zobacz wydanie github.com/mitchellh/vagrant/issues/4967 Wstaw następujący wiersz do pliku Vagrantfile, config.ssh.insert_key = falseaby zmusić Vagrant do użycia JEDNEGO insecure_key w celu uzyskania dostępu do wszystkich maszyn. Ale teraz nawet nie dostaję komunikatu o błędzie (czeka wiecznie). Również błąd github.com/ansible/ansible/issues/7250 mówi, że nie można kopiować ze zdalnego na zdalny.
therealmarv
9
To faktycznie kopiuje pliki z serverB do serverA. Jeśli chcesz skopiować je z serwera A na serwer B, użyj mode=push(lub delegate_to: serverB, ale nie obu).
Marius Gedminas
2
@MariusGedminas masz rację, mode=pushnależy użyć, ale w tej sytuacji delegate_to: serverBnie można go użyć, ponieważ spowodowałoby serverBto źródło i cel.
Strahinja Kustudic
95

Jak już wskazał ant31, możesz użyć synchronizedo tego modułu. Domyślnie moduł przesyła pliki między maszyną sterującą a bieżącym zdalnym hostem ( inventory_host), jednak można to zmienić za pomocą delegate_toparametru zadania (należy zauważyć, że jest to parametr zadania , a nie modułu).

Możesz umieścić zadanie na albo ServerAlub ServerB, ale musisz odpowiednio dostosować kierunek transferu (za pomocą modeparametru synchronize).

Włączanie zadania 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

Używa wartości domyślnej mode: push, więc plik zostanie przesłany z delegate ( ServerA) do bieżącego remote ( ServerB).

Może to brzmieć dziwnie, ponieważ zadanie zostało umieszczone na ServerB(via hosts: ServerB). Należy jednak pamiętać, że zadanie jest faktycznie wykonywane na hoście delegowanym , którym w tym przypadku jest ServerA. Zatem pchanie (od ServerAdo ServerB) jest rzeczywiście właściwym kierunkiem. Pamiętaj również, że nie możemy po prostu zrezygnować z delegowania w ogóle, ponieważ oznaczałoby to, że transfer odbywa się między maszyną sterującą a ServerB.

Włączanie zadania 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

Służy mode: pulldo odwrócenia kierunku transferu. Ponownie pamiętaj, że zadanie jest faktycznie wykonywane ServerB, więc ciągnięcie jest właściwym wyborem.

Florian Brucker
źródło
8
To jest tak dobra odpowiedź, że powinna być częścią dokumentacji Ansible . Żaden z przytoczonych tam przykładów nie wyjaśnia tego w tak jasny sposób. Dzięki!
ssc
2
Próbowałem tego na wiele sposobów, jednak zawodzi mnie Warning: Identity file /Users/myuser/.ssh/id_servers not accessible.
orotemo
@orotemo: Bez dalszych informacji mogę tylko zgadywać, ale wygląda to na problem z konfiguracją SSH. Sprawdź, czy skonfigurowałeś SSH lub Ansible do korzystania z pliku tożsamości podanego w komunikacie o błędzie i czy ten plik istnieje i ma odpowiednie uprawnienia.
Florian Brucker
2
@WilliamTurrell Zaktualizowałem moją odpowiedź, aby bardziej szczegółowo wyjaśnić kierunek transferu. Moduł jest rzeczywiście nieco zagmatwany.
Florian Brucker
1
Dzięki. Dla każdego, kto ma problem z @ orotemo, prawdopodobnym rozwiązaniem jest to, że nie masz dostępu do klucza publicznego między serwerami A i B lub, jak odkryłem, ustawiłeś go tak, aby działał tylko w jednym kierunku - niewłaściwym. W przypadku braku pary kluczy w katalogu .ssh na serwerze A, ansible próbuje użyć katalogu domowego twojego komputera lokalnego (który nie będzie istniał, jeśli jest to, powiedzmy, komputer Mac i może mieć inną nazwę konta).
William Turrell
3

Jeśli chcesz zsynchronizować pliki między dwoma zdalnymi węzłami za pośrednictwem ansible, możesz użyć tego:

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

kiedy jest włączony remote_server, musisz uruchomić rsync w trybie demona. Prosty przykład:

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
źródło
2

Udało mi się rozwiązać ten problem, używając lokalnego polecenia scp do pliku z komputera A do komputera C, a następnie kopiując plik do komputera B.

user3228188
źródło
1

Prosty sposób wykorzystania modułu kopiowania do przesłania pliku z jednego serwera na drugi

Oto poradnik

---
- 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
źródło
To wypłynęło podczas dzisiejszej sesji, ale żadne z nas nie mogło tego powtórzyć za pomocą ansible 2.6.4. Umieszczenie tego zadania w playbooku z utworzeniem najpierw pliku na komputerze 1, a następnie wyświetleniem katalogu nie powiodło się z komunikatem „Nie można znaleźć / tmp / source-49731914” lub uzyskać do niego dostępu na kontrolerze Ansible ”. Utworzenie pustego pliku na maszynie hosta rozwiązało problem, ale wykonało kopię hosta> maszyna2. Może w jakiejś wersji było jakieś błędne zachowanie?
Stephan B
0

Jeśli chcesz wykonać rsync i użyć niestandardowego użytkownika i niestandardowego klucza ssh, musisz wpisać ten klucz w opcjach 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
źródło
0

Możesz użyć również deletgatez 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

Ponieważ delegatepolecenie jest uruchamiane na innym serwerze i jest scpplikiem dla siebie.

Kris
źródło