0%

Docker数据管理-volume/bind mount/tmpfs mount

[TOC]

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 对 数据卷 的修改会立马生效
  • 对 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

-v/-mount 如何选择

最初,-v-volume 用于独立的容器,--mount 用于 swarm server。但 docker 17.06 之后,也可以使用 --mount。两者的区别在于,-v 将所有选项组合在一个字段中,--mount 则将它们分开。

新用户应使用 --mount 语法,老用户推荐使用 --mount

  • -v/--volume,由(:)分隔的三个字段组成,<卷名>:<容器路径>:<选项列表>。选项列表,如:ro只读。
  • --mount,由多个键值对组成,由,分隔,每个由一个<key=<value>>元组组成。
    • type,值可以为 bindvolumetmpfs
    • source,对于命名卷,是卷名。对于匿名卷,这个字段被省略。可能被指定为 sourcesrc
    • destination,文件或目录将被挂载到容器中的路径。可以指定为 destinationdsttarget
    • volume-opt 可以多次指定。

选择合适的挂载方式

Docker提供了3种方法将数据从Docker宿主机挂载(mount)到容器:volumesbind mountstmpfs mounts。一般来说,volumes总是最好的选择。

不管你选择哪种挂载方式,从容器中看都是一样的。数据在容器的文件系统中被展示为一个目录或者一个单独的文件。

一个简单区分volumesbind mountstmpfs mounts不同点的方法是:思考数据在宿主机上是如何存在的。

  • Volumes由Docker管理,存储在宿主机的某个地方(在linux上是/var/lib/docker/volumes/)。非Docker应用程序不能改动这一位置的数据。Volumes是Docker最好的数据持久化方法。
  • Bind mounts的数据可以存放在宿主机的任何地方。数据甚至可以是重要的系统文件或目录。非Docker应用程序可以改变这些数据。
  • tmpfs mounts的数据只存储在宿主机的内存中,不会写入到宿主机的文件系统。

详细对比

Volumes:由Docker创建和管理。你可以通过docker volume create命令显式地创建volume,Docker也可以在创建容器或服务是自己创建volume。

例如下面:

1
2
3
4
5
6
7
8
9
10
11
12
13
☁  Docker  docker volume ls
DRIVER VOLUME NAME
local my-vol
☁ Docker docker run -d \
-it \
--name demo \
--mount type=volume,target=/app \
nginx:latest
7eb04d34a87ecd4a7996f8ad4da83bd613d2e992f6860faf730b876a66efd19f
☁ Docker docker volume ls
DRIVER VOLUME NAME
local 0c06952c157c3b6550e7f71a9c6463a1b70c893c15b0d8e0b8d05ad398ced427
local my-vol

第一行:先查看下volume列表

第四行:创建container,并使用type=volume类型,指向container内部app目录

第十行:查看最新的volume列表

当你创建了一个volume,它会被存放在宿主机的一个目录下。当你将这个volume挂载到某个容器时,这个目录就是挂载到容器的东西。这一点和bind mounts类似,除了volumes是由Docker创建的,和宿主机的核心(core functionality)隔离。

一个volume可以同时被挂载到几个容器中。即使没有正在运行的容器使用这个volume,volume依然存在,不会被自动清除。可以通过docker volume prune清除不再使用的volumes。

volumes也支持volume driver,可以将数据存放在另外的机器或者云上。

Bind mounts:Docker早期就支持这个特性。与volumes相比,Bind mounts支持的功能有限。使用bind mounts时,可以将你主机上的任何文件或目录(绝对路径)挂载到容器中。

警告:使用Bind mounts的一个副作用是,容器中运行的程序可以修改宿主机的文件系统,包括创建,修改,删除重要的系统文件或目录。这个功能可能会有安全问题。

tmpfs mountstmpfs mounts的数据不会落盘。在容器的生命周期内,它可以被用来存储一些不需要持久化的状态或敏感数据。例如,swarm服务通过tmpfs mounts来将secrets挂载到一个服务的容器中去。

如何选择?

适合volume的场景

  • 在不同的容器中共享数据,如果未显式创建它,则会在第一次将其装入容器时创建。当该容器停止或被移除时,该卷仍然存在。多个容器可以同时安装相同的卷,可以是读写也可以是只读。仅在您明确删除卷时才会删除卷
  • 当Docker主机不能保证具有给定的目录或文件结构时。卷可帮助您将Docker主机的配置与容器运行时分离。
  • 如果要将容器的数据存储在远程主机或云提供程序上,而不是本地存储。
  • 当你需要备份或迁移数据的时候,当您需要能够将数据从一个Docker主机备份,还原或迁移到另一个Docker主机时,卷是更好的选择。您可以使用卷停止容器,然后备份卷的目录(例如/var/lib/docker/volumes/)

适合bind mounts的场景

  • 宿主机和容器共享配置文件。Docker提供的DNS解决方案就是如此,将宿主机的/etc/resolv.conf挂载到每个容器中。
  • 开发环境需要在宿主机和容器中共享代码。docker的开发就是如此,毕竟容器中一般是没有编辑器的
  • 当Docker主机的文件或目录结构保证与容器所需的绑定安装一致时

适合tmpfs mounts的场景

tmpfs mounts主要用在你既不想在容器内,又不想在宿主机文件系统保存数据的时候。这可能是出于安全原因,也可能是你的应用需要写非常多的非持久化数据,tmpfs mounts这时候可以保证容器性能。

本文转自这里