Docker入门之-存储(一):两类存储资源

本文深入探讨Docker的两种数据存储资源:由storagedriver管理的镜像层和容器层,以及DataVolume。详解StorageDriver的工作原理,包括Copy-on-Write机制,以及不同storagedriver的特性。此外,介绍了DataVolume的两种类型:bindmount和dockermanagedvolume,展示了如何在容器和宿主机之间共享数据,以及如何管理持久化数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Docker 为容器提供了两种存放数据的资源,一种是由 storage driver 管理的镜像层和容器层,另一种是Data Volume;

一、Storage Driver

在学习镜像的时候我们知道Docker 镜像的分层结构:容器由最上面一个可写的容器层,以及若干只读的镜像层组成,容器的数据就存放在这些层中。这样的分层结构最大的特性是 Copy-on-Write:

  • 新数据会直接存放在最上面的容器层;
  • 修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变;
  • 如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件

分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于 Docker storage driver;

Docker 支持多种 storage driver,它们都能实现分层的架构,同时又有各自的特性。

不过 Docker 官方给出了一个简单的答案:优先使用 Linux 发行版默认的 storage driver;

Docker 安装时会根据当前系统的配置选择默认的 driver。默认 driver 具有最好的稳定性,因为默认 driver 在发行版上经过了严格的测试,运行docker info查看 Ubuntu 的默认 driver:

 对于某些容器,直接将数据放在由 storage driver 维护的层中是很好的选择,比如那些无状态的应用。无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建,比如 busybox,它是一个工具箱,我们启动 busybox 是为了执行诸如 wget,ping 之类的命令,不需要保存数据供以后使用,使用完直接退出,容器删除时存放在容器层中的工作数据也一起被删除,这没问题,下次再启动新容器即可;

但对于另一类应用这种方式就不合适了,它们有持久化数据的需求,容器启动时需要加载已有的数据,容器销毁时希望保留产生的新数据,也就是说,这类容器是有状态的。这就要用到 Docker 的另一种存储机制:Data Volume

二、Data Volume

Data Volume 本质上是 Docker Host 文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中。

在具体的使用上,docker 提供了两种类型的 volume:bind mount 和 docker managed volume;

2.1  bind mount方式

即将 host 上已存在的目录或文件 mount 到容器

目录挂载:

需要注意的是:/usr/local/apache2/htdocs 就是 apache server 存放静态文件的地方;

命令格式:

#通过 -v 将其 mount 到 httpd 容器:-v 的格式为 <host path>:<container path>:
docker run -d -p 80:80 -v ~/htdocs:/usr/local/apache2/htdocs httpd

更新一下,看是否能生效:

host 中的修改确实生效了,bind mount 可以让 host 与容器共享数据。这在管理上是非常方便的;

下面我们将容器销毁,看看对 bind mount 有什么影响:

可见,即使容器没有了,bind mount 也还在;

另外,bind mount 时还可以指定数据的读写权限,默认是可读可写,可指定为只读:

docker run -d -p 80:80 --name read-only-httpd -v ~/htdocs:/usr/local/apache2/htdocs:ro httpd

结论:

ro 设置了只读权限,在容器中是无法对 bind mount 数据进行修改的。只有 host 有权修改数据,提高了安全性;

单个文件的挂载:

bind mount 单个文件的场景是:只需要向容器添加文件,不希望覆盖整个目录;

docker run -d -p 81:80 --name single-file-httpd -v ~/htdocs/index.html:/usr/local/apache2/htdocs/new_index.html httpd

2.2 docker managed volume方式

docker managed volume 与 bind mount 在使用上的最大区别是不需要指定 mount 源,指明 mount point 就行了。

还是以 httpd 容器为例:

 -v 告诉 docker 需要一个 data volume,并将其 mount 到 /usr/local/apache2/htdocs;

终端执行命令:

docker run -d -p 82:80 --name managed-volume-httpd -v /usr/local/apache2/htdocs httpd

具体结果如下所示:

 

那么这个 data volume 具体在哪儿呢?可以在容器的配置信息中找到,

docker inspect 7c201bb95b63

注意,docker inspect 的输出很多,我们感兴趣的是 Mounts 这部分,这里会显示容器当前使用的所有 data volume,包括 bind mount 和 docker managed volume,Source 就是该 volume 在 host 上的目录

即每当容器申请 mount docker manged volume 时,docker 都会在/var/lib/docker/volumes 下生成一个目录,这个目录就是 mount 源;

下面继续研究这个 volume,看看里面有些什么东西:

执行命令如下所示:

ls -l  /var/lib/docker/volumes/29032d6997df522d02bcfa46b1dea8d5cfa0cd964d53baffd35a89c9c56ff761/_data

具体结果如下:

也可以如下关键字搜索:

 volume 的内容跟容器原有 /usr/local/apache2/htdocs 完全一样,

这是因为:如果 mount point 指向的是已有目录,原有数据会被复制到 volume 中,

但要明确一点:此时的 /usr/local/apache2/htdocs 已经不再是由 storage driver 管理的层数据了,它已经是一个 data volume,我们可以像 bind mount 一样对数据进行操作,例如更新数据;

具体结果如下:

 

现在,简单回顾一下 docker managed volume 的创建过程:
  • 容器启动时,简单的告诉 docker "我需要一个 volume 存放数据,帮我 mount 到目录 /abc" "
  • docker 在 /var/lib/docker/volumes 中生成一个随机目录作为 mount 源
  • 如果 /abc 已经存在,则将数据复制到 mount 源
  • 将 volume mount 到 /abc

除了通过 docker inspect 查看 volume,我们也可以用 docker volume 命令:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值