你必须知道的Docker数据卷
本篇已加入《.NET Core on K8S學(xué)習(xí)實踐系列文章索引》(微信上暫無法訪問,可以通過cnblogs博客園訪問),可以點擊查看更多容器化技術(shù)相關(guān)系列文章。本篇預(yù)計閱讀時間為5分鐘。
01
—
Docker數(shù)據(jù)掛載到容器
在Docker中,要想實現(xiàn)數(shù)據(jù)的持久化(所謂Docker的數(shù)據(jù)持久化即數(shù)據(jù)不隨著Container的結(jié)束而結(jié)束),需要將數(shù)據(jù)從宿主機掛載到容器中。目前Docker提供了三種不同的方式將數(shù)據(jù)從宿主機掛載到容器中:
????(1)volumes:Docker管理宿主機文件系統(tǒng)的一部分,默認(rèn)位于 /var/lib/docker/volumes 目錄中;(最常用的方式)
? ?由上圖可以知道,目前所有Container的數(shù)據(jù)都保存在了這個目錄下邊,由于沒有在創(chuàng)建時指定卷,所以Docker幫我們默認(rèn)創(chuàng)建許多匿名(就上面這一堆很長ID的名字)卷。
(2)bind mounts:意為著可以存儲在宿主機系統(tǒng)的任意位置;(比較常用的方式)
但是,bind mount在不同的宿主機系統(tǒng)時不可移植的,比如Windows和Linux的目錄結(jié)構(gòu)是不一樣的,bind mount所指向的host目錄也不能一樣。這也是為什么bind mount不能出現(xiàn)在Dockerfile中的原因,因為這樣Dockerfile就不可移植了。
(3)tmpfs:掛載存儲在宿主機系統(tǒng)的內(nèi)存中,而不會寫入宿主機的文件系統(tǒng);(一般都不會用的方式)
三種方式的示意圖如下所示:
02
—
Volume的基本使用
2.1 管理卷
例如,這里我們創(chuàng)建一個自定義的容器卷,名為"edc-nginx-vol":
2.2 創(chuàng)建使用指定卷的容器
有了自定義容器卷,我們可以創(chuàng)建一個使用這個數(shù)據(jù)卷的容器,這里我們以nginx為例:
# docker run -d -it --name=edc-nginx -p 8800:80 \ # -v edc-nginx-vol:/usr/share/nginx/html nginx其中,-v代表掛載數(shù)據(jù)卷,這里使用自定數(shù)據(jù)卷edc-nginx-vol,并且將數(shù)據(jù)卷掛載到 /usr/share/nginx/html (這個目錄是yum安裝nginx的默認(rèn)網(wǎng)頁目錄)。
如果沒有通過-v指定,那么Docker會默認(rèn)幫我們創(chuàng)建匿名數(shù)據(jù)卷進(jìn)行映射和掛載。
創(chuàng)建好容器之后,我們可以進(jìn)入容器里面看看:
? 可以看到有兩個默認(rèn)頁,這時我們新啟動一個SSH連接到宿主機去到剛剛創(chuàng)建的數(shù)據(jù)卷里邊看看:
? 可以看到,我們可以訪問到容器里面的兩個默認(rèn)頁面,由此可知,volume幫我們做的類似于一個軟鏈接的功能。在容器里邊的改動,我們可以在宿主機里感知,而在宿主機里面的改動,在容器里邊可以感知到。
這時,如果我們手動stop并且remove當(dāng)前nginx容器,我們會發(fā)現(xiàn)容器卷里面的文件還在,并沒有被刪除掉。
? 由此可以驗證,在數(shù)據(jù)卷里邊的東西是可以持久化的。如果下次還需要創(chuàng)建一個nginx容器,那么還是復(fù)用當(dāng)前數(shù)據(jù)卷里面的文件。
此外,我們還可以啟動多個nginx容器實例,并且共享同一個數(shù)據(jù)卷,復(fù)用性和擴展性較強。
2.3 清理卷
如果不再使用自定義數(shù)據(jù)卷了,那么可以手動清理掉:
# docker stop edc-nginx // 暫停容器實例 # docker rm edc-nginx // 移除容器實例 # docker volume rm edc-nginx-vol // 刪除自定義數(shù)據(jù)卷03
—
Bind Mounts的基本使用
3.1 使用卷創(chuàng)建一個容器
# docker run -d -it --name=edc-nginx \ # -v /app/wwwroot:/usr/share/nginx/html nginx這里指定了將宿主機上的 /app/wwwroot 目錄(如果沒有會自動創(chuàng)建)掛載到 /usr/share/nginx/html (這個目錄是yum安裝nginx的默認(rèn)網(wǎng)頁目錄)。
這時我們再次進(jìn)入容器內(nèi)部看看:
? 可以看到,與volumes不同,bind mounts的方式會隱藏掉被掛載目錄里面的內(nèi)容(如果非空的話),這里是/usr/share/nginx/html 目錄下的內(nèi)容被隱藏掉了,因此我們看不到。
但是,我們可以將宿主機上的文件隨時掛載到容器中:
Step1.新建一個index.html
Step2.在容器中查看
3.2 驗證綁定
# docker inspect edc-nginx? 通過上述命令可以看到一大波配置,我們要關(guān)注的是:
3.3 清理
# docker stop edc-nginx # docker rm edc-nginx同volumes一樣,當(dāng)我們清理掉容器之后,掛載目錄里面的文件仍然還在,不會隨著容器的結(jié)束而消失,從而實現(xiàn)數(shù)據(jù)持久化。
3.4 應(yīng)用案例
在服務(wù)治理組件中,服務(wù)發(fā)現(xiàn)組件是一個最常用的組件之一,Consul是一個流行的服務(wù)發(fā)現(xiàn)開源項目,Consul推薦我們使用配置文件的方式注冊服務(wù)信息。因此,我們常常會將填寫好服務(wù)注冊配置文件放在宿主機的一個文件目錄下將其掛載到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數(shù)據(jù)和配置文件的地方。因此,宿主機上的配置文件的變化會及時反映到容器中,比如我們在宿主機上的目錄下更新了配置文件,那么只需要reload一下Consul的容器實例即可:
# docker exec consul-server consul reload*.這里的consul-server是容器的名字,consul reload是重新加載的命令(非restart)。
04
—
小結(jié)
本文探索了Docker的數(shù)據(jù)卷及掛載數(shù)據(jù)到容器的兩種主要方式Volumes和Bind Mounts,并介紹基本的使用方式和步驟,通過數(shù)據(jù)卷我們可以實現(xiàn)Docker的數(shù)據(jù)持久化,在實際應(yīng)用中比較廣泛。
參考資料:
(1)李振良,《Docker Volume詳解》
(2)CloudMan,《每天5分鐘玩轉(zhuǎn)Docker容器技術(shù)》
(3)阿龍,《Docker存儲卷詳解》
傳送門:
我在2019年最主要的博文《.NET Core on K8S學(xué)習(xí)實踐系列文章索引》=>https://www.cnblogs.com/edisonchou/p/aspnet_core_k8s_artcles_index.html
點個在看少個bug??
總結(jié)
以上是生活随笔為你收集整理的你必须知道的Docker数据卷的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core 3.0预览版7中的A
- 下一篇: VS Code 1.37 发布!多达数十