volume pemasangan docker pada host

135

Saya telah berhasil berbagi folder antara kontainer dengan volume menggunakan

docker run -v /host/path:/container/path ...

Tetapi pertanyaan saya adalah apa perbedaan antara ini dan menggunakan VOLUMEperintah di Dockerfile

VOLUME /path

Saya menggunakan gambar yang memiliki VOLUMEperintah, dan saya ingin tahu bagaimana membagikannya dengan host saya. Saya telah melakukannya dengan menggunakan -vperintah di atas, tetapi saya tidak tahu apakah saya membutuhkan keduanya -vdan VOLUME.

Jeff Storey
sumber

Jawaban:

155

The VOLUMEperintah akan me-mount direktori di dalam wadah dan menyimpan file yang dibuat atau diedit di dalam direktori yang di host disk Anda di luar struktur file kontainer , melewati sistem file serikat.

Idenya adalah bahwa volume Anda dapat dibagi antara kontainer buruh pelabuhan Anda dan mereka akan tetap ada selama ada wadah (berjalan atau berhenti) yang mereferensikannya.

Anda dapat membuat wadah lain memasang volume yang ada (secara efektif membagikannya di antara wadah) dengan menggunakan --volumes-fromperintah saat Anda menjalankan wadah.

Perbedaan mendasar antara VOLUMEdan -vapakah ini: -vakan me-mount file yang ada dari sistem operasi Anda di dalam wadah buruh pelabuhan Anda dan VOLUMEakan membuat volume kosong baru pada host Anda dan memasangnya di dalam wadah Anda.

Contoh:

  1. Anda memiliki Dockerfile yang mendefinisikan a VOLUME /var/lib/mysql.
  2. Anda membangun gambar buruh pelabuhan dan menandainya some-volume
  3. Anda menjalankan wadah

Lalu,

  1. Anda memiliki gambar buruh pelabuhan lain yang ingin Anda gunakan volume ini
  2. Anda menjalankan wadah buruh pelabuhan dengan yang berikut: docker run --volumes-from some-volume docker-image-name:tag
  3. Sekarang Anda memiliki wadah buruh pelabuhan berjalan yang akan memiliki volume dari some-volumeterpasang/var/lib/mysql

Catatan: Menggunakan --volumes-fromakan memasang volume di atas apa pun yang ada di lokasi volume. Yaitu, jika Anda memiliki barang-barang di /var/lib/mysqldalamnya, itu akan diganti dengan isi volume.

Chris McKinnel
sumber
12
Apa yang terjadi jika saya menggunakan -v pada direktori yang sudah ditentukan dalam VOLUME?
Jeff Storey
6
--volumes-fromakan memasang Anda VOLUMEdi atas apa pun yang Anda tentukan -v. Menariknya, sepertinya menjalankan wadah dalam mode privilege ( docker run --privileged) dan umounting /var/lib/mysqlhanya akan meninggalkan dir kosong sehingga -vmount Anda benar-benar diabaikan ketika bertentangan dengan a VOLUME.
Chris McKinnel
2
Anda mengatakan volume disimpan selama wadah referensi mereka, dan saya pernah melihatnya di tempat lain. docs.docker.com/userguide/dockervolumes mengatakan "Volume data dirancang untuk mempertahankan data, terlepas dari siklus hidup wadah. Oleh karena itu, Docker tidak pernah secara otomatis menghapus volume ketika Anda memindahkan wadah, juga tidak akan" mengumpulkan sampah "volume yang tidak lagi direferensikan oleh wadah. " Salah satu dari pernyataan ini pasti salah.
mc0e
1
File-file yang ada dalam volume disimpan di disk ketika sebuah wadah tidak lagi merujuknya, tetapi volume itu sendiri tidak lagi dapat digunakan (kecuali Anda tahu persis bagaimana cara menghubungkan volume secara manual ke sebuah wadah, tetapi bahkan kemudian saya tidak lagi t tahu apakah ini mungkin). Ketika saya katakan tidak lagi dapat digunakan, maksud saya Anda tidak dapat menggunakan --volume-from untuk menggunakannya. Ketika mereka mengatakan "pengumpulan sampah" di atas, mereka berarti menghapus file dari disk Anda yang ada dalam volume.
Chris McKinnel
1
Mereka dapat digunakan menggunakan -v, tetapi tidak --volumes-from. Volume-dari mengambil nama wadah untuk mengambil data volume dari (saya percaya ini membutuhkan SEMUA poin volume). Namun untuk -v sendiri, manual menyebutkan bahwa Anda dapat memberikan volume bernama ke -v dalam bentuk named-volume:/path/in/container. Volume yang tidak disebutkan namanya diberikan hash untuk nama dan hash tersebut dapat diberikan sebagai ganti jalur host untuk mengakses volume yatim. :) Hati-hati volume lsmungkin tidak menunjukkan semuanya - coba docker volume ls -f dangling=truejuga.
Jasmine Hegman
44

Biarkan saya menambahkan jawaban saya sendiri, karena saya percaya yang lain kehilangan titik Docker.

