docker 数据持久化

2023-10-26

在容器层的 UnionFS(联合文件系统)中对文件/目录的任何修改,无论是手工修改还是容器在运行过程中的修改,在该容器丢失或被删除后这些修改将全部丢失。即这些修改是无法保存下来的。若要保存下来这些修改,通常有两种方式:

  • 定制镜像持久化:将这个修改过的容器生成一个新的镜像,让这些修改变为只读的镜像

  • 数据卷持久化:将这些修改通过数据卷同步到宿主机

定制镜像持久化

需求

DockerHub上拉取的centos:7镜像是没有vim工具的,现在将centos:7镜像运行后下载vim工具,再将这个容器打包为一个镜像(centos7:vim)。最后运行这个镜像,可以看到这个镜像里面是有vim工具的。

实现

由于之前做过类似的需求,在此我只把使用的命令展示出来。

# 运行centos:7镜像
docker run --name centos1 -it centos:7

# 进入到centos7的shell后下载vim
yum install -y vim

# 下载完成之后输入exit退出centos7容器的shell环境。
# 并将该容器打包为一个镜像
docker commit -m="add vim" -a="bing" centos1 centos7:vim

# 打包完成后运行这个新镜像
docker run --name centos_vim -it centos7:vim

# 查看vim的版本
vim --version

数据卷持久化

数据卷简介

数据卷宿主机中的一个特殊的文件/目录,这个文件/目录与容器中的另一个文件/目录进行了直接关联,在任何一端对文件/目录的写操作,在另一端都会同时发生相应变化。在宿主中的这个文件/目录就称为数据卷,而容器中的这个关联文件/目录则称为该数据卷在该容器中的挂载点。数据卷的设计目的就是为了实现数据持久化,其完全独立于容器的生命周期,属于宿主机文件系统,但不属于 UnionFS。因此,容器被删除时,不会删除其挂载的数据卷。

数据卷的特性

数据卷具有如下明显特性:

  • 数据卷在容器启动时初始化,如果容器启动后容器本身已经包含了数据,那么,这些数据会在容器启动后直接出现在数据卷中,反之亦然。

  • 可以对数据卷或挂载点中的内容直接修改,修改后对方立即可看到。

  • 数据卷会一直存在,即使挂载数据卷的容器已经被删除。

  • 数据卷可以在容器之间共享和重用。

创建读写数据卷

数据卷是在使用 docker run 启动容器时指定的,其语法格式为:

docker run -it -v /宿主机目录绝对路径:/容器内目录绝对路径 镜像名

注:无论是宿主机中的数据卷还是容器中的挂载点,如果指定的目录不存在,那么 docker引擎都会自动创建。即使是多级目录不存在。

# 启动容器并创建数据卷
docker run --name centos1 -it -v /tmp/read_write_sour:/tmp/read_write_dest centos:7

在容器的/tmp/read_write_dest目录下创建hello.log文件,并写入数据。
image-20230913123654815

看宿主机的/tmp/read_write_sour目录下是否有文件和数据,然后向hello.log文件中添加数据。
image-20230913124045098

看看容器的/tmp/read_write_dest目录下的hello.log文件是否有宿主机添加的数据。
image-20230913124217614

停止容器后的操作

即使容器停止了,在宿主机中只要修改了数据卷目录内容,在重新启动容器后,该修改过的数据仍会出现在容器中。因为容器是一个 UnionFS,是一个存在于宿主机中的文件系统,无论容器是否运行,该 FS 都是存在的。
image-20230913125119583

查看数据卷详情

通过 docker inspect [容器] 命令可以查看到当前容器中挂载点与数据卷的绑定关系,其中Mounts表示挂载的意思。
image-20230913125316507

这里给出了数据卷 Source 与挂载点 Destination 的绑定关系,且容器对挂载点的默认操作权限是 RW 读写的。

创建只写数据卷

只读数据卷,指的是容器对挂载点的操作权限是只读的宿主机对数据卷的操作权限始终是读写的。有些情况下,为了防止容器在运行过程中对文件产生修改,就需要创建只读数据卷。创建只读数据卷的命令比之前的命令仅多了:ro,具体语法如下:

docker run -it -v /宿主机目录绝对路径:/容器内目录绝对路径:ro 镜像名

# 启动容器并创建只读数据卷
docker run --name centos2 -it -v /tmp/read_only_sour:/tmp/read_only_dest:ro centos:7

在宿主机中的/tmp/read_only_sour目录下创建一个read-only.log文件,并写入数据。
image-20230913150455156

登录到容器中的/tmp/read_only_dest目录下,看看reda-only.log文件的内容,并尝试写入数据。
image-20230913150939058

发现在容器中并不能向read-only.log写入数据,说明在该目录下,所有的文件对于容器来说都是只读的。

