Bagaimana Docker Swarm mengimplementasikan berbagi volume?

93

Docker Swarm dapat mengelola dua jenis penyimpanan:

volume dan bind

Meskipun bindtidak disarankan oleh Dokumentasi Docker karena ini membuat pengikatan antara direktori lokal (pada setiap swarm Node) ke suatu tugas, volumeimplementasinya tidak disebutkan, jadi saya tidak mengerti bagaimana volume dibagi antar tugas?

  • Bagaimana Docker Swarm berbagi volume antar node?
  • Di mana volume disimpan (pada seorang manajer? Dan jika ada lebih dari satu manajer?)
  • Apakah tidak ada masalah antar node jika dijalankan pada mesin yang berbeda di jaringan yang berbeda?
  • Apakah itu membuat VPN?
alessandro308
sumber
1
Apakah Swarm berbagi volume? Sekitar setahun yang lalu saya berurusan dengan kawanan buruh pelabuhan, tapi menurut saya swarm TIDAK bertanggung jawab untuk berbagi volume antar node. Jika Anda ingin node Anda berbagi volume yang sama, Anda harus menggunakan plugin volume seperti azure volumedriver.
Munchkin

Jawaban:

66

Apa yang Anda tanyakan adalah pertanyaan umum. Data volume dan fitur yang dapat dilakukan volume tersebut dikelola oleh pengandar volume. Sama seperti Anda dapat menggunakan driver jaringan yang berbeda seperti overlay, bridge, atau host, Anda dapat menggunakan driver volume yang berbeda.

Docker dan Swarm hanya hadir dengan localdriver standar di luar kotak. Itu tidak memiliki kesadaran Swarm, dan itu hanya akan membuat volume baru untuk data Anda di node mana pun tugas layanan Anda dijadwalkan. Ini biasanya bukan yang Anda inginkan.

Anda menginginkan plugin driver pihak ketiga yang sadar Swarm, dan akan memastikan volume yang Anda buat untuk tugas layanan tersedia di node yang tepat pada waktu yang tepat. Opsinya termasuk menggunakan "Docker untuk AWS / Azure" dan driver CloudStor yang disertakan , atau solusi REX-Ray open source yang populer .

Ada banyak driver volume pihak ke-3, yang dapat Anda temukan di Docker Store .

Bret Fisher
sumber
dapatkah hadoop bertindak sebagai volume bersama?
stackit
55

Swarm Mode itu sendiri tidak melakukan sesuatu yang berbeda dengan volume, ia menjalankan perintah volume mount yang Anda berikan pada node tempat container sedang berjalan. Jika volume mount Anda lokal ke node itu, maka data Anda akan disimpan secara lokal di node itu. Tidak ada fungsionalitas bawaan untuk memindahkan data antar node secara otomatis.

Ada beberapa solusi penyimpanan terdistribusi berbasis perangkat lunak seperti GlusterFS, dan Docker memiliki satu yang disebut Infinit yang belum menjadi GA dan pengembangannya telah mengambil kursi belakang untuk integrasi Kubernetes di EE.

Hasil tipikal adalah Anda perlu mengelola replikasi penyimpanan dalam aplikasi Anda (mis. Etcd dan algoritma berbasis rakit lainnya) atau Anda melakukan pemasangan pada sistem penyimpanan eksternal (mudah-mudahan dengan HA-nya sendiri). Memasang sistem penyimpanan eksternal memiliki dua opsi, blok atau berbasis file. Penyimpanan berbasis blok (mis. EBS) biasanya hadir dengan kinerja yang lebih tinggi, tetapi terbatas hanya untuk dipasang pada satu node. Untuk ini, Anda biasanya memerlukan driver plugin volume pihak ketiga untuk memberikan akses node docker Anda ke penyimpanan blok itu. Penyimpanan berbasis file (mis. EFS) memiliki kinerja yang lebih rendah, tetapi lebih portabel, dan dapat dipasang secara bersamaan pada beberapa node, yang berguna untuk layanan yang direplikasi.

