首页 > 其他分享 >Docker数据持久化

Docker数据持久化

时间:2024-09-08 13:51:33浏览次数:4  
标签:容器 持久 root volume nginx html Docker 数据 docker

本章将和大家分享Docker中如何实现数据的持久化。废话不多说,下面我们直接进入主题。

一、什么是数据卷

我们都知道在Docker中,容器的数据读写默认发生在容器的存储层,当容器被删除时其上的数据将会丢失。如果想实现数据的持久化,就需要将容器和宿主机建立联系(将数据从宿主机挂载到容器内),通俗的说,数据卷就是在容器和宿主机之间实现数据共享。

数据卷是一个位于宿主机上的目录或文件,可以被Docker容器挂载使用。它允许容器和宿主机之间,或者容器和容器之间共享数据。数据卷的设计目的是为了数据的持久化,即数据不会随着容器的删除而丢失,完全独立于容器的生存周期。

数据卷是由 Docker 管理的持久化数据存储区域,用于在容器之间共享和持久化数据。Docker 会在主机的特定位置(通常是 /var/lib/docker/volumes/ 目录下)创建数据卷目录。

1、使用方式

数据卷可以通过Docker命令行工具进行创建、挂载、查看和管理。常用的命令包括:

  • docker run -v /宿主机路径:/容器内路径 ...:在创建容器时挂载数据卷。
  • docker volume create:显式创建一个数据卷。
  • docker volume ls:列出所有数据卷。
  • docker volume inspect:查看数据卷的详细信息。
  • docker volume rm:删除数据卷。

2、匿名挂载和具名挂载

  • 匿名挂载:没有指定数据卷名称,只指定了容器内路径。
  • 具名挂载:在-v或--mount标志中指定了数据卷的名称和容器内路径。

二、Docker支持的三种数据挂载方式

Docker提供了三种不同的方式将数据从宿主机挂载到容器中:卷挂载(Volume Mounts)、绑定挂载(Bind Mounts)和临时文件系统挂载(tmpfs Mounts)。

  • volume:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes),是Docker默认存储数据方式。
  • bind mounts:可以存储在宿主机系统的任意位置。将宿主机的任意位置的文件或者目录挂载到容器中。
  • tmpfs mounts:挂载存储在宿主机系统的内存中,不会写入宿主机的文件系统。

三、卷挂载(Volume Mounts)

卷挂载是Docker提供的一种持久化存储方式,它将容器内的数据存储在宿主机上的一个目录里。这个目录由Docker管理,通常位于 /var/lib/docker/volumes/ 这个路径下。当容器被删除后,数据卷中的数据不会被删除,实现了数据的持久化。卷挂载支持具名数据卷挂载(Named Volumes)和匿名数据卷挂载(Anonymous Volumes)这两种方式。

1、具名数据卷挂载

特点:具名数据卷在创建时会被分配一个用户指定的名称,这个名称在Docker主机上是唯一的。这使得数据卷的管理变得更为直观和方便。

创建方式:可以通过docker volume create命令显式创建具名数据卷,或者在docker run命令中通过-v或--mount选项并指定一个名称(而非路径)来隐式创建。

示例:

  • 显式创建:docker volume create my-named-volume
  • 隐式创建并挂载:docker run -d --name my-container -v my-named-volume:/app/data nginx 或 docker run -d --name my-container --mount source=my-named-volume,target=/app/data nginx

优势:具名数据卷独立于容器的生命周期,即使容器被删除,数据卷也会保留在Docker主机上,除非显式删除数据卷。这使得数据持久化和容器迁移变得更加容易。

语法示例:

# 创建一个名为nginx_volume的数据卷(命名卷)
docker volume create nginx_volume

# 查看当前所有数据卷
docker volume ls

# 查看数据卷的详细信息
docker volume inspect nginx_volume

