当前位置: 首页 > article >正文

Docker-数据卷

1.数据卷

容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。大家思考几个问题:

  • 如果要升级MySQL版本,需要销毁旧容器,那么数据岂不是跟着被销毁了?

  • MySQL、Nginx容器运行后,如果我要修改其中的某些配置该怎么办?

  • 我想要让Nginx代理我的静态资源怎么办?

因此,容器提供程序的运行环境,但是程序运行产生的数据、程序运行依赖的配置都应该与容器解耦

2.什么是数据卷

数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁。

以Nginx为例,我们知道Nginx中有两个关键的目录:

  • html:放置一些静态资源

  • conf:放置配置文件

如果我们要让Nginx代理我们的静态资源,最好是放到html目录;如果我们要修改Nginx的配置,最好是找到conf下的nginx.conf文件。

但遗憾的是,容器运行的Nginx所有的文件都在容器内部。所以我们必须利用数据卷将两个目录与宿主机目录关联,方便我们操作。如图:

在上图中:

  • 我们创建了两个数据卷:confhtml

  • Nginx容器内部的conf目录和html目录分别与两个数据卷关联。

  • 而数据卷conf和html分别指向了宿主机的/var/lib/docker/volumes/conf/_data目录和/var/lib/docker/volumes/html/_data目录

这样以来,容器内的confhtml目录就 与宿主机的confhtml目录关联起来,我们称为挂载。此时,我们操作宿主机的/var/lib/docker/volumes/html/_data就是在操作容器内的/usr/share/nginx/html/_data目录。只要我们将静态资源放入宿主机对应目录,就可以被Nginx代理了。

小提示

/var/lib/docker/volumes这个目录就是默认的存放所有容器数据卷的目录,其下再根据数据卷名称创建新目录,格式为/数据卷名/_data

为什么不让容器目录直接指向宿主机目录呢?

  • 因为直接指向宿主机目录就与宿主机强耦合了,如果切换了环境,宿主机目录就可能发生改变了。由于容器一旦创建,目录挂载就无法修改,这样容器就无法正常工作了。

  • 但是容器指向数据卷,一个逻辑名称,而数据卷再指向宿主机目录,就不存在强耦合。如果宿主机目录发生改变,只要改变数据卷与宿主机目录之间的映射关系即可。

不过,我们通过由于数据卷目录比较深,不好寻找,通常我们也允许让容器直接与宿主机目录挂载而不使用数据卷 。

3.数据卷命令

数据卷的相关命令有:

命令说明文档地址
docker volume create创建数据卷docker volume create
docker volume ls查看所有数据卷docs.docker.com
docker volume rm删除指定数据卷docs.docker.com
docker volume inspect查看某个数据卷的详情docs.docker.com
docker volume prune清除数据卷docker volume prune

注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建

演示环节:演示一下nginx的html目录挂载

# 1.首先创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx
​
# 2.然后查看数据卷
docker volume ls
# 结果
DRIVER    VOLUME NAME
local     29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f
local     html
​
# 3.查看数据卷详情
docker volume inspect html
# 结果
[{"CreatedAt": "2024-05-17T19:57:08+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/html/_data","Name": "html","Options": null,"Scope": "local"}
]
​
# 4.查看/var/lib/docker/volumes/html/_data目录
ll /var/lib/docker/volumes/html/_data
# 可以看到与nginx的html目录内容一样,结果如下:
总用量 8
-rw-r--r--. 1 root root 497 12月 28 2021 50x.html
-rw-r--r--. 1 root root 615 12月 28 2021 index.html
​
# 5.进入该目录,并随意修改index.html内容
cd /var/lib/docker/volumes/html/_data
vi index.html
​
# 6.打开页面,查看效果
​
# 7.进入容器内部,查看/usr/share/nginx/html目录内的文件是否变化
docker exec -it nginx bash

演示环节:演示一下MySQL的匿名数据卷

# 1.查看MySQL容器详细信息
docker inspect mysql
# 关注其中.Config.Volumes部分和.Mounts部分

我们关注两部分内容,第一是.Config.Volumes部分:

{"Config": {// ... 略"Volumes": {"/var/lib/mysql": {}}// ... 略}
}

可以发现这个容器声明了一个本地目录,需要挂载数据卷,但是数据卷未定义。这就是匿名卷。

然后,我们再看结果中的.Mounts部分:

{"Mounts": [{"Type": "volume","Name": "29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f","Source": "/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data","Destination": "/var/lib/mysql","Driver": "local",}]
}

可以发现,其中有几个关键属性:

  • Name:数据卷名称。由于定义容器未设置容器名,这里的就是匿名卷自动生成的名字,一串hash值。

  • Source:宿主机目录

  • Destination : 容器内的目录

上述配置是将容器内的/var/lib/mysql这个目录,与数据卷29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f挂载。于是在宿主机中就有了/var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data这个目录。这就是匿名数据卷对应的目录,其使用方式与普通数据卷没有差别。

接下来,可以查看该目录下的MySQL的data文件:

ls -l /var/lib/docker/volumes/29524ff09715d3688eae3f99803a2796558dbd00ca584a25a4bbc193ca82459f/_data

注意:每一个不同的镜像,将来创建容器后内部有哪些目录可以挂载,可以参考DockerHub对应的页面

4.挂载本地目录或文件

可以发现,数据卷的目录结构较深,如果我们去操作数据卷目录会不太方便。在很多情况下,我们会直接将容器目录与宿主机指定目录挂载。挂载语法与数据卷类似:

# 挂载本地目录
-v 本地目录:容器内目录
# 挂载本地文件
-v 本地文件:容器内文件

注意:本地目录或文件必须以 /./开头,如果直接以名字开头,会被识别为数据卷名而非本地目录名。

例如:

-v mysql:/var/lib/mysql # 会被识别为一个数据卷叫mysql,运行时会自动创建这个数据卷
-v ./mysql:/var/lib/mysql # 会被识别为当前目录下的mysql目录,运行时如果不存在会创建目录

演示,删除并重新创建mysql容器,并完成本地目录挂载:

  • 挂载/root/mysql/data到容器内的/var/lib/mysql目录

  • 挂载/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录(初始化的SQL脚本目录)

  • 挂载/root/mysql/conf到容器内的/etc/mysql/conf.d目录(这个是MySQL配置文件目录)

在资料中已经准备好了mysql的init目录和conf目录:

以及对应的初始化SQL脚本和配置文件:

其中,hm.cnf主要是配置了MySQL的默认编码,改为utf8mb4;而hmall.sql则是后面我们要用到的黑马商城项目的初始化SQL脚本。

我们直接将整个mysql目录上传至虚拟机的/root目录下:

接下来,我们演示本地目录挂载:

# 1.删除原来的MySQL容器
docker rm -f mysql# 2.进入root目录
cd ~# 3.创建并运行新mysql容器,挂载本地目录
docker run -d \--name mysql \-p 3306:3306 \-e TZ=Asia/Shanghai \-e MYSQL_ROOT_PASSWORD=123 \-v ./mysql/data:/var/lib/mysql \-v ./mysql/conf:/etc/mysql/conf.d \-v ./mysql/init:/docker-entrypoint-initdb.d \mysql# 4.查看root目录,可以发现~/mysql/data目录已经自动创建好了
ls -l mysql
# 结果:
总用量 4
drwxr-xr-x. 2 root    root   20 5月  19 15:11 conf
drwxr-xr-x. 7 polkitd root 4096 5月  19 15:11 data
drwxr-xr-x. 2 root    root   23 5月  19 15:11 init# 查看data目录,会发现里面有大量数据库数据,说明数据库完成了初始化
ls -l data# 5.查看MySQL容器内数据
# 5.1.进入MySQL
docker exec -it mysql mysql -uroot -p123
# 5.2.查看编码表
show variables like "%char%";
# 5.3.结果,发现编码是utf8mb4没有问题
+--------------------------+--------------------------------+
| Variable_name            | Value                          |
+--------------------------+--------------------------------+
| character_set_client     | utf8mb4                        |
| character_set_connection | utf8mb4                        |
| character_set_database   | utf8mb4                        |
| character_set_filesystem | binary                         |
| character_set_results    | utf8mb4                        |
| character_set_server     | utf8mb4                        |
| character_set_system     | utf8mb3                        |
| character_sets_dir       | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+# 6.查看数据
# 6.1.查看数据库
show databases;
# 结果,hmall是黑马商城数据库
+--------------------+
| Database           |
+--------------------+
| hmall              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
# 6.2.切换到hmall数据库
use hmall;
# 6.3.查看表
show tables;
# 结果:
+-----------------+
| Tables_in_hmall |
+-----------------+
| address         |
| cart            |
| item            |
| order           |
| order_detail    |
| order_logistics |
| pay_order       |
| user            |
+-----------------+
# 6.4.查看address表数据
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
| id | user_id | province | city   | town     | mobile      | street        | contact   | is_default | notes |
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
| 59 |       1 | 北京     | 北京   | 朝阳区    | 13900112222 | 金燕龙办公楼   | 李佳诚    | 0          | NULL  |
| 60 |       1 | 北京     | 北京   | 朝阳区    | 13700221122 | 修正大厦       | 李佳红    | 0          | NULL  |
| 61 |       1 | 上海     | 上海   | 浦东新区  | 13301212233 | 航头镇航头路   | 李佳星    | 1          | NULL  |
| 63 |       1 | 广东     | 佛山   | 永春      | 13301212233 | 永春武馆       | 李晓龙    | 0          | NULL  |
+----+---------+----------+--------+----------+-------------+---------------+-----------+------------+-------+
4 rows in set (0.00 sec)

相关文章:

Docker-数据卷

1.数据卷 容器是隔离环境,容器内程序的文件、配置、运行时产生的容器都在容器内部,我们要读写容器内的文件非常不方便。大家思考几个问题: 如果要升级MySQL版本,需要销毁旧容器,那么数据岂不是跟着被销毁了&#xff1…...

在Linux系统下修改Docker的默认存储路径

在Linux系统下修改Docker的默认存储路径可以通过多种方法实现,下边是通过修改daemon.json文件方式实现 查看当前Docker存储路径 使用命令 docker info | grep "Docker Root Dir" 查看当前Docker的存储路径,默认为 /var/lib/docker 停止Docker…...

IT : 是工作還是嗜好? Delphi 30周年快乐!

又到2月14日了, 自从30多年前收到台湾宝蓝(Borland)公司一大包的3.5 磁盘片, 上面用黑色油性笔写着Delphi Beta开始, Delphi便和我的工作生涯有了密不可分的关系. 一年后Delphi大获成功, 自此对于使用Delphi的使用者来说2月14日也成了一个特殊的日子! 我清楚记得Delphi Beta使用…...

DeepPose

目录 摘要 Abstract DeepPose 算法框架 损失函数 创新点 局限性 训练过程 代码 总结 摘要 DeepPose是首个将CNN应用于姿态估计任务的模型。该模型在传统姿态估计方法的基础上,通过端到端的方式直接从图像中回归出人体关键点的二维坐标,避免了…...

[HarmonyOS]鸿蒙(添加服务卡片)推荐商品 修改卡片UI(内容)

什么是服务卡片 ? 鸿蒙系统中的服务卡片(Service Card)就是一种轻量级的应用展示形式,它可以让用户在不打开完整应用的情况下,快速访问应用内的特定功能或信息。以下是服务卡片的几个关键点: 轻量级&#…...

DeepSeek R1 本地部署和知识库搭建

一、本地部署 DeepSeek-R1,是幻方量化旗下AI公司深度求索(DeepSeek)研发的推理模型 。DeepSeek-R1采用强化学习进行后训练,旨在提升推理能力,尤其擅长数学、代码和自然语言推理等复杂任务 。 使用DeepSeek R1, 可以大大…...

领域驱动设计叕创新,平安保险申请DDD专利

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 见下图: 这个名字拼得妙:领域驱动设计模式。 是领域驱动设计?还是设计模式?还是领域驱动设计设计模式?和下面这个知乎文章的…...

团体程序设计天梯赛-练习集——L1-041 寻找250

前言 10分的题,主要的想法就一个,按这个想法可以出几个写法 L1-041 寻找250 对方不想和你说话,并向你扔了一串数…… 而你必须从这一串数字中找到“250”这个高大上的感人数字。 输入格式: 输入在一行中给出不知道多少个绝对值…...

动量突破均值回归策略

动量突破均值回归策略:量化交易中的双剑合璧 引言 在量化交易的世界中,动量策略和均值回归策略是两种经典且广泛应用的策略。动量策略基于“强者恒强”的理念,认为过去表现良好的资产在未来一段时间内仍会继续表现良好;而均值回…...

vue3.x 的provide 与 inject详细解读

在 Vue 3.x 中,provide 和 inject 是一对用于实现依赖注入的 API。它们允许父组件向其所有子组件(无论嵌套多深)传递数据或方法,而不需要通过 props 逐层传递。这在开发复杂组件或高阶组件时非常有用。 1. provide 的基本用法 p…...

C#控制台大小Console.SetWindowSize函数失效解决

在使用C#修改控制台大小相关API会失效. 由于VS将控制台由命令提示符变成了终端,因此在设置大小时会出现问题 测试代码: Console.SetWindowSize(100, 50);...

spring boot 对接aws 的S3 服务,实现上传和查询

1.aws S3介绍 AWS S3(Amazon Simple Storage Service)是亚马逊提供的一种对象存储服务,旨在提供可扩展、高可用性和安全的数据存储解决方案。以下是AWS S3的一些主要特点和功能: 1.1. 对象存储 对象存储模型:S3使用…...

25/2/16 <算法笔记> DirectPose

DirectPose 是一种直接从图像中预测物体的 6DoF(位姿:6 Degrees of Freedom)姿态 的方法,包括平移和平面旋转。它在目标检测、机器人视觉、增强现实(AR)和自动驾驶等领域中具有广泛应用。相比于传统的位姿估…...

数据结构-8.Java. 七大排序算法(下篇)

本篇博客给大家带来的是排序的知识点, 由于时间有限, 分两天来写, 下篇主要实现最后一种排序算法: 归并排序。同时把中篇剩下的快排非递归实现补上. 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是…...

缓存穿透、缓存击穿、缓存雪崩的区别与解决方案

1. 缓存穿透(Cache Penetration) 定义:大量请求查询 数据库中不存在的数据,导致请求绕过缓存直接访问数据库,造成数据库压力过大。 场景: 恶意攻击:例如用不存在的用户ID频繁请求。 业务误操作…...

DeepSeek私有化部署+JAVA通过API调用离线大模型问答

在当今快速发展的数字化时代,企业对于高效、灵活的技术解决方案需求日益增长。DeepSeek作为一款领先的智能搜索与分析平台,凭借其强大的数据处理能力和精准的搜索结果,已经成为众多企业提升运营效率的得力助手。为了更好地满足企业对数据安全…...

【go语言规范】Gopherfest 2015 | Go Proverbs with Rob Pike的 总结

根据 Gopherfest 2015 | Go Proverbs with Rob Pike 的演讲,总结内容如下: 虽然已是十年前的产物,但是proverbs的价值依旧存在 以下是整合补充内容后的完整总结,涵盖 Rob Pike 在 Gopherfest 2015 演讲 “Go Proverbs” 中的核心…...

【吾爱出品】针对红警之类老游戏适用WIN10和11的补丁cnc-ddraw7.1汉化版

针对红警之类老游戏适用WIN10和11的补丁cnc-ddraw7.1汉化版 链接:https://pan.xunlei.com/s/VOJ8PZd4avMubnDzHQAeZDxWA1?pwdnjwm# 直接复制到游戏安装目录,保持与游戏主程序同目录下。...

内容中台驱动企业数字化内容管理高效协同架构

内容概要 在数字化转型加速的背景下,企业对内容管理的需求从单一存储向全链路协同演进。内容中台作为核心支撑架构,通过统一的内容资源池与智能化管理工具,重塑了内容生产、存储、分发及迭代的流程。其核心价值在于打破部门壁垒,…...

【第14章:神经符号集成与可解释AI—14.4 神经符号集成与可解释AI的未来发展趋势与挑战】

想象一下,如果AI既能像人类一样直觉感知(比如一眼认出街角的咖啡店),又能像数学家一样逻辑推理(比如计算最优路线避开拥堵),这个世界会变成什么样?这种“双脑协同”正是神经符号集成技术的终极目标。 但现实是,当前99%的AI系统要么只会“死记硬背”数据(如深度学习模…...

[JVM篇]虚拟机性能监控、故障处理工具

虚拟机性能监控、故障处理工具 基础故障处理工具 jps(JVM Peocess Status Tool - 虚拟机进程状况工具) jstat(JVM Statistics Monitoring Too - 虚拟机统计信息监视工具) jinfo( Configuration info for Java - Java配置信息工具) jmap(Memory Map for…...

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cycle_t 类型

ngx_cycle_t 定义在 src/core/ngx_core.h typedef struct ngx_cycle_s ngx_cycle_t; ngx_cycle_s 定义在 src/core/ngx_cycle.h struct ngx_cycle_s {void ****conf_ctx;ngx_pool_t *pool;ngx_log_t *log;ngx_log_t …...

WHERE子句中的条件

在SQL查询中,WHERE子句用于指定筛选条件,以限制从数据库表中检索出的数据行。WHERE子句通常位于SELECT、UPDATE、DELETE等SQL语句中,紧跟在FROM子句(对于SELECT语句)或其他相关子句之后。 一、WHERE子句的基本语法 sq…...

Effective Objective-C 2.0 读书笔记——内存管理(下)

Effective Objective-C 2.0 读书笔记——内存管理(下) 在 dealloc 方法中只释放引用并解除监听 对象在经历其生命期后 ,最终会为系统所回收 ,这时就要执行dealloc 方法了。 在每个对象的生命期内,此方法仅执行一次&a…...

[Spring Boot] Expense API 实现

[Spring Boot] Expense API 实现 项目地址:expense-api 项目简介 最近跟着视频做的一个 spring boot 的项目,包含了比较简单的记账功能的实现(只限 API 部分),具体实现的功能有: 记账(expen…...

Pell数列【一本通在线评测】

目录 描述 输入描述 输出描述 用例输入 1 用例输出 1 什么是pell数列 一、定义与递推关系 二、数学性质 三、应用领域 四、编程实现要点 五、扩展与相关概念 C代码实现 描述 Pell数列a1​,a2​,a3​,...的定义是这样的,a1​1,a2​2,...,an​2an−1​a…...

linux ollama deepseek等大语言模型的model文件的存储目录

linux ollama deepseek等大语言模型的model文件的存储目录 一、用ollama serve启动的,模型数据存放在: /usr/share/ollama/.ollama/models二、如果在自启动文件中指定了工作目录,则在工作目录下的.ollama/models 1.自启动服务 /etc/system…...

【PyQt】工具栏(QToolBar)与动作按钮(QAction)使用指南

PyQt工具栏(QToolBar)与动作按钮(QAction)使用指南 🛠️ 一、基础用法示例 🌟 class MainWindow(QMainWindow):def __init__(self):super().__init__()# 创建工具栏 🔧self.toolbar self.addToolBar("主工具栏")# 创建动作集合 …...

软路由折腾 | OpenWrt安装后基础配置指南:联网设置与DNS优化

在PVE中安装OpenWrt教程 一、网络基础配置 1. 确认网络接口角色 OpenWrt旁路由通常仅需配置LAN口,无需WAN口。其流量通过主路由转发,因此需确保: 物理连接:OpenWrt的LAN口(如eth0)桥接到主路由的局域网&…...

设置默认构建变体 Build Variant

Android Studio在打开项目时有时会把我设置好的build Variant改为默认的变体,没注意的话可能打完包才发现打错了,浪费时间。因此,有必要通过代码设置一个我想要的默认变体。 代码其实很简单,只要在变体下面加上isDefault true即可…...