Docker镜像分层的原理详解

 更新时间:2019年12月08日 09:21:49   作者:xiongkun01  
这篇文章主要介绍了Docker镜像分层的原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

base镜像

base镜像有两层含义:

  • 不依赖其他镜像,从scratch构建
  • 其他镜像可以之为基础进行扩展

所以,base镜像一般都是各种Linux发行版本的Docker镜像,比如:Ubuntu,Debian或者CentOS等。

base镜像提供的都是最小安装的Linux发行版本。

我们大部分镜像都将是基于base镜像构建的。所以,通常使用的是官方发布的base镜像。可以在docker hub里找到。比如centos:https://hub.docker.com/_/centos

我们可以自己构建docker base镜像,也可以直接使用已有的base镜像。比如centos。我们可以直接从docker hub上拉取。
拉取

docker pull centos

查看

docker images centos 
REPOSITORY     TAG         IMAGE ID      CREATED       SIZE
centos       latest       1e1148e4cc2c    2 months ago    202MB

可以看到最新的centos镜像只有200mb,是不是觉得太小了?这是因为docker镜像在运行的时候直接使用docker宿主机器的kernel。

Linux操作系统由用户空间和内核空间构成。

内核空间是kernel,用户空间是rootfs,不同发行版的区别主要是rootfs。比如Ubuntu 14.04使用 upstart 管理服务,apt 管理软件包;而 CentOS 7 使用 systemd 和 yum。这些都是用户空间的不同,Kernel差别不大。

所以Docker可以同时支持多种 Linux 镜像,模拟出不同的操作系统环境。

base镜像只是用户空间和发行版本一致,内核空间使用的是Docker宿主机器的Kernel。

存储结构

上文里展示了如何下载一个base镜像。我们通常是基于这份base镜像来构建我们自己的镜像。比如,在centos里添加一个nginx负载均衡。首先,得需要了解镜像的结构是什么。

官方文档: https://docs.docker.com/storage/storagedriver/

Docker镜像的分层结构

启动镜像时,一个新的可写层会加载到镜像的顶层。这一层通常称为"容器层",之下是"镜像层"。

容器层可以读写,容器所有发生文件变更写都发生在这一层。镜像层只允许读取,read-only。

修改时复制策略(copy-on-write)

Docker通过一个修改时复制策略来保证base镜像的安全性,以及更高的性能和空间利用率。

  • 当容器需要读取文件的时候

从最上层的镜像层开始往下找,找到后读取到内存中,若已经在内存中,可以直接使用。换句话说,运行在同一台机器上的Docker容器共享运行时相同的文件。

  • 当容器需要修改文件的时候

从上往下查找,找到后复制到容器层,对于容器来说,可以看到的是容器层的这个文件,看不到镜像层里的文件,然后直接修改容器层的文件。

  • 当容器需要删除文件的时候

从上往下查找,找到后在容器中记录删除,并不是真正的删除,而是软删除。这导致镜像体积只会增加,不会减少。

当容器需要增加文件的时候
直接在最上层的容器可写层增加,不会影响镜像层。

镜像的精简优化

优化基础镜像

基础镜像选择时,选择合适的较小的镜像,常用的 Linux 系统镜像一般有 Ubuntu、CentOs、Alpine···等

串联Dockerfile指令

在Dockerfile中,每条指令都会创建一个镜像层,从而增加镜像的大小。当前层的修改不会影响上一层。

  • 用&&串联指令(RUN指令中)
  • 安装完软件记得clean

具体实例如下:

自定义Dockerfile:

FROM ubuntu:14.04
#基础源镜像
MAINTAINER xiongkun
#描述镜像的创建者,名称和邮箱
WORKDIR /home
RUN dd if=/dev/zero of=50M.file bs=1M count=50
#创建大小为50M的测试文件
RUN rm -rf 50M.file
#删除该文件

优化后的Dockerfile:

FROM ubuntu:14.04
#基础源镜像
MAINTAINER xiongkun
#描述镜像的创建者,名称和邮箱
WORKDIR /home
RUN dd if=/dev/zero of=50M.file bs=1M count=50 && rm -rf 50M.file
#创建文件,同时在该层删除该文件

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Docker创建镜像、怎么修改、上传镜像等详细介绍

    Docker创建镜像、怎么修改、上传镜像等详细介绍

    这篇文章主要介绍了Docker创建镜像、怎么修改、上传镜像等详细介绍的相关资料,需要的朋友可以参考下
    2016-12-12
  • Docker常用命令Study03详解

    Docker常用命令Study03详解

    这篇文章主要介绍了Docker常用命令Study03详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 查看docker中运行的JVM参数问题及解决方法

    查看docker中运行的JVM参数问题及解决方法

    这篇文章主要介绍了查看docker中运行的JVM参数,方法一使用的是jcmd命令,方法二是jinfo命令,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2022-04-04
  • docker添加网桥并设置ip地址范围操作

    docker添加网桥并设置ip地址范围操作

    这篇文章主要介绍了docker添加网桥并设置ip地址范围操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • docker-compose up -d和docker-compose up --build的区别

    docker-compose up -d和docker-compose up -

    本文主要介绍了docker-compose up -d和docker-compose up --build的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 在docker中开启sshd操作

    在docker中开启sshd操作

    这篇文章主要介绍了在docker中开启sshd操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • Docker 部署Mysql 服务和Redis 服务的方法

    Docker 部署Mysql 服务和Redis 服务的方法

    这篇文章主要介绍了Docker 部署Mysql 服务和Redis 服务的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Docker容器如何开启特权模式

    Docker容器如何开启特权模式

    文章主要解决Docker容器中无法使用systemctl命令的问题,其原因在于大部分的系统镜像移除了init软件包,导致镜像中没有/sbin/init文件,解决方法是通过编写Dockerfile文件修改镜像,构建新的镜像,并运行新构建的镜像,需要注意的是,开启特权模式虽然方便,但可能存在安全风险
    2024-10-10
  • 常用的8个应用和中间件的Docker运行示例详解

    常用的8个应用和中间件的Docker运行示例详解

    Portainer是一个轻量级的管理 UI ,可让你轻松管理不同的 Docker 环境(Docker 主机或 Swarm 群集),这篇文章主要介绍了常用的8个应用和中间件的Docker运行示例,需要的朋友可以参考下
    2024-03-03
  • Windows Docker 部署 SolrCloud的方法步骤

    Windows Docker 部署 SolrCloud的方法步骤

    本文主要介绍了Windows Docker 部署 SolrCloud的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10

最新评论