docker数据卷的使用

文章目录

  • 1、数据卷产生背景
  • 2、数据卷的使用
    • 2.1、创建数据卷
    • 2.2、挂载数据卷
    • 2.3、共享数据卷
    • 2.4、删除数据卷
    • 2.5、备份和迁移数据卷
  • 总结

1、数据卷产生背景

Docker的镜像是由一系列的只读层组合而来,当启动一个容器时,Docker加载镜像的所有只读层,并在最上层加入一个读写层。这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在一些问题:

  • 容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便地对容器中的文件进行访问。
  • 多个容器之间的数据无法共享
  • 当删除容器时,容器产生的数据将丢失。

为了解决这些问题,Docker引入了数据卷(volume)机制。Volume 是存在于一个或多个容器中的特定文件或文件夹,这个目录以独立于联合文件系统的形式在宿主机中存在,并为数据的共享和持久化提供便利。

  • volume 在容器创建时就会初始化,在容器运行时就可以使用其中的文件。
  • volume 能在不同的容器之间共享和重用。
  • 对volume中数据的操作会马上生效。
  • 对volume中数据的操作不会影响镜像本身。
  • volume的生存周期独立于容器的生命周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除。

2、数据卷的使用

Usage:  docker volume COMMANDManage volumesCommands:create      Create a volumeinspect     Display detailed information on one or more volumesls          List volumesprune       Remove all unused local volumesrm          Remove one or more volumes

2.1、创建数据卷

创建一个名为 vol_simple的存储卷:

docker volume create --name vol_simple

查看数据卷的信息:

docker volume inspect vol_simple

示例:

king@king-server:~$ docker volume inspect vol_simple 
[{"CreatedAt": "2024-01-27T11:37:11Z","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/vol_simple/_data","Name": "vol_simple","Options": null,"Scope": "local"}
]

Docker run 和 docker create 通过指定-v参数 可以为容器挂载一个数据卷。

#没有指定volume卷,只指定了容器中的挂载点/data 
docker run -d -it -v /data ubuntu /bin/bash 
# 查看随机创建的volume位置,查看mounts的内容 
docker inspect {ID}
# 创建一个指定名字的volume ,并挂载到容器中的/data目录 
docker run -d -v vol_simple:/data ubuntu

示例:

fly@fly:~$ docker run -dit -v vol_simple:/data ubuntu
e86204b7a02ccb62e6cf4f00b7246ac0d70aadf0d9915df5418ad73f0bf8f00a
fly@fly:~$ docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS          PORTS                                       NAMES
e86204b7a02c   ubuntu       "bash"                   4 seconds ago   Up 2 seconds                                                charming_bhaskara
fly@fly:~$ docker inspect charming_bhaskara 
...
"Mounts": [{"Type": "volume","Name": "vol_simple","Source": "/var/lib/docker/volumes/vol_simple/_data","Destination": "/data","Driver": "local","Mode": "z","RW": true,"Propagation": ""}],
...

测试数据持久性:

fly@fly:~$ docker exec -it charming_bhaskara bash
root@e86204b7a02c:/# ls
bin  boot  data  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@e86204b7a02c:/# echo abcd >> /data/1.txt
root@e86204b7a02c:/# cat data/1.txt 
abcd
root@e86204b7a02c:/# exit
exit
fly@fly:~$ docker stop charming_bhaskara 
charming_bhaskara
fly@fly:~$ docker rm charming_bhaskara 
charming_bhaskara
fly@fly:~$ docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED       STATUS          PORTS                                       NAMES
22634e72e7a3   registry:2   "/entrypoint.sh /etc…"   3 weeks ago   Up 21 minutes   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   registry
fly@fly:~$ sudo cat /var/lib/docker/volumes/vol_simple/_data/1.txt
abcd

2.2、挂载数据卷

使用docker run 或者 docker create 创建新容器是,可以使用-v标签为容器添加volume。可以将自行创建或者有Docker创建的volume挂载到容器中,也可以将宿主机上的目录或者文件作为volume挂载到容器中。

