淺析Docker資料管理-資料庫容器化並持久化:資料卷概念、建立資料卷的2種方式、docker volume用法
一、Docker 資料管理
在生產環境中使用Docker的過程,往往需要對資料進行持久化,或者需要在多個容器之間進行資料共享,這必然涉及容器的資料管理操作。
容器中管理資料主要有兩種方式:
(1)資料卷(Data Volumes):容器內資料直接對映到本地主機環境;
(2)資料卷容器(Data Volume Containers):使用特定容器維護資料卷。
1、資料卷
資料卷是一個可供容器使用的特殊目錄,它將主機作業系統目錄直接對映進容器,類似於Linux中的 mount 操作。
容器資料卷作用:(1)容器的持久化;(2)容器間繼承 + 共享資料。
卷 就是目錄或檔案,存在於一個或多個容器中,由docker掛載到容器中,但不屬於聯合檔案系統,因此能夠繞過Union File System提供一些用於持續儲存或共享資料的特性。
卷的設計目的就是資料的持久化,完全獨立於容器的生存週期,因此Docker不會在容器刪除時刪除其掛載的資料卷。
資料卷可以提供很多有用的特性,如下:
(1)資料卷可以在容器之間共享和重用,容器間傳遞資料將變的高效方便;
(2)對資料卷內資料的修改會立馬生效,無論是容器內操作還是本地操作;
(3)對資料卷的更新不會影響映象,解耦了應用和資料;
(4)資料卷的生命令週期預設會一直存在,即使容器被刪除。也就是說:卷會一直存在,直到沒有容器使用,可以安全的解除安裝它。
2、資料卷容器
如果使用者需要在多個容器之間共享一些持續更新的資料,最簡單的方式是使用資料卷容器。資料卷容器也是一個容器,但是它的目的是專門用來提供資料卷供其他容器掛載。
資料卷:“其實就是一個正常的容器,專門用來提供資料卷供其它容器掛載的”。感覺像是由一個容器定義的一個數據掛載資訊。其他的容器啟動可以直接掛載資料卷容器中定義的掛載資訊。
示例:docker run -v /home/dock/Downloads:/usr/Downloads --name dataVol ubuntu64 /bin/bash,建立一個普通的容器,用 --name 給他指定了一個名(不指定的話會生成一個隨機的名字)。
再建立一個新的容器,來使用這個資料卷:docker run -it --volumes-from dataVol ubuntu64 /bin/bash
--volumes-from 用來指定要從哪個資料捲來掛載資料,這樣在新建立的容器裡/usr/Downloads目錄會和宿主機目錄/home/dock/Downloads同步。
這裡資料卷容器僅做提及,有需要可後面深度瞭解。
二、建立資料卷的 2 種方式
1、直接用命令新增
(1)在容器內建立一個數據卷:在用 docker run
命令的時候,使用 -v
標記可以在容器內建立一個數據卷。多次重複使用 -v
標記可以建立多個數據卷。
(2)掛載一個主機目錄作為資料卷(推薦)
使用 -v
標記也可以指定掛載一個本地的已有目錄到容器中去作為資料卷(推薦方法)
使用 docker volume create pgdata
命令建立本地卷:
[root@CentOS /]# docker volume create pgdate
pgdate
[root@CentOS /]# find / -name pgdate
/var/lib/docker/volumes/pgdate
啟動容器:
docker run -itd --rm -v pgdata:/var/lib/postgresql/data -p 5433:5432 postgres:11.11
Docker掛載資料卷的預設許可權是讀寫(rw),使用者也可以通過 ro
指定為只讀,加了 :ro
之後,容器內對所掛載資料卷內的資料就無法修改了。
docker run -itd --rm -v pgdata:/var/lib/postgresql/data:ro -p 5433:5432 postgres:11.11
(3)掛載一個本地主機檔案作為資料卷:-v
標記也可以從主機掛載單個檔案到容器中作為資料卷(不推薦)。
2、DockerFile 建立
在 Dockerfile 中使用 Volume 指令來給映象新增一個或多個數據卷。語法格式:
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
說明:出於可移值和分享的考慮,用 -v 主機目錄:容器目錄
這種方法 不能夠直接在Dockerfile中實現。
原因是因為由於宿主機目錄是依賴於特定宿主機的,並不能保證在所有宿主機上都存在這樣的特定目錄。
3、測試:安裝並持久化PostgreSQL
以postgresql為例進行docker化並驗證資料卷的永續性。
(1)建立本地卷:docker volume create pgdate
(2)啟動容器:將建立的卷 pgdata 掛載到容器的 /var/lib/postgresql/data 目錄
docker run -itd --rm -v pgdata:/var/lib/postgresql/data -p 5433:5432 postgres:11.11
(3)連線資料庫發現連線成功,新建一張表插入一條記錄
(4)停止容器 docker stop CONTAINER ID ,因為啟動時使用了 -rm 所以當容器退出時會自動刪除容器。
(5)再次啟動一個新的容器。
docker run -itd --rm -v pgdata:/var/lib/postgresql/data -p 5433:5432 postgres:11.11
(6)檢視資料庫,發現之前的記錄還在,說明持久化是成功的。
4、可能遇到的問題
如果Docker掛載主機目錄時,Docker訪問出現 catnot open directory.:Permission denied
解決辦法:在掛載目錄後多加一個--privileged=true
引數。如
docker run -it -v /hostDataVolume:/containerDataVolume --privileged=true centos
docker 容器內新增資料卷的2種方式,具體測試可以看這篇部落格:https://xiaojin21cen.blog.csdn.net/article/details/84501206
三、docker volume用法
volume 在docker中的意思表示將宿主機上的目錄掛在到docker容器中,這樣可以保持資料持久化,當將容器刪除時,資料不會丟失。
1、手動建立一個volume可以使用命令:docker volume create wincom-node
2、檢視volume資訊使用命令:docker inspect wincom-node,如下圖所示
其中Mountpoint表示的是本機的目錄,當掛在到容器中後,容器中的目錄則顯示的是該目錄下的資訊。
3、刪除volume則使用命令:docker volume rm wincom-node
4、dockerfile 裡建立資料卷
FROM tomcat:9.1
VOLUME ["/usr/local/tomcat/webapps"]
可以看出以DockerFile中VOLUME命令指定容器中資料卷對應位置,並沒有提供能夠指定在宿主機中檔案的位置,其原因是,不同的宿主機下,無法確定一個目錄的存在。上面沒有指定資料卷在宿主機中位置,如何檢視,使用 docker inspect 容器id 檢視容器詳情: