上篇文章的最后我们使用Docker部署了一个纯前端项目,但还有一个很重要的问题就是容器中产生的数据(比如log文件),容器一旦被删除,容器内的所有数据也就没有了,为了避免这个问题我们可以将数据存储到容器之外(比如宿主机),这样即使删除容器也不会丢失数据。一旦容器故障,我们可以重新创建一个容器,将数据挂载到容器里,就可以快速恢复。

数据存储方式

Docker提供了以下几种存储方式:

  • volume卷:这种方式是在宿主机文件系统分配一块专有存储区域,由 Docker管理,并且与主机的核心功能隔离。非 Docker 进程不能修改文件系统的这一部分。卷是在 Docker 中持久保存数据的最佳方式,它适合存储数据库数据,可挂到多个容器上

  • bind mount 绑定挂载:这种方式是直接把宿主机目录映射到容器内,适合挂代码目录和配置文件,可挂到多个容器上

  • tmpfs mount临时挂载:这种方式仅存储在主机系统的内存中,并且永远不会写入主机系统的文件系统,适合存储临时文件,不可多容器共享

这张图很清晰的解释了volumebind mounttemps mount与容器和宿主机之间的关系,这三者最终都是存储在宿主机上的。

重点了解volume数据卷:(其实绑定挂载也可以当成volume来理解)

  • 数据卷其实是宿主机上的一个目录
  • 当容器目录与数据卷目录绑定之后,双方的修改都会立即同步
  • 一个数据卷可以被多个容器挂载
  • 一个容器也可以挂载多个数据卷

数据卷可以用来做容器数据持久化、外部机器与容器间接通信、容器之间间接通信

数据卷操作

数据卷(Volume)也是常见的 Docker 对象类型的一种,因此它也支持创建、查看、删除等操作

创建数据卷

使用docker volume create [name]指令来创建一个数据卷

docker volume create nanjiu-data

查看所有的数据卷

docker volume ls

查看卷信息

使用docker volume inspect [name]指令来查看对应卷信息

docker volume inspect nanjiu-data

从上图我们可以看到Mountpoint数据卷挂载的地址,需要注意的是对于非 Linux 系统而言(Windows 、Mac ),该目录不存在于你的文件系统中,而是存在于 Docker 虚拟机中。

删除数据卷

使用docker volume rm [name]指令来删除对应的数据卷

docker volume rm nanjiu-data

这里需要注意的是:

  • 数据卷是用来做持久化数据的,它的生命周期独立于容器,所以Docker不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷
  • 如果需要在删除容器的同时移除数据卷,可以在删除容器的时候使用 docker rm -v 指令

如果想要清除所有无容器引用的数据卷,可以使用以下指令:

docker volume prune

与容器一起使用

数据卷本身是用来为容器做数据持久化的,所以单独创建一个数据卷的意义并不大

创建容器与数据卷

命名数据卷

可以使用docker run指定-v-mount来创建数据卷,两者产生的结果相同,最大的区别在于-v语法将所有选项组合在一个字段中,而--mount 语法则将它们分开。

docker run -itd -v nanjiu-vol:/nanjiu-data --name nanjiu nginx:latest

这里通过-v指定了数据卷的名称为nanjiu-vol,并且对应绑定容器中的路径为/nanjiu-data

对于容器中不存在的文件夹,Docker会帮我们自动新建,所以我们可以进入到容器中查看是否有该文件夹

这里我们可以看到容器中对应的数据卷目录

匿名数据卷

这里还有一种类型叫做匿名数据卷,他的创建方式只需要省略数据卷名称就可以,然后Docker会为它生成一长串的hash值作为数据卷的名称

docker run -itd -v /nanjiu-noname --name nanjiu-noname nginx:latest

验证数据持久化

我们先在这个数据卷目录新建一个文件,再把当前容器删除

然后我们再重新创建一个容器并绑定上面那个数据卷,如果数据卷中的内容还存在,那就能够证明数据是持久化存储的,不会随着容器的删除而删除

从这里我们就能够验证数据卷可以用来做持久化存储了

绑定挂载

上面我们提到过它可以当成数据卷来理解,因为它在使用过程中几乎与数据卷类似,不同的地方是它其实是与宿主机的文件系统进行绑定

docker run -itd -v ~/Desktop/nanjiu-mount-data:/nanjiu-mount-data --name nanjiu nginx:latest

这里-v的格式为 <host path>:<container path>,对应绑定的是宿主机目录与容器目录

然后可以到桌面看对应的文件是否存在

绑定挂载可以让宿主机与容器共享数据,并且同样不会随容器的删除而删除,也可以用来实现数据持久化,上面有提到他适合用来挂载代码目录和配置文件