Penggunaan VOLUMEdi Dockerfile adalah Right Way ™, karena Anda memberi tahu Docker bahwa direktori tertentu berisi data permanen. Docker akan membuat volume untuk data itu dan tidak pernah menghapusnya, bahkan jika Anda menghapus semua kontainer yang menggunakannya.

Ini juga mem-bypass sistem file gabungan, sehingga volume sebenarnya adalah direktori aktual yang akan dipasang (baca-tulis atau baca-saja) di tempat yang tepat di semua wadah yang membagikannya.

Sekarang, untuk mengakses data dari host, Anda hanya perlu memeriksa wadah Anda:

# docker inspect myapp
[{
    .
    .
    .
    "Volumes": {
        "/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...",
        "/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...",
        "/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..."
    },
    "VolumesRW": {
        "/var/www": false,
        "/var/cache/nginx": true,
        "/var/log/nginx": true
    }
}]

Apa yang biasanya saya lakukan adalah membuat symlink di beberapa tempat standar seperti / srv , sehingga saya dapat dengan mudah mengakses volume dan mengelola data yang dikandungnya (hanya untuk volume yang Anda pedulikan):

ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log
Tobia
sumber
Bagaimana jika host buruh pelabuhan berjalan di VM? Misalnya, boot2docker di mac. Maka volume ini hanya tersedia dari jarak jauh. Juga, ketika menggunakan volume di Dockerfile seperti yang Anda jelaskan, isi gambar akan disalin ke volume. Namun, ketika melakukan pemasangan ke direktori lokal, penyalinan ini tidak terjadi. Apakah Anda tahu mengapa demikian? Apakah ada cara untuk memiliki volume yang dipasang secara lokal tetapi masih 'mulai segar' dengan file dari gambar?
LostSalad
4
dengan docker-compose Anda dapat melakukannya, pasang volume pada lokasi tertentu dari os host . Tidak perlu symlink ...
Hugo Koopmans
@Tobia: contoh susunan buruh pelabuhan lihat dokumen docs.docker.com/compose/compose-file/…
Hugo Koopmans
11

VOLUME digunakan Dockerfileuntuk mengekspos volume yang akan digunakan oleh wadah lain. Contoh, buat Dockerfilesebagai:

DARI ubuntu: 14.04

RUN mkdir /myvol  
RUN echo "hello world" > /myvol/greeting  
VOLUME /myvol

membangun gambar:

$ docker build -t testing_volume .

Jalankan kontainer, katakan container1:

$ docker run -it <image-id of above image> bash

Sekarang jalankan wadah lain dengan volume-dari opsi as (say-container2)

$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash

Anda akan mendapatkan semua data dari /myvoldirektori container1 ke container2 di lokasi yang sama.

-vopsi diberikan saat run time container yang digunakan untuk me-mount direktori kontainer pada host. Mudah digunakan, cukup berikan -vopsi dengan argumen sebagai <host-path>:<container-path>. Seluruh perintah mungkin sama$ docker run -v <host-path>:<container-path> <image-id>

Yogesh Jilhawar
sumber
8

Pada dasarnya VOLUMEdan -vopsi hampir sama. Ini berarti 'pasang direktori spesifik pada wadah Anda'. Misalnya, VOLUME /datadan -v /dataartinya persis sama. Jika Anda menjalankan gambar yang memiliki VOLUME /dataatau dengan -v /dataopsi, /datadirektori sudah terpasang wadah Anda. Direktori ini bukan milik wadah Anda.

Bayangkan bahwa Anda menambahkan beberapa file ke /datadalam wadah, lalu komit wadah ke gambar baru. Tidak ada file di direktori data karena /datadirektori yang dipasang adalah milik wadah asli.

$ docker run -it -v /data --name volume ubuntu:14.04 bash
root@2b5e0f2d37cd:/# cd /data
root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/data# cd /tmp
root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/tmp# exit
exit

$ docker commit volume nacyot/volume  
835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945
nacyot $ docker run -it nacyot/volume
root@dbe335c7e64d:/# cd /data
root@dbe335c7e64d:/data# ls
root@dbe335c7e64d:/data# cd /tmp
root@dbe335c7e64d:/tmp# ls
1  2  3  4  5  6  7  8  9
root@dbe335c7e64d:/tmp# 
root@dbe335c7e64d:/tmp# 

Direktori yang dipasang seperti /dataini digunakan untuk menyimpan data yang bukan milik aplikasi Anda. Dan Anda dapat menentukan sebelumnya direktori data yang bukan milik wadah dengan menggunakan VOLUME.

Perbedaan antara Volumedan -vopsi adalah bahwa Anda dapat menggunakan -vopsi secara dinamis pada wadah awal. Ini berarti Anda dapat memasang beberapa direktori secara dinamis. Dan perbedaan lainnya adalah Anda dapat memasang direktori host Anda di wadah dengan menggunakan-v

nacyot
sumber
8

Ini dari dokumentasi Docker itu sendiri, mungkin bisa membantu, sederhana dan sederhana:

"Direktori host, pada dasarnya, tergantung pada host. Untuk alasan ini, Anda tidak dapat me-mount direktori host dari Dockerfile, instruksi VOLUME tidak mendukung pengalihan host-dir, karena gambar yang dibuat harus portabel. Host direktori tidak akan tersedia di semua host potensial. "

Vennesa
sumber