Docker笔记(7):Docker 存储

Docker为容器提供了两种存放数据的资源:

(1)由storage driver管理的镜像层和容器层。

(2)Data Volume。

1.storage driver

镜像的分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于Docker storage driver。正是storage driver实现了多层数据的堆叠,并为用户提供一个单一的合并之后的统一视图。Docker支持多种storage driver,有AUFS、Device Mapper、Btfs、OverlayS、VFs和ZFS。它们都能实现分层的架构,同时又有各自的特性。需要根据应用的实际场景,选择合适的storage driver。Ubuntu默认使用AUFS,底层文件系统是etfs,各层数据存放在/var/lib/docker/aufs。

对于无状态的应用容器,直接将数据放在由storage driver维护的层中是很好的选择,无状态意味着容器没有需要持久化的数据,随时可以从镜像直接创建。

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

2.Data Volume

Data Volume本质上是宿主机文件系统中的目录或文件,能够直接被mount到容器的文件系统中。容器中的进程向这个目录中写数据时,绕过容器的文件系统,直接写在宿主机的目录上的,使得可以在宿主机和容器内共享数据库内容,Data Volume有以下特点:

  • Data volume是目录或文件,而非没有格式化的磁盘(块设备);
  • 容器可以读写volume中的数据,便于共享;
  • volume数据可以被永久地保存,即使使用它的容器已经销毁。

因为volume实际上是宿主机文件系统的一部分,所以volume的容量取决于文件系统当前未使用的空间,目前还没有方法设置volume的容量。docker提供了两种类型的 volume,每种类型都在容器中存在一个挂载点,但其在宿主机上位置有所不同。

Bind mount volume(绑定挂载卷): 需要在宿主机和容器内各指定一个特定的路径作为挂载点,两个挂载点建立关联关系;

Docker-managed volume(docker管理卷): 只需要在容器内指定容器的挂载点,宿主机上的挂载点固定在/var/lib/docker/volumes目录下,这种方式极大解脱用户在使用卷时的耦合关系。

(1)Bind mount volume

bind mount volume是将宿主机上已存在的目录或文件mount到容器指定的目录。bind mount volume可以让宿主机与容器共享数据,即使容器没有了,bind mount volume也还在。bind mount volume是宿主机文件系统中的数据,只是借给容器用用,docker不会销毁bind mount volume数据,删除数据的工作只能由host负责。

bind mount时还可以指定数据的读写权限,默认是可读可写,可设置为只读,在容器中无法对 bind mount volume数据进行修改,只有宿主机有权修改数据,提高了安全性。

docker run -d -v /aa/bb:/usr/local/bb:ro ubuntu

bind mount volume的使用直观高效,但不足在于bind mount需要指定host文件系统的特定路径,这就限制了容器的可移植性,当需要将容器迁移到其他host,而该host没有要mount的数据或者数据不在相同的路径时,操作会失败,移植性更好的方式是docker managed volume。

(2)Docker-managed volume

docker managed volume与bind mount volume在使用上的最大区别是不需要指定mount源(宿主机中的挂载点),指明容器中的挂载点就行了。

docker run -d -v /aa/bb ubuntu

-v告诉docker需要一个data volume,并将其挂载到容器的/aa/bb,那么这个data volume具体在哪儿呢?通过docker inspect进行查看,如下。Source就是该volume在host上的目录,每当容器申请Docker-manged volume时,docker都会/var/lib/docker/volumes下生成一个目录,这个目录就是 mount源。

img

docker managed volume的创建过程:

  1. 容器启动时,通过命令告诉docke“r需要一个volume存放数据,并挂载到容器目录/aa/bb”;
  2. docker在宿主机/var/lib/docker/volumes中生成一个随机目录作为 mount源;
  3. 如果容器中/aa/bb已经存在,则将数据复制到mount源;
  4. 将volume mount到/aa/bb。

docker managed volume的删除:

在执行docker rm删除容器时可以带上-v参数,docker会将该容器使用到的volume一并删除,但前提是没有其他容器挂载到该volume。

(3)使用存储卷的优点

使用联合文件系统存在的问题:

  • 对于修改删除这类的操作,IO效率非常低;
  • 存储于联合文件系统中,不易于宿主机访问;
  • 容器间数据共享不便;
  • 删除容器其数据会丢失;

如运行一个对于IO的要求比较高的mysql容器,如果是运行在容器中自己的文件系统之上,数据存取时效率比较低,当容器在停止时,数据也会被删除,其实现数据存取时效率比较低,要避免这个限制要使用存储卷来实现。

3.Volume Container

(1)容器与宿主机共享数据

  • Bind mount volume、Docker-managed volume均可实现在容器与宿主机之间共享数据。
  • docker cp可以在容器和宿主机之间复制数据。
  • 也直接通过Linux的cp命令,将宿主机的文件复制到volume,如/var/lib/docker/volumes/xxx与mount数据源。

(2)容器之间共享数据

  • 多个容器mount到宿主机的同一个目录,共享mount数据源。
  • 使用volume container。

(3)volume container

volume container是专门为其他容器提供volume的容器,它提供的卷可以是bind mount volume、docker-managed volume。与存储卷volume相比,不必为每一个容器指定host path,所有path都在 volume container中统一设置,容器只需与volume container关联,实现了容器与宿主机的解耦。

创建一个 volume container,命令如下:

docker create --name vc_ubuntu -v /aa/bb:/aa/bb -v /aa/cc ubuntu

这里执行的是 docker create命令,这是因为 volume container的作用只是提供数据,它本身不需要处于运行状态。该命令挂载了bind mount、docker managed volume两个volume,通过docker inspect 查看信息如下:

img

其他多个容器可以通过volumes-from使用vc_ubuntu这个volume container,然后多个容器可以共享vc_ubuntu的数据。

docker run --name web1 -d --volumes-from vc_ubuntu ubuntu

(4)data-packed volume container

volume container的数据存储在宿主机里,data-packed volume container可以将数据完全放在volume container内部,其原理是将数据打包到镜像中,然后通过docker managed volume共享,步骤如下:

首先,创建Dockerfile,将host的/aa目录添加到容器的/aa/bb,使用VOLUME命令来创建docker managed volume,mount point为/aa/bb,会将/aa/bb中已有数据复制到volume中。

FROM ubuntu:latest
ADD /aa  /aa/bb
VOLUME /aa/bb

然后,使用build命令构建镜像data_packed_vc,并用新镜像创建data-packed volume container。

docker create --name dp_vc data_packed_vc

最后,在创建其他容器是,通过–volumes-from即可访问到数据。

data-packed volume container的数据包含在镜像中,不依赖宿主机提供数据,具有很强的移植性,非常适合只使用静态数据的场景,比如应用的配置信息Web server的静态文件等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值