欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Docker卷(volume)的使用,挂载宿主机目录到容器目录,实现docker数据存储分离

程序员文章站 2022-06-16 22:52:56
...

卷的使用

创建volume:docker volume create vol_name
查看volume:docker volume ls 可以看到当前存在的所有的 volume。
删除volume:docker volume rm 删除指定的 volume。
查看volume详情:docker volume inspect vol_name可以看到它的详情,包括创建时间和宿主机上的真正挂载位置等。

可以看到这个新建的 vol_name保存在 /var/lib/docker/volumes/vol/_data 下,其中 /var/lib/docker/volumes 目录保存了所有的 Docker volume,挂载之后及时容器删除,宿主机的目录不变,除非手动删除卷数据。

运行时挂载

使用命名卷

有了 volume 之后,我们便可以使用刚才创建的 vol 来挂载容器中的某个目录:

docker run -d -v vol:/data --name temp-redis redis

如此一来,在 temp-redis 容器中 /data 下的改动,都会同步反映在宿主机的 /var/lib/docker/volumes/vol/_data 下;而宿主机的改动亦然。

使用绝对路径

使用命名的 volume 通常是为了数据共享,很多时候我们只是想指定一个挂载的目录便于记忆和管理,这个时候可以使用绝对路径,如:

docker run -d -v /data/docker_volume/temp_redis/data:/data --name temp-redis redis


自动挂载

有时候你甚至不想关心任何 volume 的形式,你只是想把某个目录持久化而已,可以这么做:

docker run -d -v /data --name temp-redis redis

Docker 会自动生成一个匿名的 volume。想要知道具体的宿主机目录可以使用:docker inspect 来查看。这种情况通常在构建纯数据容器时使用。

注意点

在 volume 创建时和创建之后仍然需要关注他们,下面是一些典型的问题。

volume 自动创建

事实上在 -v vol:/data 时候,vol volume 甚至不需要提前使用 docker volume create vol 创建,使用 docker run -v vol:/data 命令时便会自动创建。
同时地,也意味着 -v 选项不支持相对路径的使用

volume 的删除

在一个 volume 被创建之后,想删除可没那么容易,即使使用了 docker rm CONTAINER 删除了容器,volume 依然保留着。除非:

  • 使用 docker run --rm 启动的容器停止时。它除了会删除容器本身还会删除挂载的匿名 volume。
  • 使用 docker rm -v v 参数可以删除容器和创建容器时关联的匿名 volume。

那么我们在使用了 named volume 或者删除容器时忘记了 -v,那么那些在 /var/lib/docker/volumes 下的一些文件就成了僵尸文件。怎么删除呢?

  • 使用 docker volume rm VOLUME 来删除。
  • 使用 docker volume prune 删除所有不再被使用的 volume。

volume 的只读控制

一些场合下,我们提供只是需要容器内的程序去读取一些内容而非修改。我们可以严格的控制 volume,增加只读选项 ro

docker run -d \
  --name=nginxtest \
  -v nginx-vol:/usr/share/nginx/html:ro \
  nginx:latest

通过 Dockerfile 挂载

可以通过 Dockerfile 在构建镜像的时候便指定需要的 volume,这对于很多应用都是必要的,尤其是一些数据类应用。
Dockerfile 中使用 VOLUME 表明挂载目录,如:

VOLUME ["/data1", "/data2"]

任何通过该镜像构建的容器都会将 /data1/data2 两个目录进行挂载。但是 Dockerfile 形式的弱势是无法进行 named volume 或者绝对路径的挂载

数据共享与存储

共享 volume

既然数据可以在宿主机和容器间同步,那么可以使多个容器间同步吗?当然可以!

1、–volumes-from

# 首先创建一个容器,并挂载 /data
docker run -d -v /data --name ng1 nginx
# 创建第二个容器,共享前者的 volume
docker run -d --volumes-from ng1 --name gn2 nginx

2、named volume

# 首先创建一个容器,并创建命名卷 share 来挂载 /data
docker run -d -v share:/data --name ng1 nginx
# 创建第二个容器,使用同样的 /data
docker run -d -v share:/data --name ng2 nginx

 

两种方式都能达到数据共享的目的,但是由于通过命名卷的方式对多个容器的依赖进行了解耦,所以推荐第二种。

数据容器

这个话题事实上和数据共享紧密相关,由于在 Docker1.9 之前,大家广泛使用使用 --volumes-from 的形式来共享卷,导致必须要一个底层的没有依赖的容器来保存数据。

  • 通常使用和应用容器一样的镜像来构建数据容器
  • 数据容器不需要也不应该启动,仅仅是利用 volume 机制来保持数据而已

然而现在有了命名卷,完全不需要数据容器的存在了,使用 named volume 可以更直接更方便的管理共享数据。

 

 

附带:

语法:
docker run -it -v HOSTDIR:VOLUMEDIR images

我自己项目使用的命令,创建容器时挂载共享目录,宿主机作为docker的数据盘,多个-v 可以共享多个目录,我还将数据库的数据保存到宿主机。

//自定义存储目录
docker run -p 80:80 -p 88:88 -i -t -d  -v /data/jsontest/upload:/var/www/html/jsontest/upload -v /data/mysql:/var/lib/mysql  --restart=always computercenter:v5.3.0   /bin/bash -c "/etc/rc.local; /bin/bash"

//使用docker卷自动维护的方式
docker run -p 80:80 -p 88:88 -i -t -d  -v /var/www/html/jsontest/upload -v /var/lib/mysql  --restart=always computercenter:v5.3.0   /bin/bash -c "/etc/rc.local; /bin/bash"

卷的使用

参考1:Link

参考2:Link

Docker 空间使用分析与清理

参考:Link

Docker 的内置 CLI 指令 docker system df 【-v】,可用于查询镜像(Images)、容器(Containers)和本地卷(Local Volumes)等空间使用大户的空间占用情况。

Docker 实践简明指南

参考:Link

docker之如何挂载一个容器已经存在(有文件)的目录

参考:Link

原来不加-it就可以建完容器再挂载。

先正常启动 docker ruql -it -p 80:80 hofmann/zentao
把mysql数据库文件拷贝出来/tmp/zen$ sudo docker cp c3f2:/opt/zbox/data/mysql .
再通过挂载的方式启动就可以了/Desktop$ docker run -v /tmp/zen/mysql:/opt/zbox/data/mysql -it -p 80:80 hofmann/zentao