# 启动容器时将数据卷挂载到容器内的 /usr/share/nginx/html 目录
docker run -d -p 8090:80 --mount type=volume,source=nginx_volume,target=/usr/share/nginx/html --name nginx-container nginx:latest
或
docker run -d -p 8090:80 -v nginx_volume:/usr/share/nginx/html --name nginx-container nginx:latest

# 查看docker容器列表
docker ps -a  #所有容器列表(包含存活和退出容器)
docker ps -l   #列出当前运行的最后一个容器

# 查看容器具体信息
docker inspect nginx-container  #容器ID或名称

演示:

[root@localhost ~]# docker volume create nginx_volume
nginx_volume
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     nginx_volume
[root@localhost ~]# docker volume inspect nginx_volume
[
    {
        "CreatedAt": "2024-09-06T23:28:09+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/nginx_volume/_data",
        "Name": "nginx_volume",
        "Options": null,
        "Scope": "local"
    }
]
[root@localhost ~]# docker run -d -p 8090:80 -v nginx_volume:/usr/share/nginx/html --name nginx-container nginx:latest
eab6771135908196d70df10b604c5566b14571b52d806b205c8607737a85b370
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS                                   NAMES
eab677113590   nginx:latest   "/docker-entrypoint.…"   12 seconds ago   Up 11 seconds   0.0.0.0:8090->80/tcp, :::8090->80/tcp   nginx-container
[root@localhost ~]# docker inspect nginx-container
......

其中 "Mountpoint": "/var/lib/docker/volumes/nginx_volume/_data" 表示这个卷在宿主机上的挂载点(即:数据卷的工作目录)。Docker会将这个目录下的数据挂载到容器内的指定位置,供容器使用。这里的 _data 目录是Docker在创建卷时自动创建的,用于存储实际的数据。

验证数据卷是否挂载成功:

[root@localhost ~]# cd /var/lib/docker/volumes/nginx_volume/_data
[root@localhost _data]# echo "hello world" >> test.html
[root@localhost _data]# ll
总用量 12
-rw-r--r--. 1 root root 497 8月  12 22:21 50x.html
-rw-r--r--. 1 root root 615 8月  12 22:21 index.html
-rw-r--r--. 1 root root  12 9月   6 23:42 test.html
[root@localhost _data]# curl 192.168.4.250:8090/test.html
hello world
[root@localhost _data]# docker ps -l
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS                                   NAMES
eab677113590   nginx:latest   "/docker-entrypoint.…"   19 minutes ago   Up 19 minutes   0.0.0.0:8090->80/tcp, :::8090->80/tcp   nginx-container
[root@localhost _data]# docker exec -it eab677113590 /bin/bash
root@eab677113590:/# cd /usr/share/nginx/html
root@eab677113590:/usr/share/nginx/html# ls
50x.html  index.html  test.html

我们在宿主机数据卷里新增了一个test.html文件,进入到Docker容器内部的指定目录下也可以看到该文件,并且通过浏览器也能正常访问到该文件,证明我们的数据卷挂载成功了。

命名卷是数据卷的一种特殊形式,具有明确的名称,可以更容易地管理和引用。

2、匿名数据卷挂载

特点:匿名数据卷在创建时没有明确的名称,Docker会自动为其分配一个随机ID作为标识。这使得它们的管理相对复杂,因为需要通过其他方式(如docker volume ls)来查找和识别。

创建方式:通常是在docker run命令中使用-v或--mount选项时,只指定容器内的挂载点,而不指定数据卷的名称或主机路径。Docker会自动为这样的挂载点创建一个匿名数据卷。

示例:docker run -d --name my-container -v /app/data nginx 或 docker run -d --name my-container --mount type=volume,target=/app/data nginx(注意,这里虽然使用了--mount但没有指定source,因此会创建匿名卷)

注意:由于匿名数据卷没有明确的名称,因此在管理和维护上可能会更加困难。特别是当需要删除不再使用的数据卷时,可能需要额外的步骤来识别和删除它们。因此非必要不推荐使用该方式挂载。

语法示例:

# 使用匿名数据卷挂载启动一个nginx容器,Docker会自动创建一个匿名数据卷并将其挂载到容器内的 /usr/share/nginx/html 这个路径上
docker run -d -p 8091:80 --mount type=volume,target=/usr/share/nginx/html --name nginx-container-2 nginx:latest
或
docker run -d -p 8091:80 -v /usr/share/nginx/html --name nginx-container-2 nginx:latest

演示:

[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     nginx_volume
[root@localhost ~]# docker run -d -p 8091:80 -v /usr/share/nginx/html --name nginx-container-2 nginx:latest
dfbe28444ded76b621e4cf61df67336b2ce3d837445e5244ed0de3b9e928de5f
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     161adf8452b212bbd9a41a2715f6152bd0d9963c011d4d505311b4beddee102b
local     nginx_volume
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS                     PORTS                                   NAMES
dfbe28444ded   nginx:latest   "/docker-entrypoint.…"   29 seconds ago   Up 28 seconds              0.0.0.0:8091->80/tcp, :::8091->80/tcp   nginx-container-2
eab677113590   nginx:latest   "/docker-entrypoint.…"   20 hours ago     Exited (255) 2 hours ago   0.0.0.0:8090->80/tcp, :::8090->80/tcp   nginx-container

上面那个名字很长的数据卷就是匿名数据卷。

四、绑定挂载(Bind Mounts)

Docker 的绑定挂载(Bind Mounts)允许你将宿主机上的一个目录或文件挂载到容器内部的一个目录或文件上。这种方式非常适合在开发环境中使用,因为它允许你在容器外编辑文件,同时容器内可以看到文件的变化。

语法示例:

# 启动nginx容器,将宿主机的 /opt/nginx 目录挂载到容器内的 /usr/share/nginx/html 目录
docker run -d -p 8090:80 --mount type=bind,source=/opt/nginx,target=/usr/share/nginx/html --name nginx-container nginx:latest
或
docker run -d -p 8090:80 -v /opt/nginx:/usr/share/nginx/html --name nginx-container nginx:latest

演示:

在宿主机 /opt 目录下创建一个 nginx 文件夹,并在 nginx 文件夹里面添加一个 test.html 文件:

[root@localhost ~]# cd /opt
[root@localhost opt]# mkdir nginx
[root@localhost opt]# cd ./nginx/
[root@localhost nginx]# echo "hello world" >> test.html
[root@localhost nginx]# ll
总用量 4
-rw-r--r--. 1 root root 12 9月   7 23:48 test.html

启动nginx容器,将宿主机的 /opt/nginx 目录挂载到容器内的 /usr/share/nginx/html 目录:

[root@localhost nginx]# docker run -d -p 8092:80 --mount type=bind,source=/opt/nginx,target=/usr/share/nginx/html --name nginx-container-2 nginx:latest
468e94b76c55b4df2ccf4d0039940e1aa03e74e9d031dfcc0b1e6f03471024c1

进入Docker容器内部,查看容器内 /usr/share/nginx/html 目录下的文件列表:

[root@localhost nginx]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS                     PORTS                                   NAMES
468e94b76c55   nginx:latest   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes               0.0.0.0:8092->80/tcp, :::8092->80/tcp   nginx-container-2
eab677113590   nginx:latest   "/docker-entrypoint.…"   25 hours ago    Exited (255) 6 hours ago   0.0.0.0:8090->80/tcp, :::8090->80/tcp   nginx-container
[root@localhost nginx]# docker exec -it nginx-container-2 /bin/bash
root@468e94b76c55:/# cd /usr/share/nginx/html
root@468e94b76c55:/usr/share/nginx/html# ls
test.html

可以发现并没有 nginx 默认的 index.html 和 50x.html 文件,只有来自宿主机上面的 test.html 文件。

可以使用 exit 命令退出容器:

root@468e94b76c55:/usr/share/nginx/html# exit
exit
[root@localhost nginx]#

注意:

1、如果你使用 Bind mounts 挂载宿主机目录到一个容器中的非空目录,那么此容器中的非空目录中的文件会被隐藏,容器访问这个目录时能够访问到的文件均来自于宿主机目录下的文件。

2、-v 宿主机目录路径必须以 / 或 ~/ 开头,否则Docker会将其当成是 Volume Mounts 而不是 Bind Mounts 。

五、临时文件系统挂载(tmpfs Mounts)

tmpfs挂载(也称为内存文件系统挂载)是一种特殊的挂载类型,它将数据存储在容器的内存中而不是磁盘上。tmpfs主要用于需要快速读写操作的场景,或者是那些需要在容器启动时清空数据的场景。

tmpfs mount只在Linux主机内存中持久化,是临时性的。当容器停止,tmpfs mount会被移除,通常用于临时存放敏感文件。

语法示例:

# 运行容器并绑定临时数据卷
docker run -d -p 8090:80 --mount type=tmpfs,target=/usr/share/nginx/html --name nginx-container nginx:latest

演示:

[root@localhost ~]# docker run -d -p 8093:80 --mount type=tmpfs,target=/usr/share/nginx/html --name nginx-container-3 nginx:latest
cb971be9d9316c300e74155f3069de5a7639ece74d5cb63638c0f018b4b9f0bd
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                   CREATED         STATUS                      PORTS                                   NAMES
cb971be9d931   nginx:latest   "/docker-entrypoint.…"   6 seconds ago   Up 5 seconds                0.0.0.0:8093->80/tcp, :::8093->80/tcp   nginx-container-3
eab677113590   nginx:latest   "/docker-entrypoint.…"   38 hours ago    Exited (255) 19 hours ago   0.0.0.0:8090->80/tcp, :::8090->80/tcp   nginx-container
[root@localhost ~]# docker exec -it nginx-container-3 /bin/bash
root@cb971be9d931:/# cd /usr/share/nginx/html
root@cb971be9d931:/usr/share/nginx/html# ls
root@cb971be9d931:/usr/share/nginx/html# echo "hello world" >> test.html
root@cb971be9d931:/usr/share/nginx/html# ls
test.html
root@cb971be9d931:/usr/share/nginx/html# exit
exit
[root@localhost ~]# curl 192.168.4.250:8093/test.html
hello world
[root@localhost ~]#

注意事项:

  • tmpfs 中的数据在容器停止或重启时会被清除。
  • tmpfs 的大小受到宿主机可用内存的限制。
  • tmpfs 适用于需要高速读写操作的场景,如缓存或临时文件存储。
  • 由于 tmpfs 存储在内存中,它有助于提高安全性,因为数据不会永久驻留在磁盘上。
  • 如果 tmpfs 中的数据量很大,可能会导致容器启动时加载较慢。

六、三种存储方式适用场景

volume mount:

  • 多个容器间共享数据。
  • 宿主机不保证存在固定目录结构。
  • 持久化数据到远程主机或者云存储而非本地。
  • 需要备份、迁移、合并数据时。停止container,将volume整体复制,用于备份、迁移、合并等。

bind mount:

  • 主机与容器共享配置文件,如docker将宿主机文件/etc/resov.conf文件bind mount到容器上,两者会使用相同的DNS服务器。
  • 共享源代码或build artifacts(比如将Maven的target/目录挂载到容器中,每次在Docker主机中build Maven工程时,容器能够访问到那些rebuilt artifacts)。
  • 当 docker主机中的文件或目录结构和容器需要一致时。

tmpfs mount:

  • 既不想将数据存于主机,又不想存于容器中时(这可以是出于安全的考虑,或当应用需要写大量非持久性的状态数据时为了保护容器的性能)。

 

至此本文就全部介绍完了,如果觉得对您有所启发请记得点个赞哦!!!

标签:容器,持久,root,volume,nginx,html,Docker,数据,docker
From: https://www.cnblogs.com/xyh9039/p/18397502

相关文章

  • <数据集>二维码识别数据集<目标检测>
    数据集格式:VOC+YOLO格式图片数量:1601张标注数量(xml文件个数):1601标注数量(txt文件个数):1601标注类别数:1标注类别名称:['QR']序号类别名称图片数框数1QR16016286使用标注工具:labelImg标注规则:对类别进行画水平矩形框图片示例:标注示例:......
  • 【Redis】redis5种数据类型(string)
    目录redis5种数据类型和内部编码方式redis单线程模型 string字符串类型相关命令SETGETMSETMGET SETNXSETEX​编辑PSETEXvalue值为整数,进行加减操作INCRINCRBYDECRDECRBYINCRBYFLOATAPPENDGETRANGESETRANGESTRLENstring的内部编码redis5种数据类型......
  • 阿狸教你怎么恢复微信数据
    大家好我是零距离工作室主理阿狸,最近工作室接到很多订单,大多都是关于微信数据恢复的,而且尤其以恢复微信聊天记录为多。在当今这个世界上,微信已然成为我们日常生活中不可或缺的一款软件。它在我们的社交、工作以及各种日常交流场景中都发挥着至关重要的作用,无论是与亲朋好友保持......
  • LazyForEach:数据懒加载
    文章目录前言一、LazyForEach是什么?LazyForEach懒加载的原理和渲染过程使用限制二、使用步骤1.实现提供的一个IDataSource的接口2.将数据包装到对象中,实现一系列增删改查的方法3.ForEach替换为LazyForEach即可总结前言在HarmonyOS中,我们经常会遇到长列表加载的......
  • WGCLOUD使用指南 - 监测数据库的连通性
    数据可视化监测是WGCLOUD的一个重要模块,可以帮我们监控数据源是否在线,自定义sql查询数据进行可视化展示,比如新增订单、注册用户量、数据库运行参数等信息数据监控是由server来监测的,因此要保证server主机能够访问到数据库如果server无法访问被监控的数据源,怎么监控 1、......
  • 【国外比较权威的免费的卫星数据网站——ESA’s Sentinel Mission】
    ESA’sSentinelMission(欧洲航天局的哨兵系列卫星任务)是欧洲哥白尼(Copernicus)计划空间部分的核心组成部分,旨在通过一系列专用卫星提供连续、高质量的地球观测数据。以下是对ESA’sSentinelMission的详细介绍:一、任务概述哨兵系列卫星由欧洲委员会投资,欧洲航天局(ESA)负责......
  • docker容器手动更新(备忘)
    背景:nas服务中使用docker安装了思源笔记,需要对容器进行更新;我的容器是使用docker-compose文件创建的。更新步骤拉取最新镜像sudodocker-composepullsiyuan重新创建容器sudodocker-composeup-dsiyuan我的docker-compose.yamlversion:'3'#网络networks:my......
  • 掌握动态图表:使用Python的Matplotlib库实现动态数据可视化
    在数据可视化领域,Matplotlib库是Python中最流行和功能强大的工具之一。它能够生成各种静态图表,如散点图、折线图和柱状图等。然而,Matplotlib也提供了创建动态图表的功能,使得我们能够以动画的方式展示数据的变化趋势,从而更直观地理解数据。本文将介绍如何使用Matplotlib库创建动态图......
  • 数据分析训练模型后输出模型评估报告
    数据分析训练模型后输出模型评估报告1、模型评估指标1.1、概念:A:n个正样本,检测到是真值的数量B:m个负样本,检测到是真值的数量C:n个正样本,检测到假值的数量D:m个负样本,检测到假值的数量1.2、准确率(Accuracy)正确预测的样本数量与总样本数量的比值。优点:易于理解和计......
  • 微信小程序开发系列3----页面配置--WXML数据绑定+条件渲染
    1小程序布局-WXML数据绑定有的时候发现需要刷新一下全局的app.js才能有效果。。。。。  2小程序布局-WXML条件渲染  下图会报错:不能在ifelse中间插入其他的标签  如下展示一次渲染多个标签使用block 源码获取方式(免费):(1)登录-注册:http://resources.kittytig......