Docker中容器数据卷(Data Volume)和数据管理详解

发布时间 - 2026-01-10 23:15:43    点击率:

卷(Volume)

众所周知卷(Volume)是容器中的一个数据挂载点,卷可以绕过联合文件系统,从而为Docker 提供持久数据,所提供的数据还可以在宿主机-容器或多个容器之间共享。通过卷,我们可以可以使修改数据直接生效,而不必重新构建镜像。

一、数据卷

数据卷是一个可以绕过联合文件系统的,专门指定的可在一或多个容器间共享目录。卷为提供为持久化或共享数据提供了一些有用的特性。

数据卷设计的初哀是提供持久化数据,而与容器的生命周期无关。因此,在删除容器时,Docker不会自动删除卷,直到没有容器再引用。

1.1 添加数据卷

可以在docker createdocker create命令创建容器时,通过-v参数为容器添加数据卷。-v参数参数可以多次使用,以添加多个数据卷。

如,可以像下面这样为容器添加一个卷:

$ sudo docker run -t -i -v /home/test --name test itbilu/test /bin/bash

这样就会在容器内/webapp位置创建一个卷。

除了在创建容器时添加数据卷外,还可以通过Dockerfile文件中通过Volume指令添加,Volume可以多次使用以添加多个数据卷。

说明:本文中使用的示例镜像(itbilu/test)通过以下Dockerfile文件创建:

# Version: 0.0.3
FROM ubuntu:16.04
MAINTAINER 何民三 "cn.liuht@gmail.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hello World, 我是个容器' \ 
 > /var/www/html/index.html
RUN mkdir /home/itbilu/
ENV ITBILU_PATH /home/itbilu/
VOLUME [$ITBILU_PATH]
EXPOSE 80

1.2 卷位置

添加卷后,可以通过docker inspect来查看数据卷在容器中的位置:

$ sudo docker inspect test

docker inspect可以用来查看容器或镜像的详细配置信息。可以在容器的Mounts节点下,查看容器的卷信息:

...
"Mounts": [{
 "Type": "volume",
 "Name": "5f869c580c06e6079b0de2c5ce682c1c9467286c76b506703d87bf11d1271c24",
 "Source": "/var/lib/docker/volumes/5f869c580c06e6079b0de2c5ce682c1c9467286c76b506703d87bf11d1271c24/_data",
 "Destination": "/home/test",
 "Driver": "local",
 "Mode": "",
 "RW": true,
 "Propagation": ""
},
{
 "Type": "volume",
 "Name": "e4fd6c3a91ba2e03b14cf174c2025f366abbe9f2f73ca07e6bac223f68e47773",
 "Source": "/var/lib/docker/volumes/e4fd6c3a91ba2e03b14cf174c2025f366abbe9f2f73ca07e6bac223f68e47773/_data",
 "Destination": "[/home/itbilu/]",
 "Driver": "local",
 "Mode": "",
 "RW": true,
 "Propagation": ""
}],
...

在以上示例中,有两个挂载卷,一个是在docker run创建容器时创建的,而另一个是在创建运行容器镜像的Dockerfile文件中通过VOLUME指令创建。其中,Source表示宿主机源文件位置,Destination表示数据卷在容器中的挂载位置,而RW表示卷是否可读/写。

1.3 挂载本地数据到容器数据卷

在前面示例中,我们运行容器时并没有指定要挂载到容器中数据卷的本地目录,所在Docker使用一个默认数据目录。 -v参数除了可以在容器中创建数据卷外,还可以将宿主机中的目录挂载到容器中的数据卷。

如,运行容器,并将本地的~/code/itbilu目录挂载到容器的/home/itbilu数据卷上:

$ sudo docker run -t -i -v ~/code/itbilu:/home/itbilu --name test itbilu/test /bin/bas

注意:挂载本地目录到容器内的挂载目录时,如果容器内的数据卷中已经存在数据,那么本地内容将与数据卷中的数据重叠,而不会删除数据。

其中,容器目录必须使用绝对路径,而本地目录可以使用绝对路径或其它形式。

挂载共享存储

除了可以载挂本地目录到容器数据卷外,一些Docker卷插件让你可以挂载共享存储到容器的数据卷,如:iSCSI、NFS、FC。使用共享卷的好处是它们是独立于主机的,这意味着,只要有访问共享存储权限,并安装插件,就可以在任何容器上启动卷。

详细参考:

Mount a shared-storage volume as a data volume

挂载本地文件到容器数据卷

-v参数不仅可挂载目录,还可以挂载单个文件。如:

$ sudo docker run -t -i -v ~/.bash_history:/root/.bash_history \
--name test itbilu/test /bin/bash

以上会把本地的~/.bash_history文件挂载到新容器中,这样你就可以在容器内访问宿主上的bash历史记录。

二、数据卷容器

如果你有一些要在容器之间共享的持久性数据,或者希望在非持久容器中使用,那么最好创建一个命名的数据卷容器,然后从其挂载数据。

接下来,我们创建一个新的命名的共享容器。这个容器不运行一个应用程序,它利用training/postgres镜像在所有的容器之间创建了一个共享层,以节省磁盘空间。

