Docker镜像分层的原理

base镜像

base镜像有两层含义:nginx

  • 不依赖其余镜像,从scratch构建
  • 其余镜像能够之为基础进行扩展

因此,base镜像通常都是各类Linux发行版本的Docker镜像,好比:Ubuntu,Debian或者CentOS等。docker


base镜像提供的都是最小安装的Linux发行版本。
咱们大部分镜像都将是基于base镜像构建的。因此,一般使用的是官方发布的base镜像。能够在docker hub里找到。好比centos:https://hub.docker.com/_/centos
咱们能够本身构建docker base镜像,也能够直接使用已有的base镜像。好比centos。咱们能够直接从docker hub上拉取。
拉取ubuntu

docker pull centos

查看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/stora...spa

Docker镜像的分层结构

启动镜像时,一个新的可写层会加载到镜像的顶层。这一层一般称为"容器层",之下是"镜像层"。
容器层能够读写,容器全部发生文件变动写都发生在这一层。镜像层只容许读取,read-only。

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

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

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

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

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

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

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

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

  • 当容器须要增长文件的时候

直接在最上层的容器可写层增长,不会影响镜像层。


镜像的精简优化

  1. 优化基础镜像

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

  1. 串联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
#建立文件,同时在该层删除该文件
相关文章
相关标签/搜索