将宿主机中指定目录作为volume挂载到容器中的/data目录下,文件夹必须使用绝对路径,如果宿主机中不存在指定的目录,则会创建一个空文件夹;如果宿主机文件夹已经存在,容器可以通过访问挂载点/data 从而访问宿主机文件夹中的所有内容。如果容器下原本已经存在/data文件夹,且不为空,那么容器中文件夹下原有的内容将被隐藏,来保持与宿主机中的文件夹一致。

挂载方式:

  1. 创建名为vol_simple的数据卷,并挂载到容器中的/data目录下:
docker volume create --name vol_simple 
docker run -d -v vol_simple:/data ubuntu /bin/bash
  1. 创建一个随机的ID的volume,并将其挂载到容器中的/data目录下:
docker run -d -v /data ubuntu /bin/bash
  1. 关联宿主机目录:
docker run -d -v $HOME/data:/data ubuntu /bin/bash

挂载权限,ro表示只读,rw表示读写,默认为rw:

# ro表示只读,rw表示读写,默认为rw 
docker run -it -v $HOME/data:/data:ro ubuntu /bin/bash 
# 通过修改文件验证,因为是只读,所以下面会报错
echo 123456abcdefg >> /data/test

同时挂载多个数据卷:

docker run -it -v $HOME/data:/data:ro -v /data1 -v /data2 ubuntu /bin/bash

使用dockerfile VOLUME 指令,与docker run -v 不同的是,dockerfile指令不能挂载主机中指定的文件夹。这时为了保证Dockerfile的可移植性,因为不能保证所有的宿主机都有对应的文件夹。如果镜像中存才/data文件夹,这个文件夹中的内容将全部被复制到宿主机上对应文件夹中,并且根据容器中的文件设置合适的权限和所有者。

注意:
在Dockerfile中使用VOLUME指令后的代码,如果尝试对这个volume进行修改,这些修改都不会生效。因为:volume 是独立于rootfs的存储,镜像构建过程,每一层类似docker commit 提交临时镜像为镜像层,docker commit不会对挂载的volume进行保存。

示例1:
VOLUME指定了挂载点之后,再对挂载点进行操作,由于docker commit 提交临时镜像不会对volume进行保存,所以该data下的file并没有被保存,更不会同步到宿主机。

FROM ubuntu 
RUN useradd fly2
VOLUME /data 
RUN touch /data/file 
RUN chown -R fly2:fly2 /data

构建:

docker build -t test1:v1 -f Dockerfile . 
docker run -d -it test1:v1 /bin/bash

查看挂载点信息 :

docker inspect 容器ID 

查看宿主机存储卷目录 :

sudo ls 宿主机存储卷目录

示例二:
由于挂载volume时,/data目录已经存在,所以/data中的文件以及它们的权限和所有者设置都会被复制到volume中。

FROM ubuntu 
RUN useradd fly2 
RUN mkdir /data && touch /data/file 
RUN chown -R fly2:fly2 /data 
VOLUME /data

构建:

docker build -t test1:v2 -f Dockerfile1 . 
docker run -d -it test1:v2 /bin/bash 

查看挂载点信息:

docker inspect 容器ID

查看宿主机存储卷目录 :

sudo ls 宿主机存储卷目录

示例三:
通过CMD和ENTRYPOINT指令,在容器启动时执行挂载点下文件的初始化。

FROM ubuntu 
RUN useradd fly2
VOLUME /data 
CMD touch /data/file && chown -R fly2:fly2 /data

说明:
在dockerfile中使用数据卷时,如果我们仅仅想在启动容器时有这样一个空的数据卷,那么dockerfile中关于数据卷这块怎么写都行;如果我们确确实实需要初始化一些内容到我们的数据卷里头,我们先得将内容提交到镜像(比如先创建文件),然后再去创建数据卷。

2.3、共享数据卷

