Cách sao chép tệp giữa hai nút bằng cách sử dụng ansible


97

Tôi cần sao chép tệp dạng máy A sang máy B trong khi máy điều khiển của tôi từ nơi tôi chạy tất cả các tác vụ có thể thực hiện được của mình là máy C (máy cục bộ)

Tôi đã thử những cách sau:

Sử dụng lệnh scp trong mô-đun shell của ansible

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

Cách tiếp cận này cứ tiếp tục và không bao giờ kết thúc.

sử dụng mô-đun tìm nạp & sao chép

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

Cách tiếp cận này ném cho tôi một lỗi như sau:

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

Bất kỳ đề nghị sẽ là hữu ích.


1. Đây là một tính năng tiện dụng để lưu các truy cập mạng, khi máy điều khiển có thể ở xa hơn; 2.Should được cố định tại mỗi github.com/ansible/ansible/pull/16756 jctanner sáp nhập cam kết 0d94d39 vào ansible: devel vào ngày 23 tháng 9 năm 2016
AnneTheAgile

Câu trả lời:


101

Để sao chép các tệp từ xa sang từ xa, bạn có thể sử dụng mô-đun đồng bộ hóa với delegate_to: source-servertừ khóa '':

- 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 này có thể chạy từ máy của bạnC.


câu trả lời tốt! Rất tiếc, tôi đã không làm cho nó hoạt động trong môi trường Vagrant với nhiều máy ảo. Có vẻ như Vagrant làm điều gì đó đặc biệt ở đó.
therealmarv

Nó sử dụng rsync, bạn đã cài đặt nó trên vm chưa?
ant31

1
Bắt đầu với Vagrant 1.7.x, nó sử dụng các khóa riêng khác nhau tùy theo máy. Xem sự cố github.com/mitchellh/vagrant/issues/4967 Chèn dòng sau vào Vagrantfile config.ssh.insert_key = falseđể buộc Vagrant sử dụng ONE secure_key để truy cập tất cả các máy. Nhưng bây giờ tôi thậm chí không nhận được thông báo lỗi (nó đợi mãi mãi). Ngoài ra lỗi github.com/ansible/ansible/issues/7250 cho biết không thể sao chép từ xa sang điều khiển từ xa.
therealmarv

9
Điều này thực sự sao chép các tệp từ serverB sang serverA. Nếu bạn muốn sao chép chúng từ serverA sang serverB, hãy sử dụng mode=push(hoặc delegate_to: serverB, nhưng không phải cả hai).
Marius Gedminas

2
@MariusGedminas bạn nói đúng, mode=pushnên được sử dụng, nhưng trong tình huống này delegate_to: serverBkhông thể được sử dụng, vì điều đó sẽ làm cho serverBnguồn và đích.
Strahinja Kustudic

95

Như ant31 đã chỉ ra, bạn có thể sử dụng synchronizemô-đun này. Theo mặc định, mô-đun chuyển tệp giữa máy điều khiển và máy chủ từ xa hiện tại ( inventory_host), tuy nhiên, có thể thay đổi delegate_totệp đó bằng cách sử dụng tham số của tác vụ (điều quan trọng cần lưu ý là đây là tham số của tác vụ , không phải của mô-đun).

Bạn có thể đặt nhiệm vụ trên một trong hai ServerAhoặc ServerB, nhưng bạn phải điều chỉnh hướng chuyển cho phù hợp (sử dụng modetham số của synchronize).

Đặt nhiệm vụ vào 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

Điều này sử dụng mặc định mode: push, vì vậy tệp được chuyển từ ủy nhiệm ( ServerA) sang điều khiển từ xa ( ServerB) hiện tại .

