Docker的数据管理(volume/bind mount/tmpfs)

Docker提供了三种不同的方式用于将宿主的数据挂载到容器中:volumes,bind mounts,tmpfs volumes。当你不知道该选择哪种方式时,记住,volumes总是正确的选择。

volumes是Docker数据持久化机制。bind mounts依赖主机目录结构,volumes完全由Docker管理。Volumes有以下优点:

  • Volumes更容易备份和移植。
  • 可以通过Docker CLI或API进行管理
  • Volumes可以无区别的工作中Windows和Linux下。
  • 多个容器共享Volumes更安全。
  • Volume驱动可以允许你把数据存储到远程主机或者云端,并且加密数据内容,以及添加额外功能。
  • 一个新的数据内容可以由容器预填充。

而且,volumes不会增加容器的大小,生命周期独立与容器。

如果你的容器产生不需要持久化数据,请使用tmpfs mount方式,可以避免容器的写入层数据写入。

虽然我们可以在docker容器中保存写入的数据,但还是有这样几个不足:

  1. 容器中的数据会随着容器的停止运行而消失, 而且当其他的进程需要这些数据时,很难将这些数据从容器中提取出来;
  2. 容器的数据写入层是紧密地对应着他的宿主操作系统的,数据不能容易的被迁移到其他地方;
  3. 要将数据写入到容器的数据写入层,需要一个特定的存储驱动,利用linux内核构建一个统一的文件系统,来管理宿主和容器的文件系统。这层额外的虚拟化显然会降低性能。为了避免性能下降,docker使用data volumes的方式,直接对宿主文件系统进行写操作。

选择正确的挂载类型

无论选择哪种挂载方式,在容器内部看来,数据就是数据,并没有什么不同。主机的数据在容器的文件系统中总被显示为目录或文件。如何简单的理解这三种挂载方式的不同之处呢,我们可以理解为在这三种方式下,容器内的数据在宿主机中存放的位置不同,见下图:

  1. Volumes方式下:容器内的数据被存放到宿主机(linux)一个特定的目录下(/var/lib/docker/volumes/)。这个目录只有Docker可以管理,其他进程不能修改。如果想持久保存容器的应用数据,Volumes是Docker推荐的挂载方式。
  2. Bind mounts方式下:容器内的数据被存放到宿主机文件系统的任意位置,甚至存放到一些重要的系统目录或文件中。除了Docker之外的进程也可以任意对他们进行修改;
  3. tmpfs方式下:容器的数据只会存放到宿主机的内存中,不会被写到宿主机的文件系统中,因此不能持久保存容器的应用数据。

详细介绍三种挂载方式

Volumes:

  • 由Docker进程创建和管理。可以通过命令docker volume create来创建一个指定的卷,也可以由Docker进程在创建容器或服务的过程中来创建;
  • 当你为一个容器创建一个volume时,这个volume将会被存储到宿主机的一个目录下。当你挂载这个volume到一个容器中时,就是在挂载这个目录到容器中。这和bind mount的工作机制很相似,当然,除了volume是被Docker所管理并与宿主机其他核心功能隔离之外。
  • 一个volume可以被同时挂载到多个容器中。当没有任何容器在使用这个volume的时候,这个volume也仍然可以被Docker进程所使用,而不是自动被删除。当然,你可以使用命令手动删除volume:docker volume prune
  • 当你挂载一个volume时,可以选择为他命名(named),也可以不命名(anonymous). 如果不命名的话,当这个volume首次被挂载到一个容器中时,Docker进程会分配给它一个随机的名字,以保证在宿主机操作系统中这个volume的名字唯一。除了名字之外,命名和不命名的volume没有区别。
  • Volume也支持使用volume drivers,以帮助你将数据保存到远程主机或云上。

Bind mounts:

  • 在docker的早期版本中就存在的功能,与volumes相比,他的功能比较局限。当使用bind mounts时,宿主机的目录或文件被挂载到容器中。容器将按照挂载目录或文件的绝对路径来使用或修改宿主机的中的数据。宿主机中的目录或文件不需要预先存在,在需要的时候会自动创建。使用Bind mounts在性能上是非常好的,但这依赖于宿主机有一个目录妥善结构化的文件系统。如果你要创建一个新的Docker应用,我们仍推荐使用named volume的方式,因为你无法通过Docker CLI来管理bind mounts。(警告:bind mounts是一把双刃剑,因为使用bind mounts的容器可以在通过容器内部的进程对主机文件系统进行修改,包括创建,修改和删除重要的系统文件和目录,这个功能虽然很强大,但显然也会造成安全方面的影响,包括影响到宿主机上Docker以外的进程)

