Docker資料卷掛載
情況一、宿主機不存在檔案掛載到容器存在檔案(檔案到檔案)
宿主機不存在該檔案,而容器記憶體在該檔案的情況,嘗試把不存在的檔案掛載到存在該檔案的容器中。以一個 Alpine 映象為例,這裡把一個修改後的 Alpine 映象打了新標籤,叫做 volume_test:
# 本地目錄不存在 test 檔案。 $ docker run --name=test -v ~/test.txt:/etc/hosts -d volume_test 0cba2e50229df7508c616bd456c4ab131f2fe1a88385c34f8a5876fbc577b176 docker: Error response from daemon: oci runtime error: rootfs_linux.go:53: mounting "/var/lib/docker/devicemapper/mnt/6b83c07ebedcb828f34cac69eac5a85ce3a5f59e1e8688c8dae40198671d0ecb/rootfs/etc/hosts" to rootfs "/var/lib/docker/devicemapper/mnt/6b83c07ebedcb828f34cac69eac5a85ce3a5f59e1e8688c8dae40198671d0ecb/rootfs" caused "not a directory".
結論:啟動容器失敗
情況二、宿主機不存在資料夾掛載到容器存在資料夾(目錄到目錄)
把宿主機不存在的資料夾掛載到容器記憶體在的資料夾,在 volume_test 映象中存在一個 /srv 的資料夾,資料夾裡面有一個 index.php 檔案。
# 本地目錄不存在 srv資料夾。 $ docker run --name=test -v ~/srv:/srv -d volume_test c71cf1cfa4932e3e398a7d6c4e2ae94f915b832f5506e374aedb19af4cb1ac62 # 啟動正常,但是進入容器發現目錄被清空。 $ docker exec -it test sh /srv # ls /srv #
結論:情況一、情況二 這兩個例子已經說明,資料卷的掛載是通過把宿主機的目錄覆蓋到容器中目標目錄的。也就是說,當宿主機檔案不存在時,不能掛載;當資料夾不存在時,掛載到容器會建立一個空資料夾對容器目標目錄進行覆蓋。
情況三、宿主機存在檔案掛載到容器不存在檔案(檔案到檔案)
宿主機存在檔案,容器內不存在該檔案
# 本地目錄存在 test.txt檔案
$ docker run --name=test -v ~/test.txt:/srv/test.txt -d volume_test
2d6853c10643a735ae3d7f3aaac8c6344f9c75170e531f613d08db7cdf484e54
# 容器記憶體在 /srv 資料夾,裡面原本有一個 index.php 。
$ docker exec -it test sh
/srv # ls
index.php test.txt
/srv #
結論:宿主機檔案成功掛載到容器內
情況四、宿主機存在資料夾掛載到容器不存在資料夾(資料夾到資料夾)
接下來是宿主機存在資料夾,容器不存在該資料夾,宿主機的 test 資料夾裡面存在一個 hello 檔案:
$ docker run --name=test -v ~/test:/srv/test -d volume_test
c935ffa0d9fc5e5ac8f213a51a878e71056472b0597d2e385a29e5c748012958
# 進入容器,檢視是否存在 test 資料夾,以及資料夾裡面是否有 hello 檔案。
$ docker exec -it test sh
/srv # ls
index.php test
/srv # cd test/
/srv/test # ls
hello
/srv/test #
結論:情況三、情況四 這兩個例子說明了,容器內部如果不存在檔案,宿主機直接掛載。
情況五、宿主機資料夾掛載到容器檔案(資料夾到檔案)
宿主機存在 test 資料夾,而容器內部存在的是名為 test 檔案,這樣掛載會怎樣呢?
$ docker run --name=test -v ~/test:/srv/test -d volume_test
385bc78e5333460da11f04535da27a3fd226df218f95c970ff2dd5609b17f816
docker: Error response from daemon: oci runtime error: rootfs_linux.go:53: mounting "/var/lib/docker/devicemapper/mnt/fd5c42e844c3550d1a372ed939ed57f90dcacbd375dfed1bedfbb71ef6f3f185/rootfs/etc/hosts" to rootfs "/var/lib/docker/devicemapper/mnt/fd5c42e844c3550d1a372ed939ed57f90dcacbd375dfed1bedfbb71ef6f3f185/rootfs" caused "not a directory".
結論:不出意外是啟動錯誤。
情況六、同名資料夾掛載(資料夾到資料夾)
宿主機是資料夾,容器也是資料夾,兩個資料夾裡面內容不一樣,宿主機內部有一個 hello 檔案,容器的資料夾裡面有一個 index.php :
$ docker run --name=test -v ~/srv:/srv -d volume_test
3aec30122bd7010c694e0ff8b77f7b7b6bb6f850c258786db125313060fad43b $ docker exec-it test sh
/srv # ls
hello
/srv #
結論:宿主機資料夾會覆蓋容器內部的資料夾
情況七、同名檔案掛載
宿主機有一個 test.txt 檔案,裡面寫著 Hello World,而容器裡面也存在一個 test.txt 檔案,裡面寫著 Hi World,現在掛載檔案:
$ docker run --name=test -v ~/test.txt:/srv/test.txt -d volume_test
047cbfe45b5bc868c864fe94f7a22643d52b644947f40260097dbb579de56c5c
$ docker exec -it test sh
/srv # cat /test
Hello World
/srv #
結論:宿主機會覆蓋容器的檔案。
情況八、宿主機檔案掛載到容器資料夾
宿主機存在檔案 test.txt,而容器內部存在一個 test 的資料夾,把檔案掛載到資料夾中
$ docker run --name=test -v ~/test.txt:/test -d volume_test
59b5fd74a1e9e17aa2a6a9be7900b16c7dd4b3c424a4fa72a7671fa1c51bdf69
docker: Error response from daemon: oci runtime error: rootfs_linux.go:53: mounting "/var/lib/docker/devicemapper/mnt/b201054ed36a189b5abb599082d0b5bcbe31d07611a0985deefd79d1221447fd/rootfs/home" to rootfs "/var/lib/docker/devicemapper/mnt/b201054ed36a189b5abb599082d0b5bcbe31d07611a0985deefd79d1221447fd/rootfs" caused "not a directory".
結論:啟動失敗。
小結
宿主機檔案 | 容器內檔案 | 啟動引數(加粗表示不存在) | 容器啟動情況 |
---|---|---|---|
不存在 | 檔案 | -v ~/test.txt:/etc/hosts | 啟動錯誤 |
不存在 | 資料夾 | -v ~/srv:/srv | 啟動正常 |
檔案 | 不存在 | -v ~/test.txt:/srv/test.txt | 啟動正常 |
資料夾 | 不存在 | ~/test:/srv/test | 啟動正常 |
資料夾 | 檔案 | ~/test:/srv/test | 啟動錯誤 |
資料夾 | 資料夾 | -v ~/srv:/srv | 啟動正常 |
檔案 | 檔案 | -v ~/test.txt:/srv/test.txt | 啟動正常 |
檔案 | 資料夾 | -v ~/test.txt:/test | 啟動錯誤 |
結論
宿主機掛載資料捲到容器,其實質上就是將宿主機的檔案或者目錄對映/覆蓋到容器內的掛載目標,掛載型別不一致就會啟動報錯
參考:https://www.csdn.net/tags/MtTaMg1sODgwMjM5LWJsb2cO0O0O.html