容器中的数据可以存储在容器层。但是将数据存放在容器层存在以下问题:

  • 数据不是持久化。意思是如果容器删除了,这些数据也就没了

  • 主机上的其它进程不方便访问这些数据

  • 对这些数据的I/O会经过存储驱动,然后到达主机,引入了一层间接层,因此性能会有所下降

Docker 提供了3种持久化数据的方式:

  1. volumes:存于主机文件系统中的某个区域,由Docker管理(/var/lib/docker/volumes/ on linux)。非Docker进程不应该修改这些数据。卷是Docker中持久化数据的最好方式

  2. bind mount:存于主机文件系统中的任意位置。非Docker进程可以修改这些数据

  3. tmpfs mount(Linux中):存于内存中(注意,并不是持久化到磁盘)。在容器的生命周期中,它能被容器用来存放非持久化的状态或敏感信息

volumes

如果没有显式创建,一个卷会在最开始挂载时被创建。当容器停止时,卷仍然存在。多个容器可以通过read-write或read-only的方式使用同一个卷。

只有在显式删除时,卷才会被删除。如果将一个空卷挂载到容器中一个存有文件或目录的目录中,这些文件或目录会被拷贝到空卷中;如果将一个非空卷挂载到容器中一个存有文件或目录的目录中,这些文件或目录会被隐藏。

使用

  • 创建:docker volume create

  • 删除某个卷:docker volume rm 卷名

  • 删除所有未使用的卷:docker volume prune

  • 列出所有卷:docker volume ls

  • 查看某个卷的信息:docker volume inspect 卷名

  • 挂载到容器:-v--volume。如果是Docker17.06或更高:推荐使用--mount。(同 bind mount)

    • 挂载类型:key为type,value为bind、volume或tmpfs

    • 挂载源:key为source或src,对于命名卷,value为卷名,对于匿名卷,则忽略

    • 容器中的挂载点:key为destination、dst或target,value为容器中的路径

    • 读写类型:value为readonly,没有key

    • volume-opt选项,可以出现多次。比如volume-driver=local,volume-opt=type=nfs,…

    • 第一个域:对于命名卷,为卷名;匿名卷,则忽略,此时会创建匿名卷

    • 第二个域:容器中的挂载点

    • 第三个域:可选参数,由','隔开,如ro

    • -v或—volume:由3个域组成,’:’分隔

    • —mount:由多个’,’隔开的键值对

      =组成:

当使用docker service create 启动Docker服务时,只支持--mount,不支持-v--volume。并且每个服务容器使用它们各自的本地卷,因此如果使用本地(local)卷驱动,容器无法通过卷共享数据,但是一些卷驱动支持共享存储。Docker for AWS和Doocker for Azure都使用Cloundstor plugin支持持久存储

场景

  • 多个运行容器间共享数据

  • 当Docker主机不确保具有给定的目录或文件时。卷可以将容器运行时与Docker主机的配置解耦合

  • 备份、恢复、或将数据从一个Docker主机迁移到另一个Docker主机时

bind mount

主机中的文件或目录通过全路径被引用。在使用绑定挂载时,这些目录或文件不一定要已经存在。

如果使用这种方式将一个目录挂载到容器中一个存有文件或目录的目录中,这些文件或目录会被隐藏;如果主机中的文件或目录不存在,当使用--mount挂载时,Docker会报错,当使用-v--volume时,会在主机上创建目录

使用

挂载到容器:-v或—volume。如果是Docker17.06或更高:推荐使用—mount。(同 volumes)

  • -v--volume:由3个域组成,':'分隔

    • 第一个域:对于命名卷,为卷名;匿名卷,则忽略,此时会创建匿名卷

    • 第二个域:容器中的挂载点

    • 第三个域:可选参数,由','隔开,如ro

  • --mount:由多个','隔开的键值对<key>=<value>组成:

    • 挂载类型:key为type,value为bind、volume或tmpfs

    • 挂载源:key为source或src,value为主机中文件或目录的路径

    • 容器中的挂载点:key为destination、dst或target,value为容器中的路径

    • 读写类型:value为readonly,没有key

    • bind-propagation选项:key为bind-propagation,value为rprivate、private、rshared、shared、rslave或slave

    • 一致性选项:value为consistent、delegated、cached。这个选项仅仅适用于Docker for Mac

    • --mount不支持z和Z(这个不同于-v和—volume)

场景

