網站首頁 編程語言 正文
不知道你在使用docker的時候,有沒有注意到?volume mount和bind mount的使用? 進一步說,他們之間的區別到底是什么?
接下來的內容,我們就為你揭開他們的神秘面紗。
相同之處
首先,說相同之處:
volume和bind mount都是持久化容器的機制。
不同之處
再來說說,他們的不同之處:
volume是由docker來進行管理的,而bind mount完全是依賴于主機的目錄結構和操作系統
volume?相對于 bind mount的?優點
- volume更加容易進行備份和遷移
- 可以通過docker客戶端命令或者docker api來管理volume (比如:docker volume命令)
- volume可以在linux和windows容器中運行
- volume可以更加安全的在多個容器之間進行共享
- volume驅動程序允許在遠程主機或云提供商上存儲卷,以加密volume的內容或添加其他功能
- 新volume的內容可以由容器預先填充
- Docker Desktop上的卷比Mac和Windows主機上的綁定掛載具有更高的性能。
此外,與將數據持久化到容器的可寫層相比,volume通常是更好的選擇,因為volume不會增加使用它的容器的大小,而且volume的內容存在于給定容器的生命周期之外。
也就是說,當容器被移除了之后,volume中的內容還是可以獨立存在的。
下圖演示了volume和bind mount,以及和容器之間的關系圖:
我們可以看到:
- volume是可docker的存儲區域相關的
- bind mount是直接和操作系統相關的
下面,我們分別展示,volume的掛載、使用的一些操作
volume操作
創建容器,使用volume
我們可以通過下面的命令創建一個容器,使用volume
docker run -d \
--name devtest \
-v myvol2:/app \
nginx:latest
其中:-v選項,后面的第一個參數myvol2就是volume的名字,如果在容器使用volume時,volume不存在,那么會自動創建這個volume
[root@centos7 ~]# docker volume ls
DRIVER VOLUME NAME
local myvol2
[root@centos7 ~]#
可以查看該volume在docker 宿主機上的具體的路徑
[root@centos7 ~]# docker volume inspect myvol2
[
{
"CreatedAt": "2022-08-23T22:04:20-04:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/myvol2/_data",
"Name": "myvol2",
"Options": null,
"Scope": "local"
}
]
[root@centos7 ~]#
Mountpoint就指明了這個volume在文件系統上的具體位置。
容器通過:-v myvol2:/app 將volume掛載到容器的/app目錄中
[root@centos7 ~]# docker exec -it devtest df -h
Filesystem Size Used Avail Use% Mounted on
overlay 50G 3.0G 48G 6% /
tmpfs 64M 0 64M 0% /dev
tmpfs 1.4G 0 1.4G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/mapper/centos-root 50G 3.0G 48G 6% /app
tmpfs 1.4G 0 1.4G 0% /proc/asound
tmpfs 1.4G 0 1.4G 0% /proc/acpi
tmpfs 1.4G 0 1.4G 0% /proc/scsi
tmpfs 1.4G 0 1.4G 0% /sys/firmware
[root@centos7 ~]#
向/app目錄寫文件:
docker exec -it devtest bash -c "echo test > /app/myfile.test"
查看卷中的文件是否已經被創建
[root@centos7 ~]# cd /var/lib/docker/volumes/myvol2/_data
[root@centos7 _data]# ls
myfile.test
[root@centos7 _data]# cat myfile.test
test
[root@centos7 _data]#
沒錯,確實這個文件就是寫到了這個目錄中了。
注意:這個volume的內容寫的過程是由docker來進行管理的。
查看容器中mount信息
docker inspect devtest
"Mounts": [
{
"Type": "volume",
"Name": "myvol2",
"Source": "/var/lib/docker/volumes/myvol2/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
]
可以看到Mounts部分的信息:
- Type: volume
- Source:就是在宿主機上的具體的目錄位置
- Destination: 容器中的掛載路徑
- Driver: volume的驅動程序類型
- RW: 是否是讀寫模式
停止容器、移除容器
docker stop devtest
docker rm devtest
容器移除后,volume是否還存在嗎?
[root@centos7 _data]# docker volume ls
DRIVER VOLUME NAME
local myvol2
[root@centos7 _data]# ls
myfile.test
[root@centos7 _data]# cat myfile.test
test
[root@centos7 _data]#
和你想的一模一樣,volume還在,其中的寫入的內容,仍然存在
移除volume
docker volume rm myvol2
注意!
移除容器和移除volume是2個獨立的操作。
使用容器填充volume
另外一個?非常重要的點?:如果將volume掛載到目錄中,如果目錄中原來就是有文件或子目錄的,那么掛載之后,會將內容拷貝到卷中來。
啥意思?
比如,我們有個鏡像,在/app目錄下有個a.log文件
[root@centos7 test-volume]# ls
a.log Dockerfile
[root@centos7 test-volume]# cat a.log
123456
12345
[root@centos7 test-volume]# cat Dockerfile
from nginx:latest
RUN mkdir /app
copy a.log /app/a.log
[root@centos7 test-volume]#
# 構建鏡像
docker build -t vol:2 .
掛載數據卷
docker run -d --name=vo3 -v nginx-vo3:/app vol:2
發現容器運行后,/app目錄下的文件,被拷貝到volume中
[root@centos7 test-volume]# cd /var/lib/docker/volumes/nginx-vo3/_data
[root@centos7 _data]# ls
a.log
[root@centos7 _data]# cat a.log
123456
12345
[root@centos7 _data]#
而沒有,覆蓋!這個點,十分的有意思!之前肯定你沒有關注過!
以只讀方式掛載volume
如何以只讀的方式掛載volume,方法非常的簡單:
只需要加上ro選項即可
-v nginx-vol:/usr/share/nginx/html:ro
示例:
docker run -d \
--name=nginxtest \
-v nginx-vol:/usr/share/nginx/html:ro \
nginx:latest
查看容器的Mounts部分的信息
docker inspect nginxtest
"Mounts": [
{
"Type": "volume",
"Name": "nginx-vol",
"Source": "/var/lib/docker/volumes/nginx-vol/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "ro",
"RW": false,
"Propagation": ""
}
]
發現:"RW": false,也就是,非Read-Write的模式
試試向其中寫入文件:
[root@centos7 ~]# docker exec -it nginxtest bash -c "echo 1234 > /usr/share/nginx/html/1.log "
bash: line 1: /usr/share/nginx/html/1.log: Read-only file system
[root@centos7 ~]#
和你猜的一樣,會提示:只讀文件系統。
OK,OK,說完了volume的原理,相關的操作,接下來,要看的就是bind mount
bind mount
使用bind mount時,將宿主機上的文件或者目錄掛載到容器上。文件或者目錄在主機上,是以絕對路徑的方式來使用。
相比之下,當使用volume時,在主機上的Docker存儲目錄中創建一個新目錄,由Docker管理該目錄的內容。
要掛載的文件或目錄不需要在Docker主機上已經存在。如果它還不存在,則按需創建它。bind mount的性能非常好,但是它們依賴于主機的文件系統具有特定的目錄結構。
建議:如果你正在開發新的Docker應用程序,請考慮使用命名的volume。因為,對于bind mount來說,你不能使用Docker CLI命令來直接管理。
使用bind mount啟動容器
使用以下得命令,將一個容器通過bind 掛載的方式,將宿主機的目錄,掛載到容器中
docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app \
nginx:latest
查看容器的bind掛載情況
docker inspect devtest
"Mounts": [
{
"Type": "bind",
"Source": "/tmp/source/target/target",
"Destination": "/app",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
可以看到
- Type : 掛載的類型是bind
- source: 宿主機上的目錄,當然這里使用$(pwd)變量來獲取當前的工作目錄
關閉、刪除容器
docker container stop devtest
docker container rm devtest
OK,接下來的這個點,非常的關鍵,如果綁定掛載到容器中的一個非空的目錄會如何?
綁定到容器的非空目錄
nginx鏡像中/usr/share/nginx/html是非空的,有登錄頁
docker run -d \
-it \
--name non-empty \
-v /tmp/soure/base:/usr/share/nginx/html \
nginx:latest
[root@centos7 base]# docker exec -it non-empty ls /usr/share/nginx/html
[root@centos7 base]#
發現,掛載了之后,是空的,也就是把鏡像中的內容給覆蓋了。
這個和volume是一個巨大的區別!?注意?!
總結
OK,我們這里總結一下,讓你更好的理解voLume 和 bind 類型的掛載的區別:
- 管理方式,volume由docker管理,docker客戶端命令可操作,bind掛載不行
- 容器中有內容的目錄,volume會復制,bind mount直接將容器中的內容覆蓋
- bind mount可以設置 bind 傳播參數。
- volume可以設置驅動程序
后面的文章中,會帶你看看,如何安裝volume驅動,來創建特定類型的volume,實現多個節點間的數據共享······
原文鏈接:https://www.cnblogs.com/chuanzhang053/p/16620053.html
相關推薦
- 2023-03-29 Python之sklearn數據預處理中fit(),transform()與fit_transfor
- 2022-04-30 DataGridView不顯示最下面的新行、判斷新增行、刪除行操作_C#教程
- 2022-01-31 git統計當前項目代碼行數
- 2022-12-26 C++逆向分析移除鏈表元素實現方法詳解_C 語言
- 2023-01-11 C++入門教程之引用與指針_C 語言
- 2023-04-18 C++超詳細分析優化排序算法之堆排序_C 語言
- 2022-08-02 c#中task與thread的區別及使用講解_C#教程
- 2022-07-10 TypeError: Cannot read property ‘forceUpdate‘ of u
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支