Điều này nghe có vẻ lạ, vì nhiệm vụ đã được đặt trên ServerB(qua hosts: ServerB). Tuy nhiên, người ta phải nhớ rằng tác vụ thực sự được thực thi trên máy chủ được ủy quyền , trong trường hợp này là như vậy ServerA. Vì vậy, đẩy (từ ServerAsang ServerB) thực sự là hướng chính xác. Cũng nên nhớ rằng chúng ta không thể đơn giản chọn hoàn toàn không ủy quyền, vì điều đó có nghĩa là việc chuyển giao xảy ra giữa máy điều khiểnServerB.

Đặt nhiệm vụ vào 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

Điều này sử dụng mode: pullđể đảo ngược hướng chuyển giao. Một lần nữa, hãy nhớ rằng tác vụ thực sự được thực thi ServerB, vì vậy kéo là lựa chọn đúng đắn.


8
Đây là một câu trả lời hay, nó phải là một phần của tài liệu Ansible . Không có ví dụ nào giải thích điều này một cách rõ ràng như vậy. Cảm ơn!
ssc

2
Tôi đã thử điều này theo nhiều cách, tuy nhiên, tôi không thành công Warning: Identity file /Users/myuser/.ssh/id_servers not accessible.
orotemo

@orotemo: Không có thêm thông tin, tôi chỉ có thể đoán, nhưng đó có vẻ như là một vấn đề trong thiết lập SSH của bạn. Vui lòng kiểm tra xem bạn đã định cấu hình SSH hoặc Ansible để sử dụng tệp nhận dạng được cung cấp trong thông báo lỗi hay không và tệp đó có tồn tại và có quyền phù hợp hay không.
Florian Brucker

2
@WilliamTurrell Tôi đã cập nhật câu trả lời của mình để giải thích chi tiết hơn về hướng chuyển. Mô-đun thực sự là một chút khó hiểu.
Florian Brucker

1
Cảm ơn. Đối với bất kỳ ai khác gặp sự cố của @ orotemo, giải pháp có thể xảy ra là bạn không có bất kỳ quyền truy cập khóa công khai nào giữa các máy chủ A và B, hoặc như tôi thấy, bạn đã thiết lập nó chỉ hoạt động theo một hướng - một hướng sai. Trong trường hợp không có bất kỳ cặp khóa nào trong thư mục .ssh của bạn trên máy chủ A, không thể sử dụng được thư mục chính của máy cục bộ của bạn (sẽ không tồn tại nếu nó là máy Mac và có thể có tên tài khoản khác.)
William Turrell,

2

Tôi đã có thể giải quyết vấn đề này bằng cách sử dụng local_action để chuyển sang tệp từ machineA sang machineC và sau đó sao chép tệp vào machineB.


2

Nếu bạn cần đồng bộ hóa tệp giữa hai nút từ xa qua ansible, bạn có thể sử dụng điều này:

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

khi remote_serverbạn cần khởi động rsync với chế độ daemon. Ví dụ đơn giản:

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

Một cách đơn giản để sử dụng mô-đun sao chép để chuyển tệp từ máy chủ này sang máy chủ khác

Đây là sách vở

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

Điều này nổi lên trong một phiên hôm nay, nhưng không ai trong chúng tôi có thể lặp lại điều này bằng cách sử dụng ansible 2.6.4. Việc đưa tác vụ này vào playbook với việc tạo tệp trên machine1 trước và liệt kê thư mục sau đó không thành công với "Không thể tìm thấy hoặc truy cập '/ tmp / source-49731914' trên Bộ điều khiển Ansible." Tạo một tệp trống trên máy chủ đã giải quyết được vấn đề này, nhưng máy chủ lưu trữ sao chép> machine2 đã giải quyết được. Có thể có một hành vi lỗi trong một số phiên bản?
Stephan B

0

Nếu bạn muốn thực hiện rsync và sử dụng người dùng tùy chỉnh và khóa ssh tùy chỉnh, bạn cần viết khóa này trong tùy chọn 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

Bạn cũng có thể sử dụng deletgatevới 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

delegatelệnh được chạy trên máy chủ khác và nó scplà tệp của chính nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.