Docker数据存储指南

概述

在Docker容器中创建的文件默认是存储在可写的容器文件层中,而容器停止后这些数据将会丢失。为了在容器停止后保留文件数据,可以使用以下三种方法:volumes、bind mounts和tmpfs。这些方法允许将容器中的文件存储到宿主机上,确保数据持久性。下面是对这三种方法的简要解释:

Volumes(卷):Volumes是一种持久性存储的方法,它允许将数据存储在宿主机的文件系统中,而不是容器文件层。数据存储在宿主机上的特定目录中,不会随着容器的删除而丢失。Volumes可以用于共享数据,也可以用于备份和恢复。在Docker中,可以通过-v或--mount标志来创建和使用volumes。

Volumes提供了一种持久性存储的机制,可以将数据存储在宿主机的文件系统中。这些数据不会随着容器的删除而丢失,可以在多个容器之间共享。多个容器可以通过挂载相同的volume来共享数据,实现数据共享的需求。

Volumes中的数据可以轻松备份到宿主机上的外部存储系统中,也可以通过备份工具将数据定期备份到远程服务器。这样,在容器发生故障或需要迁移时,可以方便地将数据从备份中恢复,确保数据的安全性和可靠性。

可以使用-v或--mount标志来创建和使用volumes。例如,使用以下命令创建一个volume并将宿主机上的/path/to/host/directory挂载到容器的/path/to/container/directory:

bash 复制代码
docker run -v /path/to/host/directory:/path/to/container/directory my_container

这个命令会在容器启动时,创建一个volume,并将宿主机目录挂载到容器目录,实现了数据的共享。

Bind Mounts(绑定挂载):Bind mounts允许将宿主机上的特定文件或目录挂载到容器中,容器中的数据将与宿主机上的文件或目录保持同步。这意味着对绑定挂载中的文件的修改会同时反映在容器和宿主机之间。Bind mounts适用于需要与宿主机文件系统共享数据的场景。在Docker中,可以通过-v或--mount标志来创建和使用bind mounts。

Bind mounts允许将宿主机上的特定文件或目录挂载到容器中,容器中的数据将与宿主机上的文件或目录保持同步。这意味着对绑定挂载中的文件的修改会同时反映在容器和宿主机之间。Bind mounts适用于需要容器与宿主机文件系统之间实时共享数据的场景,例如,在开发环境中,容器需要访问宿主机上的代码文件或配置文件。

可以使用-v或--mount标志来创建和使用Bind Mounts。例如,使用以下命令将宿主机上的/path/to/host/directory挂载到容器的/path/to/container/directory:

bash 复制代码
docker run -v /path/to/host/directory:/path/to/container/directory my_container

这个命令会在容器启动时,创建一个Bind Mounts,并将宿主机目录挂载到容器目录,实现了数据的实时共享和同步。Bind Mounts提供了一种方便的方式,允许容器与宿主机文件系统实时共享数据

Tmpfs(临时文件系统):Tmpfs是一种将数据存储在内存中而非硬盘上的文件系统。在Linux系统上,可以

使用tmpfs来创建一个临时文件系统,将数据保存在内存中。Tmpfs适用于需要在容器内部临时存储数据的场景,但是请注意,一旦容器停止,tmpfs中的数据也会丢失。例如临时文件、缓存数据或临时计算结果等。由于数据存储在内存中,读写速度非常快,因此适合处理对速度要求较高的临时数据。

数据丢失风险:尽管tmpfs提供了高速的读写性能,但它的一个重要特点是,一旦容器停止,tmpfs中的数据就会丢失。因为数据存储在内存中,内存的内容在系统关机或容器停止时会被清空,所以不适合用于需要长期保存数据的场景。如果容器重启,tmpfs将重新创建,并且之前存储在其中的数据将不再可用。

总的来说,使用volumes、bind mounts或tmpfs可以确保在Docker容器停止后,创建的文件依然存在于宿主机上,提供了数据持久性和灵活性,可以根据具体需求选择适合的存储方法。

volumes