查看数据卷详情

通过 docker inspect centos2 命令可以查看到该数据卷的RW为false,也就是该容器对数据卷有只读属性。
image-20230913151351735

创建共享数据卷

当一个容器与另一个容器使用相同的数据卷时,就称这两个容器实现了“数据卷共享”。而数据卷容器是实现数据卷共享的一种非常有效的方案。当一个容器 C 启动运行时创建并挂载了数据卷,若其它容器也需要共享该容器 C 挂载的数据卷,这些容器只需在 docker run 启动时通过 --volumes-from “容器C” 选项即可实现数据卷共享。此时容器 C 就称为数据卷容器。

现在搭建如下环境的各种容器以及数据卷。
image-20230913160517198

# 首先创建一个使用读写数据卷的centos:3的容器并运行。
docker run --name centos3 -it -v /tmp/share_sour:/tmp/share_dest centos:7

# 然后创建两个容器分别是tomcat1和tomcat2,注意加上--volumes-from centos3的选项。
docker run --name tomcat1 --volumes-from centos3 -it tomcat:8.5.32 /bin/bash
docker run --name tomcat2 --volumes-from centos3 -it tomcat:8.5.32 /bin/bash

容器创建完成后,首先宿主机在/tmp/share_sour目录下创建一个share.log的文件,并写入数据。
image-20230913161915530

第二步是centos3容器在/tmp/share_dest目录下读取数据并写入数据。
image-20230913162126945

第三步是tomcat1容器在/tmp/share_dest目录下读取数据并写入数据。
image-20230913162300903

第四步是tomcat2容器在/tmp/share_dest目录下读取数据并写入数据。
image-20230913162353465

可以看到这三个容器和宿主机之间实现了数据共享。

Dockerfile持久化

Dockerfile 持久化,其实就是通过使用 Dockerfile 的 VOLUME 指令指定数据卷方式实现的持久化。VOLUME 指令可以在容器中创建可以挂载数据卷的挂载点。其参数可以是字符串数组,也可以是使用空格隔开的多个纯字符串。例如,VOLUME [ “/tmp/demo”, “/etc/apache”] 或VOLUME /tmp/demo /etc/apache。

创建Dockerfile、构建和运行镜像

首先mkdir 一个目录,例如 volume,然后在其中新建 Dockerfile,内容如下。这里指定/tmp/demo1 与/opt/demo2 为容器端的挂载点。

FROM centos:7
VOLUME /tmp/demo1 /opt/demo2
CMD /bin/bash

然后就是构建和运行镜像,命令如下:

# 构建镜像
docker build -t volume .

# 运行镜像
docker run --name vols -it volume

查看宿主机端的目录

Ctrl + P + Q 退出容器后,使用 docker inspect vols 查看当前容器中的挂载点目录到底与宿主机中的哪个数据卷对应。
image-20230913164350487

Source是宿主机的目录,Destination是容器的目录。向/var/lib/docker/volumes/0083b3d0a8c8ea137e2bf43a7e43ad1c68e5155415eb293489041bd6dadd50fc/_data 中写入数据,看看容器的/opt/demo2下是否有数据。
image-20230913164929604

这就是使用Dockerfile实现数据持久化的方式,即使删除了容器和镜像,数据也还在宿主机的/var/lib/docker/volumes/······/_data目录下。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

docker 数据持久化 的相关文章

