Kopieren von Dateien zwischen zwei Knoten mit ansible

97

Ich muss die Datei von Maschine A auf Maschine B kopieren, während meine Kontrollmaschine, von der aus ich alle meine ansible Aufgaben ausführe, Maschine C (lokale Maschine) ist.

Ich habe folgendes versucht:

Verwenden Sie den Befehl scp im Shell-Modul von ansible

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

Dieser Ansatz geht einfach weiter und endet nie.

Verwenden Sie Fetch & Copy-Module

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

Dieser Ansatz führt zu einem Fehler wie folgt:

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

Anregungen wären hilfreich.

user3228188
quelle
1.Dies ist eine praktische Funktion zum Speichern von Netzwerkzugriffen, wenn die Steuerungsmaschine möglicherweise weiter entfernt ist. 2. Sollte jetzt per github.com/ansible/ansible/pull/16756 behoben werden. Jctanner hat Commit 0d94d39 in Ansible zusammengeführt. Entwickelt am 23. September 2016
AnneTheAgile

Antworten:

101

Um Remote-zu-Remote-Dateien zu kopieren, können Sie das Synchronisierungsmodul mit delegate_to: source-serverdem Schlüsselwort ' ' verwenden:

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

Dieses Playbook kann von Ihrem Computer aus ausgeführt werden.

ant31
quelle
gute Antwort! Leider habe ich es in einer Vagrant-Umgebung mit mehreren VMs nicht zum Laufen gebracht. Vagrant scheint dort etwas Besonderes zu tun.
Therealmarv
Es verwendet rsync. Haben Sie es auf VM installiert?
Ant31
1
Ab Vagrant 1.7.x werden je nach Computer unterschiedliche private Schlüssel verwendet. Siehe Ausgabe github.com/mitchellh/vagrant/issues/4967 Fügen Sie die folgende Zeile in die config.ssh.insert_key = falseVagrant- Datei ein , um Vagrant zu zwingen, den EINEN unsicheren_Schlüssel für den Zugriff auf alle Computer zu verwenden. Aber jetzt bekomme ich sogar keine Fehlermeldung (es wartet ewig). Auch Fehler github.com/ansible/ansible/issues/7250 besagt, dass es nicht möglich ist, von Remote zu Remote zu kopieren.
Therealmarv
9
Dadurch werden die Dateien tatsächlich von Server B nach Server A kopiert. Wenn Sie sie von ServerA nach ServerB kopieren möchten, verwenden Sie mode=push(oder delegate_to: serverB, aber nicht beide).
Marius Gedminas
2
@MariusGedminas Sie sind richtig, mode=pushsollte verwendet werden, aber in dieser Situationdelegate_to: serverB nicht verwendet werden, da dies serverBdie Quelle und das Ziel machen würde .
Strahinja Kustudic
95

Wie bereits von ant31 erwähnt, können Sie das synchronizeModul dazu verwenden. Standardmäßig überträgt das Modul Dateien zwischen dem Steuergerät und dem aktuellen Remote-Host ( inventory_host). delegate_toDiese können jedoch mithilfe des Task- Parameters geändert werden (es ist wichtig zu beachten, dass dies ein Parameter der Task und nicht des Moduls ist).

Sie können die Aufgabe entweder auf ServerAoder platzieren ServerB, müssen jedoch die Übertragungsrichtung entsprechend anpassen (mit dem modeParameter von synchronize).

Aufgabe aufsetzen 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

Dies verwendet die Standardeinstellung mode: push, sodass die Datei vom delegate ( ServerA) auf die aktuelle remote ( ServerB) übertragen wird.

Dies mag seltsam klingen, da die Aufgabe aktiviert wurde ServerB(viahosts: ServerB ) gestellt wurde. Es ist jedoch zu beachten, dass die Aufgabe tatsächlich auf dem delegierten Host ausgeführt wird , in diesem Fall ServerA. Das Drücken (von ServerAnach ServerB) ist also in der Tat die richtige Richtung. Denken Sie auch daran, dass wir uns nicht einfach dafür entscheiden können, überhaupt nicht zu delegieren, da dies bedeuten würde, dass die Übertragung zwischen der Steuerungsmaschine und erfolgt ServerB.