Penyimpanan jaringan berbasis file yang paling umum adalah NFS (ini adalah protokol yang sama yang digunakan oleh EFS). Dan Anda dapat memasangnya tanpa driver plugin pihak ketiga. Sayangnya, driver plugin volume "lokal" yang dikirimkan oleh buruh pelabuhan memberi Anda opsi untuk meneruskan nilai apa pun yang Anda inginkan ke perintah mount dengan opsi driver, dan tanpa opsi, defaultnya adalah menyimpan volume di direktori buruh pelabuhan / var / lib / buruh pelabuhan / volume. Dengan opsi, Anda dapat meneruskannya ke parameter NFS, dan bahkan akan melakukan pencarian DNS pada nama host NFS (sesuatu yang biasanya tidak Anda miliki dengan NFS). Berikut adalah contoh dari berbagai cara untuk memasang sistem file NFS menggunakan driver volume lokal:

  # create a reusable volume
  $ docker volume create --driver local \
      --opt type=nfs \
      --opt o=nfsvers=4,addr=192.168.1.1,rw \
      --opt device=:/path/to/dir \
      foo

  # or from the docker run command
  $ docker run -it --rm \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # or to create a service
  $ docker service create \
    --mount type=volume,dst=/container/path,volume-driver=local,volume-opt=type=nfs,\"volume-opt=o=nfsvers=4,addr=192.168.1.1\",volume-opt=device=:/host/path \
    foo

  # inside a docker-compose file
  ...
  volumes:
    nfs-data:
      driver: local
      driver_opts:
        type: nfs
        o: nfsvers=4,addr=192.168.1.1,rw
        device: ":/path/to/dir"
  ...

Jika Anda menggunakan contoh compose file di bagian akhir, perhatikan bahwa perubahan volume (misalnya memperbarui jalur atau alamat server) tidak tercermin dalam volume bernama yang ada selama ada. Anda perlu mengganti nama volume Anda, atau menghapusnya, untuk memungkinkan swarm membuatnya kembali dengan nilai baru.

Masalah umum lainnya yang saya lihat di sebagian besar penggunaan NFS adalah "root squash" yang diaktifkan di server. Hal ini menyebabkan masalah izin saat penampung yang berjalan sebagai root mencoba menulis file ke volume. Anda juga memiliki masalah izin UID / GID yang serupa dengan UID / GID penampung yang memerlukan izin untuk menulis ke volume, yang mungkin memerlukan kepemilikan direktori dan izin untuk disesuaikan di server NFS.

BMitch
sumber
9

Solusi saya untuk AWS EFS, yang berfungsi:

  1. Buat EFS (jangan lupa untuk membuka port NFS 2049 di grup keamanan)
  2. Instal paket nfs-common:

    sudo apt-get install -y nfs-common

  3. Periksa apakah efs Anda berfungsi:

    mkdir efs-test-point
    sudo chmod go + rw efs-test-point
    sudo mount -t nfs -o nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2, noresvport [YOUR_EFS_DNS]: / efs-test-point
    sentuh efs-test-point / 1.txt
    sudo umount efs-test-point /
    ls -la efs-test-point /

    direktori harus kosong

    sudo mount -t nfs -o nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2, noresvport [YOUR_EFS_DNS]: / efs-test-point

    ls -la efs-test-point/

    file 1.txt harus ada

  4. Konfigurasikan file docker-compose.yml:

    jasa:
      sidekiq:
        volume:
          - uploads_tmp_efs: / home / application / public / uploads / tmp
      ...
    volume:
      uploads_tmp_efs:
        sopir: lokal
        driver_opts:
          ketik: nfs
          o: addr = [YOUR_EFS_DNS], nfsvers = 4.1, rsize = 1048576, wsize = 1048576, hard, timeo = 600, retrans = 2
          perangkat: [YOUR_EFS_DNS]: /

super_p
sumber
6

Solusi saya untuk swarm yang dihosting secara lokal: setiap node pekerja telah memasang nfs-share, yang disediakan oleh fileserver kami di /mnt/docker-data. Ketika saya menentukan volume di layanan saya membuat file, saya mengatur perangkat ke beberapa jalur di bawah /mnt/docker-data, misalnya:

volumes:
  traefik-logs:
    driver: local
    driver_opts:
      o: bind
      device: /mnt/docker-data/services/traefik/logs
      type: none

Dengan solusi ini, buruh pelabuhan menciptakan volume pada setiap node, layanan ini diterapkan dan - kejutan - sudah ada data, karena itu adalah jalur yang sama, yang digunakan oleh volume pada node lain.

Jika Anda melihat lebih dekat pada filesystem node, Anda melihat bahwa mount ke mount fileserver saya dibuat di bawah /var/lib/docker/volumes, lihat di sini:

root@node-3:~# df -h
Dateisystem                                                                                                   Größe Benutzt Verf. Verw% Eingehängt auf
[...]
fs.mydomain.com:/srv/shares/docker-data/services/traefik/logs                                 194G    141G   53G   73% /var/lib/docker/volumes/traefik_traefik-logs/_data
tigu
sumber