docker中的volume和bind?mount區(qū)別講解
不知道你在使用docker的時(shí)候,有沒有注意到 volume mount和bind mount的使用? 進(jìn)一步說,他們之間的區(qū)別到底是什么?
接下來的內(nèi)容,我們就為你揭開他們的神秘面紗。
相同之處
首先,說相同之處:
volume和bind mount都是持久化容器的機(jī)制。
不同之處
再來說說,他們的不同之處:
volume是由docker來進(jìn)行管理的,而bind mount完全是依賴于主機(jī)的目錄結(jié)構(gòu)和操作系統(tǒng)
volume 相對(duì)于 bind mount的 優(yōu)點(diǎn)
- volume更加容易進(jìn)行備份和遷移
- 可以通過docker客戶端命令或者docker api來管理volume (比如:docker volume命令)
- volume可以在linux和windows容器中運(yùn)行
- volume可以更加安全的在多個(gè)容器之間進(jìn)行共享
- volume驅(qū)動(dòng)程序允許在遠(yuǎn)程主機(jī)或云提供商上存儲(chǔ)卷,以加密volume的內(nèi)容或添加其他功能
- 新volume的內(nèi)容可以由容器預(yù)先填充
- Docker Desktop上的卷比Mac和Windows主機(jī)上的綁定掛載具有更高的性能。
此外,與將數(shù)據(jù)持久化到容器的可寫層相比,volume通常是更好的選擇,因?yàn)関olume不會(huì)增加使用它的容器的大小,而且volume的內(nèi)容存在于給定容器的生命周期之外。
也就是說,當(dāng)容器被移除了之后,volume中的內(nèi)容還是可以獨(dú)立存在的。
下圖演示了volume和bind mount,以及和容器之間的關(guān)系圖:
我們可以看到:
- volume是可docker的存儲(chǔ)區(qū)域相關(guān)的
- bind mount是直接和操作系統(tǒng)相關(guān)的
下面,我們分別展示,volume的掛載、使用的一些操作
volume操作
創(chuàng)建容器,使用volume
我們可以通過下面的命令創(chuàng)建一個(gè)容器,使用volume
docker run -d \ --name devtest \ -v myvol2:/app \ nginx:latest
其中:-v選項(xiàng),后面的第一個(gè)參數(shù)myvol2就是volume的名字,如果在容器使用volume時(shí),volume不存在,那么會(huì)自動(dòng)創(chuàng)建這個(gè)volume
[root@centos7 ~]# docker volume ls DRIVER VOLUME NAME local myvol2 [root@centos7 ~]#
可以查看該volume在docker 宿主機(jī)上的具體的路徑
[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就指明了這個(gè)volume在文件系統(tǒng)上的具體位置。
容器通過:-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"
查看卷中的文件是否已經(jīng)被創(chuàng)建
[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]#
沒錯(cuò),確實(shí)這個(gè)文件就是寫到了這個(gè)目錄中了。
注意:這個(gè)volume的內(nèi)容寫的過程是由docker來進(jìn)行管理的。
查看容器中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:就是在宿主機(jī)上的具體的目錄位置
- Destination: 容器中的掛載路徑
- Driver: volume的驅(qū)動(dòng)程序類型
- 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還在,其中的寫入的內(nèi)容,仍然存在
移除volume
docker volume rm myvol2
注意!
移除容器和移除volume是2個(gè)獨(dú)立的操作。
使用容器填充volume
另外一個(gè) 非常重要的點(diǎn) :如果將volume掛載到目錄中,如果目錄中原來就是有文件或子目錄的,那么掛載之后,會(huì)將內(nèi)容拷貝到卷中來。
啥意思?
比如,我們有個(gè)鏡像,在/app目錄下有個(gè)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]#
# 構(gòu)建鏡像
docker build -t vol:2 .
掛載數(shù)據(jù)卷
docker run -d --name=vo3 -v nginx-vo3:/app vol:2
發(fā)現(xiàn)容器運(yùn)行后,/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]#
而沒有,覆蓋!這個(gè)點(diǎn),十分的有意思!之前肯定你沒有關(guān)注過!
以只讀方式掛載volume
如何以只讀的方式掛載volume,方法非常的簡單:
只需要加上ro選項(xiàng)即可
-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": "" } ]
發(fā)現(xiàn):"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 ~]#
和你猜的一樣,會(huì)提示:只讀文件系統(tǒng)。
OK,OK,說完了volume的原理,相關(guān)的操作,接下來,要看的就是bind mount
bind mount
使用bind mount時(shí),將宿主機(jī)上的文件或者目錄掛載到容器上。文件或者目錄在主機(jī)上,是以絕對(duì)路徑的方式來使用。
相比之下,當(dāng)使用volume時(shí),在主機(jī)上的Docker存儲(chǔ)目錄中創(chuàng)建一個(gè)新目錄,由Docker管理該目錄的內(nèi)容。
要掛載的文件或目錄不需要在Docker主機(jī)上已經(jīng)存在。如果它還不存在,則按需創(chuàng)建它。bind mount的性能非常好,但是它們依賴于主機(jī)的文件系統(tǒng)具有特定的目錄結(jié)構(gòu)。
建議:如果你正在開發(fā)新的Docker應(yīng)用程序,請(qǐng)考慮使用命名的volume。因?yàn)椋瑢?duì)于bind mount來說,你不能使用Docker CLI命令來直接管理。
使用bind mount啟動(dòng)容器
使用以下得命令,將一個(gè)容器通過bind 掛載的方式,將宿主機(jī)的目錄,掛載到容器中
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: 宿主機(jī)上的目錄,當(dāng)然這里使用$(pwd)變量來獲取當(dāng)前的工作目錄
關(guān)閉、刪除容器
docker container stop devtest docker container rm devtest
OK,接下來的這個(gè)點(diǎn),非常的關(guān)鍵,如果綁定掛載到容器中的一個(gè)非空的目錄會(huì)如何?
綁定到容器的非空目錄
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]#
發(fā)現(xiàn),掛載了之后,是空的,也就是把鏡像中的內(nèi)容給覆蓋了。
這個(gè)和volume是一個(gè)巨大的區(qū)別! 注意 !
總結(jié)
OK,我們這里總結(jié)一下,讓你更好的理解voLume 和 bind 類型的掛載的區(qū)別:
- 管理方式,volume由docker管理,docker客戶端命令可操作,bind掛載不行
- 容器中有內(nèi)容的目錄,volume會(huì)復(fù)制,bind mount直接將容器中的內(nèi)容覆蓋
- bind mount可以設(shè)置 bind 傳播參數(shù)。
- volume可以設(shè)置驅(qū)動(dòng)程序
后面的文章中,會(huì)帶你看看,如何安裝volume驅(qū)動(dòng),來創(chuàng)建特定類型的volume,實(shí)現(xiàn)多個(gè)節(jié)點(diǎn)間的數(shù)據(jù)共享······
到此這篇關(guān)于docker的volume和bind mount區(qū)別介紹的文章就介紹到這了,更多相關(guān)docker volume和bind mount內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Ubuntu15.04上安裝Docker的步驟以及基本用法
Docker是一種輕量型的的類虛擬機(jī)的平臺(tái),在開發(fā)項(xiàng)目上還是很有優(yōu)勢(shì)的,這僅是我的一種直觀理解。所以這篇文章主要給大家介紹了在Ubuntu15.04上安裝Docker的步驟以及基本用法,有需要的朋友們可以參考借鑒。2016-10-10linux環(huán)境部署及docker安裝redis的方法
這篇文章主要介紹了linux環(huán)境部署及docker安裝redis的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08docker安裝redis 5.0.7并掛載外部配置和數(shù)據(jù)問題
Redis 是一個(gè)開源的使用 ANSI C 語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value 的 NoSQL 數(shù)據(jù)庫,并提供多種語言的 API。這篇文章主要介紹了docker安裝redis 5.0.7并掛載外部配置和數(shù)據(jù),需要的朋友可以參考下2019-12-12一次Docker中Redis連接暴增的問題排查實(shí)戰(zhàn)記錄
這篇文章主要給大家介紹了一次Docker中Redis連接暴增的問題排查的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06給docker創(chuàng)建的elasticsearch容器添加密碼簡單步驟
在使用Elasticsearch(ES)Docker容器時(shí),有時(shí)需要設(shè)置密碼來保護(hù)數(shù)據(jù)的安全性,這篇文章主要給大家介紹了關(guān)于給docker創(chuàng)建的elasticsearch容器添加密碼的簡單步驟,需要的朋友可以參考下2024-02-02Docker部署Tomcat及Web應(yīng)用的實(shí)現(xiàn)
這篇文章主要介紹了Docker部署Tomcat及Web應(yīng)用的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09如何解決docker logs無法實(shí)時(shí)輸出腳本打印的內(nèi)容
這篇文章主要介紹了如何解決docker logs無法實(shí)時(shí)輸出腳本打印的內(nèi)容問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07使用Docker registry鏡像創(chuàng)建私有倉庫的方法
本篇文章主要介紹了使用Docker registry鏡像創(chuàng)建私有倉庫的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04