Volumes可以由Docker创建和管理。可以使用命令docker volume create显式地创建一个volume,也可以由Docker进程在需要时自动创建,例如在服务初始化的时候。创建的volume的数据存储在宿主机的指定目录中。

创建的volume可以被挂载到容器内部的指定挂载点。通过挂载,容器可以在指定的挂载点访问volume中的数据。这种挂载方式与Bind Mounts(绑定挂载)相似,但是volume只能由Docker进程管理,而不是手动设置。

  • 多容器共享:同一个volume可以同时挂载到多个容器内部,实现多个容器之间共享数据的需求。

举例说明,创建一个Volume:首先,你可以使用Docker命令或者Docker Compose定义一个volume,比如:

lua 复制代码
docker volume create my_volume

将Volume挂载到多个容器:然后,你可以将这个volume挂载到多个容器中,

javascript 复制代码
docker run -d --name container1 -v my_volume:/path/to/mountpoint my_image
docker run -d --name container2 -v my_volume:/path/to/mountpoint my_image

这会在宿主机上创建一个名为my_volume的volume。在上述命令中,-v my_volume:/path/to/mountpoint表示将my_volume挂载到容器内部的/path/to/mountpoint目录。这样,container1和container2两个容器就可以共享my_volume中的数据。

这种共享数据的方式非常实用,特别是在微服务架构中,不同的服务可能需要共享某些配置文件、日志文件或其他数据。通过挂载相同的volume,这些服务可以方便地共享数据,实现数据共享和协作。

  • 自动删除:Docker不会在没有容器使用volume的时候自动删除该volume。可以使用docker volume prune命令来移除不再使用的volume。
  • 命名和随机分配:在创建volume时,可以指定一个名字,也可以由系统分配一个唯一的随机名字。命名volume可以更容易管理和识别。
  • 支持Volume Driver:Volumes支持volume driver,通过这种方式,数据可以存储到远程的机器或云平台上,提供了更多的数据存储选项。

总的来说,Volumes提供了一种方便和灵活的数据管理方式,允许容器和宿主机之间共享数据,并且支持多容器间共享,提高了数据的可用性和灵活性。

接下来详细介绍如何使用volume

bash 复制代码
# docker volume create my-vol
# docker volume ls

执行结果

perl 复制代码
DRIVER              VOLUME NAME
local               0d677566872e112e6792b7dd1e71f4b5c26fec701de4d43fe401fd1d5bd93afd
local               12a0226aff0e607425bd2f8ed6544154ec276feda24dee39255e377b978d4014
local               22340dc6d144f4f4be30c93afc1186734f8559acb20aeeb861fa929d4c26e30b
local               a7fe694cc0abea99d1e455e31d25a49a523e4ff661f4172d48e3b61ccd00c2c0
local               my-vol

DRIVER为local:在Docker中,DRIVER参数用于指定Volume的驱动程序。这里提到DRIVER为local,表示这些Volume都是本地存储,即它们的数据存储在宿主机的本地文件系统中。每个Volume都有一个指定的驱动程序,它确定了Volume的后端存储类型。在提到DRIVER为local时,意味着使用了本地存储驱动程序。当DRIVER参数被设置为local时,表示使用了本地存储驱动程序。这意味着Docker会将Volume的数据存储在宿主机的本地文件系统中,确保数据持久性。本地存储通常用于简单的场景,比如数据共享或持久性存储需求较低的应用。

当使用本地存储驱动程序时,Volume的数据被存储在宿主机的本地文件系统中,通常于/var/lib/docker/volumes目录下。这个目录是Docker默认用来存储Volume数据的位置。

查看Volume列表:通过命令ls,可以查看所有的Volume列表。在这个文本中,提到了一个手动创建的Volume,名为my-vol,以及其他几个都是由Docker自动生成的Volume名称。

Volume存储位置:所有的Volume实际上都被存储在宿主机的一个特定目录中,即/var/lib/docker/volumes。这个目录是Docker用来存储Volume数据的默认位置。

