在docker中,數據卷是宿主機的一個可以供一個或多個容器使用的特殊目錄,它可以在容器之間共享和重用,本地與容器間傳遞數據更高效;對數據卷的修改會立馬有效,在容器內部與本地目錄均可對數據卷進行修改。
本教程操作環境:linux5.9.8系統、docker-1.13.1版、Dell G3電腦。
docker數據卷是什么
數據卷(Data Volumes)是宿主機中的一個目錄或文件,數據卷的設計目的就是數據的持久化,完全獨立于容器的生存周期,因此Docker不會在容器刪除時刪除其掛載的數據卷。當容器目錄和數據卷目錄綁定后,對方的修改會立即同步,一個數據卷可以被多個容器同時掛載,一個容器也可以被掛載多個數據卷。
數據卷特性
-
數據卷可以在容器之間共享和重用,本地與容器間傳遞數據更高效
-
對數據卷的修改會立馬有效,在容器內部與本地目錄均可對數據卷進行修改
-
對數據卷的更新,不會影響鏡像,對數據與應用進行了解耦操作
-
卷會一直存在,直到沒有容器使用
一、將Docker數據掛載到容器
在Docker中,要想實現數據的持久化(所謂Docker的數據持久化即數據不隨著Container的結束而結束),需要將數據從宿主機掛載到容器中。目前Docker提供了三種不同的方式將數據從宿主機掛載到容器中:
(1)volumes:Docker管理宿主機文件系統的一部分,默認位于 /var/lib/docker/volumes 目錄中;(最常用的方式)
由上圖可以知道,目前所有Container的數據都保存在了這個目錄下邊,由于沒有在創建時指定卷,所以Docker幫我們默認創建許多匿名(就上面這一堆很長ID的名字)卷。
(2)bind mounts:意為著可以存儲在宿主機系統的任意位置;(比較常用的方式)
但是,bind mount在不同的宿主機系統時不可移植的,比如Windows和Linux的目錄結構是不一樣的,bind mount所指向的host目錄也不能一樣。這也是為什么bind mount不能出現在Dockerfile中的原因,因為這樣Dockerfile就不可移植了。
(3)tmpfs:掛載存儲在宿主機系統的內存中,而不會寫入宿主機的文件系統;(一般都不會用的方式)
三種方式的示意圖如下所示:
二、Volume的基本使用
2.1 管理卷
#?docker?volume?create?edc-nginx-vol?//?創建一個自定義容器卷 #?docker?volume?ls?//?查看所有容器卷 #?docker?volume?inspect?edc-nginx-vol?//?查看指定容器卷詳情信息
例如,這里我們創建一個自定義的容器卷,名為”edc-nginx-vol”:
2.2 創建使用指定卷的容器
有了自定義容器卷,我們可以創建一個使用這個數據卷的容器,這里我們以nginx為例:
#?docker?run?-d?-it?--name=edc-nginx?-p?8800:80?-v?edc-nginx-vol:/usr/share/nginx/
其中,-v代表掛載數據卷,這里使用自定數據卷edc-nginx-vol,并且將數據卷掛載到 /usr/share/nginx/html (這個目錄是yum安裝nginx的默認網頁目錄)。
如果沒有通過-v指定,那么Docker會默認幫我們創建匿名數據卷進行映射和掛載。
創建好容器之后,我們可以進入容器里面看看:
? 可以看到有兩個默認頁,這時我們新啟動一個SSH連接到宿主機去到剛剛創建的數據卷里邊看看:
? 可以看到,我們可以訪問到容器里面的兩個默認頁面,由此可知,volume幫我們做的類似于一個軟鏈接的功能。在容器里邊的改動,我們可以在宿主機里感知,而在宿主機里面的改動,在容器里邊可以感知到。
這時,如果我們手動stop并且remove當前nginx容器,我們會發現容器卷里面的文件還在,并沒有被刪除掉。
? 由此可以驗證,在數據卷里邊的東西是可以持久化的。如果下次還需要創建一個nginx容器,那么還是復用當前數據卷里面的文件。
此外,我們還可以啟動多個nginx容器實例,并且共享同一個數據卷,復用性和擴展性較強。
2.3 清理卷
如果不再使用自定義數據卷了,那么可以手動清理掉:
#?docker?stop?edc-nginx?//?暫停容器實例 #?docker?rm?edc-nginx?//?移除容器實例 #?docker?volume?rm?edc-nginx-vol?//?刪除自定義數據卷
三、Bind Mounts的基本使用
3.1 使用卷創建一個容器
docker?run?-d?-it?--name=edc-nginx?-v?/app/wwwroot:/usr/share/nginx/html?nginx
這里指定了將宿主機上的 /app/wwwroot 目錄(如果沒有會自動創建)掛載到 /usr/share/nginx/html (這個目錄是yum安裝nginx的默認網頁目錄)。
這時我們再次進入容器內部看看:
? 可以看到,與volumes不同,bind mounts的方式會隱藏掉被掛載目錄里面的內容(如果非空的話),這里是/usr/share/nginx/html 目錄下的內容被隱藏掉了,因此我們看不到。
但是,我們可以將宿主機上的文件隨時掛載到容器中:
Step1.新建一個index.html
Step2.在容器中查看
3.2 驗證綁定
docker?inspect?edc-nginx
? 通過上述命令可以看到一大波配置,我們要關注的是:
3.3 清理
docker?stop?edc-nginx docker?rm?edc-nginx
同volumes一樣,當我們清理掉容器之后,掛載目錄里面的文件仍然還在,不會隨著容器的結束而消失,從而實現數據持久化。
3.4 應用案例
在服務治理組件中,服務發現組件是一個最常用的組件之一,Consul是一個流行的服務發現開源項目,Consul推薦我們使用配置文件的方式注冊服務信息。因此,我們常常會將填寫好服務注冊配置文件放在宿主機的一個文件目錄下將其掛載到Consul的容器指定目錄下,如下所示:
docker?run?-d?-p?:?--restart=always? -v?/XiLife/consul/data/server1:/consul/data?-v?/XiLife/consul/conf/server1:/consul/config? -e?CONSUL_BIND_INTERFACE=?--privileged=? --name=consul_server_1?consul:.?agent?-server?-bootstrap-expect=?-ui?-node=consul_server_1?-client=? -data-?/consul/data?-config-?/consul/config?-datacenter=xdp_dc;
可以看到,我們通過Bind Mounts的方式將宿主機上的/XiLife/consul/data/server1目錄掛載到了容器的/consul/data目錄下,還將/XiLife/consul/conf/server1目錄掛載到了容器的/consul/config目錄下,而容器下的兩個目錄/consul/data和/consul/config則是我們指定的存放agent數據和配置文件的地方。因此,宿主機上的配置文件的變化會及時反映到容器中,比如我們在宿主機上的目錄下更新了配置文件,那么只需要reload一下Consul的容器實例即可:
docker?exec?consul-server?consul?reload
*.這里的consul-server是容器的名字,consul reload是重新加載的命令(非restart)。
推薦學習:《docker視頻教程》