Aufgabe aufsetzen 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

Dies verwendet mode: pull , um die Übertragungsrichtung umzukehren. Denken Sie auch hier daran, dass die Aufgabe tatsächlich ausgeführt wird ServerB, sodass das Ziehen die richtige Wahl ist.

Florian Brucker
quelle
8
Dies ist eine so gute Antwort, dass sie Teil der Ansible-Dokumentation sein sollte . Keines der dortigen Beispiele erklärt dies so deutlich. Vielen Dank!
SSC
2
Ich habe dies auf vielfältige Weise versucht, scheitert aber an mir Warning: Identity file /Users/myuser/.ssh/id_servers not accessible.
Orotemo
@orotemo: Ohne weitere Informationen kann ich nur raten, aber das scheint ein Problem in Ihrem SSH-Setup zu sein. Überprüfen Sie, ob Sie SSH oder Ansible für die Verwendung der in der Fehlermeldung angegebenen Identitätsdatei konfiguriert haben und ob diese Datei vorhanden ist und über die richtigen Berechtigungen verfügt.
Florian Brucker
2
@WilliamTurrell Ich habe meine Antwort aktualisiert, um die Übertragungsrichtung genauer zu erläutern. Das Modul ist in der Tat etwas verwirrend.
Florian Brucker
1
Vielen Dank. Für alle anderen, die das Problem von @ orotemo haben, besteht die wahrscheinliche Lösung darin, dass Sie nur keinen öffentlichen Schlüsselzugriff zwischen den Servern A und B haben, oder wie ich festgestellt habe, haben Sie ihn so eingerichtet, dass er nur in eine Richtung funktioniert - in die falsche. Wenn in Ihrem .ssh-Verzeichnis auf Server A kein Schlüsselpaar vorhanden ist, versucht ansible, das Home-Verzeichnis Ihres lokalen Computers zu verwenden (das nicht vorhanden ist, wenn es sich beispielsweise um einen Mac handelt und möglicherweise einen anderen Kontonamen hat.)
William Turrell
2

Ich konnte dies mit local_action lösen, um von Maschine A nach Maschine C zu scp und dann die Datei nach Maschine B zu kopieren.

user3228188
quelle
2

Wenn Sie Dateien zwischen zwei Remote-Knoten über ansible synchronisieren müssen, können Sie Folgendes verwenden:

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

Wenn remote_serverdiese Option aktiviert ist, müssen Sie rsync im Dämonmodus starten. Einfaches Beispiel:

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
quelle
1

Eine einfache Möglichkeit, das Kopiermodul zum Übertragen der Datei von einem Server auf einen anderen zu verwenden

Hier ist ein Spielbuch

---
- 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
quelle
Dies trat heute während einer Sitzung auf, aber keiner von uns konnte dies mit ansible 2.6.4 replizieren. Das Einfügen dieser Aufgabe in ein Playbook mit dem Erstellen einer Datei auf Maschine1 und dem anschließenden Auflisten des Verzeichnisses schlug fehl mit "Auf dem Ansible Controller konnte '/ tmp / source-49731914' auf dem Ansible Controller nicht gefunden werden." Das Erstellen einer leeren Datei auf dem Host-Computer löste das Problem, kopierte jedoch Host> machine2. Vielleicht gab es in einer Version ein fehlerhaftes Verhalten?
Stephan B
0

Wenn Sie rsync ausführen und einen benutzerdefinierten Benutzer und einen benutzerdefinierten ssh-Schlüssel verwenden möchten, müssen Sie diesen Schlüssel in die rsync-Optionen schreiben.

---
 - 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
quelle
0

Sie können auch verwenden deletgatemit 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

Aufgrund des delegateBefehls wird auf dem anderen Server ausgeführt und es ist scpdie Datei für sich.

Kris
quelle