$ sudo docker create -v /dbdata --name dbstore training/postgres /bin/true

注意:training/postgres是Docker 官方文档中提供的一个镜像,本文拿来直接使用了。

使用数据卷容器

创建数据卷容器后,我们可以通过--volumes-from选项,将一个数据容器挂载到其它容器:

$ sudo docker run -d --volumes-from dbstore --name db1 training/postgres

也可以在多个容器间共享。如,挂载到另一个容器:

$ sudo docker run -d --volumes-from dbstore --name db2 training/postgres

这时,如果training/postgres镜像内有名/dbdata的目录,则会从dbstore容器挂载卷,并会隐藏training/postgres镜像中/dbdata下的文件。最终只有dbstore容器中的文件可见。

还可以扩展挂载链,从已经存在的dbstore容器(如:db1、db2)来挂载卷:

$ sudo docker run -d --name db3 --volumes-from db1 training/postgres

这种情况下,如果移除己挂载卷的容器,无论是最初的dbstore容器,还是其后的db1或db2容器,卷都不会被移除。要将卷从硬盘上移除,必须使用docker rm -v命令删除最后一个引用了该卷的容器。

三、备份、恢复与迁移数据卷

除上述操作外,数据卷的常用操作还有数据卷备份、恢复、合并操作。以下是一些常用操作:

3.1 备份数据卷

在前面介绍数据卷容器时,我们创建了一个名为dbdata容器,并在容器中创建了一个/dbdata的数据卷。接下来,可以在创建容器使用--volumes-from参数来挂载这个数据卷,并对数据进行备份:

$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

在这个操作中,我们通过ubuntu镜像创建了一个容器,创建容器时通过--volumes-from参数共享了数据卷容器中的数据,并将当前目录($(pwd) )挂载到了数据卷中。容器运行后,使用tar命令对数据卷进行了备份。

命令执行结束后,容器就会停止,之后就可以在本地当前操作目录下找到所备份的数据。

3.2 备份数据卷

数据备份后,可以在创建容器恢复备份数据到容器内的数据卷中,从而实现数据的迁移。

首先,创建并运行容器并添加一个数据卷:

$ sudo docker run -i -t -v /dbdata --name dbdata2 ubuntu /bin/bash

然后通过tar命令恢复备份数据:

$ sudo docker run --rm --volumes-from dbdata2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

这样,数据就被恢复到了容器dbdata2的/dbdata目录下,我们可以容器中操作和使用这些数据。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# docker  # data  # volume  # 容器  # 数据卷容器  # Docker学习之数据卷和Dockerfile详解  # docker数据卷容器挂载不上的解决方法  # docker-compose:数据卷volumes挂载规则说明  # 删除docker中没有被使用的数据卷volume  # 深入理解 Docker 数据卷(Data Volume)  # 镜像  # 还可以  # 多个  # 容器内  # 我们可以  # 创建一个  # 是在  # 移除  # 并将  # 在前面  # 文件系统  # 就可以  # 是一个  # 就会  # 如果你  # 让你  # 在这个  # 目录下  # 会在  # 并在 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: js实现点击每个li节点,都弹出其文本值及修改  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  详解CentOS6.5 安装 MySQL5.1.71的方法  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  黑客入侵网站服务器的常见手法有哪些?  Laravel如何使用Service Container和依赖注入?(代码示例)  1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤  Laravel如何使用Eloquent进行子查询  Laravel如何实现密码重置功能_Laravel密码找回与重置流程  Android Socket接口实现即时通讯实例代码  Laravel如何使用模型观察者?(Observer代码示例)  node.js报错:Cannot find module 'ejs'的解决办法  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  详解jQuery中的事件  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析  打开php文件提示内存不足_怎么调整php内存限制【解决方案】  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  Python进程池调度策略_任务分发说明【指导】  🚀拖拽式CMS建站能否实现高效与个性化并存?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  Laravel如何使用withoutEvents方法临时禁用模型事件  Python文件流缓冲机制_IO性能解析【教程】  UC浏览器如何设置启动页 UC浏览器启动页设置方法  如何快速搭建支持数据库操作的智能建站平台?  HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】  微信小程序 input输入框控件详解及实例(多种示例)  如何彻底删除建站之星生成的Banner?  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  Java解压缩zip - 解压缩多个文件或文件夹实例  Laravel如何保护应用免受CSRF攻击?(原理和示例)  制作公司内部网站有哪些,内网如何建网站?  Laravel如何优化应用性能?(缓存和优化命令)  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  EditPlus中的正则表达式实战(6)  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  jQuery validate插件功能与用法详解  java获取注册ip实例  如何在宝塔面板创建新站点?  Laravel怎么判断请求类型_Laravel Request isMethod用法  JavaScript如何实现类型判断_typeof和instanceof有什么区别  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  QQ浏览器网页版登录入口 个人中心在线进入  如何在 Python 中将列表项按字母顺序编号(a.、b.、c. …)  Laravel如何记录自定义日志?(Log频道配置)