在Docker容器内部创建的文件默认存储在可写的容器层,容易产生几个问题:

  • 当容器不存在时,数据文件不能持久化,同时这些数据文件不方便在容器之外被其他进程使用。
  • 当容器运行的时候容器可写层严重依赖宿主机,不能轻易移动这些数据文件到其他地方。
  • 在容器层写数据文件需要存储驱动(storage driver)来管理文件系统,存储驱动使用Linux内核提供的联合文件系统, 与data volumes直接将文件写到宿主机文件系统相比,性能降低。

Docker为容器提供了两种方式将数据文件存储到宿主机上,即使容器停止运行或者被删除数据文件都可以持久化,这两种方式分别为 volumes与bind mounts,当然如果Docker容器在Linux运行,也可以使用tmpfs mounts。不管使用哪种mount方式,数据文件在Docker容器内部文件系统中是相同的, 要么是一个文件夹,或者一个独立的文件。

  • volumes 存储在Docker安装目录下,在Linux上默认指的是/var/lib/docker/volumes,Docker会自动管理,非Docker进程不应该修改这些文件系统,volumes是在Docker中是最好的数据持久化方式。
  • bind mount 存储在宿主机文件系统的任何地方,宿主机上的非Docker进程或者Docker容器都可以在任何时候修改它。
  • tmpfs mount 始终存储在宿主机系统内存中,不会被写到宿主机的文件系统中。

详细介绍

  • volumes

Docker会自动创建并管理volumes,当然可以通过命令docker volumes create明确的创建一个volume,当成功创建了一个volume时,它存储在宿主机的某个目录下, 当把这个volume挂载到一个Docker容器时,这个目录自然会挂载到容器内部,volumes与bind mount工作方式类似,除了volumes是被Docker自动管理以及隔离性, 两者没什么区别。

[root@ins ~]# docker volume create mmmm[root@ins ~]# docker volume createcc0613fe5a32273134a76e5670f166f6e248634e909d64cf00061130086f5ae5[root@ins ~]# docker volume lsDRIVER VOLUME NAMElocal cc0613fe5a32273134a76e5670f166f6e248634e909d64cf00061130086f5ae5local mm[root@ins ~]# 

一个volume可以同时挂载到多个Docker容器,当没有任何Running状态的容器使用这个volume,这个volume仍然有效并且不会被自动删除,除非通过执行命令 docker volume prune进行删除。当挂载一个volume时,这个volume可能匿名或者有一个名字,当它首次挂载到容器中的时候如果Docker发现该volume没有一个明确的名字, 则会给它分配一个随机的名字,这个名字在Docker宿主机上是唯一的。

volumes支持volume driver,允许通过driver将数据存储到远程机器或者云厂商等。

  • bind mounts

这种方式与volumes相比,有一些功能限制。当使用bind mounts时,宿主机上的一个文件或者目录被挂载到Docker容器中,这个文件或者目录通过它在 宿主机上的完整路径名被引用,他们在宿主机上不是必须存在的,在需要的时候Docker会自动创建它。bind mounts非常高效,但是他们依赖于宿主机文件系统明确的目录结构, 同时通过Docker CLI命令无法直接管理这些bind mounts。

注意:正在运行的容器中进程可以直接改变宿主机上的文件系统,包括创建、修改以及删除重要的文件或者目录,会引发安全风险问题,影响宿主机上运行的其它非Docker进程,请注意控制权限。

  • tmpfs mounts

这种方式不能将数据持久化到磁盘,一个tmpfs可以被一个容器在整个生命周期内使用,用于存储一些非持久状态或者敏感数据,比如swarm services使用tmpfs将secrets 挂载到service的容器中。

volumes与bind mounts都能通过-v 或者 --volume flag参数挂载到容器中,对于 tmpfs mount,可以使用--tmpfs flag参数,在Docker17.06以及更高版本中, 推荐使用--mount,对于这三种方式--mount语法更明确。


三种方式优点

volumes可以在多个运行的容器之间共享,解耦Docker容器与宿主机文件系统,支持存储远程以及云厂商,方便在不同的Docker机器上迁移数据。

bind mounts可以让多个容器共享宿主机文件,比如Docker就是通过将/etc/resolv.conf挂载到每个容器方式实现DNS解决方案,开发的时候可以共享项目源代码,在容器内编译运行。

tmpfs保存敏感数据,非持久化数据,由于保存在内存中,相比文件系统性能更高。

默认规则:

  • 如果将一个空的volumes挂载到容器内的某个目录,如果该目录中已经有一些文件或者目录,那么这些文件或者目录会直接复制到volumes中。
  • 如果将一个bind mount或者非空volume挂载到容器的某个目录,这个目录中已经存在文件或者目录,那么这个目录中的文件或者目录会被mount覆盖,被覆盖的文件或者目录只是暂时被隐藏,当移除挂载时即可恢复。

使用介绍

早期,Docker都是通过flag -v或者--volume给单机容器实现挂载,而swarm service则是通过 flag --mount实现,在Docker 17.06版本开始,--mount也适用于单机容器挂载,该命令的 语法更灵活明确,在使用-v或者--volume时尽量使用--mount代替。

-v or –volume

-v db:/var/lib/mysql,通过英文冒号分隔,如果volume有名字,冒号之前的是volume,如果volume匿名,则直接 -v /var/lib/mysql,如果需要控制容器读写volume权限,可以 -v db:/var/lib/mysql:ro

–mount