在Docker中,使用-v或--volume参数来挂载Volume到容器内部,该参数包含三个字段,以冒号分隔:

  • 第一个字段(可选):这是Volume的名字,在单台宿主机上Volume的名字必须是唯一的。如果你希望创建一个匿名的Volume,即不指定名字,可以省略这个字段。例如,-v my_volume:/path/to/mountpoint中的my_volume就是Volume的名字。
  • 第二个字段:这是容器内的挂载点(mount point),即Volume将被挂载到容器内部的哪个路径。例如,-v my_volume:/path/to/mountpoint中的/path/to/mountpoint就是容器内的挂载点。
  • 第三个字段(可选):这是以逗号分隔开的一系列可选参数。这些参数可以用来设置Volume的特性,比如读写权限、传播行为等。例如,-v my_volume:/path/to/mountpoint:ro中的ro表示只读权限。这部分参数是可选的,根据需求可以省略。

总的来说,-v/--volume参数的格式为[Volume名字:]容器内挂载点[:可选参数],通过这个参数,你可以将宿主机上的Volume挂载到容器内的指定路径,并且可以配置Volume的特性。

bind mounts

Bind Mounts与Volume的区别:

  • 文件位置不固定:Bind Mounts模式与Volume非常相似,区别在于Bind Mounts可以将宿主机上的文件位置固定到任意目录,而不限制在/var/lib/docker/volumes/目录下。这意味着在Bind Mounts中,宿主机的文件可以位于任意位置,而不受Docker内部目录结构的限制。
  • 数据可被任意程序改动:由于Bind Mounts将宿主机上的目录直接映射到容器内部,所以这些数据可以被宿主机上的任意程序改动。这种灵活性也带来了潜在的风险,因为其他程序可能会意外修改这些数据。

容器内部挂载目录非空时的行为差异:

  • 使用Volume:当容器内部的挂载目录非空时,使用Volume时,容器目录中的文件会被复制到Volume中。换句话说,容器内部目录原有的文件会被复制到Volume中,容器在运行时操作的是Volume中的数据,而不是原始文件。
  • 使用Bind Mounts:而使用Bind Mounts时,容器内部挂载目录中原有的文件会被隐藏,只能读取到宿主机目录下的文件。容器内部的数据实际上是宿主机上对应目录的数据的引用,而不是复制,所以对挂载目录的修改会直接影响宿主机上的文件。

一般情况下,推荐尽可能使用Volume,因为它提供了更受控和隔离的数据管理方式。但在以下情况下,可以考虑使用Bind Mounts:

  • 在宿主机和容器之间共享配置:例如,容器可能需要访问宿主机的特定配置文件,如/etc/resolv.conf用于DNS解析。通过Bind Mounts,可以将宿主机上的配置文件映射到容器内部,实现配置共享。
  • 在宿主机和容器之间共享代码或可执行文件:例如,将Maven项目的target/目录(包含编译后的代码和可执行文件)挂载到容器内部。这样,每次在宿主机上编译后,容器内部就能获取到最新的文件。这种做法可以确保容器内部使用的代码始终与宿主机上的代码保持同步,方便开发和测试过程中的调试和验证。
相关推荐
shelby_loo4 小时前
在Ubuntu下通过Docker部署NAS服务器
服务器·ubuntu·docker
敲代码不忘补水5 小时前
Docker 启动 PostgreSQL 主从架构:实现数据同步的高效部署指南
docker·postgresql·架构·数据库架构
长天一色8 小时前
【Docker从入门到进阶】06.常见问题与解决方案 & 07.总结与资源
运维·docker·容器
iangyu13 小时前
docker常用命令
运维·docker·容器
老齐谈电商16 小时前
开源电商erp系统启航电商ERP系统centos Docker部署
docker·开源·centos
-$_$-17 小时前
【黑马点评】 使用RabbitMQ实现消息队列——1.Docker与RabbitMQ环境安装
分布式·docker·rabbitmq
芯的一天17 小时前
windows下DockerDesktop命令行方式指定目录安装
windows·docker
帅气的人12318 小时前
使用 docker-compose 启动 es 集群 + kibana
elasticsearch·docker
獨枭19 小时前
Ubuntu 通过 Docker 搭建 GitLab
ubuntu·docker·gitlab
zixingcai19 小时前
dockertop提示Failed to fetch extensions
docker