docker进阶篇(一) ---- Volume(数据卷)
引言
docker的鏡像是由多個只讀的文件系統(tǒng)疊加在一起形成的。當(dāng)我們在我啟動一個容器的時候,docker會加載這些只讀層并在這些只讀層的上面(棧頂)增加一個讀寫層。這時如果修改正在運行的容器中已有的文件,那么這個文件將會從只讀層復(fù)制到讀寫層。該文件的只讀版本還在,只是被上面讀寫層的該文件的副本隱藏。當(dāng)刪除docker,或者重新啟動時,之前的更改將會消失。在Docker中,只讀層及在頂部的讀寫層的組合被稱為Union File System(聯(lián)合文件系統(tǒng))。
為了很好的實現(xiàn)數(shù)據(jù)保存和數(shù)據(jù)共享,Docker提出了Volume這個概念,簡單的說就是繞過默認(rèn)的聯(lián)合文件系統(tǒng),而以正常的文件或者目錄的形式存在于宿主機(jī)上。又被稱作數(shù)據(jù)卷。
?
?
Volume的作用
- 通過數(shù)據(jù)卷可以在容器之間實現(xiàn)共享和重用
- 對數(shù)據(jù)卷的修改會立馬生效(非常適合作為開發(fā)環(huán)境)
- 對數(shù)據(jù)卷的更新,不會影響鏡像
- 卷會一直存在,直到?jīng)]有容器使用
?
?
初始化Volume
在使用docker run的時候我們可以通過 -v 來創(chuàng)建一個數(shù)據(jù)卷并掛載到容器上,在一次run中多次使用可以掛載多個容器。
如果使用Dockerfile方式進(jìn)行初始化時可以使用 VOLUME 來添加一個或者多個新的卷到由該鏡像創(chuàng)建的任意容器。
創(chuàng)建一個數(shù)據(jù)卷
docker run -p 8080:80 -d --name shanlei-nginx -v /usr/share/nginx/html nginx上面的命令的意思是,我們創(chuàng)建了一個名稱為shanlei-nginx的容器,將本機(jī)的8080端口映射到容器中nginx服務(wù)器的默認(rèn)web訪問端口80下,創(chuàng)建一個數(shù)據(jù)卷,并掛載到容器的/usr/share/nginx/html目錄下。
這時我們就可以繞過聯(lián)合文件系統(tǒng),直接在主機(jī)上操作該目錄了,任何在該鏡像/usr/share/nginx/html下的文件都會被復(fù)制到Volume。
我們可以通過docker?inspect指令找到Volume在主機(jī)上的存儲位置
docker inspect inspect shanlei-nginxdocker inspect指令后面的參數(shù)可以跟容器名稱。通過這個命令我們可以獲得容器所有的相關(guān)信息。我們需要看這一部分
... ..."Mounts": [{"Type": "volume","Name": "057f911105d4c77d2cfe16ee6acb7f5a43f2643d571708da40f5db55e27b1155","Source": "/var/lib/docker/volumes/057f911105d4c77d2cfe16ee6acb7f5a43f2643d571708da40f5db55e27b1155/_data","Destination": "/usr/share/nginx/html","Driver": "local","Mode": "","RW": true,"Propagation": ""} ], ... ...這說明docker把本機(jī)的“Source”指向目錄,也就是
/var/lib/docker/volumes/057f911105d4c77d2cfe16ee6acb7f5a43f2643d571708da40f5db55e27b1155/_data掛載到了容器的“Destination”指向的目錄。
在Linux中我們可以直接進(jìn)入“Source”指向的路徑(注意在訪問該目錄時可能會有權(quán)限問題)
?
只要將主機(jī)的目錄掛載到容器的目錄上,那改變就會立即生效。在Dockerfile中我們可以通過VOLUME達(dá)到相同的目的
FROM nginx VOLUME /usr/share/nginx/html目錄作為數(shù)據(jù)卷
通過-v標(biāo)識可以將主機(jī)的目錄掛載到容器中去
sudo docker run -d -p 8080:80 -v $PWD/html:/usr/share/nginx/html nginx上面的命令將本機(jī)的$PWD/html目錄掛載到容器的/usr/share/nginx/html目錄。$PWD在是一個系統(tǒng)環(huán)境變量,指代當(dāng)前目錄環(huán)境。這個功能在進(jìn)行測試的時候十分方便,比如用戶可以放置一些程序到本地目錄中,來查看容器是否正常工作。本地目錄的路徑必須是絕對路徑,如果目錄不存在 Docker 會自動為你創(chuàng)建它。
注意:Dockerfile中不支持這種語法.
docker掛載數(shù)據(jù)卷的默認(rèn)權(quán)限是讀寫,當(dāng)然我們可以通過指令:ro指定為只讀。
sudo docker run -d -p 8080:80 -v $PWD/html:/usr/share/nginx/html:ro nginx在我的本機(jī)主機(jī)的$PWD/html中有一個index.html文件,內(nèi)容如下:
this is old我們運行上面的命令,并將本機(jī)8080端口映射到容器中nginx服務(wù)器的默認(rèn)web端口80下,現(xiàn)在我們來訪問localhost:8080
現(xiàn)在我們修改本機(jī)下的$PWD/html/index.html
this is new訪問localhost:8080
文件作為數(shù)據(jù)卷
我們也可以使用-v指令從主機(jī)掛載單個文件到容器中去
docker run -d -p 8080:80 -v $PWD/html/index.html:/usr/share/nginx/html/index.html nginx當(dāng)修改本機(jī)$PWD/html/index.html時,容器中的/usr/share/nginx/html/index.html也會隨之變化。效果和上面相同,在這里就不做贅述了。
注意:如果直接掛載一個文件,很多文件編輯工具,包括 vi 或者 sed --in-place ,可能會造成文件 inode的改變,從 Docker 1.1 .0起,這會導(dǎo)致報錯誤信息。所以最簡單的辦法就直接掛載文件的父目錄。
?
?
數(shù)據(jù)共享
如果想要實現(xiàn)容器間的數(shù)據(jù)共享,那么需要授權(quán)一個容器訪問另一個容器的Volume。我們可以在使用docker run時使用-volumes-from參數(shù)來進(jìn)行指定。
docker run -it -h NEWCONTAINER --volumes-from shanlei-nginx ubuntu /bin/bash
?
注意:值得注意的是不管shanlei-nginx是否運行,它都會起作用。只要有容器連接Volume,它就不會被刪除。
數(shù)據(jù)卷容器
如果我們有一些持續(xù)更新的數(shù)據(jù)需要在容器之間共享,最好創(chuàng)建數(shù)據(jù)卷容器。常見的使用場景是使用純數(shù)據(jù)容器來持久化數(shù)據(jù)庫、配置文件或者數(shù)據(jù)文件等。
數(shù)據(jù)卷容器,其實就是一個正常的容器,專門用來提供數(shù)據(jù)卷供其它容器掛載的。
首先我們需要先創(chuàng)建一個數(shù)據(jù)卷容器
docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
?
然后通過--volumes-from指令參數(shù)來掛載 dbdata 容器中的數(shù)據(jù)卷。
docker run -d --volumes-from dbdata --name db1 training/postgres當(dāng)然,我們也可以使用多個 --volumes-from 參數(shù)來從多個容器掛載多個數(shù)據(jù)卷。 也可以從其他已經(jīng)掛載了數(shù)據(jù)卷的容器
來掛載數(shù)據(jù)卷。
現(xiàn)在我們進(jìn)入容器中查看數(shù)據(jù)卷容器是否掛載成功
docker exec -it db1 /bin/bash
說明數(shù)據(jù)卷容器掛載已經(jīng)成功了。
注意:如果刪除了掛載的容器(包括 dbdata、db1 和 db2等),數(shù)據(jù)卷并不會被自動刪除。如果要刪除一個數(shù)據(jù)卷,必
須在刪除最后一個還掛載著它的容器時使用 docker rm -v 命令來指定同時刪除關(guān)聯(lián)的容器。
備份和恢復(fù)
我們可以利用數(shù)據(jù)卷對其中的數(shù)據(jù)進(jìn)行進(jìn)行備份、恢復(fù)和遷移。
首先使用 --volumes-from 標(biāo)記來創(chuàng)建一個加載 dbdata 容器卷的容器,并從本地主機(jī)掛載當(dāng)前到容器的 /backup 目錄。命令如下:
docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata容器啟動后,使用了 tar 命令來將 dbdata 卷備份為本地的 /backup/backup.tar 。
恢復(fù)
如果要恢復(fù)數(shù)據(jù)到一個容器,首先創(chuàng)建一個帶有數(shù)據(jù)卷的容器 dbdata2。
docker run -v /dbdata --name dbdata2 ubuntu /bin/bash然后創(chuàng)建另一個容器,掛載 dbdata2 的容器,并使用 untar 解壓備份文件到掛載的容器卷中。
?
?
以上
轉(zhuǎn)載于:https://www.cnblogs.com/lishanlei/p/9503596.html
總結(jié)
以上是生活随笔為你收集整理的docker进阶篇(一) ---- Volume(数据卷)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 周报告
- 下一篇: Codeforces Round #50