数据共享

容器与宿主机共享数据

绑定挂载

这个很好理解,上面那种bind mount绑定挂载方式就是最明确的,它是直接将宿主机上的目录挂载到容器。

docker cp

volume数据卷的方式想要实现容器与宿主机共享数据稍微有点麻烦,因为这种方式是在宿主机文件系统分配一块专有存储区域,由 Docker管理,并且与主机的核心功能隔离。非 Docker 进程不能修改文件系统的这一部分

但好在docker提供的docker cp命令可以用来拷贝文件,该docker cp命令可以将内容从SRC_PATH复制到DEST_PATH. 您可以从容器的文件系统复制到本地计算机,或者相反,从本地文件系统复制到容器。

docker cp 88eecfd2dd14:/nanjiu-data ~/Desktop/cpDir

然后查看本地桌面是否有了拷贝过来的内容

通过这种方式也能实现宿主机与容器之间的数据共享,但它的缺点在于每次都需要手动操作,数据共享比较麻烦。

容器与容器之间共享数据

绑定挂载

这里第一种方式仍然是可以使用bind mount绑定挂载,因为同一个文件可以挂载到多个容器,这样就可以借助宿主机中转来实现容器之间的数据共享了,这种方式比较简单易懂。

数据卷容器

数据卷容器是一个专门为其它容器提供卷的容器,它提供的卷可以是bind mount,也可以是docker volume

数据卷容器在为其它容器提供卷功能时可以不需要处于运行状态

这里创建了两种类型的volume,同时挂载在nanjiu-vc这个数据卷容器上,这个容器可以不启动

docker create --name nanjiu-vc \
> -v ~/Desktop/nanjiu-vc:/nanjiu-vc \
> -v nanjiu-vc:/nanjiu-vc2 \
> nginx:latest

其他容器可以通过--volumes-from使用nannie-vc这个数据卷容器

这里建了两个容器都使用nanjiu-vc这个数据卷容器

这样两个容器就通过数据卷容器实现了数据共享。

这种方式的优点在于:

  • bind mount相比,不必为每一个容器指定宿主机path,所有path都在volume container中定义好了,容器只需与volume container关联,实现了容器与host的解耦。

  • 使用volume container的容器,其mount point是一致的,有利于配置的规范和标准化,但也带来一定的局限,使用时需要综合考虑。

改造之前的log存储方式

之前的那种部署方式存在一个问题,如果容器出现故障被销毁,那么容器内产生的log文件也就没有了,现在我们可以把它改造成将nginx产生的log文件使用数据卷存储,当容器出现故障,我们只需要重新创建一个容器并挂载数据就可以快速恢复log文件排查问题

修改Dockerfile

# 指定node镜像
FROM node:16-alpine as builder
# 指定工作目录
WORKDIR /code
# 代码复制到工作目录
ADD . /code
# 安装依赖
RUN npm install --registry=https://registry.npm.taobao.org
# 打包
RUN npm run build
# 指定nginx镜像
FROM nginx:alpine
# 创建nginx日志目录数据卷
VOLUME ["/var/log/nginx"]
# 复制打包后的代码到nginx容器中
COPY --from=builder /code/dist /usr/share/nginx/html
COPY /nginx.conf /etc/nginx/nginx.conf
# 暴露端口
EXPOSE 8080

重新打包镜像

docker build -t nanjiu:1.0.1 .

创建容器

基于上面nanjiu:1.0.1镜像创建一个容器nanjiu-web3

docker run -d -p 9099:8080 --name nanjiu-web3 nanjiu:1.0.1

访问页面

这里主要是为了产生nginx日志文件

将容器删除

docker stop 4355deda547f # 停止容器
docker rm 4355deda547f # 删除容器

容器虽然被删除了,但数据卷并不会跟随容器的删除而删除

新建容器绑定数据卷查看数据

docker run -d \
-v 3690f4f3b2d15466a9dfa7f692cba06add99daba3f76b8e7ffdc99b1c5937a8a:/nginx-data \
--name nanjiu-web4 nginx:latest

这样一来即使容器出现故障被删除,也不影响查看log文件排查问题。

