Docker Volume

"Ice in my vein" 


Docker Volume(存储卷)

什么是存储卷?

        存储卷就是: “将宿主机的本地文件系统中存在的某个目录,与容器内部的文件系统上的某一目录建立绑定关系”。

存储卷与容器本身的联合文件系统?

        在宿主机上的这个与容器形成绑定关系的目录被称作“存储卷”。而这个卷的本质就是文件或者目录,它可以绕过默认的联合文件系统,直接以文件或目录的形式存在于宿主机上。

        使得可以在宿主机和容器内共享数据库内容让容器直接访问宿主机中的内容,也可以宿主机向容器写入内容,容器和宿主机的数据读写是同步的

        

为什么需要存储卷?

        存储卷技术的产生,主要来源于解决四个问题的需求。

✨ 数据丢失

容器按照业务类型,总体可以分为两类:

• 无状态(数据不需要被持久化)

• 有状态(数据需要被持久化)

        显然,容器更擅长无状态应用。因为,容器根目录的生命周期,同容器的生命周期一样。容器文件系统的本质是在镜像层上面创建的读写层,运行中的容器对任何文件的修改都存在于该读写层,当容器被删除时,容器中的读写层也会随之消失。 

        但实际业务总是有各种需要数据持久化的场景: 比如 MySQLKafka 等有状态的业务。所以,Docker 提出了卷(volume)的概念

✨ 性能问题

        UnionFS 对于修改删除等,一般效率非常低。

✨  宿主机和容器互访不方便
宿主机访问容器,或者容器访问要通过 docker cp 来完成,应用很难操作。
✨  容器和容器共享不方便
两个容器内部不同的目录,同时绑定宿主机上的某一目录,就可以实现数据共享。

        

存储卷分类

        目前 Docker 提供了三种方式将数据从宿主机挂载到容器中:

🩰 volume docker 管理卷

🩰 bind mount 绑定数据卷

🩰 tmpfs mount 临时数据卷

        下图表示三类存储卷,在Docker存储卷中的结构:


存储卷详解

管理卷 Volume

        docker管理卷默认映射到宿主机的 /var/lib/docker/volumes(如果修改了默认目录,就不是这条路径)目录下,只需要在容器内指定要挂在点是什么。容器引擎daemon会自行创建一个空的目录在被绑定的宿主机目录下。或者使用一个已经存在的目录,与存储卷建立存储关系。

        这种方式极大解脱用户在使用卷时的耦合关系,缺陷是用户无法指定那些使用目录,临时存储比较适合。

创建卷:

        存储卷可以通过命令方式创建,也可以通过在创建容器的时候通过 -v and --mount 指定。

方法一:Volume 命令操作    

        操作docker管理卷的命令清单如下:

命令别名功能
docker volume create创建存储卷
docker volume inspect显示存储卷的详细信息
docker volume lsdocker volume list列出存储卷
docker volume prune清理无用的存储卷
docker volume rm删除存储卷

🎱 docker volume create

语法:

# 创建存储卷
docker volume create [OPTIONS] [VOLUME]OPTIONS:
-d, --driver:指定驱动,默认是 local
--label:指定元数据

🎱 docker volume inspect

语法:

# 查看卷详细信息
docker volume inspect [OPTIONS] VOLUME [VOLUME...]OPTIONS:
-f:指定相应个格式

🎱 docker volume ls

语法:

# 列出卷
docker volume ls [OPTIONS]OPTIONS:
--format:指定相应个格式
--filter,-f: 过滤
-q: 仅显示名称    

🎱 docker volume rm

语法:

# 删除卷,需要容器不使用    
ocker volume rm [OPTIONS] VOLUME [VOLUME...]OPTIONS:
-f,--force:强制删除

🎱 docker volume prune

语法:

# 删除不使用的本地卷
docker volume prune [OPTIONS]OPTIONS:
--filter:过滤
-f, --force :不提示是否删除
方法二: -v 或者 --mount 指定
# -v参数 完成目录映射
docker run -v name:directory[:options]ARGS:
name:卷名称
directory:卷映射到容器的目录
options:如 ro 表示 readonly

# --mount 参数--mount '<key>=<value>,<key>=<value>'ARGS:
type:类型表示 bind, volume, or tmpfs
source\src :对于命名卷,这是卷的名称。[对于匿名卷,省略此字段]
destination\dst\target:文件或目录挂载在容器中的路径
ro,readonly: 只读方式挂载
方法三: Dockerfile 匿名卷

        通过Dockerfile的VOLUME可以创建docker管理卷。但不在本篇细说。

操作案例:

Docker 命令创建管理卷

        使用 "docker create" 创建一个名为 "test_volume"的存储卷:

        输入 "docker volume ls" 查看我们创建的存储卷: 

       检查存储卷的内部信息“docker volume inspect”:

        我们现在访问这个目录:

        此时可以发现,该目录是被自动创建的空目录。

        我们给该存储卷分配给一个nginx容器时,就会发现:

        宿主机和容器之间数据是同步的