在使用docker run 或docker create创建新容器时,可以使用–volumes-from 标签使得容器与已有容器共享volume。可以使用多个–volumes-from标签,使得容器与多个已有容器共享volume。

一个容器挂载了一个volume,即使这个容器停止运行,该volume仍然存在,其他容器也可以使用–volumes-from与这个容器共享volume。

共享数据卷作用:
如果有一些数据,比如配置文件、数据文件等,要在多个容器之间共享,一种常见的做法是创建一个数据容器,其他的容器与之共享volume。

示例:创建一个带数据卷的容器。
创建目录和数据卷:

mkdir $HOME/data 
mkdir $HOME/readOlny_data 
docker volume create vol_simple 
docker volume create vol_simple1 

创建一个数据容器 包含已创建数据卷,只读数据卷,私有数据卷等 :

docker run -d -it -v vol_simple:/vol_simple -v $HOME/data:/data -v $HOME/readOlny_data:/readOlny_data:ro --name share_data ubuntu /bin/bash 
docker run -d -it -v vol_simple1:/vol_simple1 --name share_data1 ubuntu /bin/bash 

进入容器查看 :

docker exec -it 容器ID /bin/bash

运行新的容器通过数据容器共享数据卷 容器名:

volume_from1 docker run -d -it --volumes-from share_data --volumes-from share_data1 --name volume_from1 ubuntu /bin/bash 

运行新的容器通过数据容器共享数据卷 容器名:

volume_from2 docker run -d -it --volumes-from share_data --volumes-from share_data1 --name volume_from2 ubuntu /bin/bash

说明:

  1. 只读共享点不能被写入。
  2. 可以同时共享多个容器的数据卷。
  3. docker inspect 查看容器元数据。

2.4、删除数据卷

如果创建容器时从容器中挂载了volume,在/var/lib/docker/volumes下会生成与volume对应的目录(可使用docker inspect 命令查看容器信息找到对应的信息)。

删除volume的三种方式:

  1. 使用docker volume rm <volume_name> 删除数据卷。
  2. 使用docker rm -v <container_name> 删除容器时一并删除它挂载的数据卷。
  3. 在运行容器时使用docker run --rm 标签会在容器停止运行时删除容器以及容器所挂载的volume。

注意:

  1. 在使用第一种docker volume rm 删除时,只有当没有任何容器使用该volume的时候,才能被删除成功。
  2. 另外两种删除方式,只会对挂载在该容器上的未指定名称(匿名的)的volume进行删除,而会对用户指定名称的(具名的)volume进行保留。
  3. 如果volume 是在创建容器时从宿主机中挂载的,无论对容器进行任何操作都不会导致其在宿主机中被删除,如果不需要这些文件,只能手动删除。(从宿主机中挂载是指 docker run -v dir:dir 这种模式)。

2.5、备份和迁移数据卷

volume 作为数据的载体,在很多情况下需要对其中的数据进行备份、迁移,或是从已有数据恢复。

最简单的备份还原的方式:

  1. 通过inspect 命令查看容器信息,找到对应的数据卷,手动打包数据;
  2. 同样的还原那就是把打包好的数据解压到对应的数据卷。

用–volumes-from实现备份与还原:

  1. 备份:启动另外一个临时容器,共享挂载数据容器share_data,同时挂载当前目录到容器的/backup。启动容器时执行打包命令,将/data挂载点下的数据打包到/backup/data.tar 文件中。–rm 表示该容器停止后会删除该容器和该容器的数据卷。
docker run --rm --volumes-from share_data -v $(pwd):/backup ubuntu tar cvf /backup/data.tar /data
  1. 恢复:创建临时容器,通过共享存储的方式与目标容器共享存储,同时挂载当前目录到容器的/backup。启动容器时从backup挂载点下的data.tar 解压文件到容器的根目录。
docker run -d -it --name vol_bck -v /data ubuntu /bin/bash
docker run --rm --volumes-from vol_bck -v $(pwd):/backup ubuntu tar xvf /backup/data.tar -C /

