docker系列8:容器卷挂载(上)

目录

传送门

从安装redis说起

什么是容器卷挂载

操作系统的挂载

日志文件一般是"首恶元凶"

挂载命令

容器卷挂载 

卷挂载命令

启动时挂载

查看挂载卷信息

容器卷管理

查看卷列表

创建容器卷

具名挂载与匿名挂载

具名挂载


传送门

docker系列1:docker安装

docker系列2:阿里云镜像加速器

 docker系列3:docker镜像基本命令

docker系列4:docker容器基本命令

docker系列5:docker安装nginx

docker系列6:docker安装redis

docker系列7:docker安装ES

从安装redis说起

在前面几节通过docker安装过了nginx、redis和ES,会发现通过docker安装运行软件的过程都差不多。但是在redis章节时,有一点区别:在使用Docker容器管理时,有时候需要对Redis进行配置,但是Docker镜像中并没有默认的redis.conf,需要手动设置redis.conf文件。

当时的解决方案是在启动命令中加入了一个配置:

docker run --name test_redis -p 6379:6379 -v /root/redis/redis.conf:/usr/local/etc/redis/redis.conf -d redis

其中的-v /root/redis/redis.conf:/usr/local/etc/redis/redis.conf就是容器卷挂载!

什么是容器卷挂载

在具体解释上面这条命令参数之前,先使用docker run --help看下官方的解释:

-v, --volume list                    Bind mount a volume  绑定挂载一个卷;可以指定多个为一个列表--volume-driver string           Optional volume driver for the container  指定容器卷驱动--volumes-from list              Mount volumes from the specified container(s)

 光看上面这个解释第一次接触的可能还是比较模糊,要说清楚这个问题,可以先从传统操作操作系统的的挂载讲起

操作系统的挂载

日志文件一般是"首恶元凶"

不知道你有没有过这种经历:在linux上面搭建的应用系统服务,跑了一段时间之后会发生磁盘被占满了,甚至连登录服务器都登录不上,而且一般是客户上报的错误,开发很慌啊~~。

图片来自网络

最后各种排查,发现在是日志过大(比如nacos默认的系统日志,XXL-job的触发日志)导致磁盘容量不够,这时可能就会让"运维背锅":

  • 每隔一段时间手动去服务器删除日志文件(相关文件)
  • 或者写个cron任务,自动删除日志文件

这种比较暴力的处理方式,在不那么"草台班子"的公司可能不会出现,这时运维能力强的公司一般会要求日志必须保留多久或者做备份:

  • 对服务器各项指标做监控,并配置对应的自动化运维手段对日志备份
  • 提前对日志容量做评估,配置对应的磁盘容量水位做预留
  • 要求开发将日志输出到指定挂载盘上,空间足够大

对于传统自建的服务器,可以在购买物理机的时候选用磁盘容量比较大的机器,这个时候如果硬盘不量不够可以挂载单独的外设硬盘。随着云计算的发展,很多公司上云之后都会购买云主机(虚拟机)来搭建应用服务,这样扩容很方便且在一定规模下降低成本(这个命题最近非常火,此处不过多讨论持保留很意见)?这样就出现了NFS还有OSS等网络存储设备。不管是物理机还是虚拟机的挂载都可以统一称为磁盘挂载(用来区分前面提到的docker容器卷挂载)。下图是实际项目使用的一种解决方案:

挂载命令

对于挂载命令不是这里的重点,可以自行搜索或者查看

容器卷挂载 

而容器的卷挂载跟磁盘挂载其实原理相似,不过容器卷挂载的初衷更多的是由于容器内的存储是易失的不能持久化,虽然容器容量也是其中很重要的一个原因。对此看下官方的解释:

By default all files created inside a container are stored on a writable container layer. This means that:

The data doesn't persist when that container no longer exists, and it can be difficult to get the data out of the container if another process needs it.

A container's writable layer is tightly coupled to the host machine where the container is running. You can't easily move the data somewhere else.

Writing into a container's writable layer requires a storage driver to manage the filesystem. The storage driver provides a union filesystem, using the Linux kernel. This extra abstraction reduces performance as compared to using data volumes, which write directly to the host filesystem.