大体上来说,只要可能,最好使用volumes

  • 主机与容器共享配置文件(Docker默认情况下通过这种方式为容器提供DNS解析,通过将/etc/resolv.conf挂载到容器中)

  • 共享源代码或build artifacts(比如将Maven的target/目录挂载到容器中,每次在Docker主机中build Maven工程时,容器能够访问到那些rebuilt artifacts)

  • 当 docker主机中的文件或目录结构和容器需要的一致时

bind propagation

对于bind mount和volumes,默认都是rprivate。只有在使用bind mount时可配置,且必须在linux下。bind propagation是个超前主题,对于大多数用户来说,并不需要配置

对于一个挂载点/mnt,假设它同时也被挂载到/tmp。bind propagation控制 whether a mount on /tmp/a would also be available on /mnt/a

在设置bind propagation之前,主机文件系统需要支持bind propagation

下面的例子将主机中的target/挂载到容器中2次:

docker run -d \-it \--name devtest \--mount type=bind,source="$(pwd)"/target,target=/app \--mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave \nginx:latest

此时如果创建/app/foo//app2/foo也会存在

selinux label

你能添加zZ选项来修改挂载到容器中的主机文件或目录的selinux label:

  • z选项指明bind mount的内容在多个容器间是共享的

  • Z选项指明bind mount的内容是私有不共享的

要特别小心的使用这两个选项。”Bind-mounting a system directory such as /home or /usr with the Z option renders your host machine inoperable and you may need to relabel the host machine files by hand”

tmpfs mount

只在linux中支持

相对于volumes和bind mount,tmpfs mount是临时的,只在主机内存中持久化。当容器停止,tmpfs mount会被移除。对于临时存放敏感文件很有用

不同于volumes和bind mount,多个容器无法共享tmpfs mount

使用

  • 挂载到容器:—tmpfs。如果是Docker17.06或更高:推荐使用—mount

    • 挂载类型:key为type,value为bind、volume或tmpfs

    • 容器中的挂载点:key为destination、dst或target,value为容器中的路径

    • tmpfs-size和tmpfs-mode选项

    • —tmpfs:直接指定容器中的挂载点。不允许指定任何配置选项

    • —mount:由多个’,’隔开的键值对

      =组成:

场景

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

volume drivers

机器间共享数据

当构建错误容忍应用时,可能需要配置同一个服务的多个副本来访问相同的文件:

有多种方法来实现这个目的:

  • 为应用添加逻辑,将文件存储到一个云对象存储系统(如Amazon S3)中

  • 使用一个支持将文件写入外部存储系统(如NFS或Amazon S3)的driver来创建卷

volume drivers可以将底层存储系统从应用逻辑中抽象出来。比如,如果你的服务使用一个具有NFS driver的卷,你能更新你的服务使用不同的driver,作为在云中存储数据的示例,而不更改应用程序逻辑

使用

在使用docker volume create或驱动容器创建匿名卷时,可以指定一个volume drivers。下面的例子使用vieux/sshfs作为volume drivers

假设有2个节点,第一个节点是Docker主机,它能SSH到第二个节点

1、在Docker主机中,安装vieux/sshfs插件

docker plugin install --grant-all-permissions vieux/sshfs

2、使用卷驱动创建卷
1)创建命名卷

docker volume create --driver vieux/sshfs \-o sshcmd=test@node2:/home/test \-o password=testpassword \sshvolume

2)启动容器时使用卷驱动创建匿名卷

docker run -d \--name sshfs-container \--volume-driver vieux/sshfs \--mount src=sshvolume,target=/app,volume-opt=sshcmd=test@node2:/home/test,volume-opt=password=testpassword \nginx:latest

3、备份、恢复、迁移数据卷
1)备份一个容器

docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
  • 启动一个新容器,挂载dbstore容器中的卷

  • 挂载一个本地主机目录到容器/backup

  • 使用tar将dbdata卷中的数据打包成backup.tar

2)用备份恢复容器
使用刚刚创建的备份来恢复容器:

docker run -v /dbdata --name dbstore2 ubuntu /bin/bash

然后,在新创建的容器的卷中使用tar解包备份的数据:

docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /dbdata && tar xvf /backup/backup.tar --strip 1"

