四种方式区别
- docker四种方式:默认、volumes数据卷、bind mounts挂载、tmpfs mount(仅在linux环境中提供),其中volumes、bind mounts两种实现持久化容器数据;
- 默认:数据保存在运行的容器中,容器删除后,数据也随之删除;
- volumes:数据卷,数据存放在主机文件系统/var/lib/docker/volumes/目录下,该目录由docker管理,其它进程不允许修改,推荐该种方式持久化数据;
- Bind mounts:直接挂载主机文件系统的任何目录或文件,类似主机和容器的共享目录,主机上任何进程都可以访问修改,容器中也可以看到修改,这种方式最简单。
- tmpfs:数据暂存在主机内存中,不会写入文件系统,重启后,数据删除。
默认方式
默认方式,容器本身管理自己的数据,容器文件系统实际是一系列只读的文件层和最上层的容器可写文件层组成,最上层的容器可写文件层保留容器运行过程中产生的所有数据修改,这些层的管理是利用容器的Storage drivers实现(默认是Overlay2,可以通过docker的dameon.json配置文件修改),对容器内部文件系统是透明的。
由于容器在文件系统之上又封装了一层storage drivers,性能比不上bind或volumes,不建议生产环境使用。
volumes
简单理解,volumes是由docker创建和管理,存放在主机文件系统的某个目录,linux下面就在/var/lib/docker/volumes/.
要点:
- 适用于多个容器之间共享数据,特别是Bind mounts无法使用时;
- docker volume create命令创建或者docker run启动容器时选项 --volume 或者–mount 时创建;
- 同一个volume可以同时被多个容器挂载,当没有容器使用该volume,也不会自动删除;
- 空volume挂载到容器已有文件的目录,容器目录的文件则会被拷贝到该volume;
- bind mount或者非空volume被挂载到容器已有文件的目录,则容器已有的文件被隐藏,无法访问,直到unmount;
- 支持volume drivers选项,可以存储数据在本机、远程主机、或云平台;
- 方便备份:/var/lib/docker/volumes/ 备份即可
Bind mounts
直接将主机的目录挂载到容器内部,容器内部的操作会影响宿主机的文件,docker无法管理,依赖主机文件系统管理。
要点:
- 适合主机和容器间共享配置文件,例如docker默认将主机的/etc/resolv.conf共享给每个容器,提供dns服务;
- 主机开发环境和容器共享源代码或构件组件,例如将本机的Maven 的target/目录挂载进入容器,每次本机构建完毕,容器即可看到最新的版本;
- 挂载的目录必须在主机上存在,容器中则会根据需要创建;
tmpfs mounts
直接将数据临时存放在主机内存中,在容器运行期间有效,容器停止运行或删除,数据丢失,适用于存放非持久化的状态或者敏感信息,因数据安全考虑或者提供更高的性能使用。tmpfs数据不支持在多个容器间共享。
常用命令一览表(备查)
volumes管理命令
docker volume create // 手工创建volume
docker volume inspect // 查看已创建volume详细信息
docker volume ls // 查看docker中已创建的volumes列表
docker volume prune // 删除所有未使用的本地volumes,远程的无法删除
docker volume rm // 删除指定的volume
# docker volume create my-vol // 创建my-vol
# docker volume ls | grep my-vol // 查看是否创建成功
# docker inspect my-vol // 查看my-vol元数据信息,可以看到Mountpoint指出在本机的文件目录
# cd /var/lib/docker/volumes/ // docker管理的volumes本机目录
# ls | grep my-vol // docker在本机创建my-vol目录和_data子目录
# docker volume rm my-vol //删除
挂载选项-v,–volume,–mount区别
- docker 17.06版本之前,-v等同于–volume:被用于单个容器,–mount用于docker swarm services;
- 新版本之后,–mount可以用于单个容器,–mount语法更加明确易读;
- 在service中使用volumes,只有–mount语法支持;
- 推荐使用–mount选项
-v <vol_name>:<container_path>:<options> // 其中options是选项,只读ro
--mount 'type=volume|bind|tmpfs,src=<vol_name>,dst=<container_path>' // src或source,dst或target或destination
// docker service 不支持-v或--volume语法
// 使用volume启动一个服务
# docker service create \
--mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume -opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"'
--name myservice \
<IMAGE>
// docker run支持-v或--mount
// 使用volume启动一个容器
# docker run -d --name devtest --mount source=myvol2,target=/app nginx:latest
# docker run -d --name devtest -v myvol2:/app nginx:latest
// 使用容器的目录内容自动填充空volume
# docker run -d --name=nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html nginx:latest
# docker run -d --name=nginxtest -v nginx-vol:/usr/share/nginx/html nginx:latest
// 只读方式挂载
# docker run -d --name=nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly nginx:latest
# docker run -d --name=nginxtest -v nginx-vol:/usr/share/nginx/html:ro nginx:latest
共享存储volume drivers
// 共享存储,以上都是挂载本机的卷
// 使用不同的volume driver提供共享存储,例如nfs,s3
// 安装sshfs volume driver
# docker plugin install --grant-all-permissions vieux/sshfs
// 创建sshfs volume,提供ssh密码
# docker volume create --driver vieux/sshfs -o sshcmd=test@node2:/home/test -o password=testpassword sshvolume
// 创建服务使用NFS volume
// NFSV3
# docker service create -d --name nfs-service \
--mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,volume-opt=o=addr=10.0.0.10' \
nginx:latest
// NFSV4
# docker service create -d \
--name nfs-service \
--mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/,"volume-opt=o=10.0.0.10,rw,nfsvers=4,async"' \
nginx:latest
备份、恢复、删除容器数据
// 备份一个容器的数据
// 启动新容器,备份其它容器的数据目录/dbdata
# docker run --rm --volumes-from dbstore_container -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
// 恢复数据
# docker run -v /dbdata --name dbstore2 ubuntu /bin/bash
# docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"
// 匿名volume删除,--rm会在容器删除时,自动删除匿名volume /foo
# docker run --rm -v /foo -v awesome:/bar busybox top
# docker volume prune // 删除未使用的所有volume
Bind Mount
同样支持-v和–mount两种方式。
// 启动容器,挂载本机目录$(pwd)/target
// --mount方式
# docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app \
nginx:latest
// -v方式挂载
# docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app \
nginx:latest
// 只读选项
# docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app,readonly \
nginx:latest
# docker run -d \
-it \
--name devtest \
-v "$(pwd)"/target:/app:ro \
nginx:latest
–tmpfs,–mount区别
–tmpfs不支持任何配置选项,不支持docker swarm services, --mount支持所有;
// 以下两条命令等价
# docker run -d \
-it \
--name tmptest \
--mount type=tmpfs,destination=/app \
nginx:latest
# docker run -d \
-it \
--name tmptest \
--tmpfs /app \
nginx:latest
// --mount支持选项
// tmpfs-size:大小,默认无限
// tmpfs-mode:文件权限模式,默认是1777
# docker run -d \
-it \
--name tmptest \
--mount type=tmpfs,destination=/app,tmpfs-mode=1770 \
nginx:latest