Docker数据持久化与数据共享的更多相关文章

  1. Docker | 数据持久化与数据共享

    数据持久化(安装MySQL) 参考另一篇Docker安装mysql: https://www.cnblogs.com/all-smile/p/16778376.html MySQL的数据持久化问题 # ...

  2. Docker数据持久化及实战(Nginx+Spring Boot项目+MySQL)

    Docker数据持久化: Volume: (1)创建mysql数据库的container docker run -d --name mysql01 -e MYSQL_ROOT_PASSWORD= my ...

  3. docker 系列 - 容器数据持久化和数据共享

    docker 主要有两种数据存储形式, 一种是storage driver(也叫做 Graph driver), 另一种是 volume driver. stroage driver主要是存储那些无状 ...

  4. Docker数据持久化与容器迁移

    上节讲到当容器运行期间产生的数据是不会在写镜像里面的,重新用此镜像启动新的容器就会初始化镜像,会加一个全新的读写入层来保存数据.如果想做到数据持久化,Docker提供数据卷(Data volume)或 ...

  5. docker数据持久化

    转载/参考: https://www.jianshu.com/p/ef0f24fd0674 Docker的数据持久化主要有两种方式: bind mount docker managed volume ...

  6. docker数据持久化/共享---volume,bind-mount,tmpfs-mount

    一.将Docker数据挂载到容器 在Docker中,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中.目前Docker提供 ...

  7. `docker数据持久化volume和bind mounts两种方式

    将数据从宿主机到容器的三种方式: ,volumes:docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)保存数据的最佳方式 ,bind mounts 将宿主机上的任 ...

  8. 22. docker 数据持久化 Data Volume

    1 . 使用场景 在docker 容器被删除的时候  希望数据不丢失 2 . Volume 的使用 * 注意 在 mysql 的 Dockerfile 内 定义了 VOLUME ["var/ ...

  9. docker 数据持久化

    confluence #!/bin/bash docker run \ --name confluence \ --volume "$PWD/data/opt":/opt \ -- ...

  10. 23. docker 数据持久化 bind mounting

    1. bind mounting 和 data volume 的区别 data volume 需要在 Dockerfile 定义 Volume bind mounting 只需要 -v 指明 容器外部 ...

随机推荐

  1. 2022-09-01:字符串的 波动 定义为子字符串中出现次数 最多 的字符次数与出现次数 最少 的字符次数之差。 给你一个字符串 s ,它只包含小写英文字母。请你返回 s 里所有 子字符串的 最大波

    2022-09-01:字符串的 波动 定义为子字符串中出现次数 最多 的字符次数与出现次数 最少 的字符次数之差. 给你一个字符串 s ,它只包含小写英文字母.请你返回 s 里所有 子字符串的 最大波 ...

  2. 2022-04-19:A*算法, 过程和Dijskra高度相处, 有到终点的预估函数, 只要预估值<=客观上最优距离,就是对的。 预估函数是一种吸引力: 1)合适的吸引力可以提升算法的速度; 2)吸引

    2022-04-19:A*算法, 过程和Dijskra高度相处, 有到终点的预估函数, 只要预估值<=客观上最优距离,就是对的. 预估函数是一种吸引力: 1)合适的吸引力可以提升算法的速度; 2 ...

  3. UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list

    错误: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_l ...

  4. 利用简单的IO操作实现M3U8文件之间的合并

    先上代码: 1 @SneakyThrows //合并操作,最终文件不包含结束标识,方便多次合并 2 private static void mergeM3U8File(String source, S ...

  5. AI 绘画 - 如何 0 成本在线体验 AI 绘画的魅力

    要想体验 AI 绘画,比较流行的三种方式是 Midjourney.OpenAI 的 DALL·E 2 以及 Stable Diffusion.而 Midjourney 已经停止免费试用,且使用价格不太 ...

  6. Vulnhub Broken

    Vulnhub Broken 一.操作文档 [Vulnhub - Broken-Gallery writeup (mzfr.me)](https://blog.mzfr.me/vulnhub-writ ...

  7. 如何使用 Blazor 框架在前端浏览器中导入和导出 Excel

    前言 Blazor 是一个相对较新的框架,用于构建具有 .NET 强大功能的交互式客户端 Web UI.一个常见的用例是将现有的 Excel 文件导入 Blazor 应用程序,将电子表格数据呈现给用户 ...

  8. 计算机网络 vlan

    目录 一.vlan的概念 二.vlan的优势 三.vlan的种类 四.静态vlan的配置 五.trunk的概念和配值 六.实验 一.vlan的概念 在传统的以太网中,所有的用户都是同一个广播域,当数据 ...

  9. 【python基础】if语句-语法格式

    if语句-语法格式 简单理解if语句之后,我们的if语句语法格式有多种,选择使用哪种取决于要测试的条件数 1.if结构 最简单的if语句只有一个条件测试和一个代码块 其语法格式: 假设想要指导一个学员 ...

  10. 如何在2023年开启React项目

    在这里,我想给你一个新的React项目入门的简要概述.我想反思一下优点和缺点,反思一下作为一个开发者所需要的技术水平,反思一下作为一个React开发者,每个启动项目都能为你提供哪些功能.最后,你将了解 ...