Docker 数据持久化的三种方案相关推荐

  1. 多租户数据隔离的三种方案

    一.多租户在数据存储上存在三种主要的方案,分别是: 1. 独立数据库 这是第一种方案,即一个租户一个数据库,这种方案的用户数据隔离级别最高,安全性最好,但成本较高. 优点: 为不同的租户提供独立的数据 ...

  2. mongo数据同步的三种方案

    (一)直接复制data目录(需要停止源和目标的mongo服务) 1.针对目标mongo服务已经存在,并正在运行的(mongo2-->mongo). 执行步骤: (1).停止源/目标服务器的mon ...

  3. docker容器运行mysql持久化_docker容器实现数据持久化的两种方式及其区别

    前言 这篇博文是我对docker实现数据持久化几种方式的特征进行一个总结. 在docker中,它的存储文件系统是在dockerhost上原有的xfs或ext4架设了一层文件系统:overlay2(将此 ...

  4. sql优化之:数据库索引创建原则,or/in/union与索引优化,聚集索引/非聚集索引/联合索引/索引覆盖,MySQL冗余数据的三种方案,MySQL双主一致性架构优化(来源:架构师之路)

    一.一些常见的SQL实践 (1)负向条件查询不能使用索引 select * from order where status!=0 and stauts!=1 not in/not exists都不是好 ...

  5. mysql数据冗余_MySQL冗余数据的三种方案

    一,为什么要冗余数据 互联网数据量很大的业务场景,往往数据库需要进行水平切分来降低单库数据量. 水平切分会有一个patition key,通过patition key的查询能够直接定位到库,但是非pa ...

  6. docker学习笔记(四)docker数据持久化volume

    docker数据持久化 官网:https://docs.docker.com/storage/volumes/ docker中的容器是可以随时销毁的,容器中的数据会随着容器的消亡而消亡.然而很多容器都 ...

  7. Redis 消息队列的三种方案选型

    文章目录 Redis 消息队列的三种方案选型 消息队列(Message Queue,简称 MQ) 消息队列使用场景 Redis 消息队列应用背景,选型思考 Redis消息队列发展历程 在Redis中提 ...

  8. 【Win 10 应用开发】文件读写的三种方案

    本文老周就跟伙伴们探讨一下关于文件读写的方法.总得来说嘛,有三种方案可以用,而且每种方案都各有特色,也说不上哪种较好.反正你得记住老祖宗留给我们的大智慧--事无定法,灵活运用者为上. OK,咱们开始吧 ...

  9. 数据脱敏的 6 种方案

    一.什么是数据脱敏 英文全称:Data Masking . 先来看看什么是数据脱敏?数据脱敏也叫数据的去隐私化,在我们给定脱敏规则和策略的情况下,对敏感数据比如 手机号.银行卡号 等信息,进行转换或者 ...

最新文章

  1. 1.5K star量,上古老番变4K,B站开源超分辨率算法
  2. [异常解决] ubuntu上安装虚拟机遇到的问题(vmware坑了,virtual-box简单安装,在virtual-box中安装精简版win7)
  3. 经典动态规划之过河卒【洛谷 P1002】
  4. 详解「递归」正确的打开方式
  5. Go中bytes.Buffer理解
  6. 学习方法之01高效学习方程式,你的学习到底是哪里出了问题
  7. @RunWith@ContextConfiguration进行Spring上下文测试报错
  8. python21天打卡Day10-string和bytes互转
  9. Redis主从复制和集群配置
  10. window.open()
  11. 05.javascript访问CSS
  12. 共模电感适用的频率_共模电感差模分量计算
  13. springcloudalibaba 架构图_Spring Cloud Alibaba 架构实战
  14. CORS(跨域资源共享) 的配置
  15. GD32F303 移植 FreeRTOS
  16. TwinCAT 3 首次运行报错4115
  17. 摘自《大江大河1949》
  18. strtoupper php 中文,strtoupper来导致中文乱码么
  19. CVE-2021-1647:Microsoft Defender远程代码执行漏洞通告
  20. 从大数据看技术,为什么天猫双11是史上最大数字经济节日

热门文章

  1. mysql 用户管理表_mysql用户管理
  2. Python str 函数 - Python零基础入门教程
  3. Linux服务器硬盘更换,[ Linux ] 服务器更换硬盘
  4. 搭建java_搭建JAVA环境
  5. move std 函数 示例_C++ STL迭代器辅助函数
  6. mysql for loop_MySQL循环语句 - Linux就该这么学的个人空间 - OSCHINA - 中文开源技术交流社区...
  7. shader 获取法线_Unity Shader 入门到改行5——法线贴图
  8. 整活插件 炉石传说_酒馆战旗整活插件 免安装版
  9. html5怎么改为vue_Vue实战——编程式导航打开新窗口,登录状态本地存储
  10. qt 飞扬青云_Qt编写带频谱的音乐播放器