默認狀況下,Docker容器內部新建立文件或者修改文件,結果會保存在容器的可讀寫層中,所以:
(1)當container消失時,與container一體的可讀寫層也一併消失,數據並未持久化。當一個container須要其它container中可讀寫層的數據時,讀取操做很是困難。
(2)container可讀寫層與宿主機的文件系統緊密結合,很難進行遷移。
(3)寫入數據到container可讀寫層須要storage driver,與直接在宿主機文件系統中讀寫數據相比效率要低。
Docker支持的數據持久化方案以下:
(1)volume。
(2)bind mount。
(3)tmpfs mount,僅限Linux操做系統中。
Docker建立容器時經過參數選項指定數據持久化路徑,bind mount與volume使用-v或者--volume選項,tmpfs經過--tmpfs選項。從docker17.0.6開始,推薦使用新選項--mount。
--mount參數選項以下:
type:能夠是bind、volume或者tmpfs,默認是volume
source:宿主機上目錄路徑,能夠用縮寫src
destination:目標路徑,容器上掛載的路徑,能夠用dst或者 target
readonly :可選項,容器掛載的路徑會被設置爲只讀
volume-opt:可選項,當volume驅動接受同時多個參數做爲選項時,能夠以多個鍵值對的方式傳入。
若是主機中的文件或目錄不存在,當使用--mount掛載時,Docker會報錯,當使用-v或--volume時,會在主機上建立目錄。docker
volume是Docker官方推薦的持久化方案,默認狀況下,volume的存儲空間來自於宿主機文件系統中的某個目錄,如/var/lib/docker/volumes/,docker系統外的程序無權限修改其中的數據。
volume由Docker負責建立、管理。用戶能夠顯式的調用命令docker volume create建立volume,也能夠經過container、service的啓動隱式建立。
一個volume能夠同時供多個container使用,若是沒有container使用volume,其不會自動刪除,用戶需運行docker volume prune明確刪除。
若是用戶顯式建立volume,則須要給其指定一個名稱;若是是隱式建立volume,Docker會自動爲其分配一個在宿主機範圍內惟一的名字。
Docker引入Volume緣由以下:
(1)刪除容器時,volume不會被刪除。
(2)在不一樣容器間共享volume(存儲 / 數據)。
(3)容器與存儲分離。
(4)將volume存儲在遠程主機或雲上。數據庫
docker volume create -v 建立volume時,宿主機目錄路徑必須以/或~/開頭,不然Docker會將其當成volume 而不是bind mount。
若是宿主機上的目錄不存在,docker 會自動建立目錄;若是容器中的目錄不存在,docker會自動建立目錄;若是容器中的目錄已有內容,docker會使用宿主機上目錄的內容覆蓋容器目錄的內容。安全
docker run -it -v my-volume:/data --name container1 busybox
啓動容器 container1 時,掛載名爲my-volume的volume到容器的 /data目錄。若是 my-volume不存在,docker會自動建立my-volume,並掛載到 /data 目錄。
my-volume在宿主機目錄爲 /var/lib/docker/volumes/my-volume/_data
。
docker run -v 命令中,若是沒有指定volume名稱,docker會默認建立一個匿名的volume。docker run -it -v /data --name container1 busybox
建立匿名volume位於/var/lib/docker/volumes/xxxxx/_data
。
可使用docker inspect container1查看容器的volume的具體信息。docker run -it -v test:/test --name test busybox
建立的volume位於/var/lib/docker/volumes/test/_data
。bash
經過使用第三方提供的volume driver,用戶能夠將數據持久到遠程主機或者雲存儲中。
(1)多個容器間共享數據。
(2)宿主機不保證存在固定目錄結構。
(3)持久化數據到遠程主機或者雲存儲而非本地。
(4)須要備份、遷移、合併數據時。中止container,將volume總體複製,用於備份、遷移、合併等。服務器
bind mount持久化方式將宿主機中的文件、目錄掛載到容器上,相應文件、目錄能夠被宿主機讀寫,也能夠被容器讀寫。
bind mount持久化方式能夠將數據存儲在宿主機器任何地方,但會依賴宿主機的目錄結構,所以不能經過docker CLI直接管理,而且非Docker進程和Docker進程均可以修改。docker run -it -v host-dava:container-data alpine sh
將host主機host-data目錄mount到container中的container-data目錄
bind mount注意事項:
(1)-v 宿主機目錄路徑必須以/或~/開頭,不然docker會將其當成是volume 而不是bind mount。
(2)若是宿主機上的目錄不存在,docker會自動建立目錄。
(3)若是容器中的目錄不存在,docker會自動建立目錄。
(4)若是容器中目錄已有內容,那麼docker會使用宿主機上目錄的內容覆蓋容器目錄的內容。docker volume create vm_test
建立volumedocker run -it --mount source=vm_test,target=/test test /bin/bash
啓動容器,掛載vm_test到容器/test目錄ide
(1)性能最好
(2)Docker容器與宿主機耦合過於緊密,移植性較差。性能
(1)container共享宿主機配置文件,如docker將宿主機文件/etc/resov.conf文件bind mount到容器上,二者會使用相同的DNS服務器。
(2)開發環境中build容器化。開發過程當中將build過程container化,將宿主機上源代碼目錄bind mount到build container中。修改代碼後,運行build container的build命令,build container則將build結果寫入另外一個bind mount的目錄中。
(3)監控服務container化。讀取宿主機固定文件中的數據實現監控。ui
tmpfs mount只在Linux主機內存中持久化,是臨時性的。當容器中止,tmpfs mount會被移除,一般用於臨時存放敏感文件。
在docker內部,swarm服務使用tmpfs方式來將secrets掛載到服務的容器中。docker run -d -it --name tmptest --tmpfs /test busybox
操作系統
(1)只能在Linux主機內存中,不會持久化到磁盤。
(2)不支持多容器間共享。code
Docker可將用戶名與密碼等敏感數據保存在某個數據庫中,當啓動須要訪問這些敏感數據的container或者service時,docker會在宿主機上建立一個tmpfs,而後將敏感數據從數據庫讀出寫到tmpfs中,再將tmpfs mount到container中,安樣能保證數據安全。當容器中止運行時,則相應的tmpfs也從系統中刪除。