Docker 存储卷

为何需要存储卷

Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层。
如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,这个就是写时复制(COW)机制。

数据存储的问题

Docker 容器数据的存储,存在以下问题:

  • 存储于联合文件系统中,不易于宿主机访问
  • 容器间数据共享不便
  • 删除容器其数据会丢失

关闭并重启容器,容器的数据不受影响。但删除容器会是之前的更改全部丢失。

解决方案:卷(volume),或者便于区分叫做存储卷。
卷是容器上的一个或多个目录,此类目录可绕过联合文件系统,与宿主机上的某个目录绑定(关联)。

Data volumes

Volume在容器初始化之时就会创建,由base image提供的卷中的数据会于此期间完成复制。

Volumn的初衷就是独立于容器的生命周期实现数据持久化,因此删除容器之时既不会删除卷,也不会对哪怕未被引用的卷做垃圾回收操作。

卷为docker提供了独立于容器的数据管理机制:

  • 可以把镜像想象成静态文件,例如程序。把卷类比为动态内容,例如数据。于是,镜像可以重用,而卷可以共享
  • 卷实现了程序(镜像)和数据(卷)的分离,以及程序(镜像)和制作镜像的主机的分离。用户制作镜像时无须再考虑镜像运行的容器所在主机的环境。

在容器中使用volumes

现在,在创建容器时,加上volumes的相关选项。

Volumes types

Docker有两种类型的卷,每种类型都在容器中存在一个挂载点,但是在宿主机上的位置有所不同:

  • Bind-mount volume: 容器内的目录和宿主机上的目录都需要指定
  • Docker-managed volume: 容器内的目录需要指定,宿主机上目录由docker维护

为docker run命令使用-v选项,即可使用Volume。

Docker-managed volume

开一个会话创建容器并绑定volume:

$ docker run --name v1 --rm -it -v /data busybox

在宿主机上操作目录
在另一个会话中查询这个容器的inspect,不过内容比较多。在Volumes里能看到卷的信息:

            "Volumes": {
                "/data": {}
            },

还有挂载点的信息,这里使用-f参数只看Mounts的内容:

$ docker inspect -f ‘{{json .Mounts}}‘ v1
[{"Type":"volume","Name":"bdd48fb729e802b7d3a067da74b748037e83ff770a84f7215c657f6cc2af2c9d","Source":"/var/lib/docker/volumes/bdd48fb729e802b7d3a067da74b748037e83ff770a84f7215c657f6cc2af2c9d/_data","Destination":"/data","Driver":"local","Mode":"","RW":true,"Propagation":""}]
$ 

宿主机自动分配的卷的路径在Source字段中,下面的方法直接获取路径并调用ls命令:

$ docker inspect -f ‘{{range .Mounts}}{{.Source}} {{end}}‘ v1 | xargs ls
$ docker inspect -f ‘{{with index .Mounts 0}}{{.Source}}{{end}}‘ v1 | xargs ls

Mounts里是一个数组,可能有多个挂载点。第一行的命令是遍历所有的目录,第二行的命令是只输出第一个目录。
在挂载点的目录中,容器和宿主机可以共享数据。容器中对目录的修改,在宿主机中可以查看到。反之,在宿主机中对这个目录的修改,容器也能够查看到。

删除镜像
上面创建容器的命令使用了--rm参数,这样一旦容器停止,该容器也就会自动被删除。容器删除后,Docker-managed volume也会一并被删除。
所以这是一个临时的卷,卷内存储的数据依然会随着容器的删除而丢失。没有解决容器内数据持久保存的目的,但是现在容器的数据可以和宿主机共享,并且数据存储的I/O也直接是由宿主机的文件系统决定。好处是用户不用额外来管理这个卷,卷内存放的临时数据会随着容器的删除而删除。适合用于存放临时性的但是需要在容器外的共享的数据。

Bind-mount Volme

使用的参数还是和之前一样,但是-v参数的内容提供两部分,宿主机的目录和卷的目录,中间用冒号分隔:-v HOSTDIR:VOLUMEDIR

绑定 Bind-mount Volme
开一个会话创建容器并绑定Bind-mount Volme:

$ docker run --name v2 --rm -it -v ~/data/volumes/v2:/data busybox

仍然可以使用docker inspect命令来查看详细信息,这里就不演示了。
这里指定的宿主机的路径如果不存在,docker会自动创建。

删除容器
容器删除后,宿主机上的文件会依然存在。这样就实现了数据在容器删除后依然可以使用。

共享卷

前面说了,docker有两种类型的卷,两种都已经说了。这里的共享卷本质上还是上面两种类型中的某一种,只是是实现了容器间共享同一个卷的两种方法。

多个容器卷使用同一个主机目录
这个没什么问题,主机上同一个目录是允许被多个容器同时使用的。

复制使用其他容器的卷
使用--volumes-from选项:

$ docker run --name v3.0 --rm -itd -v /data busybox
e24397fffb44717a7f140010c829ec88f540ed7d95f7c8fb328a35a819becfb0
$ docker run --name v3.1 --rm -itd --volumes-from v3.0 busybox
28543eb6fc13e972a000ab955b9623630ebb9d90c8d3dc37a8b7608f24188926
$ docker container attach v3.0
/ # touch /data/test_v3_0
/ # exit
$ docker container attach v3.1
/ # ls /data
test_v3_0
/ # exit
$ 

这里的示例复制的是Docker-managed volume,对于Bind-mount Volme也是一样的。

共享网络
网络也可以共享,即联盟式网络。这里,卷也可以共享。在有些场景下,两个或几个容器有可能需要共享同一个网络并且共享同一个卷。

原文地址:https://blog.51cto.com/steed/2422611

时间: 2024-10-04 13:37:37

Docker 存储卷的相关文章

Docker存储卷

docker存储卷: docker容器卷的使用方式: 1 Docker 管理卷: docker run -it --name [名称] -v [docker内部的卷] [镜像名称] 具体使用: docker run -it --name testvolume -d -v /data/mydata 75835a67d134 查看存储卷映射的目录: 命令:docker inspect f878a628f152 "Mounts": [ { "Type": "vo

Docker之七---Docker存储卷与容器卷详解

1.存储卷介绍 1.1 背景 (1)docker 的 AFUS 分层文件系统 docker镜像由多个只读层叠加而成,启动容器时,docker会加载只读镜像层并在镜像栈顶部加一个读写层: 如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写时复制(COW)”机制. 描述:如果一个文件在最底层是可见的,如果在layer1上标记为删除,最高的层是用户看到的Layer2的层,在layer0上的文件

docker存储卷篇

在之前的文章中,我们说过,容器的服务如果需要提供给外部访问,需要把端口映射出来.docker的数据存储卷也是一样的道理,我们在使用docker的时候,有些应用是需要保存数据的,这些需要保存数据的应用就可以把docker容器内的数据目录映射到宿主机上,如果没有指定,写入的数据会存储在docker的联合挂在存储系统上(性能低下),如果指定了挂载的目录(这里是/data),则可以绕过docker的文件系统,直接写在宿主机(或其他文件系统,如:nfs)上,如下图:上面的/data目录也又两种形式,一种是

Docker第五回(Docker存储卷)

一.Docker底层存储机制介绍 对于Docker来讲,它作为容器运行的底层引擎,在组织和运行其容器时,每个容器内运行一个程序及子程序,容器启动时依赖于底层可能不止一层的只读镜像联合挂载启动而成.它底层能够存储此类分层构建并联合挂载镜像的文件系统包含AUFS.Overlayfs2.devmapper文件系统.最后一定要在最上层构建一个可写层.对于此可写层来说,所有在容器中所执行的写操作(对数据的修改.对内容的修改),都是保存在最上层的可写层.对下层内容的增删改操作我们需要使用“写时复制”(COW

基于Gluster分布式实现docker存储卷

1.安装配置glusterfs基础配置:centos7 关闭firewalld/selinux配置/etc/hosts和hostname 1 [[email protected] ~]# cat /etc/hosts 2 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 3 ::1 localhost localhost.localdomain localhost6 localhost6.lo

你必须知道的Docker数据卷(Volume)

本篇已加入<.NET Core on K8S学习实践系列文章索引>,可以点击查看更多容器化技术相关系列文章. 一.将Docker数据挂载到容器 在Docker中,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中.目前Docker提供了三种不同的方式将数据从宿主机挂载到容器中: (1)volumes:Docker管理宿主机文件系统的一部分,默认位于 /var/lib/docker/volumes 目录中:(最常用的方式

理解Docker(8):Docker 存储之卷(Volume)

(1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 (4)Docker 容器的隔离性 - 使用 cgroups 限制容器使用的资源 (5)Docker 网络 (6)若干企业生产环境中的容器网络方案 (7)Docker 存储 - AUFS (8)Docker 存储 - Volume 1. Docker volume 的几种形态 有状态容器都有数据持久化需求.前一篇文章中提到过,Docker 采

Docker存储驱动之Device Mapper简介

Device Mapper是一个基于kernel的框架,它增强了很多Linux上的高级卷管理技术.Docker的devicemapper驱动在镜像和容器管理上,利用了该框架的超配和快照功能.为了区别,本文使用Device Mapper指驱动中的框架,而devicemapper指Docker的存储驱动. 注意:商业支持的Docker Engine(CS-Engine)建议在RHEL和CentOS上使用devicemapper存储驱动. AUFS之外的另一种选择 Docker最初运行在Ubuntu和

理解Docker(7):Docker 存储 - AUFS

(1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 Linux namespace 隔离容器的运行环境 (4)Docker 容器的隔离性 - 使用 cgroups 限制容器使用的资源 (5)Docker 网络 (6)若干企业生产环境中的容器网络方案 (7)Docker 存储 - AUFS Docker 存储可以分为分层文件系统和卷,本文将介绍 AUFS 分层文件系统. 1. 基础知识 1.1 Linux 的 rootfs 和 bootfs 一