[Docker#9] 存储卷 | Volume、Bind、Tmpfs | -v/mount | MySQL 灾难恢复 | 问题

目录

1. 什么是存储卷?

2. 生活案例

3. 为什么需要存储卷?

4. 存储卷分类

一. 管理卷 Volume

创建卷

通过 -v 或 --mount 指定

1. -v 语法

命令格式

参数说明

2. --mount 语法

命令格式

参数说明

验证

二. 绑定卷 (Bind Mount)

1. 绑定卷概述

2. 创建绑定卷

2.1 使用 -v 参数创建绑定卷

2.2 使用 --mount 参数创建绑定卷

3. 操作案例

使用 -v 创建绑定卷

4. 绑定卷共享

三. 临时卷 (tmpfs)

1. 临时卷概述

2. 创建临时卷

方式一:使用 --tmpfs 参数创建

方式二:使用 --mount 参数创建

3. 操作案例

使用 --tmpfs 创建临时卷

四. 运用

MySQL 灾难恢复

实战目的

实战步骤

五. 常见问题

Volume、Bind、Tmpfs 的使用时机

问题

1. 跨主机使用

2. 启动参数未知

3. 复杂场景仍需运维


1. 什么是存储卷?
  • 存储卷是指将宿主机上的某个目录与容器内的某个目录建立绑定关系
  • 这意味着当容器在这个目录下写入数据时,实际上是直接写入宿主机上的对应目录。
  • 存储卷的本质是一个文件或目录,它允许数据绕过容器的联合文件系统,直接存在于宿主机上,从而实现宿主机与容器之间的数据共享。
  • 容器和宿主机的数据读写 是同步的。

2. 生活案例

存储卷就像租用了一个地下室,你可以通过这把“钥匙”(即映射关系)来使用房子外的空间。即使房子(容器)被毁,地下室(存储卷)中的数据仍然安全无损。

3. 为什么需要存储卷?
  • 数据丢失问题:对于需要持久化的数据,容器销毁后其读写层的数据也会丢失。存储卷确保了即使容器被删除,数据也能被保存。
  • 性能问题:UnionFS 对于频繁的读写操作效率较低,而存储卷可以提供更好的I/O性能。
  • 宿主机与容器互访不便:通过存储卷,可以轻松地在宿主机与容器之间共享文件,无需使用 docker cp 命令。
  • 容器间共享不便:存储卷也方便了不同容器间的文件共享。
4. 存储卷分类

Docker提供了三种主要的存储卷类型:

  • volume:由Docker管理,默认映射到 /var/lib/docker/volumes/ 下,适合临时存储。
  • bind mount:映射到宿主机的指定路径,适用于需要精确控制宿主机目录的情况。
  • tmpfs mount:映射到宿主机的内存中,适合需要高速度临时存储的场景.

对于 mount 的理解:

可以类比为将磁盘挂载到操作系统上,操作系统会提供一个访问接口。同样,Docker 的 mount 也是将一个资源(如存储卷)挂载到容器中,并提供一个访问路径。

一. 管理卷 Volume

创建卷

命令操作

  • docker volume create [OPTIONS] [VOLUME]:创建存储卷。
  • docker volume inspect [OPTIONS] VOLUME [VOLUME...]:查看卷的详细信息。
  • docker volume ls [OPTIONS]:列出所有卷。
  • docker volume rm [OPTIONS] VOLUME [VOLUME...]:删除卷。
  • docker volume prune [OPTIONS]:清理所有未使用的卷。

实操:

通过 -v--mount 指定

1. -v 语法
命令格式
docker run -v name:directory[:option]
参数说明
  • name:绑定的现有卷的名称,可以省略,此时会创建一个新的匿名卷。
  • directory:数据卷在容器内部的路径。
  • option:可以指定 ro 表示只读,此时只有宿主机可以修改数据卷,容器只读。

操作:

注意

  • 即使删除容器,存储卷内的内容依然存在。
  • 如果指定存储卷名时,存储卷不存在,Docker 会自动创建一个新的命名卷。新创建的:

2. --mount 语法
命令格式
docker run --mount key=value [key=value ...]
参数说明
  • type:存储卷类型,指定 volume 表示数据卷。
  • src:对于命名卷,表示卷名;对于匿名卷,此字段省略。
  • dst:文件在容器的挂载路径。
  • ro:只读方式挂载。

使用 --mount 创建命名卷

假设我们要创建一个命名卷 test_vm_3 并挂载到 Nginx 容器的 /usr/share/nginx/html 目录下,且设置为只读。

示例

docker run -d --name nginx-read-only --mount type=volume,src=test_vm_3,dst=/usr/share/nginx/html,ro nginx
验证
  1. 进入容器内部:
docker exec -it nginx-read-only /bin/bash
  1. 尝试修改 /usr/share/nginx/html 目录下的文件,会提示 Read-only file system,表示该目录是只读的。

对于管理卷 volume 默认路径的查看

总结:

  • -v 语法:简单直观,适用于快速创建和挂载数据卷。
  • --mount 语法:更加灵活,支持更多选项,适用于复杂场景。
  • 数据卷:无论是命名卷还是匿名卷,都可以实现宿主机与容器之间的数据共享
  • 数据卷在容器删除后依然保留。

二. 绑定卷 (Bind Mount)

1. 绑定卷概述
  • 绑定卷(Bind Mount)是将宿主机上的某个目录直接挂载到容器内的某个目录。
  • 这种方式允许容器和宿主机之间共享文件和目录,且数据直接存储在宿主机的文件系统中。

2. 创建绑定卷

2.1 使用 -v 参数创建绑定卷
  • 功能:完成卷映射。

语法

docker run -v host-dir:container-dir[:options] ...

参数

  • host-dir:宿主机目录,不同于管理卷。
  • container-dir:卷映射到容器的目录。
  • options:选项,如 ro 表示只读。

样例

docker run -d \-it \--name devtest \-v "$(pwd)"/target:/app \nginx:latest
2.2 使用 --mount 参数创建绑定卷
  • 功能:完成目录映射。
  • 语法
docker run --mount 'type=bind,source=host-dir,target=container-dir,readonly'

关键参数

  • type:类型,表示 bind
  • sourcesrc:宿主机目录,不同于管理卷。
  • destinationdsttarget:文件或目录挂载在容器中的路径。
  • roreadonly:只读方式挂载。

样例

docker run -d \-it \--name devtest \--mount type=bind,source="$(pwd)"/target,target=/app \nginx:latest

对比观察:

3. 操作案例

使用 -v 创建绑定卷
  1. 创建容器
docker run -d -p 8080:80 --name bind2 -v /data/myworkdir/fs/webapp2:/usr/share/nginx/html nginx:1.22.1

注意:如果 webapp2 目录不存在,启动不会报错,这是 -v--mount 方式的区别。

  1. 查看挂载信息
docker inspect bind2

输出示例:

  1. 进入容器终端,查看挂载点目录
docker exec -it bind2 ls /usr/share/nginx/html

宿主机上查看:

ll /data/myworkdir/fs/webapp2

容器中的 /usr/share/nginx/html 目录原本存在的文件消失了,这是因为 bind mount 模式会覆盖容器内的原有内容,而 volume 模式则不会。这是两者最大的不同点。

  1. 在宿主机上添加 index.html
echo "Hello bit bind2 mount" > /data/myworkdir/fs/webapp2/index.html

查看:

  1. 通过浏览器访问,可以看到容器已经读取到宿主机的共享内容。
  2. 删除容器,查看宿主机上的文件
docker stop bind2
docker rm bind2
ll /data/myworkdir/fs/webapp2

宿主机上的文件依然存在,说明容器删除并不影响 bind 映射。

4. 绑定卷共享

  1. 启动两个绑定卷,都绑定到宿主机的同一个目录
docker run -d -p 8770:80 --name bind3 -v /data/myworkdir/fs/webapp1:/usr/share/nginx/html nginx:1.22.1
docker run -d -p 7705:80 --name bind4 -v /data/myworkdir/fs/webapp1:/usr/share/nginx/html nginx:1.22.1
  1. 访问两个页面,可以看到相应内容一样:
curl 127.0.0.1:8770
curl 127.0.0.1:7705

查看

  1. 修改 index.html
echo "bind mount after edit" > /data/myworkdir/fs/webapp1/index.html
  1. 再次访问两个页面,可以看到我们实现了容器间的数据共享:
curl 127.0.0.1:8770
curl 127.0.0.1:7705

  1. 清理空间
docker stop bind3
docker rm bind3
docker stop bind4
docker rm bind4

三. 临时卷 (tmpfs)

1. 临时卷概述

临时卷(tmpfs)的数据存储在内存中,不在容器和宿主机的文件系统中。因此,tmpfs 具有以下特点:

  • 数据仅存在于内存中,容器停止后数据会丢失。
  • 不能在容器之间共享 tmpfs 挂载。
  • 仅在 Linux 上运行 Docker 时可用。
2. 创建临时卷
方式一:使用 --tmpfs 参数创建
  • 功能:完成临时卷映射。
  • 语法
--tmpfs /app
  • 样例
docker run -d \-it \--name tmptest \--tmpfs /app \nginx:1.22.1
方式二:使用 --mount 参数创建
  • 功能:完成目录映射。
  • 语法
--mount 'type=tmpfs,destination=/app,tmpfs-size=1m,tmpfs-mode=0770'
  • 关键参数
    • type:类型,表示 tmpfs
    • destinationdsttarget:挂载在容器中的路径。
    • tmpfs-size:tmpfs 挂载的大小(以字节为单位)。默认无限制。
    • tmpfs-mode:tmpfs 的八进制文件模式。例如,700 或 0770。默认为 1777 或全局可写。
  • 样例
docker run -d \-it \--name tmptest \--mount type=tmpfs,destination=/app \nginx:latest

3. 操作案例

使用 --tmpfs 创建临时卷

  1. 创建临时卷并启动容器
docker container run --name tmpfs1 -d -p 80:80 --tmpfs /usr/share/nginx/html nginx:1.22.1

进入容器查看挂载点目录

docker exec -it tmpfs1 bash
cd /usr/share/nginx/html/
ls -l

发现容器中的 /usr/share/nginx/html 目录原本存在的文件被覆盖了。

添加一个首页

echo "Hello bit from tmpfs" > index.html
cat index.html

浏览器查看
访问 http://localhost,可以看到页面显示 "Hello bit from tmpfs"。

说明:

  • 重启容器后可以发现, tmpfs 的内容完全消失了,说明内容是存在内存中的
  • tmpfs 的内容不是存储在容器的可写层中。

总结

  • 临时卷(tmpfs)是一种将数据存储在内存中的方式,适用于需要临时存储数据的场景。
  • tmpfs 的数据在容器停止后会丢失,且不能在容器之间共享。
  • 通过 --tmpfs--mount 参数可以创建 tmpfs 挂载,但需要注意 tmpfs 的大小限制和内存占用。

四. 运用

MySQL 灾难恢复

实战目的

掌握挂载卷的使用,将 MySQL 的业务数据存储到外部,以便在容器故障或服务器重启后能够快速恢复数据。

实战步骤

准备镜像

docker pull mysql:5.7

创建容器

docker container run --name mysql-demo -e MYSQL_ROOT_PASSWORD=bite -itd -v /data/myworkdir/mysql-data:/var/lib/mysql mysql:5.7
  • -e MYSQL_ROOT_PASSWORD=bite:设置 MySQL 的 root 密码。
  • -v /data/myworkdir/mysql-data:/var/lib/mysql:将宿主机的 /data/myworkdir/mysql-data 目录挂载到容器的 /var/lib/mysql 目录。

查看容器挂载信息

docker container inspect mysql-demo | grep "Mounts" -A 10

输出示例:

连接 MySQL 并创建数据库和表

docker container exec -it mysql-demo /bin/bash
bash-4.2# mysql -u root -p

在 MySQL 中执行以下命令:

在宿主机中查看 volume

ll /data/myworkdir/mysql-data/

输出示例:

进入 user 目录查看:

cd /data/myworkdir/mysql-data/user
ll

输出示例:

模拟灾难情况

docker stop mysql-demo
docker rm mysql-demo
  • 假设服务器突然断电,重启后 MySQL 无法启动。
  • 为了节省磁盘空间,删除了所有停止的容器。

恢复数据

docker container run --name mysql-demo-new -e MYSQL_ROOT_PASSWORD=bite -itd -v /data/myworkdir/mysql-data:/var/lib/mysql mysql:5.7
  • 重新启动容器,确保目录映射一致。

验证数据恢复

docker exec -it mysql-demo-new bash
mysql -u root -p
Enter password: bite

在 MySQL 中执行以下命令:

  • 进入新容器并连接 MySQL,发现数据还在~

释放空间

docker stop mysql-demo-new
docker rm mysql-demo-new

五. 常见问题

Volume、Bind、Tmpfs 的使用时机

Volume:

  • 适用场景:当不需要规划具体目录时使用,如日志文件、数据库数据等。
  • 特点:是 Docker 宿主机文件系统的一部分

Bind:

  • 适用场景:当目录需要提前规划时使用,例如 MySQL 数据目录需要较大空间。
  • mysql 的目录需要个空间大的,其他服务有不占用的时候,用 volume 就不太合 适了
  • 特点:依赖于主机的目录结构和操作系统。

Tmpfs:

  • 适用场景:用于存储敏感文件,文件不希望存储在宿主机的可写层或容器内。

问题

1. 跨主机使用
  • 问题: Docker 存储卷默认使用宿主机的本地文件系统,不支持跨主机调度。
  • 解决方案: 可以通过搭建共享存储(如 NFS)来实现跨主机存储,但依赖运维人员能力。
  • 趋势: 应用存储和数据分离,分布式存储方案(如 S3、NFS)逐渐流行。
2. 启动参数未知
  • 问题: 容器启动参数较多,容易忘记。
  • 解决方案: 使用容器编排工具记录启动参数,通过文件读取启动配置。
  • 工具: Kubernetes(k8s)或云厂商的企业版编排软件。
3. 复杂场景仍需运维
  • 问题: 对于有状态且需要持久化的集群化组件(如 MySQL 主从),部署和维护需要丰富的运维经验和知识。
  • 挑战: 需要了解集群规模、节点数量、数据分布等,以便于故障修复和扩展。
  • 现状: 复杂场景仍依赖人力,难以完全自动化。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

CVPR2024-6-可学习点云采样“LTA-PCS: Learnable Task-Agnostic Point Cloud Sampling”

文章摘要: 最近,许多方法直接对不同任务的点云进行操作。当点云尺寸较大时,这些方法的计算量和存储要求更高。为了减少所需的计算和存储,一种可能的解决方案是对点云进行采样。在本文中,我们提出了第一个可学习的与任务…

react + ts定义接口类型写法

接口&#xff08;未进行ts定义&#xff09; export async function UserList(params: {// keyword?: string;current?: number;pageSize?: number;},// options?: { [key: string]: any }, ) {return request<API1.UserList>(http://geek.itheima.net/v1_0/mp/artic…

数据库基础

数据库基础 什么是数据库主流数据库数据库的基本使用连接服务器服务器管理服务器、数据库、表之间的关系数据库基本指令 MySQL架构SQL分类存储引擎什么是存储引擎查看存储引擎存储引擎对比 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库&#xff1f; …

【论文复现】基于标签相关性的多标签学习

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀基于标签相关性的多标签学习 论文概述什么是多标签学习论文贡献 算法流程挖掘“主题“——提取标签相关性训练 &#x1d440; &#x1d447; …

MMCloud+JuiceFS:云端Nextflow工作流的新方案

在云计算和生物信息学领域&#xff0c;执行大规模计算任务时的性能与成本效率至关重要。MemVerge推出的JuiceFlow通过JuiceFS和云端Memory Machine Cloud&#xff08;简称“MMCloud”&#xff09;平台&#xff0c;为Nextflow工作流&#xff08;pipeline&#xff09;提供了一种高…

【Linux】 shell 学习汇总[转载]

转载地址&#xff1a;https://blog.csdn.net/baidu_33718858/article/details/81453835 一些平时使用过程中的知识点积累&#xff0c;来源都附上了博客&#xff0c;添加了一些自己的总结。 感触&#xff1a;linux命令用熟了相当提高工作效率&#xff0c;有时候用Python写十几行…

天云数据联手举办“科学传播沙龙”活动,探讨Sora是否会带来新的科学革命

4月18日&#xff0c;由北京市科协主办&#xff0c;北京科技记协承办&#xff0c;中关村创新研修学院、天云融创数据科技&#xff08;北京&#xff09;有限公司协办的“AIGC塑造数字内容生产新范式”科学传播沙龙在京举办&#xff0c;活动由北京市科协宣传文化部二级调研员、北京…

LlamaIndex+本地部署InternLM实践

1.环境配置 1.1 配置基础环境 这里以在 Intern Studio 服务器上部署 LlamaIndex 为例。 首先&#xff0c;打开 Intern Studio 界面&#xff0c;点击 创建开发机 配置开发机系统 填写 开发机名称 后&#xff0c;点击 选择镜像 使用 Cuda11.7-conda 镜像&#xff0c;然后在资源…

uni-segmented-control 分段器添加数量提示

1、 在 template 内写入 uni-segmented-control 基础写法 <uni-segmented-control :current"current" :values"items" :style-type"styleType" clickItem"onClickItem" activeColor"#81D8D0" />2、在 script 里面写…

Linux篇(用户管理命令)

目录 一、用户与用户组 1. 为什么要做用户与用户组管理 2. Linux的用户及用户组 2.1. Linux的多用户多任务 2.2. 什么是用户 2.3. 什么是用户组 2.4. 用户和用户组的关系 二、用户和用户组管理 1. 用户组管理 1.1. 用户组添加 /etc/group文件结构 1.2. 用户组修改 …

编程之路,从0开始:内存函数

Hello大家好&#xff01;很高兴我们又见面了。 给生活添点passion&#xff0c;开始今天的编程之路&#xff01; 今天我们来讲C语言中的内存函数。 目录 1、memcpy内存复制 2、memmove可重叠内存拷贝 3、memset设置字符 4、memcmp比较 1、memcpy内存复制 memcpy就是内存复制…

PyCharm 中的【控制台】和【终端】的区别

pycharm专业版-使用 PyCharm 中的【控制台】和【终端】的区别如下&#xff1a; 1.环境&#xff1a;控制台是 PyCharm 的内部环境&#xff0c; 终端 是操作系统的命令行界面。 2.功能&#xff1a;控制台可以运行 Python 代码&#xff0c;并显示执行结果&#xff1b; 终端可以…

IDEA修改注释颜色—图文教程

老的注释颜色用习惯了&#xff0c;新电脑的灰色注释不习惯&#xff0c;还是喜欢黄色哈哈哈哈&#x1f923;&#x1f923;&#x1f923; Block comment &#xff1a; 多行注释 Doc comment&#xff1a;文档注释 Line comment&#xff1a;单行注释 小伙伴们可以改自己喜欢的颜色…

C++ String(2)

reserve 这个地方要和reverse区分清楚&#xff0c;reserve是保留的意思&#xff0c;而reverse是逆置的意思 reserve函数可以预先分配内存 reserve(n)代表至少保留可以容纳n个字符的空间&#xff08;具体多大和编译器有关&#xff09; 比如reserve(100)&#xff0c;代表开10…

网络基础Linux

目录 计算机网络背景 网络发展 认识 "协议" 网络协议初识 OSI七层模型 TCP/IP五层(或四层)模型 网络传输基本流程 网络传输流程图 ​编辑 数据包封装和分用 网络中的地址管理 认识IP地址 认识MAC地址 笔记&#xff08;画的图&#xff09; 协议&#x…

干货 | WiFi 7(802.11BE)技术规范详解

1 概述 1.1 简介 当前全球有近200亿的Wi-Fi设备正在使用&#xff0c;Wi-Fi已成为生活、工作中不可或缺的一部分。在实际应用中&#xff0c;Wi-Fi协议所传输无线流量&#xff0c;已占到无线总流量的90%。海量数据快速、安全传输受益于巨量Wi-Fi设备高效、安全、可靠地工作&a…

线程的状态

目录 一、线程的所有状态 二、状态转换 三、多线程初体验 一、线程的所有状态 状态是针对当前线程调度情况所描述的&#xff0c;又因为线程是调度的基本单位&#xff0c;所以我们所谈到的状态都是线程的属性。在java里对线程的状态&#xff0c;进行了一个更细的划分。 我们可…

基于SpringBoot网上超市的设计与实现录像

基于SpringBoot网上超市的设计与实现录像 SpringBoot网上超市的设计与实现录像

认证鉴权框架SpringSecurity-3--代码集成_认证篇1(重写UserDetailsService示例)

上一篇介绍了springSecurity中常用的组件和过滤器链&#xff0c;明白了springSecurity管理认证和授权的基本过程和所用到的组件。之后几篇我们通过在Java代码集成springSecurity&#xff0c;来学习下代码上认证是如何实现的。 代码上常用的认证方式有两种&#xff0c;一种是实现…

C语言操作符终极揭秘:表达式求值秘籍

C语言中操作符详解&#xff08;终结篇&#xff09; 放在最前面的表达式求值定义&#xff08;1&#xff09; 操作数的求值&#xff08;2&#xff09; 操作符的应用&#xff08;3&#xff09;类型转换&#xff08;3.1&#xff09;隐式类型转换&#xff08;Type Promotion&#xf…