tmpfs mounts:

  • 在这种挂载方式下,容器内的应用数据将不会被持久的保存到硬盘上,其中的数据只能在某个容器的生存周期内被使用,或者用于保存一些不需要持久存储,或一些敏感的数据信息。比如,在docker内部,swarm服务使用tmpfs方式来将secrets挂载到服务的容器中。(关于secrets,参考https://docs.docker.com/engine/swarm/secrets/)

Bind mounts和volumes都可以通过使用标志-v或--volume来挂载到容器中,只是格式有些许不同。tmpfs可以使用标志--tmpfs进行挂载。然而,在Docker17.06及其以上版本中,我们推荐使用--mount来对容器或服务进行这三种方式的挂载,因为这种格式更加清晰。

Volume的适用场景

  • 多个容器间需要共享数据。如果volume没有手动被创建,它将会在首次挂载到某个容器之前被自动创建,当容器被停止或删除时,这个volume不会随之被删除。多个容器可以同时以rw或ro的方式挂载这个volume。只有手动指定删除volume,它才会被删除。
  • 当宿主机并没有专用于Docker的文件系统结构时。使用volume可以使宿主机的配置与容器的运行解耦。
  • 当你希望将数据保存到远程主机或云上。
  • 当你希望在不同的宿主机直接备份/恢复/迁移数据时,volume是一个很好的选择。你可以停止运行使用volume的容器,然后直接备份volume所在的目录即可,如/var/lib/docker/volumes/<volume-name>

bind mounts的适用场景

  • 将宿主机的系统配置文件共享给容器,这是Docker为容器提供DNS配置的默认方式,即通过bind mounts的方式将宿主的的/etc/resolv.conf文件挂载到容器中。
  • 将宿主机开发环境中的源代码或实验结果共享给容器。例如:你在宿主机上进行一个项目Maven的测试,每次你在宿主机上对Maven项目进行了更改后,容器就可以直接获取更改后的结果
  • 当你可以确定宿主机的文件系统结构应该与容器内部完全一致时。

tmpfs的适用场景

  • 当你出于安全原因,或者容器性能优化的原因(如需要写入大量的不持久的状态数据时),不需要容器的数据长久保存时可以使用这种方式。

使用bind mounts和volumes的小Tips

  • 如果你使用volumes的方式挂载了一个空的volume到某个容器的一个非空目录中,则这个非空目录中已存在的内容会被拷贝到这个volume中。类似的,如果在启动容器时指定了一个不存在的volume,一个空的volume会被自动创建;
  • 如果使用bind mounts的方式挂载,或者用volumes的方式挂载了一个非空的volume到容器的一个非空目录中,则容器中这个非空目录下的内容将暂时被挂载过来的volume中的内容所覆盖(并未被删除),当取消挂载后,容器中那个非空目录中的文件仍然存在。就像在linux下的/mnt目录下如果存在一些文件,在把USB挂载到/mnt时,在/mnt下就只能看到USB中的内容而看不见原先的文件,当取消USB挂载后,再进入/mnt就可以看见原先的文件了。

选择使用 -v还是--mount

起初,-v或者--volume用于独立容器,--mount用于swarm services。然而,从Docker 17.06开始,也可是使用--mount用于独立容器。—mount命令更精准详细。-v将选项进行了合并。使用--mount。

如果你需要制定volume驱动选项,你必须使用 --mount。

  • -v或者--volume:由3部分参数组成,使用“:”间隔。顺序不能颠倒。

    • 第一个部分是volumes名字,在宿主机上具有唯一性。匿名卷名字系统给出。
    • 第二部分是挂载到容器里的文件或文件夹路径。
    • 第三部分是可选项列表分隔符,例如“or”,这些可选项在下面会讨论。
  • —mount:由多个键值对组成,<key>=<value>。—mount要比-v或者--volume命令更长,但是更容易理解。
    • type,可以是bind,volume或者tmpfs。这篇文章主要讨论volumes,所以type一直使用volume.
    • source,volumes的名字,匿名volume可以省略。source可缩写为src.
    • destination,挂载到容器中的文件或目录路径。可也缩写为dst或者使用target。
    • readonly,指定挂载在容器中为只读。
    • volume-opt,可选属性,可以多次使用。

-v和--mount的不同行为

与bind mounts不同,对于—mount和-v所有的选项都可以使用。

当使用volumes服务时,只支持--mount.

创建和管理volumes

不像bind mount,你可以在容器外创建和管理volumes。

创建一个volume:

$ docker volume create my-vol

显示所有volumes

$ docker volume ls

local               my-vol

查看volumes

$ docker volume inspect my-vol

[

{

"Driver": "local",

"Labels": {},

"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",

"Name": "my-vol",

"Options": {},

"Scope": "local"

}

]

删除一个volume:

$ docker volume rm my-vol

启动一个带volume的容器

如果你启动一个带有volume容器,volume还没有创建,Docker会为你创建。下面的例子挂载myvol2到容器中的/app/下。

下面的例子-v和—mount结果是一样的。

--mount:

$ docker run -d \

--name devtest \

--mount source=myvol2,target=/app \

nginx:latest

-v:

$ docker run -d \

--name devtest \

-v myvol2:/app \

nginx:latest

使用inspect查看挂载是否正确,查看Mounts部分:

"Mounts": [

{

"Type": "volume",

"Name": "myvol2",

"Source": "/var/lib/docker/volumes/myvol2/_data",

"Destination": "/app",

"Driver": "local",

"Mode": "",

"RW": true,

"Propagation": ""

}

],

可以看出挂载正确,并且是可读写的。

停止容器然后删除volume

$ docker container stop devtest

$ docker container rm devtest

$ docker volume rm myvol2

启动一个带有volumes服务

当你启动服务定义一个volume,每个服务可以使用自己本地人volume.如果你使用local volume,容器不能分享数据,但是一些volume驱动支持分享存储。Docker for AWS and Docker for Azure使用Cloudstor插件都支持持久化存储。

下面的例子启动4份nginx服务,每个使用一个本地存储myvol2。

$ docker service create -d \

--replicas=4 \

--name devtest-service \

--mount source=myvol2,target=/app \

nginx:latest

使用docker service ps devtest-service 查看服务是否运行:

$ docker service ps devtest-service

ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS

4d7oz1j85wwn        devtest-service.1   nginx:latest        moby                Running             Running 14 seconds ago

删除服务

$ docker service rm devtest-service

服务标识的不同

docker service create 命令不支持-v或者—volume。必须使用—mount。

使用容器加载一个volume

和上面一样,如果你启动一个容器创建一个新的volume,在容器被挂载的目录(/app/)中有文件或者文件夹,这个目录中的内容会被拷贝到volume中。然后容器挂载使用volume,其他容器使用这个volume也可以访问预加载内容。

为了说明这个,这个例子启动一个nginx容器并且加载一个新volume nginx-vol,里面包括容器中/usr/share/nginx/html 目录中的内容,里面存储的是nginx默认的HTML内容。

--mount and -v具有相同结果

--mount:

$ docker run -d \

--name=nginxtest \

--mount source=nginx-vol,destination=/usr/share/nginx/html \

nginx:latest

-v

$ docker run -d \

--name=nginxtest \

-v nginx-vol:/usr/share/nginx/html \

nginx:latest

以下是运行后清理命令

$ docker container stop nginxtest

$ docker container rm nginxtest

$ docker volume rm nginx-vol

使用只读volume

对于一些开发应用,容器需要回写数据到Docker主机。但有时容器只需要读数据。请记住多个容器可以挂载相同volume,一个挂载读写容器,也可以挂载只读容器,还可以两种同时挂载。

这个例子修改上面的例子,但是挂载的是只读容器,使用’or’分隔符处理选项列表,

--mount and -v具有相同结果

--mount

$ docker run -d \

--name=nginxtest \

--mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \

nginx:latest

-v

$ docker run -d \

--name=nginxtest \

-v nginx-vol:/usr/share/nginx/html:ro \

nginx:latest

使用 docker inspect nginxtest 命令查看是否挂载正确,查看Mounts部分

"Mounts": [

{

"Type": "volume",

"Name": "nginx-vol",

"Source": "/var/lib/docker/volumes/nginx-vol/_data",

"Destination": "/usr/share/nginx/html",

"Driver": "local",

"Mode": "",

"RW": false,

"Propagation": ""

}

],

清理命令

$ docker container stop nginxtest

$ docker container rm nginxtest

$ docker volume rm nginx-vol

机器间共享数据

当构建高可用应用程序,你需要配置多个相同的服务访问相同文件。

有几种方法可以达到这种效果。一种是在你的应用中添加对云存储文件的访问,如Amazon S3。另一种是使用支持外服存储驱动(NFS, Amazon S3)的volume。

Volume驱动允许你在应用中抽象下层的存储系统。例如,如果你的服务使用NFS驱动volume,你可以使用不同的驱动更新服务,就像存储在云中的数据,不需要修改应用逻辑。

使用volume驱动

当你使用docker volume create创建一个volume,或者当你启动一个带有没创建volume的容器,你可以指定volume驱动。下面例子使用vieux/sshfs volume驱动 ,首先创建一个独立的volume,然后启动一个创建新volume的容器。

初始化设置

这个例子假设你有两个节点,第一个是Docker主机而且可以连接到第二个的ssh.

在Docker主机中安装vieux/sshfs插件:

$ docker plugin install --grant-all-permissions vieux/sshfs

使用volume驱动创建volume

这个样例指定一个SSH密码,但是如果两个主机共享keys配置,你可以省略密码。每个volume驱动可以没有或者更多配置选项,可以使用-o标识。

$ docker volume create --driver vieux/sshfs \

-o [email protected]:/home/test \

-o password=testpassword \

sshvolume

[email protected]:/home/test 为远程主机挂载点

启动一个带有使用volume驱动创建volume的容器

这个样例指定一个SSH密码,但是如果两个主机共享keys配置,你可以省略密码。每个volume驱动可以没有或者更多配置选项。如果volume驱动要穿可选参数,你必须使用—mount。

$ docker run -d \

--name sshfs-container \

--volume-driver vieux/sshfs \

--mount src=sshvolume,target=/app,[email protected]:/home/test,volume-opt=password=testpassword \

nginx:latest

原文地址:https://www.cnblogs.com/ExMan/p/11613073.html

时间: 2024-10-08 10:45:23

Docker的数据管理(volume/bind mount/tmpfs)的相关文章

Data Volume 之 bind mount - 每天5分钟玩转 Docker 容器技术(39)

storage driver 和 data volume 是容器存放数据的两种方式,上一节我们学习了 storage driver,本节开始讨论 Data Volume. Data Volume 本质上是 Docker Host 文件系统中的目录或文件,能够直接被 mount 到容器的文件系统中.Data Volume 有以下特点: Data Volume 是目录或文件,而非没有格式化的磁盘(块设备). 容器可以读写 volume 中的数据. volume 数据可以被永久的保存,即使使用它的容器

Docker Bind Mount 与 Volume

为了防止docker里序列化数据的丢失,docker采用了挂载的方式 volume docker -v volumeName:containerPath 或者 docker -v containerPath 这种方式,linux中,docker会在/var/lib/docker/volumes下生成volumeName目录,将containerPath的目录挂载在/var/lib/docker/volumes/$volumeName/_data里 如果不指定volumeName,将随机生成一个文

039、Data Volume 之 bind mount (2019-02-28 周四)

参考https://www.cnblogs.com/CloudMan6/p/7142150.html Date Volume 本质上是Dokcer host文件系统中的目录或者文件,能够直接被mount到容器的文件系统中. Data Volume 有如下特点: 1.Data Volume 是目录或者文件,而非没有格式化的磁盘(块设备) 2.容器可以读写volume中的数据 3.volume数据可以被永久的保存,即使使用他的容器已经销毁 现在有三种方式来存储数据:镜像层.容器层.volume .考

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

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

有容云——窥探Docker中的Volume Plugin内幕

编者注: 本文根据有容云技术实施团队原创分享内容整理.对Docker技术感兴趣.或对本文中细节需继续探讨的朋友,欢迎加入我们参与讨论! 特别鸣谢中生代技术群分享支持. 注:本期分享由张朝潞原创,有容云整理发布,转载请注明出处 作者介绍: 张朝潞,有容云(Yourun Cloud)平台存储架构师.曾工作于UIT,华三,腾讯,专注分布式存储的研究和开发,对云计算存储解决方案方面有很深的技术造诣和行业理解. 本次交流将与大家分享Docker Volume plugin相关的内容.今日主题是窥探Dock

Docker的数据管理及网络通信问题

博文大纲: 一.docker的数据管理1.数据卷2.数据卷容器 二.docker网络通信1.端口映射2.容器互联 一.docker的数据管理 在docker中,为了方便查看容器内产生的数据或者将多个容器之间的数据实现共享,会涉及到容器的数据管理操作,管理docker容器中的数据主要有两种方式:数据卷和数据卷容器. 1.数据卷 数据卷是一个供容器使用的特殊目录,位于容器中,可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立即可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移,数

kubernetes学习 数据管理 Volume (一)

一.Volume 为了持久化保存容器的数据,可以使用 Kubernetes Volume.       Volume的生命周期独立于容器,Pod中的容器可能被销毁和重建,但Volume会被保存. 本质上,Kubernetes Volume 是一个目录,这一点与 Docker Volume 类似.当 Volume 被 mount 到 Pod,Pod 中的所有容器都可以访问这个 Volume.       Kubernetes 也支持多种 backend 类型, 包括 emptyDir.hostPa

解决 Windows Docker 安装 Gitlab Volume 权限问题

本文首发于我的个人博客,解决 Windows Docker 安装 Gitlab Volume 权限问题 ,欢迎访问! 记录一下 Windows10 下 Docker 安装 Gitlab 的步骤. Caution: We do not officially support running on Docker for Windows. There are known issues with volume permissions, and potentially other unknown issue

docker+ bind mount 部署复杂flask应用

报错如下: [[email protected] flask-skeleton]# docker run -d -p 80:5000 -v $(pwd):/skeleton --name flask zhaiwenqiang/flask-skeleton 9b705abd5e280723b8d271394769163224e3fcc052e7313637f42c5fec703e19 /usr/bin/docker-current: Error response from daemon: oci