Docker has two options for containers to store files on the host machine, so that the files are persisted even after the container stops: volumes, and bind mounts.

---------------------------------------------- 以下为机译 -----------------------------------------------------

默认情况下,在容器内创建的所有文件都存储在可写容器层上。这意味着:
当容器不存在时,数据不会持久存在,如果另一个进程需要,则很难将数据从容器中取出。
容器的可写层与运行容器的主机紧密耦合。你不能轻易地将数据移动到其他地方。
写入容器的可写层需要一个存储驱动程序来管理文件系统。存储驱动程序使用Linux内核提供了一个联合文件系统。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象降低了性能。
Docker为容器在主机上存储文件提供了两个选项,这样即使在容器停止后文件也会被持久化:卷和绑定装载。

以上面的redis为例,docker运行redis镜像时不一定要强行增加-v才行:

  • 在宿主机放置一分redis.conf文件
  • 将上面的redis.conf文件拷贝到容器中
  • 修改容器中的redis.conf文件达到修改redis配置的目的

现在来启动一个redis容器:docker run -it -d --name myredis redis

将宿主机的redis.conf文件拷贝到容器中:docker cp /root/redis/redis.conf myredis:/usr/local/etc/redis-conf/redis.conf

进入容器查看redis.conf文件: docker exec -it myredis /bin/bash

后面就可以指定redis.conf文件启动服务了,注意这里的redis.conf文件需要跟redis的版本一致,不然可能会启动失败

卷挂载命令

虽然上述方式可以达到跟卷挂载一样的效果,但是还是不如挂载来的方便,先看一下挂载命令!

启动时挂载

前面的redis运行时,通过-v命令称作启动时自动挂载:

docker run --name test_redis -p 6379:6379 -v /root/redis/redis.conf:/usr/local/etc/redis/redis.conf -d redis
  • -v,表明进行卷挂载
  • 后面接着路径:宿主机路径:容器内路径,比如/root/redis/redis.conf表示宿主机上面的redis.conf路径;/usr/local/etc/redis/redis.conf表示容器内的路径

既然是路径,除了上面挂载文件之外,肯定也可以挂载目录的。比如在刚才的命令中增加一个数据目录:-v /root/redis/data:/usr/local/etc/redis/data

然后分别查看宿主机与容器内的目录:

 对于这一点,官网的解释:

If you start a container with a volume that doesn't yet exist, Docker creates the volume for you

从上面磁盘挂载特性,在容器内操作文件就跟操作本地一样。比如在容器内创建一个测试文件test.txt,然后在宿主机观察一下:

从这说明容器的挂载成功了! 

查看挂载卷信息

如果要查看刚才redis挂载的卷信息,可以通过如下docker命令:docker inspect 容器名

在显示的容器里面查找到挂载卷信息:

容器卷管理

查看卷列表

如果要查看刚才redis挂载的卷信息,除了可以通过如下docker命令:docker inspect 容器名之外,还有专门的卷查看命令:docker volume ls

但是这个卷名字VOLUME NAME怎么这么奇怪? 因为这个是卷挂载自动生成的挂载卷名称,也称为"匿名挂载"。仔细看的话,前面的inspect里面有一项里面的Name也是类似:9287eb2555a9b48bb1f91c69489dd806e777aca0b22448d0d718e0c1c4bb7640

{"Type": "volume","Name": "9287eb2555a9b48bb1f91c69489dd806e777aca0b22448d0d718e0c1c4bb7640","Source": "/var/lib/docker/volumes/9287eb2555a9b48bb1f91c69489dd806e777aca0b22448d0d718e0c1c4bb7640/_data","Destination": "/data","Driver": "local","Mode": "","RW": true,"Propagation": ""}

而这一项就对应docker volume ls里面的一个卷:

如果查看此挂载卷信息:

会发现的确是刚才创建的,而匿名卷会默认跟宿主机的/var/lib/docker/volumes/VOLUME NAME/_data关联起来!

现在再测试一下,启动一个新的容器:

docker run --name test_redis3 -p 6379:6379 -v -v /root/redis/data2:/usr/local/etc/redis/data2 -d redis

运行之后,查看容器卷信息:

"Mounts": [{"Type": "bind","Source": "/root/redis/data2","Destination": "/usr/local/etc/redis/data2","Mode": "","RW": true,"Propagation": "rprivate"},{"Type": "volume","Name": "109806e8fe95be922b8cb8b6a54bcc7bc664edaaca0cc2803dbb9c41bfce206c","Source": "/var/lib/docker/volumes/109806e8fe95be922b8cb8b6a54bcc7bc664edaaca0cc2803dbb9c41bfce206c/_data","Destination": "/data","Driver": "local","Mode": "","RW": true,"Propagation": ""}]
创建容器卷

除了前面介绍的启动时自动挂载,还可以手动创建容器卷:

# my-vol为卷名称
docker volume create my-vol

 执行一下上面的命令,并查看对应的卷列表:

具名挂载与匿名挂载

但是你会发现这种指定卷名称的创建方式,卷的名称不再是一种"看不懂"的字符串了。这种方式也叫作"具名挂载" !不过此时需要挂载的卷的宿主机路径都默认放到docker指定的目录下面了。而"匿名挂载"可以动态指定宿主机路径挂载的目录

具名挂载

有了手动创建的卷,那现在也可以通过启动时挂载具体的卷:

docker run --name test_redis -p 6379:6379 -v my-vol:/usr/local/etc/redis/data -d redis

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

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

相关文章

C++ : list类及其模拟实现

目录 一、list的介绍和使用 list的介绍 list的使用 1.list的构造 构造函数 2.list iterator 的使用 3.list capacity 4.list element access 5.list modifiers 6.list的迭代器失效 二、list的模拟实现 要点 list类模拟实现部分接口全部代码展示 一、list的介绍和使…

Docker:centos7安装docker

官网:https://www.docker.com/官网 文档地址 - 确认centos7及其以上的版本 查看当前系统版本 cat /etc/redhat-release- 卸载旧版本 依照官网执行 - yum安装gcc相关 yum -y install gccyum -y install gcc-c- 安装需要的软件包 yum install -y yum-utils- 设置s…

深入学习Linux内核页框回收