--mount包含许多以英文逗号分隔的key-value键值对,它的语法比-v以及--volume更详细,key的顺序无关紧要,主要包含以下key(只列举部分)

  • type 它的值可以为 volume、bind或者tmpfs
  • source 对于已命名的volume,source即为volume名字,volume匿名,则该值为空,source也可定义为src
  • destination 指定挂载到容器中的path路径,可以定义为dst、destination或者target
  • readonly 如果存在,则被挂载的volume在容器中只能读
  • volume-opt 可选参数,可以定义多次,key-value形式

基础使用

创建一个volume

docker volume create sunjinfu

查看volume

docker inspect sunjinfu[ { "CreatedAt": "2019-04-20T15:00:12+08:00

docker 挂载目录_Docker容器数据管理相关推荐

  1. docker 挂载目录_完美解决:Docker部署SpringBoot项目后图片无法访问和上传,3招搞定!...

    以前使用FTP在Linux中使用java -jar xxx.jar部署SpringBoot项目时,由于在项目中指定了主机文件存放路径映射,可以直接访问服务器的文件. 但是最近入坑Docker,将Spr ...

  2. docker挂载内容与容器内容不同步(有时候延迟同步)

    记录:docker挂载内容与容器内容不同步,有时候等很久后才会同步 网上查找的其他参考都不符合,过程 略 今天突然想到,会不会是因为容器跟挂载目录所在磁盘不一致导致的? 原配置: windows 10 ...

  3. docker 内部ping不通宿主机_Docker容器数据管理

    在Docker容器内部创建的文件默认存储在可写的容器层,容易产生几个问题: 当容器不存在时,数据文件不能持久化,同时这些数据文件不方便在容器之外被其他进程使用. 当容器运行的时候容器可写层严重依赖宿主 ...

  4. Docker - 挂载目录(bind mounts)和Volume是不同的

    2019/10/25更新: docker commit是不能对容器中volume声明的目录改动进行保存的,无论是Dockerfile中的VOLUME字段,还是docker-compose.yaml中的 ...

  5. desktop docker 无法卸载_Docker容器无法停止或移除-权限被拒绝错误

    问题 :无法停止泊坞窗容器,每当我尝试停止容器时,都会收到以下错误消息, ERROR: for yattyadocker_web_1 cannot stop container: 1f04148910 ...

  6. docker run退出_docker容器run之后马上又自动关闭退出

    问题现象: centos 启动一个容器添加了-d 参数,但是docker ps 或者docker ps -a查看却已经退出了 shell>docker run -d centos f99e679 ...

  7. docker挂载目录原理

    One:JVM实践思维图(完整版) Two: 走近Java 概述+ Java技术体系+Java发展史+Java虚拟机家族:(Sun Classic/Exact VM.HotSpot VM.Mobile ...

  8. Docker 入门系列(4)- Docker 数据管理(挂载目录、挂载文件、数据卷挂载、数据卷共享、数据卷删除、数据卷容器备份和恢复)

    基于底层存储实现,Docker 提供了三种适用于不同场景的文件系统挂载方式:Bind Mount.Volume 和 Tmpfs Mount. Bind Mount 能够直接将宿主操作系统中的目录和文件 ...

  9. docker对已经启动的容器添加目录映射(挂载目录)

    文章目录 1. 背景 2. 开始新增挂载目录 3. 注意 1. 背景 在自己安装sharding-proxy时,使用docker run -v的方式启动时,只挂载了/opt/shardingspher ...

最新文章

  1. rabbitmq怎样确认是否已经消费了消息_【朝夕专刊】RabbitMQ生产者/消费者消息确认...
  2. 机器学习、超参数、最优超参数、网格搜索、随机搜索、贝叶斯优化、Google Vizier、Adviser
  3. Can't connect to local MySQL Server throught socket '/var/run/mysqld/mysqld.sock'(2)
  4. rocketmq sql解析过滤
  5. 沉思录---Windows Phone软件开发Beta版回首
  6. jmeter常用插件介绍
  7. java中pagex_Java/5_get和post比较.md at master · zaoshangyaochifan/Java · GitHub
  8. ubuntu安装linux deepin,如何在Ubuntu中安装Deepin终端 | MOS86
  9. 线上问题随笔记录数据库连接池问题
  10. 禅道开源版用户手册_Docker搭建开源版禅道以及项目基本流程介绍
  11. android 自定义switch控件,Android中switch自定义样式
  12. 随想录(在实践中学习kernel代码)
  13. 强化学习10-Deep Q Learning-fix target
  14. 洛谷 P1168 中位数(优先队列)
  15. IPQ8074板载12天线符合802.11ax标准双频工业级嵌入式无线AP主板
  16. 软件测试--面试时怎么介绍前公司的项目经验
  17. Rxjava2中Single的just操作符源码学习
  18. Linux下qt程序部署到ARM开发板上: error: Upload of file “你的程序“ failed. The server said: “Failure
  19. Windows平台下 C++注册表项重命名实现
  20. CMS 常见问题分析和解决方案

热门文章

  1. C Builder中如何利用消息
  2. oracle数据库卸载(需要完全卸载oracl才能重装)
  3. 文字滚动的另一方法 拆分文字来做到文字滚动
  4. (转)一段挺好的领导者应该记得的话
  5. 计算机网络(二十六)-IP数据报分片
  6. 浅析ThreadLocal
  7. springboot jar中没有主清单属性_Spring Boot 常见错误及解决方法
  8. sql server如何输出排序序号_Group by中子查询order by排序失效问题分析
  9. vlc 缓冲大小 设置_用libvlc 播放指定缓冲区中的视频流
  10. java进度条_自学java你需要知道的,适合编程小白