วิธีคัดลอกไฟล์ระหว่างสองโหนดโดยใช้ ansible


101

ฉันต้องการคัดลอกไฟล์ฟอร์มเครื่อง 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

คำตอบ:


102

ในการคัดลอกไฟล์จากระยะไกลสู่ระยะไกลคุณสามารถใช้โมดูลซิงโครไนซ์ด้วย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

Playbook นี้สามารถเรียกใช้จากเครื่องของคุณ C.


คำตอบที่ดี! น่าเสียดายที่ฉันไม่ได้ทำให้มันทำงานในสภาพแวดล้อม Vagrant ที่มี VM หลายเครื่อง ดูเหมือนว่า Vagrant จะทำอะไรพิเศษที่นั่น
therealmarv

มันใช้ rsync คุณติดตั้งบน vm หรือไม่?
มด 31

2
เริ่มต้นด้วย Vagrant 1.7.x จะใช้คีย์ส่วนตัวที่แตกต่างกันขึ้นอยู่กับเครื่อง ดูปัญหาgithub.com/mitchellh/vagrant/issues/4967แทรกบรรทัดต่อไปนี้ใน Vagrantfile config.ssh.insert_key = falseเพื่อบังคับให้ Vagrant ใช้ ONE insecure_key เพื่อเข้าถึงทุกเครื่อง แต่ตอนนี้ฉันยังไม่ได้รับข้อความแสดงข้อผิดพลาด (รอตลอดไป) ข้อผิดพลาดgithub.com/ansible/ansible/issues/7250กล่าวว่าไม่สามารถคัดลอกจากระยะไกลไปยังระยะไกลได้
therealmarv

9
นี่เป็นการคัดลอกไฟล์จากเซิร์ฟเวอร์ B ไปยังเซิร์ฟเวอร์ หากคุณต้องการคัดลอกจากเซิร์ฟเวอร์ A ไปยังเซิร์ฟเวอร์ B ให้ใช้mode=push(หรือdelegate_to: serverBแต่ไม่ใช่ทั้งสองอย่าง)
Marius Gedminas

2
@MariusGedminas คุณถูกต้องmode=pushควรใช้ แต่ในสถานการณ์นี้delegate_to: serverBใช้ไม่ได้เพราะจะทำให้serverBต้นทางและปลายทาง
Strahinja Kustudic

96

ตามที่ 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
นี่คือคำตอบที่ดีเช่นมันควรจะเป็นส่วนหนึ่งของเอกสารเบิ้ล ไม่มีตัวอย่างใดที่อธิบายเรื่องนี้ได้อย่างชัดเจน ขอบคุณ!
ssc

2
ฉันได้พยายามนี้ในหลายวิธี Warning: Identity file /Users/myuser/.ssh/id_servers not accessibleแต่ล้มเหลวฉันบน
orotemo

@orotemo: หากไม่มีข้อมูลเพิ่มเติมฉันสามารถเดาได้ แต่ดูเหมือนว่าจะมีปัญหาในการตั้งค่า SSH ของคุณ โปรดตรวจสอบว่าคุณได้กำหนดค่า SSH หรือ Ansible ให้ใช้ไฟล์ข้อมูลประจำตัวที่ระบุในข้อความแสดงข้อผิดพลาดหรือไม่และไฟล์นั้นมีอยู่และมีสิทธิ์ที่ถูกต้องหรือไม่
Florian Brucker

2
@WilliamTurrell ฉันได้อัปเดตคำตอบของฉันเพื่ออธิบายทิศทางการถ่ายโอนในรายละเอียดเพิ่มเติม โมดูลนี้ค่อนข้างสับสน
Florian Brucker

1
ขอบคุณ. สำหรับใครก็ตามที่มีปัญหาของ @ orotemo วิธีแก้ปัญหาที่เป็นไปได้คือคุณไม่มีการเข้าถึงคีย์สาธารณะระหว่างเซิร์ฟเวอร์ A และ B หรืออย่างที่ฉันพบคุณได้ตั้งค่าให้ทำงานในทิศทางเดียวเท่านั้น - ผิด ในกรณีที่ไม่มีคู่คีย์ใด ๆ ในไดเร็กทอรี. ssh ของคุณบนเซิร์ฟเวอร์ A ความพยายามที่จะใช้โฮมไดเร็กทอรีของเครื่องในพื้นที่ของคุณเป็นไปได้ (ซึ่งจะไม่มีอยู่หากเป็นเช่น Mac และอาจมีชื่อบัญชีอื่น)
William Turrell

3

หากคุณต้องการซิงค์ไฟล์ระหว่างสองโหนดระยะไกลผ่าน 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 ด้วยโหมด daemon ตัวอย่างง่ายๆ:

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

2

ฉันสามารถแก้ปัญหานี้ได้โดยใช้ local_action เพื่อ scp ไปยังไฟล์จาก machineA ไปยัง machineC แล้วคัดลอกไฟล์ไปยัง machineB


1

วิธีง่ายๆในการใช้โมดูลการคัดลอกเพื่อถ่ายโอนไฟล์จากเซิร์ฟเวอร์หนึ่งไปยังอีกเซิร์ฟเวอร์หนึ่ง

นี่คือ 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}

สิ่งนี้ลอยขึ้นระหว่างเซสชันวันนี้ แต่เราทั้งคู่ไม่สามารถจำลองสิ่งนี้ได้โดยใช้ ansible 2.6.4 การใส่งานนี้ลงใน playbook ด้วยการสร้างไฟล์บน machine1 ก่อนและแสดงรายการไดเร็กทอรีหลังจากนั้นล้มเหลวด้วย "ไม่พบหรือเข้าถึง" / tmp / source-49731914 "บน Ansible Controller" การสร้างไฟล์เปล่าบนเครื่องโฮสต์แก้ไขได้ แต่คัดลอกโฮสต์> machine2 อาจมีพฤติกรรมบั๊กกี้ในบางเวอร์ชัน?
Stephan B

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เป็นไฟล์ไปเอง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.