Docker容器Container镜像Image如何存储详解

 更新时间:2023年09月26日 14:11:37   作者:Mr_csc  
本文主要介绍Docker容器(Container)和镜像(Image)是如何进行数据存储详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

容器如何读写文件

镜像(Image)是由若干个层(Layer)所组成的,当用户使用image运行了一个container之后,就会在这个image的最上面再加上一个可读可写的layer,如下图所示:

除了最上面那一个layer是可读写的之外,下面的所有layer都是属于image的,都是只读的。

在container运行时,任何在container文件系统中写入和修改的数据都会被写入到最上层的可读写layer(这里不包括volume、bind mount和tmpfs这些持久化存储手段),并不会影响到下面的那些只读layer。当container运行结束的时候,最上层的可读写layer就会被丢弃,而下面的那些只读layer是属于image的,并不会受到影响。

这也就是为什么使用同一个image运行container,该container结束之后,重新使用该image启动一个新的container,上一个container写入和修改的数据全都不见了,用户能看见的依旧是当初编写Dockerfile时写入该image的那些数据的原因。

如果使用同一个image启动了多个container,那么这些container会有各自的最上层的可读写layer,但是下面的那些只读layer是共用的,如下图所示:

镜像的layer管理

一个image的多个layer并不是绑定和存储在一起的,它们之间是低耦合的。

使用docker pull命令拉取一个image的时候,并不是一次性拉取的,而是一个layer一个layer地拉取,然后存储在本机(在linux上默认是/var/lib/docker/<storage-driver>/下)。

一台主机中存在多个image时,有可能会出现多个image的某些layer相同的情况,那么此时在主机中就只会存储一份该layer,而不是存储多个。

那么问题来了:既然多个layer是分开存储的,那么用户在container中却可以看到所有的layer中存储的文件,这又是怎么做到的呢?这就涉及到了union file system和union mount。

可以通过docker image history以及docker image inspect来查看某个image的所有layer。

Copy On Write

当container想要更改原本就存在于image中的那些数据的时候该怎么办呢?那些数据是位于下面那些属于image的只读层的,因此肯定不能直接修改。Docker采用的解决方案一般是copy-on-write。

当container想要读取原本就存在于image中的数据时,直接从数据所在的只读layer读取即可。而如果想要修改原本就存在于image中的数据时,Docker就会先把要被修改的文件拷贝到最上层的属于container的可读写layer中,然后再在这个可读写的layer中进行数据的修改即可。

值得一提的是,哪怕是对文件的元数据(meta data)的修改(例如修改文件权限、所属用户等等),也会触发copy-on-write机制。

Docker有多种存储引擎(storage driver),不同的storage driver对copy-on-write的具体实现是不一样的。

注意:并不是所有的Docker存储引擎都支持copy on write的,例如vfs就不支持!

查看容器占用磁盘大小

使用docker ps -s来查看一个container在运行时占用的磁盘大小,例如:

SIZE指的是该container最上层的可读写layer的大小,而virtual指的是启动了该container的image的那些只读layer的大小。
需要注意的是,通过这个命令得到的container磁盘空间大小是不包括以下这些的:

  • log文件所使用的磁盘空间
  • volume和bind mount所使用的磁盘空间
  • container的配置文件所使用的磁盘空间
  • 内存交换所使用的磁盘空间
  • Checkpoints所使用的磁盘空间

Docker存储引擎

Docker在linux下提供了如下的存储引擎选项:

存储引擎描述
overlay2在linux上首选的存储引擎,不需要额外的配置
fuse-overlayfs推荐在运行rootless的Docker时使用
btrfs和zfs可以提供更多的功能,例如快照等等,但是需要额外的配置
vfs目前仍处于测试中,用于不支持copy on write的文件系统中,性能堪忧,不推荐使用在生产环境中
devicemapper在生产环境中需要direct-lvm的支持

可以通过docker info命令来查看自己使用的Docker用的是哪一个storage driver:

上图中使用的storage driver是overlay2。

参考资料 https://docs.docker.com/storage/storagedriver/

以上就是Docker容器Container镜像Image如何存储详解的详细内容,更多关于Docker容器镜像存储的资料请关注脚本之家其它相关文章!

相关文章

  • docker打包前端镜像的超详细步骤

    docker打包前端镜像的超详细步骤

    要打包前端项目可以使用 Docker 容器技术,下面这篇文章主要给大家介绍了关于docker打包前端镜像的超详细步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Docker下SqlServer发布订阅启用的方法

    Docker下SqlServer发布订阅启用的方法

    发布订阅主要用来做数据库的读写分离,当单台数据库的压力太大时,可以考虑这种方案,本文主要介绍了Docker下SqlServer发布订阅启用的方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Docker实践--部署Nodejs应用

    Docker实践--部署Nodejs应用

    本篇文章主要介绍了Docker实践--部署Nodejs应用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • Docker容器通过独立IP暴露给局域网的方法

    Docker容器通过独立IP暴露给局域网的方法

    这篇文章主要介绍了Docker容器通过独立IP暴露给局域网的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-04-04
  • Linux下Docker安装配置教程

    Linux下Docker安装配置教程

    这篇文章主要为大家详细介绍了Linux下Docker安装配置教程,步骤简单清晰,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • 如何使用Celery和Docker处理Django中的定期任务

    如何使用Celery和Docker处理Django中的定期任务

    这篇文章主要介绍了使用Celery和Docker处理Django中的定期任务的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • SpringCloud与Docker的集成原理解析

    SpringCloud与Docker的集成原理解析

    Docker的核心原理是通过将应用程序及其所有依赖项封装到独立的容器中,实现了跨平台、一致性和可移植性,这篇文章主要介绍了SpringCloud-Docker原理解析,需要的朋友可以参考下
    2024-02-02
  • Docker+Jupyter 部署算力服务的解决方案

    Docker+Jupyter 部署算力服务的解决方案

    Docker+Jupyter部署算力服务为AI学习框架提供了一种高效的发布和使用方案,本文以Windows环境为例,介绍了如何下载安装Docker工具,以及如何根据AI框架所需的Python版本拉取合适的Jupyter镜像,本文介绍了Docker+Jupyter 部署算力服务的相关知识,一起看看吧
    2024-11-11
  • 基于docker Desktop一键式搭建k8s环境的步骤

    基于docker Desktop一键式搭建k8s环境的步骤

    在docker desktop中一键启动k8s环境很简单,下面介绍如何启动dashboard,dashboard仪表盘是新手学习k8s至关重要的一个工具,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2023-11-11
  • docker镜像如何启动es/kibana

    docker镜像如何启动es/kibana

    这篇文章主要介绍了docker镜像如何启动es/kibana问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01

最新评论