你必須知道的Docker資料卷(Volume)
一、將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/html 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 8500:8500 --restart=always \
-v /XiLife/consul/data/server1:/consul/data -v /XiLife/consul/conf/server1:/consul/config \
-e CONSUL_BIND_INTERFACE='eth0' --privileged=true \
--name=consul_server_1 consul:1.4.4 agent -server -bootstrap-expect=3 -ui -node=consul_server_1 -client='0.0.0.0' \
-data-dir /consul/data -config-dir /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的資料卷及掛載資料到容器的兩種主要方式Volumes和Bind Mounts,並介紹基本的使用方式和步驟,通過資料卷我們可以實現Docker的資料持久化,在實際應用中比較廣泛。