上篇文章的最后我们使用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. IDEA output 输出中文乱码解决方案

    1. 事发场景 最近在用idea 运行 spring 的项目发现运行之后 tomcat 的 output 输出 中文是乱码样子 2. 解决方法 点击右上角tomcat旁边的小三角 下拉框 点击Edit ...

  2. js 关于 replace 取值、替换第几个匹配项

    〇.前言 在日常开发中,经常遇到针对字符串的替换.截取,知识点比较碎容易混淆,特此总结一下,仅供参考. 一.替换第一个匹配项 字符串替换 let strtest = "0123测试repla ...

  3. 有管django使用orm 字段报错问题

    直接删除表,重新生成,首先删除:migrations 中,上传记录,然后django_migrations,

  4. 洛谷 P7579 「RdOI R2」称重(weigh) 题解

    题意: 题目 一道交互题. 有 n 个球,里面有两个假球,假球比普通球的要轻,每次可以询问任意两组球的轻重关系,第一组轻为 < ,第二组轻为 > ,一样重量为 = . 思路: 先考虑在一个 ...

  5. MAUI Blazor 项目实战 - 从0到1轻松构建多平台应用UI

    前言 最近在项目中尝鲜了MAUI,总体感受下来还是挺不错的,优缺点并存,但是瑕不掩瑜,目前随着.Net版本的迭代升级对它的支持也越来越友好,相信未来可期!感兴趣的朋友欢迎关注.文章中如有不妥的地方,也 ...

  6. 时隔多年,从新认识浮动float

    开场白 随着css的发展,在加上各种优秀ui库的兴起. 我们在项目中浮动用的很少. 但并不意味着我们不使用浮动了. 曾几何时,浮动这个属性是那个遥远时代的'超级明星' 排版,布局,都需要使用他. 今不 ...

  7. 程序包xx不存在解决方案:java: 程序包org.aspectj.lang.annotation

    java: 程序包org.aspectj.lang.annotation不存在 #我自己已经配置好pom.xml文件,但是一直报错这个 aspectj 不存在 下面是我的pom.xml配置 可以看出来 ...

  8. Pinot2的无人机传感器和摄像头

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 无人机传感器和摄像头在Pinot 2中得到广泛应用,其目的是为Pinot 2提供全面的传感器和 ...

  9. LeetCode 双周赛 107(2023/06/24)滑动窗口与离散化

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 和 [BaguTree Pro] 知识星球提问. 往期回顾:LeetCode 单周赛第 348 场 · 数位 DP ...

  10. 解密Prompt系列10. 思维链COT原理探究

    前一章思维链基础和进阶玩法我们介绍了如何写Chain-of-thought Prompt来激活生成逐步推理,并提高模型解决复杂问题的能力,这一章我们追本溯源,讨论下COT的哪些元素是提升模型表现的核心 ...