Як скопіювати файли між двома вузлами за допомогою ansible


97

Мені потрібно скопіювати машину у формі файлу A на машину B, тоді як моя машина управління, звідки я запускаю всі свої завдання, відповідає машині C (локальна машина)

Я спробував таке:

Використовуйте команду scp в оболонковому модулі ansible

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

Будь-які пропозиції були б корисними.


1.Це зручна функція для збереження доступу до мережі, коли машина управління може бути далі; 2.Це має бути виправлено зараз за github.com/ansible/ansible/pull/16756 jctanner об'єднав коміт 0d94d39 в ansible: devel 23 вересня 2016 р.
AnneTheAgile 02

Відповіді:


101

Для копіювання віддалених віддалених файлів ви можете використовувати модуль синхронізації з 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

Цей посібник можна запускати з вашого комп'ютераC.


хороша відповідь! На жаль, я не змусив це працювати у бродячому середовищі з кількома VM. Здається, Вагрант робить щось там особливе.
therealmarv

Він використовує rsync, чи встановлений він у vm?
ant31

1
Починаючи з Vagrant 1.7.x, він використовує різні приватні ключі залежно від машини. Див. Випуск github.com/mitchellh/vagrant/issues/4967 Вставте наступний рядок у файл config.ssh.insert_key = falseVagrant, щоб змусити Vagrant використовувати ОДИН unscure_key для доступу до всіх машин. Але зараз я навіть не отримую повідомлення про помилку (воно чекає вічно). Також помилка github.com/ansible/ansible/issues/7250 каже, що неможливо скопіювати з віддаленого на віддалений.
therealmarv

9
Це фактично копіює файли з serverB на serverA. Якщо ви хочете скопіювати їх з serverA на serverB, використовуйте mode=push(або delegate_to: serverB, але не обидва).
Маріус Гедмінас

2
@MariusGedminas ви маєте рацію, mode=pushслід використовувати, але в цій ситуації delegate_to: serverBвикористовувати не можна, оскільки це зробить serverBджерелом і пунктом призначення.
Strahinja Kustudic

95

Як вже зазначав ant31, ви можете використовувати synchronizeмодуль для цього. За замовчуванням модуль передає файли між машиною управління та поточним віддаленим хостом ( inventory_host), однак це можна змінити за допомогою параметра завдання delegate_to(важливо зазначити, що це параметр завдання , а не модуля).

Ви можете розмістити завдання або на, ServerAабо ServerB, але вам потрібно відповідно відрегулювати напрямок передачі (використовуючи modeпараметр synchronize).

Розміщення завдання на 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

Для цього використовується за замовчуванням mode: push, тому файл передається від делегата ( ServerA) до поточного віддаленого ( ServerB).

Це може здатися дивним, оскільки завдання було розміщено ServerB(через hosts: ServerB). Однак слід пам’ятати, що завдання фактично виконується на делегованому хості , що в даному випадку є ServerA. Тож натискання (від ServerAдо ServerB) справді правильний напрямок. Також пам’ятайте, що ми не можемо просто не відмовлятись взагалі, оскільки це означало б, що передача відбувається між машиною управління та 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, тож тягнути - це правильний вибір.


8
Це така гарна відповідь, що вона повинна бути частиною документації Ansible . Жоден із прикладів там не пояснює це так чітко. Дякую!
ssc

2
Я пробував це по-різному, проте не вдається Warning: Identity file /Users/myuser/.ssh/id_servers not accessible.
orotemo

@orotemo: Без додаткової інформації я можу лише здогадуватися, але це виглядає як проблема у вашому налаштуванні SSH. Будь ласка, перевірте, чи ви налаштували SSH або Ansible для використання файлу ідентифікації, вказаного в повідомленні про помилку, і чи існує цей файл та має належні дозволи.
Флоріан Брукер

2
@WilliamTurrell Я оновив свою відповідь, щоб детальніше пояснити напрямок передачі. Модуль справді трохи заплутаний.
Флоріан Брукер

1
Дякую. Для тих, хто має проблему @ orotemo, ймовірне рішення полягає лише в тому, що ви не маєте доступу до відкритого ключа між серверами A і B, або, як я з'ясував, ви налаштували його працювати лише в одному напрямку - неправильному. Якщо у вашому .ssh-каталозі на сервері A відсутні будь-які ключі, кореспонденція намагається використовувати домашній каталог вашої локальної машини (який не буде існувати, якщо це, скажімо, Mac та може мати іншу назву облікового запису.)
Вільям Туррелл

2

Я зміг вирішити це за допомогою local_action для scp у файл з machineA на machineC, а потім скопіював файл на machineB.


2

Якщо вам потрібно синхронізувати файли між двома віддаленими вузлами через ansible, ви можете скористатися цим:

- 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

1

Простий спосіб використаного модуля копіювання для передачі файлу з одного сервера на інший

Ось іграшка

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

Це випливало під час сеансу сьогодні, але ніхто з нас не міг повторити це, використовуючи функціональну 2.6.4. Помістити це завдання в програму зі створення файлу на машині1, а потім перерахувати каталог після цього не вдалося: "Не вдалося знайти або отримати доступ до '/ tmp / source-49731914' на контролері Ansible". Створення порожнього файлу на хост-машині вирішило це, але зробило хост копіювання> machine2. Можливо, в якійсь версії була поведінка баггі?
Стефан Б

0

Якщо ви хочете зробити rsync та використовувати користувальницький та користувальницький ключ ssh, вам потрібно написати цей ключ у параметрах 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

0

Ви можете використовувати і deletgateз 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

Через delegateце команда виконується на іншому сервері, і це scpфайл для себе.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.