寫在前面
我們在上篇學習了容器網路,對容器網路驅動bridge工作原理做了較為詳細的介紹,今天小作文一起看看容器中另一個關鍵域-儲存。
容器的儲存可以分為兩大類:
一種是與映象相關的即我們在《docker容器技術基礎之聯合檔案系統OverlayFS》一文提到的容器層Copy-On-Write
特性。預設情況下,在容器內建立的所有檔案都儲存在可寫容器層上,這種直接將檔案儲存在容器層的方式資料難以持久化和共享,由於依賴儲存驅動與使用直接寫入主機檔案系統的資料卷相比,這種額外的抽象會降低效能 。
另一中是宿主機儲存即通過將宿主機目錄繫結或掛在到容器中使用,容器停止後資料也能持久化。小作文主要介紹後者。
幾種儲存掛載方式
這裡我們根據資料儲存在 Docker 主機上的不同位置繪製如下圖:
1.bind mounts
繫結掛載與卷相比,功能有限。使用繫結掛載時,主機上的檔案或目錄會掛載到容器中。檔案或目錄由其在主機上的完整路徑引用。目錄不需要已經存在於 Docker 主機上,如果不存在,docker會幫我們建立。注意一下,只能自動建立目錄哦。
我們通過 -v 選項繫結掛載一個目錄 /nginx/html 到容器中看看
docker run -dt -v /nginx/html:/usr/share/nginx/html --name nginx nginx
通過docker inspect nginx 檢視容器 Mounts欄位
"Mounts": [
{
"Type": "bind",
"Source": "/nginx/html",
"Destination": "/usr/share/nginx/html",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
接著我們在docker主機上建立一個index.html並寫入hello nginx,然後訪問容器IP,顯然我們的掛載已經生效了。
[root@localhost ~]# echo "hello nginx" > /nginx/html/index.html
[root@localhost ~]# curl 172.17.0.4
hello nginx
這裡有一個問題,我們可以通過docker主機修改檔案使容器內檔案生效,反過來也一樣,容器可以修改、建立和刪除主機檔案系統上的內容。處理這個問題我們可以在建立容器的時候配置掛載目錄的許可權,比如下面的只讀許可權:
docker run -dt -v /nginx/html:/usr/share/nginx/html:ro --name nginx nginx
所以在我們使用繫結掛載的時候,你操作的是主機檔案系統,你必須清楚如下:
- 你掛載的目錄包含哪些內容,以免對其他應用造成影響。
- 你的容器是否應該有權操作這些目錄。
2.volumes
volume儲存卷由 Docker 建立和管理,我們可以使用該docker volume create
命令顯式的建立卷,或者在容器建立時建立卷。
[root@localhost ~]# docker volume create nginx_volume
nginx_volume
[root@localhost volumes]# docker inspect nginx_volume
[
{
"CreatedAt": "2021-08-12T01:58:04-04:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx_volume/_data",
"Name": "nginx_volume",
"Options": {},
"Scope": "local"
}
]
可以看到掛載點處於docker的根目錄/var/lib/docker/volumes下
通過docker volume rm/prune
清除單個或所有未再使用的卷,可以通過docker 命令來管理卷是對比繫結掛載的一個優勢。
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local owncloud-docker-server_files
local owncloud-docker-server_mysql
local owncloud-docker-server_redis
[root@localhost ~]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
owncloud-docker-server_files
owncloud-docker-server_mysql
owncloud-docker-server_redis
Total reclaimed space: 199.4MB
在建立容器時如果未指定容器掛載的源則docker會自動為我們建立一個匿名卷,同樣位於docker根目錄下。
[root@localhost volumes]# docker run -dt -v /usr/share/nginx/html --name nginx_with_volume nginx
d25bdfce9c7ac7bde5ae35067f6d9cf9f0cd2c9cbea6d1bbd7127b3949ef5ac6
[root@localhost volumes]# docker volume ls
DRIVER VOLUME NAME
local d8e943f57d17a255f8a4ac3ecbd6471a735aa64cc7a606c52f61319a6c754980
local nginx_volume
[root@localhost volumes]# ls /var/lib/docker/volumes/
backingFsBlockDev d8e943f57d17a255f8a4ac3ecbd6471a735aa64cc7a606c52f61319a6c754980 metadata.db nginx_volume
當我們建立掛載卷之後,此時的儲存與bind mounts是一致,不過當 docker 主機不能保證具有給定的目錄或檔案結構時,卷可幫助我們將 docker 主機的配置與容器執行時分離。這樣一來當我們需要將資料從一臺 Docker 主機備份、還原或遷移到另一臺時,卷就很方便了,可以脫離host path的限制。
在使用繫結掛載和卷時我們要注意下面傳播覆蓋原則:
掛載一個空卷時:容器內目錄的內容會傳播(複製)到卷中。
繫結掛載或非空卷時:容器內目錄的內容會被卷或繫結的主機目錄覆蓋。
3.tmpfs mount
tmpfs
掛載僅適用於linux主機,當我們使用tmpfs
掛載建立容器時,容器可以在容器的可寫層之外建立檔案。將資料保留在記憶體中,當容器停止時,寫入的資料也將被移除。主要用於臨時儲存不想保留在主機或容器可寫層中的敏感檔案。
通過--tmpfs
選項掛載一個記憶體塊。
docker run -dt --name busybox_tmpfs --tmpfs /etc/running busybox
通過--mount
的方式帶上引數,指定臨時儲存大小。
docker run -dt --name busybox_tmpfs2 --mount type=tmpfs,tmpfs-size=2048,destination=/etc/running busybox
儲存資料共享
在容器之間共享資料主要有兩種方法,第一種比較簡單,只需要將目錄或者volume掛載到多個容器中即可。這裡不做贅述,我們來看一下通過中間容器
實現共享的方式。
我們建立一箇中間容器,包含繫結掛載目錄和一個卷。
docker create -v /share:/volume1 -v /volume2 --name volume_share busybox
在我們需要共享的容器中通過選項--volumes-from
拿過來用即可
docker run -d -t --volumes-from volume_share --name container1 busybox
我們inspect檢查一下Mounts欄位,此時container1已經掛載到了一個bind
目錄和一個volume
"Mounts": [
{
"Type": "bind",
"Source": "/share",
"Destination": "/volume1",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "volume",
"Name": "21605e49a0ba90a1b952a32c1b3f0d42735da8bfe718f0dc76c37e91f1e51c0e",
"Source": "/var/lib/docker/volumes/21605e49a0ba90a1b952a32c1b3f0d42735da8bfe718f0dc76c37e91f1e51c0e/_data",
"Destination": "/volume2",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
關於docker容器儲存我們先學習到這,希望這篇小作文在你需要時對你有點用。
blog:iqsing.github.io
您可以隨意轉載、修改、釋出本文章,無需經過本人同意。