默認情況下鼎俘,容器內(nèi)創(chuàng)建的所有文件都存儲在可寫容器層上哲身。
這意味著:
當容器不再運行時,數(shù)據(jù)不會持續(xù)存在贸伐,并且如果另一個進程需要數(shù)據(jù)勘天,則很難從容器中獲取數(shù)據(jù)。
容器的可寫層緊密耦合到容器運行的主機。您無法輕松地將數(shù)據(jù)移到其他地方误辑。
寫入容器的可寫層需要 存儲驅(qū)動程序來管理文件系統(tǒng)沧踏。存儲驅(qū)動程序使用Linux內(nèi)核提供聯(lián)合文件系統(tǒng)。與使用直接寫入主機文件系統(tǒng)的數(shù)據(jù)卷相比巾钉,這種額外的抽象性能會降低性能 翘狱。
Docker 容器有兩種方式 卷
和 綁定掛載
可將容器中的文件存儲在宿主機的文件系統(tǒng)上,這樣即使在容器停止之后這些文件也會被保留砰苍。如果你在Linux上運行Docker潦匈,你也可以使用tmpfs 掛載
。
1. volume
, bind
和 tmpfs
三者的相同點和區(qū)別
a. 相同之處
無論您選擇使用哪種類型去使用赚导,數(shù)據(jù)在容器內(nèi)看起來都是相同的茬缩。它被視為容器文件系統(tǒng)中的目錄或單個文件。
b. 不同之處
卷(volume)存儲在于 由Docker管理 的主機文件系統(tǒng)的一部分中(在Linux上是:
/var/lib/docker/volumes/
)吼旧。非Docker進程不應該修改這部分文件系統(tǒng)凰锡。卷是在Docker中保留數(shù)據(jù)的最佳方式。綁定掛載(bind mount) 也就是把主機的本地目錄掛載到容器中某個掛載點圈暗〉辔可以存儲在主機系統(tǒng)的任何位置。他們甚至可能是重要的系統(tǒng)文件或目錄员串。Docker主機或Docker容器上的非Docker進程可以隨時修改它們勇哗。
tmpfs掛載(tmpfs mount)僅存儲在主機系統(tǒng)的內(nèi)存中,而不會寫入主機系統(tǒng)的文件系統(tǒng)寸齐。
2. -v
還是 --mount
使用-v
或者 --volume
標志可將綁定掛載和卷掛載到容器中
對于tmpfs
可以使用--tmpfs
在Docker 17.06及更高版本中欲诺,官方建議使用 --mount
,因為語法更清晰渺鹦。
關(guān)于使用數(shù)據(jù)卷和掛載主機目錄的提示
如果將
空卷
掛載到容器中的含有內(nèi)容的目錄中扰法,則會將這些內(nèi)容復制到卷中。同樣海铆,如果您啟動容器并指定一個尚不存在的卷迹恐,則會為您創(chuàng)建一個空卷
。如果將一個
bind mount
或非空的數(shù)據(jù)卷
掛載到容器中的一個非空目錄中卧斟,則這些內(nèi)容會被遮蓋隱藏殴边。隱藏的內(nèi)容不會被刪除或更改,此時也不可被訪問珍语。就像在 Linux 機器中使用mount
命令一樣的效果
3. 數(shù)據(jù)卷 (volume)詳解
由Docker創(chuàng)建和管理锤岸。
可以使用該docker volume create
命令顯式的去創(chuàng)建一個卷,或者在創(chuàng)建容器或服務期間Docker可以創(chuàng)建一個卷板乙。這與綁定掛載的工作方式類似是偷,區(qū)別在于卷由Docker管理拳氢。
卷還支持使用卷驅(qū)動程序,這些卷驅(qū)動程序可讓您將數(shù)據(jù)存儲在遠程主機或云提供程序中蛋铆,以及其他可能性馋评。
是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS刺啦,可以提供很多有用的特性:
數(shù)據(jù)卷
可以在容器之間共享和重用對
數(shù)據(jù)卷
的修改會立馬生效對
數(shù)據(jù)卷
的更新留特,不會影響鏡像數(shù)據(jù)卷
默認會一直存在,即使容器被刪除
注意:
數(shù)據(jù)卷
的使用玛瘸,類似于 Linux 下對目錄或文件進行mount
蜕青,鏡像中的被指定為掛載點的目錄中的文件會隱藏掉,能顯示和看的是掛載的數(shù)據(jù)卷
糊渊,而不是被作為掛載點兒的目錄中原來的內(nèi)容右核。
a. volume 的使用場景
卷是在Docker容器和服務中保存數(shù)據(jù)的首選方式。卷的一些用例包括:
在多個運行容器之間共享數(shù)據(jù)渺绒。如果您沒有明確創(chuàng)建它贺喝,則會在第一次將其裝入容器時創(chuàng)建卷。當該容器停止或被移除時芒篷,該卷仍然存在搜变。多個容器可以同時安裝相同的卷,無論是讀寫還是只讀针炉。僅當您明確刪除卷時才會刪除卷。
當您想要將容器的數(shù)據(jù)存儲在遠程主機或云提供商上而不是本地時扳抽。
當您需要備份篡帕,還原或?qū)?shù)據(jù)從一臺Docker主機遷移到另一臺時,卷是更好的選擇贸呢。您可以停止使用卷的容器镰烧,然后備份卷的目錄實現(xiàn)數(shù)據(jù)的備份和遷移(如
/var/lib/docker/volumes/<volume-name>
)。
b. volume 基本使用
實驗場景一:
創(chuàng)建一個新的數(shù)據(jù)卷楞陷,之后運行一個容器怔鳖,并把數(shù)據(jù)卷掛載到容器的一個目錄
/webapp
下。在容器的
/webapp
目錄下創(chuàng)建文件nginx.txt
并寫入一些內(nèi)容接著退出這個容器固蛾,并刪除這個容器结执。
運行一個新的容器,并掛載剛才的數(shù)據(jù)卷到容器的目錄
/yangge
觀察容器目錄
/yangge
下是否有之前創(chuàng)建的文件nginx.txt
--mount
語法:
--mount type=volume, source=數(shù)據(jù)卷名, target=容器中的掛載點
type
的值可以是 volume
, bind
, tmpfs
默認是 volume
source
也可以簡寫成 src
target
可以簡寫成 dst
創(chuàng)建一個數(shù)據(jù)卷
$ docker volume create yangge_vol
啟動一個容器并掛載一個已經(jīng)創(chuàng)建好的數(shù)據(jù)卷
在用 docker run
命令的時候艾凯,使用 --mount
標記來將 數(shù)據(jù)卷
掛載到容器里献幔。
下面創(chuàng)建一個名為 mynginx
的容器,并加載一個 數(shù)據(jù)卷
到容器的 /webapp
目錄趾诗。*
$ docker run -it --mount source=yangge_vol,target=/webapp --name myanginx nginx /bin/sh
進入容器后蜡感,創(chuàng)建文件
此時在容器的 /webapp 目錄下創(chuàng)建文件 nginx.txt
$ docker exec -it my
/ # touch /webapp/nginx.txt
/ # echo "nginx server" > /webapp/nginx.txt
退出并刪除容器
/ # exit
[root@docker data_volume]# docker rm mynginx
啟動一個新的容器,并且把剛才的數(shù)據(jù)卷 yangge_vol
掛載到新的容器里
[root@docker data_volume]# docker run -it --name nginx_new \
> --mount source=yangge_vol,target=/yangge \
> alpine \
> /bin/sh
接著查看容器中目錄 /yangge
下是否有個剛才的文件 nginx.txt
/ # cat /yangge/nginx.txt
nginx server
實驗場景二:(作業(yè))
- 直接運行一個容器,并且掛載兩個數(shù)據(jù)卷到容器中郑兴。
數(shù)據(jù)卷一:
qf_vol
目標掛載點:/qf_data
數(shù)據(jù)卷二:
shark_vol
目標掛載點:/shark_data
之后分別在容器的兩個目錄創(chuàng)建一些文件犀斋。
退出容器,并刪除容器
把其中的一個數(shù)據(jù)卷掛載到一個新運行的容器情连。
觀察原來建立的數(shù)據(jù)是否還存在
4. bind mount 詳解
就是掛載主機目錄
與卷相比叽粹,綁定安裝具有有限的功能。
當您使用綁定掛載時蒙具,主機上的文件或目錄被掛載到容器中球榆。主機上的文件或目錄必須是完整路徑。
不存在禁筏,它會根據(jù)需求被創(chuàng)建持钉。
您不能使用Docker CLI命令直接管理被掛載的目錄或文件。
會非常高效篱昔,但這點每强,依賴于具有特定目錄結(jié)構(gòu)的主機的文件系統(tǒng)。
副作用是您可以通過容器中運行的進程更改主機文件系統(tǒng) 州刽,包括創(chuàng)建空执,修改或刪除重要的系統(tǒng)文件或目錄。這是一個強大的能力穗椅,可能會對安全產(chǎn)生影響辨绊,包括影響主機系統(tǒng)上的非Docker進程。
a. bind mount
的使用場景
從主機共享配置文件到容器匹表。例如门坷,Docker如何為容器提供DNS解析,默認情況下袍镀,通過將本地的
/etc/resolv.conf
從主機掛載到每個容器默蚌,。在Docker主機上的開發(fā)環(huán)境與容器之間共享源碼苇羡。
當需要保證Docker主機的文件或目錄結(jié)構(gòu)與容器所需的一致時绸吸。
b. 掛載一個主機目錄到容器中
使用 --mount
標記可以指定掛載一個本地主機的目錄到容器中去。
也可以使用 :
-v /src/webapp:/opt/webapp
$ docker run -it --name web --mount type=bind,source=/src/webapp,target=/opt/webapp/ alpine /bin/sh
使用 --mount
參數(shù)時如果本地目錄不存在设江,Docker 會報錯锦茁,并且source 指定的本地文件路徑必須是據(jù)對路徑
。
Docker 掛載主機目錄的默認權(quán)限是 讀寫
绣硝,用戶也可以通過增加 readonly
指定為 只讀
蜻势。
$ docker run -it --name web --mount type=bind,src=/tmp/,dst=/opt/webapp/,readonly alpine /bin/sh
加了 readonly
之后,就掛載為 只讀
了鹉胖。如果你在容器內(nèi) /opt/webapp
目錄新建文件握玛,會顯示如下錯誤
\# touch new.txt
touch: new.txt: Read-only file system
掛載 Docker 主機的本地文件到容器中
$ docker run -it --rm --mount type=bind, src=/root/.bash_history,dst=/root/.bash_history alpine /bin/sh
/ # ls /root/.bash_history
/root/.bash_history
/ #
5. 查看數(shù)據(jù)卷的具體信息
a. 查看所有的 數(shù)據(jù)卷
$ docker volume ls
?
local yangge_vol
b. 在Docker 宿主機里使用以下命令可以查看指定 數(shù)據(jù)卷
的元數(shù)據(jù)信息
$ docker volume inspect yangge_vol
[
{
"CreatedAt": "2018-06-01T11:48:14+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/yangge_vol/_data",
"Name": "yangge_vol",
"Options": {},
"Scope": "local"
}
]
c. 通過容器查看數(shù)據(jù)卷掛載的具體信息**
在主機里使用以下命令可以查看 nginx_new
容器的信息
數(shù)據(jù)卷
信息在 "Mounts" Key 下面
$ docker inspect nginx_new -f "{{json .Mounts}}" |python -m json.tool
[
{
"Destination": "/yangge",
"Driver": "local",
"Mode": "z",
"Name": "yangge_vol",
"Propagation": "",
"RW": true,
"Source": "/var/lib/docker/volumes/yangge_vol/_data",
"Type": "volume"
}
]
d. 刪除數(shù)據(jù)卷
$ docker volume rm yangge_vol
數(shù)據(jù)卷
是被設(shè)計用來持久化數(shù)據(jù)的够傍,它的生命周期獨立于容器,Docker 不會在容器被刪除后自動刪除 數(shù)據(jù)卷
挠铲,并且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的 數(shù)據(jù)卷
冕屯。如果需要在刪除容器的同時移除數(shù)據(jù)卷》髌唬可以在刪除容器的時候使用 docker rm -v
這個命令安聘。
數(shù)據(jù)卷可能會占據(jù)很多空間,可以使用以下命令清理掉沒有容器使用的 數(shù)據(jù)卷
瓢棒。
謹慎操作浴韭,這需要你確認現(xiàn)在暫時沒有使用
數(shù)據(jù)卷在以后也不會再使用,里面也沒有有價值的數(shù)據(jù)脯宿。
$ docker volume prune