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上拉取
#拉取
[root@base ~]# docker pull centos
#查看
[root@base ~]# docker images centos 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              1e1148e4cc2c        2 months ago      

可以看到最新的centos镜像只有200MB,这是因为docker镜像在运行的时候直接使用docker宿主机器的kernel

Linux操作系统由用户空间和内核空间构成
内核空间是kernel,用户空间是rootfs,不同发行版的区别主要是rootfs,比如Ubuntu 14.04使用 upstart 管理服务,apt 管理软件包;而 CentOS 7 使用 systemd 和 yum,这些都是用户空间的不同,Kernel差别不大。所以Docker可以同时支持多种 Linux 镜像,模拟出不同的操作系统环境
base镜像只是用户空间和发行版本一致,内核空间使用的是Docker宿主机器的Kernel

典型的Linux启动到运行需要两个FS,bootfs + rootfs,如下图
Docker分层1.png

存储结构

下载一个base镜像,基于这份base镜像来构建镜像,比如在centos里添加一个nginx负载均衡,首先得需要了解镜像的结构是什么

Docker镜像的分层结构

启动镜像时,一个新的可写层会加载到镜像的顶层,这一层通常称为"容器层",之下是"镜像层",容器层可以读写,容器所有发生文件变更写都发生在这一层,镜像层只允许读取,read-only
Docker分层2.png

FROM debian      1.新镜像不再是从scratch开始,而是直接在Debian base镜像上构建
MAINTAINER allenlu
RUN apt-get update && apt-get install -y emacs   2.安装emacs编辑器
RUN apt-get install -y apache            3.安装apache
CMD ["/bin/bash"]              4.容器启动时运行bash

构建过程如下图所示
Docker分层3.png
在启动后,首先将rootfs置为readonly, 进行一系列检查, 然后将其切换为 “readwrite” 供用户使用,在docker中起初也是将 rootfs 以readonly方式加载并检查,然而接下来利用 union mount 的将一个readwrite文件系统挂载在readonly的rootfs之上,并且允许再次将下层的 file system设定为readonly 并且向上叠加, 这样一组readonly和一个writeable的结构构成一个container的运行目录, 每一个被称作一个Layer
Docker分层4.png

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

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

  • 当容器需要读取文件的时候
    从最上层的镜像层开始往下找,找到后读取到内存中,若已经在内存中,可以直接使用,换句话说运行在同一台机器上的Docker容器共享运行时相同的文件
  • 当容器需要修改文件的时候
    从上往下查找,找到后复制到容器层,对于容器来说,可以看到的是容器层的这个文件,看不到镜像层里的文件,然后直接修改容器层的文件
  • 当容器需要删除文件的时候
    从上往下查找,找到后在容器中记录删除,并不是真正的删除,而是软删除。这导致镜像体积只会增加,不会减少
  • 当容器需要增加文件的时候
    直接在最上层的容器可写层增加,不会影响镜像层

镜像的精简优化

  1. 优化基础镜像
    基础镜像选择时,选择合适的较小的镜像,常用的 Linux 系统镜像一般有 Ubuntu、CentOs、Alpine···等
  2. 串联Dockerfile指令
    在Dockerfile中,每条指令都会创建一个镜像层,从而增加镜像的大小,当前层的修改不会影响上一层
  • 用&&串联指令(RUN指令中)
  • 安装完软件记得clean
    Dockerfile
    优化前
FROM ubuntu:14.04
MAINTAINER allenlu
WORKDIR /home
#创建大小为50M的测试文件
RUN dd if=/dev/zero of=50M.file bs=1M count=50
#删除该文件
RUN rm -rf 50M.file

优化后

FROM ubuntu:14.04
MAINTAINER allenlu
WORKDIR /home
#创建文件,同时在该层删除该文件
RUN dd if=/dev/zero of=50M.file bs=1M count=50 && rm -rf 50M.file
文章作者: 鲜花的主人
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 爱吃可爱多
Docker Docker
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