目录 算法 1.选择目标页 2.PFRA设计 3.反向映射 3.1.匿名页的反向映射 3.2.try_to_unmap_anon()函数 3.3.try_to_unmap_one()函数 映射页的反向映射 优先搜索树 try_to_unmap_file()函数 PFRA实现 最近最少使用(LRU)链表 在LRU链表之间移动页 mark_page_accessed(…

Android使用kts发布aar到JitPack仓库

Android使用kts发布aar到JitPack 之前做过sdk开发,需要将仓库上传到maven、JitPack或JCenter,但是JCenter已停止维护,本文是讲解上传到JitPack的方式,使用KTS语法,记录使用过程中遇到的一些坑.相信Groovy的方式是大家经常使用的,…

Java基于Spring Boot框架的课程管理系统(附源码,说明文档)

博主介绍:✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇&#x1f3…

基于Springboot的校园疫情防控系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的校园疫情防控系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构…

C# WCF服务(由于内部错误,服务器无法处理该请求。)

由于内部错误&#xff0c;服务器无法处理该请求。有关该错误的详细信息&#xff0c;请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端&#xff0c;或打开对每个 Microsoft .NET …

从零开始:Django项目的创建与配置指南

title: 从零开始&#xff1a;Django项目的创建与配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 后端开发 tags: DjangoWebDevPythonORMSecurityDeploymentOptimization Django简介&#xff1a; Django是一个开源的高级Python Web框架&#xff…

抖音直播怎么赚钱的?有多少种方法?

抖音直播确实很能挣钱&#xff0c;它一般有两种方式赚钱&#xff0c;一种是靠粉丝打赏赚钱&#xff0c;一种是在直播间卖货赚钱&#xff01; 1、抖音直播的赚钱方法一&#xff1a;粉丝打赏 主播在抖音直播&#xff0c;首先的收入来源就是靠粉丝的打赏&#xff0c;粉丝打赏的礼…

C语言之整形提升和算术转换

目录 前言 一、整形提升 二、算术转换 总结 前言 本文主要介绍C语言中的整形提升和算术转换的概念和意义&#xff0c;以及例题帮助理解&#xff0c;了解之后&#xff0c;我们就能知道在C语言中&#xff0c;字符型变量如何计算以及如果变量的类型、字节大小不一致的情况下&am…

2012NOIP普及组真题 4. 文化之旅

线上OJ&#xff1a; 一本通&#xff1a;http://ybt.ssoier.cn:8088/problem_show.php?pid1960 相似题目&#xff1a; 本题和 2017年 NOIP J 组第3题 棋盘 类似。 核心思想&#xff1a; 由于本题的数据范围 n ≤ 100,非常小&#xff0c;所以可以采用 深搜 dfs 进行。同时&am…

C++程序设计:new和malloc的区别

new和malloc的区别 1.用法和语法2.类型安全性3.初始化4.分配数组5.异常处理示例代码 1.用法和语法 new 是 C 中的运算符&#xff0c;而 malloc 是 C 语言中的函数。new 用于动态分配单个对象或数组&#xff0c;并且在分配内存后调用对象的构造函数进行初始化。malloc 用于动态分…

golang学习笔记(内存模型和分配机制)

操作系统的存储管理 虚拟内存管理 虚拟内存是一种内存管理技术&#xff0c;它允许操作系统为每个进程提供一个比实际物理内存更大的地址空间。这个地址空间被称为虚拟地址空间&#xff0c;而实际的物理内存则被称为物理地址空间。使用虚拟内存有以下几点好处&#xff1a; 内…

C# 用户控件UserControl事件解绑资源释放

用户控件继承子 UserControl 。 现在有个业务需求在UserControl 所在的窗体关闭时解除事件HMouseDown绑定。 因没有相关的Close事件。后来本人想了一个办法在 ROICtlDesigner类的 Dispose 方法中执行相关的释放代码 比如解除事件绑定 释放资源 public partial class ROICt…

git 第一次安装设置用户名密码

git config --global user.name ljq git config --global user.email 15137659164qq.com创建公钥命令 输入后一直回车 ssh-keygen -t rsa下面这样代表成功 这里是公钥的 信息输入gitee 中 输入下面命令看是否和本机绑定成功 ssh -T gitgitee.com如何是这样&#xff0c;恭喜…

Ubuntu系统重装

1、删除相关卷&#xff0c;ubuntu引导项&#xff08;select disk、assign letter的方法&#xff09; Ubuntu20.04重装系统过程&#xff08;多图&#xff0c;含保存文件卸载旧系统安装新系统&#xff09;_ubuntu重装系统-CSDN博客 2、分配空间 efi 1024MB 逻辑分区 swap 8*1…

基于51单片机PWM控制直流电机—数码管显示

基于51单片机PWM控制直流电机 &#xff08;仿真&#xff0b;程序&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.L298驱动直流电机&#xff1b; 2.数码管显示转动方向和PWM占空比&#xff08;0-100%&#xff09;&#xff1b; 3.按键控制PWM占空比来加/…

20232803 2023-2024-2 《网络攻防实践》实践八报告

目录 1. 实践内容2. 实践过程2.1 动手实践任务一2.2 动手实践任务二&#xff1a;分析Crackme程序2.2.1 crackme1.exe2.2.2 crackme2.exe 2.3 分析实践任务一2.4 分析实践任务二 3. 学习中遇到的问题及解决4. 学习感悟、思考等 1. 实践内容 动手实践任务一&#xff1a;对提供的r…

Vue入门到关门之第三方框架elementui

1、什么是ElementUI&#xff1f; Element UI 是一个基于 Vue.js 的组件库&#xff0c;它提供了丰富的 UI 组件和一套完整的解决方案&#xff0c;用于快速构建现代化的 Web 应用程序。Element UI 的目标是帮助开发者快速构建出美观、易用的界面&#xff0c;并提供了丰富的组件&…

四种粒子群算法的Matlab实现

粒子群算法&#xff0c;又称为粒子群优化&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;&#xff0c;是一种基于群体智能的优化算法。它最初由James Kennedy和Russell Eberhart于1995年提出&#xff0c;灵感来源于鸟群捕食行为的研究。在PSO中&#…