docker資料卷
概述
資料卷
是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:
資料卷
可以在容器之間共享和重用- 對
資料卷
的修改會立馬生效 - 對
資料卷
的更新,不會影響映象 資料卷
預設會一直存在,即使容器被刪除
資料卷掛載的三種方式
在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
掛載儲存在宿主機系統的記憶體中,而不會寫入宿主機的檔案系統;(一般都不會用的方式
三種方式的示意圖如下所示:
建立資料卷
[root@localhost ~]# docker volume create test-volume1
test-volume1
[root@localhost ~]# docker volume create test-volume2
test-volume2
[root@localhost ~]# docker volume create test-volume3
test-volume3
檢視所有的資料卷
[root@localhost ~]# docker volume ls DRIVER VOLUME NAME local test-volume1 local test-volume2 local test-volume3
檢視指定資料卷詳情資訊
[root@localhost ~]# docker volume inspect test-volume1
[
{
"CreatedAt": "2020-12-24T10:34:20+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/test-volume1/_data",
"Name": "test-volume1",
"Options": {},
"Scope": "local"
}
]
容器掛載資料卷
方式一:volumes
這裡以nginx為例,建立一個數據卷test-nginx-vol,並且將資料卷掛載到 /usr/share/nginx/html (這個目錄是yum安裝nginx的預設網頁目錄)
[root@localhost volumes]# docker volume create test-nginx-vol
test-nginx-vol
[root@localhost volumes]# docker run -d -it --name=test-nginx -p 8800:80 -v test-nginx-vol:/usr/share/nginx/html nginx
5478064f3ab2cce8f8f858806d56b47ceeea44de549db9027ac8417c8a49d26f
如果沒有通過-v指定,那麼Docker會預設幫我們建立匿名資料捲進行對映和掛載。建立好容器之後,我們可以進入容器裡面看看:
[root@localhost volumes]# docker exec -it test-nginx bash
root@5478064f3ab2:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@5478064f3ab2:/# cd /usr/share/nginx/html
root@5478064f3ab2:/usr/share/nginx/html# ls
50x.html index.html
進入宿主機建立的資料卷test-nginx-vol中,可以看看:
[root@localhost test-nginx-vol]# cd /var/lib/docker/volumes/test-nginx-vol/_data/
[root@localhost _data]# ls
50x.html index.html
當stop並且remove當前nginx容器,會發現容器卷裡面的檔案還在,由此可見資料卷裡邊的東西是可以持久化的。
[root@localhost _data]# docker stop test-nginx
test-nginx
[root@localhost _data]# docker rm test-nginx
test-nginx
[root@localhost _data]# ls
50x.html index.html
[root@localhost _data]# docker volume rm test-nginx-vol
test-nginx-vol
[root@localhost _data]# ls
[root@localhost _data]#
使用 --mount
或者-v
標記來將 資料卷
掛載到容器裡。
--mount
和-v
的區別:
- -v :如果宿主機上沒有這個檔案,也會自動建立
- --mount時:宿主機中沒有這個檔案會報錯找不到這個檔案,並建立失敗
方式二:Bind Mounts
docker run -d -it --name=test-nginx -v /app/wwwroot:/usr/share/nginx/html nginx
指定了將宿主機上的 /app/wwwroot 目錄(如果沒有會自動建立)掛載到 /usr/share/nginx/html (這個目錄是yum安裝nginx的預設網頁目錄)。
這時我們再次進入容器內部看看:
[root@localhost _data]# docker run -d -it --name=test-nginx -v /app/wwwroot:/usr/share/nginx/html nginx
47a9ec3d0b3d16af216b443af26cde6d2c0e507104840aaf27a0e06545e37219
[root@localhost _data]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47a9ec3d0b3d nginx "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 80/tcp test-nginx
[root@localhost _data]# docker exec -it test-nginx bash
root@47a9ec3d0b3d:/# cd /usr/share/nginx/html
root@47a9ec3d0b3d:/usr/share/nginx/html# ls
root@47a9ec3d0b3d:/usr/share/nginx/html#
可以看到,與volumes不同,bind mounts的方式會隱藏掉被掛載目錄裡面的內容(如果非空的話),這裡是/usr/share/nginx/html 目錄下的內容被隱藏掉了,因此我們看不到。
但是,我們可以將宿主機上的檔案隨時掛載到容器中:
[root@localhost _data]# cd /app/wwwroot
[root@localhost wwwroot]# ls
[root@localhost wwwroot]# touch index.html
[root@localhost wwwroot]# ls
index.html
[root@localhost wwwroot]# docker exec -it test-nginx bash
root@47a9ec3d0b3d:/# cd /usr/share/nginx/html
root@47a9ec3d0b3d:/usr/share/nginx/html# ls
index.html
root@47a9ec3d0b3d:/usr/share/nginx/html#
檢視容器掛載資料卷的具體資訊
docker inspect test-nginx
資料卷
資訊在 "Mounts" Key 下面
"Mounts": [
{
"Type": "volume",
"Name": "test-nginx-vol",
"Source": "/var/lib/docker/volumes/test-nginx-vol/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
刪除資料卷
[root@localhost ~]# docker volume rm test-volume3
test-volume3
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local test-volume1
local test-volume2
資料卷
是被設計用來持久化資料的,它的生命週期獨立於容器,Docker 不會在容器被刪除後自動刪除 資料卷
,並且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的 資料卷
。如果需要在刪除容器的同時移除資料卷。可以在刪除容器的時候使用 docker rm -v
這個命令。
沒有容器掛載的資料卷可能會佔據很多空間,要清理請使用以下命令
[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:
test-volume1
test-volume2
Total reclaimed space: 0B
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME