Docker中的volume
1、关于volume
1.1 UFS(联合文件系统)
当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(译者注:镜像栈顶部)添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。
1.2 volume
2、使用volume
2.1 创建含volume的容器
创建容器volume-container,挂载/data目录:
$ docker run -it --name volume-container -h CONTAINER -v /data ubuntu /bin/bash
root@CONTAINER:/# ls /data
root@CONTAINER:/#
2.2 挂载volume容器的相关说明
inspect该容器:
$ docker inspect -f {{.Volumes}} volume-container
map[/data:/var/lib/docker/volumes/80a9f0bee29d98bf7cf93666703d0e3cfbaa6d6ce00241387892014d48648c6c/_data]
可以看到/data对应的主机目录。
在主机上创建文件在该目录下:
root@python-Lenovo:/var/lib/docker/volumes/80a9f0bee29d98bf7cf93666703d0e3cfbaa6d6ce00241387892014d48648c6c/_data# touch test
在容器中查看:
root@CONTAINER:/data# ll
total 8
drwxr-xr-x 2 root root 4096 Sep 1 07:09 ./
drwxr-xr-x 33 root root 4096 Sep 1 07:03 ../
-rw-r--r-- 1 root root 0 Sep 1 07:09 test
可以看到该目录在容器和主机之间是共享的。
同样可以在dockerfile中挂在/data:
VOLUME /data
但是,-v参数可以指定主机上的目录挂载到容器上,而通过dockerfile则不能实现这个功能:
$ docker run -v /home/python:/data ubuntu ls /data
Desktop
Documents
Downloads
Music
Pictures
Public
PycharmProjects
Templates
Videos
docker
examples.desktop
learn_deploy.tar
learn_deploy_con.tar
temptest
2.3 数据共享
使用-volumes-from参数来执行docker run:
$ docker run -it -name new-container -h CONTAINER --volumes-from volume-container ubuntu ls /data
test
之前,在volume-container中的/data创建过文件test,现在通过共享volume,容器new-container也能看到这个文件。
2.4 数据容器
通常会使用纯数据容器来持久化数据库、配置文件或者数据文件等。
$ docker run --name dbdata postgres
该命令将会创建一个已经包含在Dockerfile里定义过Volume的postgres镜像。
使用数据容器的两个注意点:
不要运行数据容器,这纯粹是在浪费资源。
不要为了数据容器而使用“最小的镜像”,如busybox或scratch,只使用数据库镜像本身就可以了。你已经拥有该镜像,所以并不需要占用额外的空间。
2.5 删除Volumes
使用命令docker rm -v命令才能同时删除volumes,否则会遗留僵尸文件。
注意:docker run -v /host/path:/some/path ...指定本机目录挂载到容器的情况下,不会删除volume。
共享volume的情况下,除非删除所有container,否则不会删除volume。
3、Dockerfile中volume的测试
创建文件Dockerfile,内容如下:
FROM ubuntu
VOLUME /data
RUN touch /data/test
构建镜像:
docker build -t volume_test .
进入容器查看:
root@6402c1a176cd:/data# ll
total 8
drwxr-xr-x 2 root root 4096 Sep 1 08:08 ./
drwxr-xr-x 33 root root 4096 Sep 1 08:08 ../
并没有创建文件test。
因此,在Dockerfile中,不能在VOLUME后面使用RUN命令试图在volume中生成文件。
1、关于volume
1.1 UFS(联合文件系统)
当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(译者注:镜像栈顶部)添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。
1.2 volume
简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。
Volume不是用来实现持久化(镜像和容器本身就是“持久”的),而是用来分离容器与数据。
2、使用volume
2.1 创建含volume的容器
创建容器volume-container,挂载/data目录:
$ docker run -it --name volume-container -h CONTAINER -v /data ubuntu /bin/bash
root@CONTAINER:/# ls /data
root@CONTAINER:/#
2.2 挂载volume容器的相关说明
inspect该容器:
$ docker inspect -f {{.Volumes}} volume-container
map[/data:/var/lib/docker/volumes/80a9f0bee29d98bf7cf93666703d0e3cfbaa6d6ce00241387892014d48648c6c/_data]
可以看到/data对应的主机目录。
在主机上创建文件在该目录下:
root@python-Lenovo:/var/lib/docker/volumes/80a9f0bee29d98bf7cf93666703d0e3cfbaa6d6ce00241387892014d48648c6c/_data# touch test
在容器中查看:
root@CONTAINER:/data# ll
total 8
drwxr-xr-x 2 root root 4096 Sep 1 07:09 ./
drwxr-xr-x 33 root root 4096 Sep 1 07:03 ../
-rw-r--r-- 1 root root 0 Sep 1 07:09 test
可以看到该目录在容器和主机之间是共享的。
同样可以在dockerfile中挂在/data:
VOLUME /data
但是,-v参数可以指定主机上的目录挂载到容器上,而通过dockerfile则不能实现这个功能:
$ docker run -v /home/python:/data ubuntu ls /data
Desktop
Documents
Downloads
Music
Pictures
Public
PycharmProjects
Templates
Videos
docker
examples.desktop
learn_deploy.tar
learn_deploy_con.tar
temptest
2.3 数据共享
使用-volumes-from参数来执行docker run:
$ docker run -it -name new-container -h CONTAINER --volumes-from volume-container ubuntu ls /data
test
之前,在volume-container中的/data创建过文件test,现在通过共享volume,容器new-container也能看到这个文件。
2.4 数据容器
通常会使用纯数据容器来持久化数据库、配置文件或者数据文件等。
$ docker run --name dbdata postgres
该命令将会创建一个已经包含在Dockerfile里定义过Volume的postgres镜像。
使用数据容器的两个注意点:
不要运行数据容器,这纯粹是在浪费资源。
不要为了数据容器而使用“最小的镜像”,如busybox或scratch,只使用数据库镜像本身就可以了。你已经拥有该镜像,所以并不需要占用额外的空间。
2.5 删除Volumes
使用命令docker rm -v命令才能同时删除volumes,否则会遗留僵尸文件。
注意:docker run -v /host/path:/some/path ...指定本机目录挂载到容器的情况下,不会删除volume。
共享volume的情况下,除非删除所有container,否则不会删除volume。
3、Dockerfile中volume的测试
创建文件Dockerfile,内容如下:
FROM ubuntu
VOLUME /data
RUN touch /data/test
构建镜像:
docker build -t volume_test .
进入容器查看:
root@6402c1a176cd:/data# ll
total 8
drwxr-xr-x 2 root root 4096 Sep 1 08:08 ./
drwxr-xr-x 33 root root 4096 Sep 1 08:08 ../
并没有创建文件test。
因此,在Dockerfile中,不能在VOLUME后面使用RUN命令试图在volume中生成文件。