在學習Dockerfile的過程中有個VOLUME命令,很多教程或書中說的是用來定義匿名卷的,其作用如下:
容器運行時應該盡量保持容器存儲層不發生寫操作,對於數據庫類需要保存動態數據的應用,其數據庫文件應該保存於卷(volume)中。為了防止運行時用戶忘記將動態文件所保存目錄掛載為卷,在Dockerfile 中,我們可以事先指定某些目錄掛載為匿名卷,這樣在運行時如果用戶不指定掛載,其應用也可以正常運行,不會向容器存儲層寫入大量數據。
這令我們想起docker的run命令中的 "-v"參數的作用
# docker run --help | grep volume
-v, --volume list Bind mount a volume
--volume-driver string Optional volume driver for the container
--volumes-from list Mount volumes from the specified
那么Dockerfile中的VOLUME指令實際使用中是不是就是跟docker run中的-v參數一樣是將宿主機的一個目錄綁定到容器中的目錄以達到共享目錄的作用呢?
並不然,其實VOLUME指令只是起到了聲明了容器中的目錄作為匿名卷,但是並沒有將匿名卷綁定到宿主機指定目錄的功能。
但是當我們生成鏡像的Dockerfile中以Volume聲明了匿名卷,並且我們以這個鏡像run了一個容器的時候,docker會在安裝目錄下的指定目錄下面生成一個目錄來綁定容器的匿名卷(這個指定目錄不同版本的docker會有所不同)。如我使用的版本如下:
# docker --version
Docker version 18.09.0, build 4d60db4 //docker版本
# pwd
/var/lib/docker/volumes //默認綁定容器的匿名卷的目錄
# ll
total 32
drwxr-xr-x. 3 root root 4096 Nov 25 20:18 593fda6d7b8296bfca22894b326727c734133eebb11c9bc2c25a73b892157a37 //其中一個容器的共享目錄文件夾
drwxr-xr-x. 3 root root 4096 Nov 25 20:14 78d890eeb15ac6295484d5e84e97928e981b01501fa40bac40b965fc9e54899a //其中一個容器的共享目錄文件夾
-rw-------. 1 root root 32768 Nov 25 20:18 metadata.db
就是說當Dockerfile中聲明了匿名卷,但是run的時候沒有使用-v
綁定匿名卷的話,那么docker就會在/var/lib/docker/volumes這個目錄下創建一個目錄來綁定匿名卷。
所以真正使用的時候我們在Dockerfile構建鏡像的時候如:
FROM centos:latest
RUN groupadd -r redis && useradd -r -g redis redis
RUN yum -y update && yum -y install epel-release && yum -y install redis && yum -y install net-tools
RUN mkdir -p /config && chown -R redis:redis /config
VOLUME /share/data #聲明容器中/share/data為匿名卷
EXPOSE 6379
那么使用該Dockerfile構建鏡像的為
# docker build -t image-redis //構建鏡像image-redis
......
#docker run -d -it -name redis1 -v /data:/share/data image-redis //運行一個容器並且將當前機器的/data目錄綁定到容器的匿名卷中
.....
#docker run -d -it -name redis2 image-redis //運行一個容器但是不綁定目錄到容器的匿名卷,這時候再/var/lib/docker/volumes(不同版本目錄不一樣)中就會創建一個目錄綁定匿名卷