总结

  1. 数据卷解决的问题就是容器数据的持久化问题,比如日志、容器间共享数据、配置文件等。
  2. 容器和镜像使用的同一套文件,即依赖相同的镜像层,这是一个只读的权限;要修改底层文件内容,就需要将文件从只读层拷贝出来放到读写层进行改变;改变后会隐藏只读层的那个文件,使用读写层的文件。
  3. 一般,底层文件系统是不允许改变的,所以容器关闭之后,容器的所有改变内容都会被删除,为解决这个问题引入了数据卷。
  4. 匿名数据卷可以在删除容器的时候一并删除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/653088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript高级:构造函数

1 引言 构造函数是一种特殊的函数&#xff0c;主要用来初始化对象&#xff1b;常规的 {...} 语法允许创建一个对象&#xff0c;但是通过构造函数可以快速创建多个类似的对象 2 约定 1. 命名以大写字母开头&#xff1b; 2. 它们只能由 “new” 操作符来执行 <script>//…

【C++】filesystem

文章目录 1. 基本配置1.1. VS2019修改C标准1.2. filesystem的引入 2. 日常使用2.1. 认识2.2. 控制台输入路径并对路径进行基本操作 <filesystem>是C 17标准引入的标准库&#xff0c;主要用于处理文件系统的目录和文件操作&#xff0c;接下来总结该库的基本配置和日常使用…

Docker搭建Mysql5.7双主双从集群步骤

记录下在Docker搭建mysql5.7双主双从集群步骤 1.拉取镜像 docker pull mysql:5.72.创建对应数据卷 由于我们需要做数据持久化,所以先在本地创建对应四个节点的相应文件夹 #conf文件夹用于存放配置文件 mkdir -p /root/mysql/mysql-master/conf #data文件夹用于存放mysql数…

BIGVGAN: A UNIVERSAL NEURAL VOCODER WITHLARGE-SCALE TRAINING——TTS论文阅读

笔记地址&#xff1a;https://flowus.cn/share/a16a61b3-fcd0-4e0e-be5a-22ba641c6792 【FlowUs 息流】Bigvgan 论文地址&#xff1a; BigVGAN: A Universal Neural Vocoder with Large-Scale Training Abstract 背景&#xff1a; 最近基于生成对抗网络&#xff08;GAN&am…

【第十八课】DFS:深度优先搜索( acwing-843 n-皇后问题 / c++代码 )