随机推荐

  • 《UVM实战》学习笔记——第六章 sequence机制

    文章目录 前言 一 sequence的启动与执行 1 启动 2 启动方式 3 sequence分类 二 sequence的仲裁机制 1 sequence相关的宏 2 sequencer的仲裁算法 6种 3 sequence独占sequenc
  • USB HUB简述

    概述 hub 集线器 连接在host与device之间的一种用于usb接口扩展的usb设备 可以将一个usb上行接口扩展为多个下行接口 使得一个host可以同时与多个device连接 一般来说 一块hub桥接芯片可扩展4个usb接口 而市面
  • ‘dtools’不是内部或外部命令,也不是可运行的程序或批处理文件,个人解决方案

    powershell或cmd执行时出现 dtools 不是内部或外部命令 也不是可运行的程序或批处理文件 奇怪的是 我的工程目录下明明有dtools exe可执行文件 搜索引擎上多数反馈是添加C system32等路径到环境变量 但后续发现
  • 亲密关系-【沟通提示】-如何把学习到的东西用到生活中

    关于亲密关系 我学到了这么多 可为什么ta对这些毫不在意 我知道课里的观点都很重要 可我该怎么教会ta ta没有意识 看画面 案例 妈妈说话总是带有攻击性 总是骂她 怎么说 常见误区 你不要老师贬低我 对方苦苦思考 我到底该怎么办 你下意识
  • java中的多重循环

    多重循环 一个循环体内又包含另一个完整的循环结构 如下 while 循环条件1 循环操作1 while 循环条件2 循环操作2 do 循环操作1 do 循环操作2 while 循环条件2 while 循环条件1 for 循环条件1 循环操作
  • Docker - 使用Docker Compose部署应用

    简介 Docker Compose是一个基于Docker Engine进行安装的Python工具 该工具使得用户可以在一个声明式的配置文件中定义一个多容器的应用 在Docker节点上 以单引擎模式 Single Engine Mode 进行
  • 手写算法-python代码实现Lasso回归

    手写算法 python代码实现Lasso回归 Lasso回归简介 Lasso回归分析与python代码实现 1 python实现坐标轴下降法求解Lasso 调用sklearn的Lasso回归对比 2 近似梯度下降法python代码实现Las
  • 【直达本质讲运放】运放的“第一原理”式定量分析法

    数电 模电那两本书我也完整地翻过一 二遍 诶我为什么用 也 下面就是来点不复杂的 如果是那还不如直接把书的内容粘过来呢 对于运放的定量分析 虚短虚断 就如同 奇变偶不变 一样喜闻乐见的普及 但是对于什么时候用 虚短 什么时候用 虚断 学习的
  • Ridge和Lasso回归

    上周看了看回归方面的知识 顺便复 xue 习一下Ridge 岭回归 和Lasso回归 套索回归 瞅到了一篇英文博客讲得不错 翻译一下 本文翻译自 Ridge and Lasso Regression 本文是一篇Josh Starmer关于
  • 常用网络协议神图

  • 凸优化(一)——Introduction

    Introduction 一 最优化问题的数学表达 在最优问题中 其数学表达往往能化成标准形式 如下 minimizef0 x subject tofi x bi i 1 m begin aligned minimize quad f 0
  • 微信小程序对上传的图片进行裁剪

    背景 使用uniapp中uni chooseImage的裁剪参数crop只能在App中生效 在微信小程序中不生效 实现思路 uni chooseImage打开相册获取图片路径 uni chooseImage OBJECT uni app官网
  • c++面试记录

    1 数组与指针区别 数组 数组是用于储存多个相同类型数据的集合 指针 指针是一个变量 但是它和普通变量不一样 它存放的是其它变量在内存中的地址 赋值 数组 只能一个一个元素的赋值或拷贝 指针 指针变量可以相互赋值 表示范围 数组有效范围就是
  • flink table 使用Kafka Connector处理嵌套json

    使用flink table api 连接kafka 处理json类型数据 单层json处理比较简单 官方或网上都有很多例子 处理嵌套的json数据没什么介绍 处理嵌套json数据主要是schema定义 StreamExecutionEnvi
  • Linux系统之使用yum安装Redis数据库

    Linux系统之使用yum安装Redis数据库 一 redis介绍 1 redis解释 2 redis特点 3 redis使用场景 二 检查系统版本 1 检查系统版本 2 检查内核版本 三 检查yum仓库状态 四 查看系统默认提供的redi
  • mysql数据恢复,使用binlog配置恢复未备份数据

    使用mysqlbinlog配置 恢复数据库 什么是mysqlbinlog binlog是记录所有数据库表结构变更 例如CREATE ALTER TABLE 以及表数据修改 INSERT UPDATE DELETE 的二进制日志 binlog
  • 命令行参数设计

    1 目的 众多通用的小功能 制作为一个小工具 然后通过命令行来进行交互 使用非常的简便 本规范是为了统一命令行参数的设计 使得大家在制作或使用命令行工具时 能够更加有共享 进行会更加方便 2 适用范围 所有命令行工具参数的设计 3 基本原则
  • #SATA# SATA 实际管脚接线图

    前言 概述 实际接线管脚图 PATA 接口 M 2 U 2 AHCI NVMe 概述 SATA是Serial ATA的缩写 即串行ATA 它是一种电脑总线 主要功能是用作主板和大量存储设备 如硬盘及光盘驱动器 之间的数据传输 这是一种完全不
  • 迁移学习:他山之石,可以攻玉【VALSE Webinar】Panel实录

    编者按 迁移学习是机器学习与计算机视觉中的重要研究问题之一 旨在研究如何将一个领域的知识迁移到另外的领域 具有重要的研究意义与应用价值 但迁移学习又会存在哪些局限性 在实际应用中的价值是什么 未来的发展方向在哪里 为此 VALSE Webi
  • docker 数据持久化

    文章目录 定制镜像持久化 需求 实现 数据卷持久化 数据卷简介 数据卷的特性 创建读写数据卷 停止容器后的操作 查看数据卷详情 创建只写数据卷 查看数据卷详情 创建共享数据卷 Dockerfile持久化 创建Dockerfile 构建和运行