Docker -v 创建管理卷

        -v 创建管理卷,并且启动容器:

docker run --name nginx1 -d -p 80:80 -vtest_volume:/usr/share/nginx/html:ro nginx:1.24.0

        进入卷的目录:

        我们看到,创建docker管理卷后,宿主机的目录同容器目录文件实际是共享的~我们可以借此修改index.html文件:

        这是修改前的原Nginx首页:

        修改后(注:我们是在宿主机的目录,对这个首页文件进行修改):

        我们再次进入docker容器中,看看修改容器内的文件后,宿主机会不会更新:

        我们会发现,在容器内部是不能对该关联目录内的文件进行修改的!答案是,我们在创建管理卷的时候,设置了“ro”参数 —— 所以,这个ro参数针对的对象是,谨防从容器内部对文件进行修改!

        最后,我们再清理释放空间。

        指定 ro 的话宿主机可以修改,但是容器里面无法修改

Docker mount 创建管理卷

        mount 创建管理卷,并且启动容器:

docker run -d -p 80:80 --name nginx 
--mount    type=volume,source=test_volume,target=/usr/share/nginx/html nginx:latestARGS:
type有很多: volume表示管理存储卷 bind表示绑定存储卷 tmpfs表示临时存储卷

        查看卷、容器创建成功:

        查看卷挂载点:

Docker 卷生命周期

        我们继续上接前文,为一个nginx容器创建了一个存储卷,我们可以在容器内、宿主机上找到这个存储卷同步的内容:

        当我们将容器删除时:

        存储卷的内容还是存在的,如果此时我们使用命令删除存储卷时,存储卷的内容就会被彻底清空:        

Docker 卷共享

        -v 创建管理卷,并且启动 2 容器,指定同一个存储卷。

docker container run --name nginx1 -d -p 80:80 -v mutual_volume:/usr/share/nginx/html nginx:1.24.0
docker container run --name nginx2 -d -p 81:80 -v mutual_volume:/usr/share/nginx/html nginx:1.23.0

        观察存储卷信息修改 index.html:

        观察容器内部的文件,发现都是同一份:

绑定卷 bind mount

        绑定数据卷,需要人工在宿主机上指定一个特定路径,在容器中指定一个特定路径,再建立这两个特定路径的关联。

        与管理卷不同,绑定卷的有些参数是不一样的。

docker run -v name:directory[:options]ARGS:
name:宿主机目录,这个和管理卷是不一样的
--mount '<key>=<value>,<key>=<value>'ARGS:
source\src: 宿主机目录,这个和管理卷是不一样的

        其余参数都大差不差,咱们在这儿就不多费舌,直接上操作案例。

操作案例: 

--mount 创建管理卷

        使用-mount 方式创建容器:

        创建 nginx 容器,并将宿主机 “/webapp” 目录挂载至容器“/usr/share/nginx/html”目录。

注:如果这个目录不存在,就会报错

docker run -d -p 80:80 --name bind 
--mounttype=bind,source=/data/webapp,target=/usr/share/nginx/html nginx:1.23.0# source:人为指定路径

        查看挂载信息:

 docker inspect bind

        进入容器的终端,查看挂载点目录,和在宿主机上查看里面都是没有文件:

         这是 bind mount 模式和 volume 模式最大的不同点!!
我们在宿主机上添加 index.html,通过浏览器,我们可以访问到这个文件内容:
删除容器,然后查看宿主机上的文件 , 还是存在,说明容器删除并不影响 bind 映射。

-v 创建绑定卷

        使用-v 方式创建容器: 创建 nginx 容器:

        并将宿主机/webapp2 目录挂载至容器 /usr/share/nginx/html 目录。注:当目录不存在时,仍然会报错。

docker run -d -p 80:80 --name bind -v /data/webapp2:/usr/share/nginx/html nginx:1.23.0

        查看挂在信息:

        后面的演示情况可以参照 使用 --mount方式创建的存储卷。

绑定卷共享

        我们启动两个绑定卷,都绑定到宿主机的同一个目录:

        我们使用本机回环,这两个容器看到的内容是一样的。

临时卷 tmpfs

        临时卷数据位于内存中,在容器和宿主机之外。映射到于宿主机内存中,一旦容器停止运行,tmpfs mounts就会被移除,数据就会丢失,用于高性能的临时数据存储。

tmpfs 局限性:     

🪀 不同于卷和绑定挂载,不能在容器之间共享 tmpfs 挂载

🪀 这个功能只有在 Linux 上运行 Docker 时才可用

创建卷:

方式一: 指定--tmpfs 创建
--tmpfs /path
方式二:--mount 指定参数创建
--mount '<key>=<value>,<key>=<value>'OPTIONS:
destination,dst,target:挂载在容器中的路径
tmpfs-size:tmpfs 挂载的大小(以字节为单位)。默认无限制
tmpfs-mode:tmpfs 的八进制文件模式。例如,700 或 0770。默认为 1777或全局可写

操作案例:

tmpfs 参数创建临时卷

        创建临时卷并启动容器

docker container run --name tmpfs -d -p 80:80 --tmpfs /usr/share/nginx/html/ nginx:latest

        进入容器可以看到 nginx 里面的文件被覆盖了,也就是说 tmpfs 也会覆盖容器里面的文件。绑定卷也是如此。

        添加一个首页:

         我们可以在浏览器中查看:

        我们现在重启容器,发现之前的文件不存在了!

mount 创建临时卷

        创建临时卷并启动容器:

docker container run --name tmpfs -d -p 80:80 
--mounttype=tmpfs,target=/usr/share/nginx/html,tmpfs-size=1m nginx:1.23.0

        添加一个首页:

tmp-size: 

        拷贝一个大文件到容器里面:

        拷贝文件到我们的卷目录,超过了限制(tmpfs-size),空间限制为了 1m,会提示没有空间。 

tmpfs 失踪了

        创建一个普通的容器:

docker run -d -it --name tmpfs nginx:1.23.0 

        在容器里面写入一个文件 mylabel.txt:

        我们在宿主机上查找文件,文件被找到了,是因为他在容器的可写层:

        我们再创建个临时卷:

docker run -d --name tmpfs2 --tmpfs /app nginx:1.24.0

        进入容器,/app 目录下创建 mynewlabel.txt。

        在宿主机上查找 mynewlabel.txt,可以发现,文件找不到。

         所以 tmpfs 的内容不是存储在我们的容器的可写层里面的。更加进一步佐证其存储的位置是在内存上。


本篇到此结束,感谢你的阅读。

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

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

相关文章

实用区块链应用:去中心化投票系统的部署与实施

一、需求分析背景 随着技术的发展&#xff0c;传统的投票系统面临着越来越多的挑战&#xff0c;如中心化控制、透明度不足和易受攻击等问题。为了解决这些问题&#xff0c;我们可以利用区块链技术去中心化、透明性和安全性来构建一个去中心化投票系统。这样的系统能够确保投票过…

vue2.0及起步(前端面试知识积累)

1、需要了解的vue概要知识 1、vue是什么&#xff1f; 一套用于构建用户界面的渐进式JavaScript框架。 为什么vue被称为是渐进式JS框架&#xff1f; 答&#xff1a;Vue允许开发者在不同的项目中以渐进式的方式使用它&#xff0c;这种渐进式表现在以下的方面&#xff1a; 逐步采…

数据可视化--了解数据可视化和Excel数据可视化

目录 1.1科学可视化&#xff1a; 可视化是模式、关系、异常 1.2三基色原理&#xff1a; 三基色:红色、绿色和蓝色 1.3Excel数据可视化 1.3.1 excel数据分析-13个图表可视化技巧 1.3.2 excel数据分析-28个常用可视化图表&#xff08;video&#xff09; 1.3.3Excel可视化…

Java面试——锁

​ 公平锁&#xff1a; 是指多个线程按照申请锁的顺序来获取锁&#xff0c;有点先来后到的意思。在并发环境中&#xff0c;每个线程在获取锁时会先查看此锁维护的队列&#xff0c;如果为空&#xff0c;或者当前线程是等待队列的第一个&#xff0c;就占有锁&#xff0c;否则就会…

Apache Doris 发展历程、技术特性及云原生时代的未来规划

本文节选自《基础软件之路&#xff1a;企业级实践及开源之路》一书&#xff0c;该书集结了中国几乎所有主流基础软件企业的实践案例&#xff0c;由 28 位知名专家共同编写&#xff0c;系统剖析了基础软件发展趋势、四大基础软件&#xff08;数据库、操作系统、编程语言与中间件…

js里面有引用传递吗?

一&#xff1a;什么是引用传递 引用传递是相对于值传递的。那什么是值传递呢&#xff1f;值传递就是在传递过程中再复制一份&#xff0c;然后再赋值给变量&#xff0c;例如&#xff1a; let a 2; let b a;在这个代码中&#xff0c;let b a; 就是一个值传递&#xff0c;首先…

深度学习手写字符识别:推理过程

说明 本篇博客主要是跟着B站中国计量大学杨老师的视频实战深度学习手写字符识别。 第一个深度学习实例手写字符识别 深度学习环境配置 可以参考下篇博客&#xff0c;网上也有很多教程&#xff0c;很容易搭建好深度学习的环境。 Windows11搭建GPU版本PyTorch环境详细过程 数…