目录 错误写法(可跳 DFS-剪枝 代码 思路二&#xff1a; 原始解法 错误写法(可跳 看到这道题&#xff0c;我想这不还是n个数的全排列的问题么?也就是把数字变成了字符&#xff0c;一些输出格式上的变化。于是就在原有代码上修改一下应该就行。 我的思路就还是path存有可能…

跨站脚本攻击漏洞概述-XSS

什么是跨站脚本攻击 跨站脚本( Cross-site Scripting ) 攻击&#xff0c;攻击者通过网站注入点注入客户端可执行解析的payload(脚本代码)&#xff0c;当用户访问网页时&#xff0c;恶意payload自动加载并执行&#xff0c;以达到攻击者目的(窃取cookie、恶意传播、钓鱼欺骗等)。…

十大排序算法之非线性时间比较类排序

前言 接下来就开始我们的算法学习之路了&#xff0c;代码会分别使用Java与Python来实现&#xff0c;数据处理的算法很多&#xff0c;排序是最基础且最重要的一类&#xff0c;大多数人都是通过学习排序算法入门的。接下来让我们一起学习闻名遐迩的十大排序算法&#xff0c;它们…

非官方 Bevy 作弊书07-09

源自 网页 Working with 2D - Unofficial Bevy Cheat Book 个人用 有道 翻译&#xff0c;希望能够帮助像我一样的 英语不好 的 bevy 初学者 非官方 Bevy 作弊书 7 使用 bevy 2D 本章涵盖与使用 Bevy 制作 2D 游戏相关的主题。 2D Camera Setup - Unofficial Bevy Cheat Book 非…

java.util.LinkedHashMap cannot be cast to xxx

java.util.LinkedHashMap cannot be cast to com.entity.Person 使用mybatis, resultMap映射的是实体类Person, 查询出来的结果是一个ArrayList,然后结果存放在一个ListObject的data属性中, 存放结果的类 public class ListObject { private Object data; public Object get…

R语言【taxlist】——match_names():字符和 taxlist 对象之间的搜索匹配

Package taxlist version 0.2.4 Description 字符向量中提供的名称将使用函数 stringsim&#xff08;&#xff09; 与存储在类 taxlist 对象中的插槽 taxonNames 中的名称进行比较。 Usage match_names(x, object, ...)## S4 method for signature character,character match…

Java算法 leetcode简单刷题记录10

Java算法 leetcode简单刷题记录10 庆祝一下&#xff1a;大概花费了9天&#xff0c;我把所有leetcode Java 的简单题都刷完了&#xff0c;接下来开始冲刺中等和复杂&#xff1b; 简单题里用到的比较多的是字符串的处理&#xff0c;转换&#xff0c;拆分&#xff0c;替换&#x…

【LeetCode: Z 字形变换 + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Redis学习——高级篇②

Redis学习——高级篇② Redis7高级之BigKey&#xff08;二&#xff09; 1.MoreKey案例2.BigKey案例2.1 多大算 BigKey以及它的危害2.2 如何产生、发现、删除 3. bigKey生产调优 Redis7高级之BigKey&#xff08;二&#xff09; 1.MoreKe…

【高效开发工具系列】Java读取Html

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Linux系统安装Nginx

一、Nginx的简介 Nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;是由伊戈尔赛索耶夫为俄罗斯访问量第二站点开发的&#xff0c;因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名&#xff0c;第一个公开版本0.1.0发布于2004年10月4日。 Nginx是一…

C# RichTextBox常用属性、方法学习1

1 字体 Font font1 new Font("宋体", 18); richTextBox1.Font font1; Font font2 new Font("宋体", 10, FontStyle.Underline); richTextBox1.SelectionFont font2; 定义字体&#xff0c;可以带2个参数&#…

LeetCode---122双周赛

题目列表 3010. 将数组分成最小总代价的子数组 I 3011. 判断一个数组是否可以变为有序 3012. 通过操作使数组长度最小 3013. 将数组分成最小总代价的子数组 II 一、将数组分成最小总代价的子数组I 这道题纯纯阅读理解题&#xff0c;关键在于理解题意。注意&#xff1a;第一…

总体方差与样本方差的区别是什么?

总体方差和样本方差是统计学中两个重要概念&#xff0c;它们在定义和计算上有所不同&#xff0c;主要区别体现在数据集的性质和计算公式的分母上&#xff1a; 1. 总体方差&#xff08;Population Variance&#xff09;&#xff1a; 定义&#xff1a; 总体方差是指将一个完整数…

嵌入式——窗口看门狗(WWDG)补充

目录 一、独立看门狗与窗口看门狗 1.功能描述 2.两者区别 二、WWDG功能描述 1.窗口看门狗时钟 2.计数器时钟 3. 计数器 4.窗口值 三、WWDG超时时间 一、独立看门狗与窗口看门狗 1.功能描述 STM32有两个看门狗&#xff1a;一个是独立看门狗&#xff08;IWDG&#xff0…

在知乎上如何写科技文章?

当在知乎上撰写关于科技趋势的文章时&#xff0c;有几个关键的写作技巧和建议可以帮助你获得更好的传播效果&#xff1a; 选题关注热点&#xff1a; 在选择科技趋势时&#xff0c;关注当前的热点话题是很重要的。了解最新的技术、行业动向&#xff0c;选择用户普遍关心和讨论的…