Docker Volume存儲(chǔ)卷的實(shí)現(xiàn)
什么是存儲(chǔ)卷?
Docker的存儲(chǔ)卷是一種將宿主機(jī)的本地文件系統(tǒng)中的某個(gè)目錄與容器內(nèi)部的文件系統(tǒng)中的某個(gè)目錄建立綁定關(guān)系的機(jī)制。這種綁定關(guān)系意味著,當(dāng)在容器的這個(gè)目錄下寫入數(shù)據(jù)時(shí),會(huì)同步到宿主機(jī)的這個(gè)目錄中;同樣,在宿主機(jī)的這個(gè)目錄下寫入數(shù)據(jù)也會(huì)同步到容器的這個(gè)目錄下。
存儲(chǔ)卷的作用
- 數(shù)據(jù)持久化:存儲(chǔ)卷使得數(shù)據(jù)可以獨(dú)立于容器的生命周期存在。即使容器被刪除,只要存儲(chǔ)卷不被刪除,數(shù)據(jù)就不會(huì)丟失。
- 數(shù)據(jù)共享:多個(gè)容器可以共享同一個(gè)存儲(chǔ)卷,從而實(shí)現(xiàn)數(shù)據(jù)共享。
- 提高數(shù)據(jù)訪問效率:通過存儲(chǔ)卷,容器可以直接訪問宿主機(jī)上的數(shù)據(jù),避免了通過鏡像層訪問數(shù)據(jù)的低效率問題。
存儲(chǔ)卷的類型
- Bind mount volume(綁定掛載卷):指向主機(jī)文件系統(tǒng)上用戶指定位置的卷。使用
-v
或--volume
命令時(shí),需要指定宿主機(jī)上卷的名稱或完整路徑,以及容器內(nèi)的掛載點(diǎn)。如果指定的卷不存在,Docker會(huì)自動(dòng)創(chuàng)建它。 - Docker-managed volume(Docker管理卷):由Docker守護(hù)進(jìn)程在主機(jī)文件系統(tǒng)的一部分中創(chuàng)建的托管卷。使用
docker volume create
命令可以創(chuàng)建一個(gè)新的Docker管理卷。這些卷存儲(chǔ)在主機(jī)文件夾中(在Linux系統(tǒng)中,通常位于/var/lib/docker/volumes/
路徑下),并由Docker進(jìn)行管理。 - tmpfs mount (臨時(shí)數(shù)據(jù)卷):映射到于宿主機(jī)內(nèi)存中,一旦容器停止運(yùn)行,
tmpfs mounts
會(huì)被移除,數(shù)據(jù)就會(huì)丟失,用于高性能的臨時(shí)數(shù)據(jù)存儲(chǔ)。
命令操作
創(chuàng)建卷 docker create volume
docker volume create [OPTIONS] [VOLUME]
創(chuàng)建一個(gè)存儲(chǔ)卷;
參數(shù):
- -d, --driver:指定驅(qū)動(dòng),默認(rèn)是 local
- –label:指定元數(shù)據(jù)
例如:
root@VM-8-12-ubuntu:~#docker volume create my-vol my-vol
docker volume inspect
查看卷的詳細(xì)信息
docker volume inspect [OPTIONS] VOLUME [VOLUME...]
參數(shù):
- -f:指定相應(yīng)個(gè)格式,如 json
例如:
docker volume ls
列出存儲(chǔ)卷的列表
docker volume ls [OPTIONS]
參數(shù):
- –format:指定相應(yīng)個(gè)格式,如 json,table
- –filter,-f: 過濾
- -q: 僅顯示名稱
例如
docker volume rm
刪除存儲(chǔ)卷,需要讓容器不使用對(duì)應(yīng)卷才可以刪除
docker volume rm [OPTIONS] VOLUME [VOLUME...]
參數(shù):
- -f,–force:強(qiáng)制刪除
docker volume prune
刪除不使用的卷
docker volume prune [OPTIONS]
參數(shù):
- -f,–force:強(qiáng)制刪除
- –filter:過濾
通過 docker run 命令 選項(xiàng) -v 進(jìn)行創(chuàng)建卷
docker run -v name:directory[:options]
第一個(gè)參數(shù):卷名稱
第二個(gè)參數(shù):卷映射到容器的目錄
第三個(gè)參數(shù):選項(xiàng),如 ro 表示 readonly
例如:
docker run -d --name devtest -v myvol2:/app nginx:1.23.4
通過命令查看:
docker container inspect devtest
通過 docker run 命令 選項(xiàng)–mount進(jìn)行創(chuàng)建卷
目的:完成目錄映射
--mount '<key>=<value>,<key>=<value>'
參數(shù):
- type : 類型表示 bind, volume, or tmpfs
- source ,src :對(duì)于命名卷,這是卷的名稱。對(duì)于匿名卷,省略此字段。
- destination,dst,target:文件或目錄掛載在容器中的路徑
- ro,readonly: 只讀方式掛載
例如:
docker run -d --name devtest2 --mount source=myvol2,target=/app nginx:1.23.4
通過命令查看:
docker container inspect devtest2
操作實(shí)例:docker -v 創(chuàng)建管理卷
創(chuàng)建一個(gè)nginx容器,映射端口8080,創(chuàng)建管理卷為test_volume :
docker run --name mynginx1 -d -p 8080:80 -v test_volume:/usr/share/nginx/html:ro nginx:1.23.4
查看對(duì)應(yīng)信息:
docker inspect test_volume
進(jìn)入掛載點(diǎn)的對(duì)應(yīng)目錄里
cd /data/var/lib/docker/volumes/test_volume/_data
修改對(duì)應(yīng)的內(nèi)容:
echo "Test Volume " > index.html
瀏覽器查看:
進(jìn)入到容器中,并且進(jìn)入到對(duì)應(yīng)的html目錄下
docker exec -it mynginx1 bash cd /usr/share/nginx/html
無法對(duì)其進(jìn)行刪除指定 ro 的話宿主機(jī)可以修改,但是容器里面無法修改
卷的生命周期:如果卷沒有被刪除,那么不管容器怎么樣,卷仍然存在;只有卷被刪除了,那么卷的生命周期才會(huì)結(jié)束.
如果兩個(gè)容器指定同一個(gè)卷,那么卷可以被共享;
利用docker run 參數(shù)-v創(chuàng)建綁定卷
docker run -v name:directory[:options] .........
第一個(gè)參數(shù):宿主機(jī)目錄,這個(gè)和管理卷是不一樣的
第二個(gè)參數(shù):卷映射到容器的目錄
第三個(gè)參數(shù):選項(xiàng),如 ro 表示 readonly
例如:
docker run -d -it --name mynginx2 -v "$(pwd)"/target:/app nginx:latest
如果 target 目錄不存在,啟動(dòng)不會(huì)報(bào)錯(cuò),這是-v 和–mount 方式的區(qū)別
這樣 當(dāng)前目錄下target目錄就與容器的app目錄綁定好了。
利用docker run 參數(shù) --mount 參數(shù)創(chuàng)建綁定卷
--mount '<key>=<value>,<key>=<value>'
參數(shù):
- type : 類型表示 bind, volume, or tmpfs
- source ,src :宿主機(jī)目錄,這個(gè)和管理卷是不一樣的。
- destination,dst,target:文件或目錄掛載在容器中的路徑
- ro,readonly: 只讀方式掛載
例如:
創(chuàng)建一個(gè)容器,端口映射為8081,將宿主機(jī)的webapp1/掛載到容器指定目錄中
docker run -d -p 8081:80 --name mynginx4 --mount type=bind,source=/data/ahri/webapp1,target=/usr/share/nginx/html nginx:1.23.4
如果 webapp1 目錄不存在會(huì)啟動(dòng)報(bào)錯(cuò)
查看容器的詳細(xì)內(nèi)容,可以看到對(duì)應(yīng)的掛載信息:
docker inspect mynginx4
查看容器的html目錄下的內(nèi)容,發(fā)現(xiàn)為空:
docker exec -it mynginx4 ls /usr/share/nginx/html
這是 bind mount 模式和 volume 模式最大的不同點(diǎn)
進(jìn)入宿主機(jī)的webapp1目錄中,向index.html目錄寫入內(nèi)容:
cd webapp1 echo "Test Bind Volume" >>index.html
通過瀏覽器可以看到相對(duì)應(yīng)的內(nèi)容:
操作實(shí)例 綁定卷的共享
再次創(chuàng)建一個(gè)容器綁定相同的卷:
docker run -d --name mynginx5 -p 8082:80 -v /data/ahri/webapp1:/usr/share/nginx/html nginx:1.23.4
curl 127.0.0.1:8081 curl 127.0.0.1:8082
可以看到內(nèi)容相同;
改變文件內(nèi)容,結(jié)果隨之改變:
echo "bind mount after edit" > index.html
臨時(shí)卷 tmpfs 的創(chuàng)建 -v
不同于其他卷,tmpfs臨時(shí)卷無法共享;且這個(gè)功能只能在Linux上使用.
創(chuàng)建一個(gè)容器,并且有一個(gè)臨時(shí)卷掛載在html目錄下:
docker container run --name tmpfs1 -d -p 8080:80 --tmpfs /usr/share/nginx/html nginx:1.23.4
進(jìn)入到容器中的html目錄下,并查看目錄下的內(nèi)容,發(fā)現(xiàn)tmpfs 也會(huì)覆蓋容器里面的文件:
docker exec -it tmpfs1 bash cd /usr/share/nginx/html ls -l
向index.html寫入內(nèi)容,并通過瀏覽器查看:
echo "Hello World from tmpfs" > index.html
退出容器并停止運(yùn)行,再次啟動(dòng)容器并進(jìn)入到html目錄下,發(fā)現(xiàn)目錄為空,也就是說內(nèi)容是存在內(nèi)存里面的:
exit docker stop tmpfs1 docker start tmpfs1 docker exec -it tmpfs1 bash ls /usr/share/nginx/html/
臨時(shí)卷 tmpfs 的創(chuàng)建 --mount
不同于其他卷,tmpfs臨時(shí)卷無法共享;且這個(gè)功能只能在Linux上使用.
docker run --name tmpfs1 -d -p 8080:80 --mount type=tmpfs,destination=/usr/share/nginx/thml,tmpfs-size=1m nginx:1.23.4
–mount還能指定參數(shù)來限制內(nèi)存的大小.
實(shí)例 tmpfs失蹤
創(chuàng)建一個(gè)容器,并進(jìn)入:
docker run -d -it --name tmptest nginx:1.23.4 docker exec -it tmptest bash
創(chuàng)建一個(gè)app目錄向該目錄創(chuàng)建一個(gè)新文件mylabel.txt ,然后在宿主機(jī)查看:
mkdir -p /app echo 1 > /app/mylabel.txt exit find / -name mylabel.txt
可以看到,文件被找到了,是因?yàn)樗谌萜鞯目蓪憣?
創(chuàng)建一個(gè)有臨時(shí)卷的容器,掛載點(diǎn)是/app,然后進(jìn)入到容器中:
docker run -d --name tmptest2 --tmpfs /app nginx:1.23.4 docker exec -it tmptest2 bash
向該目錄寫入新文件,退出到宿主機(jī),并查看,發(fā)現(xiàn)查看不到對(duì)應(yīng)文件,所以 tmpfs 的內(nèi)容不是存儲(chǔ)在我們的容器的可寫層里面的。
echo 222 > /app/mynewlabel.txt exit find / -name mynewlabel.txt
實(shí)例 mysql的災(zāi)難性恢復(fù)
創(chuàng)建一個(gè)mysql容器,并且將宿主機(jī)的mysql-data掛載到容器中,設(shè)置初始密碼123456
docker run --name mysql-demo -e MYSQL_ROOT_PASSWORD=123456 -it -d -v /data/ahri/mysql-data:/var/lib/mysql mysql:5.7
查看容器的掛載詳情:
docker container inspect mysql-demo | grep "Mounts" -A 10
進(jìn)入容器并啟動(dòng)MySQL客戶端:
docker exec -it mysql-demo /bin/bash mysql -u root -p
創(chuàng)建一個(gè)數(shù)據(jù)庫:
create database user;
創(chuàng)建一個(gè)表并寫入數(shù)據(jù):
use user; create table student(sno char(3),sname varchar(10)); insert into student values('1','zs'),('2','ls');
退出容器,并查看mysql-data掛載的內(nèi)容:
exit
停止容器的運(yùn)行并刪除:
docker stop mysql-demo docker rm mysql-demo
雖然容器被刪除了,但數(shù)據(jù)仍然保存在mysql-data目錄下.
我們重新啟動(dòng)容器
docker run --name mysql-demo-new -e MYSQL_ROOT_PASSWORD=123456 -it -d -v /data/ahri/mysql-data:/var/lib/mysql mysql:5.7
docker exec -it mysql-demo-new bash mysql -u root -p
進(jìn)入到user數(shù)據(jù)庫中,并查看列表:
use user;
常見問題:什么時(shí)候用 Volume,什么時(shí)候用 bind、tmpfs?
Volume
**Volume是Docker管理的一個(gè)存儲(chǔ)卷,獨(dú)立于容器的生命周期。**當(dāng)容器被刪除時(shí),Volume中的數(shù)據(jù)不會(huì)丟失,除非顯式地刪除Volume。
適用場(chǎng)景:
- 數(shù)據(jù)持久化:需要確保數(shù)據(jù)在容器刪除或重新創(chuàng)建后仍然可用。
- 數(shù)據(jù)共享:多個(gè)容器之間需要共享數(shù)據(jù)。
- 數(shù)據(jù)管理:利用Docker的Volume管理功能,可以更方便地進(jìn)行數(shù)據(jù)的備份、恢復(fù)和遷移。
Bind mounts
Bind mounts是將宿主機(jī)上的文件或目錄直接掛載到容器中,實(shí)現(xiàn)數(shù)據(jù)的共享和訪問。這種方式的數(shù)據(jù)由宿主機(jī)管理,而不是Docker。
適用場(chǎng)景:
- 靈活的數(shù)據(jù)掛載:需要指定宿主機(jī)上的任意文件或目錄作為掛載目標(biāo)。
- 現(xiàn)有數(shù)據(jù)的集成:容器需要訪問宿主機(jī)上已經(jīng)存在的數(shù)據(jù),例如配置文件、日志文件等。
- 性能要求:在某些情況下,Bind mounts可能比Volume具有更好的性能,因?yàn)樗鼈冎苯釉L問宿主機(jī)的文件系統(tǒng)。
Tmpfs
Tmpfs是一種特殊的掛載方式,它將數(shù)據(jù)存儲(chǔ)在宿主機(jī)的內(nèi)存中,而不是持久化存儲(chǔ)。當(dāng)容器停止時(shí),Tmpfs中的數(shù)據(jù)將被刪除。
適用場(chǎng)景:
- 臨時(shí)存儲(chǔ):需要臨時(shí)存儲(chǔ)數(shù)據(jù),例如在處理請(qǐng)求時(shí)生成的中間結(jié)果。
- 提高性能:需要頻繁讀寫臨時(shí)數(shù)據(jù)的場(chǎng)景,因?yàn)門mpfs的數(shù)據(jù)存儲(chǔ)在內(nèi)存中,讀寫速度更快。
- 安全性:不希望數(shù)據(jù)在容器停止后仍然保留在宿主機(jī)上。
到此這篇關(guān)于Docker Volume存儲(chǔ)卷的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Docker Volume存儲(chǔ)卷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
win10子系統(tǒng)ubuntu(WSL) 安裝Docker的教程(圖文詳解)
現(xiàn)在 Docker 有專門的 Win10 專業(yè)版系統(tǒng)的安裝包,需要開啟Hyper-V,具體開啟方法文中給大家介紹的很詳細(xì),這篇文章主要介紹了win10子系統(tǒng)ubuntu(WSL) 安裝Docker,需要的朋友可以參考下2019-10-10docker中run、start和create命令的區(qū)別
對(duì)于 Docker 初學(xué)者來說,docker start、docker run 和 docker create 等術(shù)語可能會(huì)令人困惑,本文就來介紹一下docker中run、start和create命令的區(qū)別,感興趣的可以了解一下2023-11-11Linux系統(tǒng)通過Docker安裝SQL?Server數(shù)據(jù)庫
這篇文章介紹了Linux系統(tǒng)通過Docker安裝SQL?Server數(shù)據(jù)庫的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03Docker命令讓普通用戶能夠執(zhí)行的實(shí)現(xiàn)
這篇文章主要介紹了Docker命令讓普通用戶能夠執(zhí)行的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03docker容器環(huán)境安裝及鏡像基礎(chǔ)操作
容器是一種輕量級(jí)虛擬化技術(shù),能夠快速構(gòu)建業(yè)務(wù)環(huán)境并便于業(yè)務(wù)遷移,解決兼容性問題,這篇文章主要介紹了docker容器環(huán)境安裝及鏡像基礎(chǔ)操作,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09Linux下定時(shí)自動(dòng)備份Docker中所有SqlServer數(shù)據(jù)庫的腳本
這篇文章主要介紹了Linux下定時(shí)自動(dòng)備份Docker中所有SqlServer數(shù)據(jù)庫?,編寫shell文件給出一個(gè)備份的范例,在Linux添加定時(shí)任務(wù),通過下列命令來檢測(cè)并安裝這個(gè)服務(wù),需要的朋友可以參考下2022-09-09