设计模式(十) - 工厂方式模式

前言 在此前的设计模式&#xff08;四&#xff09;简单工厂模式中我们介绍了简单工厂模式&#xff0c;在这篇文章中我们来介绍下工厂方法模式&#xff0c;它同样是创建型设计模式&#xff0c;而且又有些类似&#xff0c;文章的末尾会介绍他们之间的不同。 1.工厂方法模式简介 …

小程序性能优化

背景 在开发小程序的过程中我们发现&#xff0c;小程序的经常会遇到性能问题&#xff0c;尤其是在微信开发者工具的时候更是格外的卡&#xff0c;经过排查发现&#xff0c;卡顿的页面有这么多的js代码需要加载&#xff0c;而且都是在进入这个页面的时候加载&#xff0c;这就会…

面试redis篇-10Redis集群方案-主从复制

在Redis中提供的集群方案总共有三种: 主从复制哨兵模式分片集群主从复制 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。 主从数据同步原理 Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每…

React18源码: Fiber树的初次创建过程图文详解

fiber树构造&#xff08;初次创建&#xff09; fiber树构造的2种情况&#xff1a; 1.初次创建 在React应用首次启动时&#xff0c;界面还没有渲染此时并不会进入对比过程&#xff0c;相当于直接构造一棵全新的树 2.对比更新 React应用启动后&#xff0c;界面已经渲染如果再次发…

软考45-上午题-【数据库】-数据操纵语言DML

一、INSERT插入语句 向SQL的基本表中插入数据有两种方式&#xff1a; ①直接插入元组值 ②插入一个查询的结果值 1-1、直接插入元组值 【注意】&#xff1a; 列名序列是可选的&#xff0c;若是所有列都要插入数值&#xff0c;则可以不写列名序列。 示例&#xff1a; 1-2、插…

跟着cherno手搓游戏引擎【26】Profile和Profile网页可视化

封装Profile&#xff1a; Sandbox2D.h:ProfileResult结构体和ProfileResult容器&#xff0c;存储相应的信息 #pragma once #include "YOTO.h" class Sandbox2D :public YOTO::Layer {public:Sandbox2D();virtual ~Sandbox2D() default;virtual void OnAttach()ove…

微信小程序的医院体检预约管理系统springboot+uniapp+python

本系统设计的目的是建立一个简化信息管理工作、便于操作的体检导引平台。共有以下四个模块&#xff1a; uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 语言&#xff1a;pythonjavanode.js…

React Hooks概述及常用的React Hooks介绍

Hook可以让你在不编写class的情况下使用state以及其他React特性 useState ● useState就是一个Hook ● 通过在函数组件里调用它来给组件添加一些内部state,React会在重复渲染时保留这个state 纯函数组件没有状态&#xff0c;useState()用于设置和使用组件的状态属性。语法如下…

传统推荐算法库使用--mahout初体验

文章目录 前言环境准备调用混合总结 前言 郑重声明&#xff1a;本博文做法仅限毕设糊弄老师使用&#xff0c;不建议生产环境使用&#xff01;&#xff01;&#xff01; 老项目缝缝补补又是三年&#xff0c;本来是打算直接重写写个社区然后给毕设使用的。但是怎么说呢&#xff…

【ArcGIS】基于DEM/LUCC等数据统计得到各集水区流域特征

基于DEM/LUCC等数据统计得到各集水区流域特征 提取不同集水区各类土地利用类型比例步骤1&#xff1a;划分集水区为独立面单元步骤2&#xff1a;批量掩膜提取得到各集水区土地利用类型比例步骤3&#xff1a;导入各集水区LUCC数据并统计得到各类型占比 提取坡度特征流域面坡度河道…

现在学Oracle是49年入国军么?

今天周末&#xff0c;不聊技术&#xff0c;聊聊大家说的最多的一个话题 先说明一下&#xff0c;防止挨喷&#x1f606; 本人并不是职业dba&#xff0c;对数据库就是爱好&#xff0c;偶尔兼职&#xff0c;以下仅个人观点分析&#xff0c;如有不同观点请轻喷&#xff0c;哈哈&…

JSP实现数据传递与保存(一)

一、Web开发步骤 1.1两类模式 后端——————前端 先有前端&#xff0c;前端用的时候直接调用 后端已实现注册接口&#xff0c;接口名为doRegister.jsp 前端此时&#xff1a; 前端的form表单中的action提交地址就只能填doRegister.jsp&#xff0c;即&#xff1a; <f…

设计模式——抽象工厂模式

定义: 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;提供一个创建一系列或相互依赖对象的接口&#xff0c;而无须指定它们具体的类。 概述:一个工厂可以提供创建多种相关产品的接口&#xff0c;而无需像工厂方法一样&#xff0c;为每一个产品都提供一个具体…