【Docker】镜像分层存储与镜像精简

Linux操作系统

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

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

分层存储

  因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
  镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
  分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

docker镜像原理

  docker镜像在构建的时候利用了aufs文件系统的挂载原理,对文件系统进行构建。
  首先,存在一个 docker 容器在启动时其内部进程可见的文件系统视角,或者称为docker 容器的根目录rootfs。目录下含有 docker 容器所需要的系统文件、工具、容器文件等。(只读属性)
  接着,在特定的镜像中存在每一个镜像独有的文件系统(读写属性),以ubuntu镜像为例,如下图:

  在docker实际应用中,镜像相当于只读层,而容器则相当去上图中的可写层。已构建的镜像会设置成只读模式,read-write写操作是在read-only上的一种增量操作,固不影响read-only层。
??无论是unbuntu这种OS系统,还是mysql,mongo这种具体应用。docker利用的aufs文件系统在文件系统挂载时对镜像进行复用。
??所以我们假设 docker build 构建出来的镜像名分别为 image 1 和 image 2,由于两个 Dockerfile 均基于ubuntu:14.04,因此,image 1 和 image 2 这两个镜像均复用了镜像 ubuntu:14.04。 假设 RUN apt-get update 修改的文件系统内容为 20 MB,最终本地三个镜像的大小关系应该如下 :

 ubuntu:14.04: 200 MB
 image 1:200 MB(ubuntu:14.04 的大小)+ 20 MB = 220 MB
 image 2:200 MB(ubuntu:14.04 的大小)+ 100 MB = 300 MB

  如果仅仅是单纯的累加三个镜像的大小,那结果应该是:200 + 220 + 300 = 720 MB,但是由于镜像复用的存在,实际占用的磁盘空间大小是:200 + 20 + 100 + 320 MB,足足节省了 400 MB 的磁盘空间。在此,足以证明镜像复用的巨大好处。
  由此可以说明docker images 列表下镜像大小之和并非是镜像实际硬盘消耗.

镜像的精简优化

1.优化基础镜像

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

2.串联 Dockerfile 指令

  在 Dockerfile 中, 每一条指令都会创建一个镜像层,继而会增加整体镜像的大小。当前层作出的操作修改不会影响上一层。
  -用&&串联指令(一般是RUN指令)
  -安装完软件记得clean
  具体实例如下:
  创建自定义Dockerfile,

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

  用该文件生成镜像,执行创建镜像命令:

docker build -t test:A .

查看生成镜像信息:

可以看到生成的镜像test:A大小为240M,接下来我们将dockerfile命令进行串联,从而减少层,具体操作如下:
修改Dockerfile文件,将RUN指令通过&&合并到一起:

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

以此创建新镜像,具体操作与以前相同,镜像名为test:A,同样查看docker images如下:

到此可见同样命令,通过run命令串联,镜像大小缩减了240M-188M=52M
注:
??其实我们可以发现,前面例子中的dockerfile中只是简单执行了创建文件,然后删除该文件的操作,文件创建后再删除。常规我们一般会认为这种操作实际没有占用存储空间,这里就是docker 镜像的不同之处,由上文我们可以得知,dockerfile创建每条指令都是一个layers层,之后layers层的操作不会影响上一层,也就是说即使我们在该RUN层进行rm -rf 50M.file删除操作,也只是在本层中起作用,而上一层创建的文件依然保留,不会受到影响。所有尽可能将操作指令合并到同一个RUN层中,从而达到精简镜像的目的。

原文地址:https://www.cnblogs.com/wucaiyun1/p/11820947.html

时间: 2024-07-30 10:16:25

【Docker】镜像分层存储与镜像精简的相关文章

理解Docker镜像分层

原文:理解Docker镜像分层 关于base镜像 base 镜像有两层含义: 不依赖其他镜像,从 scratch 构建. 其他镜像可以之为基础进行扩展. 所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,比如 Ubuntu, Debian, CentOS 等. base 镜像提供的是最小安装的 Linux 发行版. 我们大部分镜像都将是基于base镜像构建的.所以,通常使用的是官方发布的base镜像.可以在docker hub里找到.比如centos: htt

docker的架构,镜像分层特性,dockerfile缓存特性

Docker网站:https://hub.docker.com/?Docker镜像分层的概念:Docker的最小镜像下载镜像(dockerfile的组成)docker pull hello-world Dockerfile的组成1.>FROM:scratch 抓,挠(从零开始构建)2>COPY: hello /3>CMD: ["/hello"] Base镜像(基础镜像) > ***个人理解: > 用户空间:rootfs > 内核空间 :bootfs

docker定义、安装、镜像、容器

Docker是什么 使用最广泛的开源容器引擎 一种操作系统级的虚拟化技术 依赖于Linux内核特性:Namespace(资源隔离)和Cgroups(资源限制) 一个简单的应用程序打包工具 Docker设计目标 提供简单的应用程序打包工具 开发人员和运维人员职责逻辑分离 多环境保持一致性 像一艘货船,通过集装箱把代码打包,分开,然后再传输 Docker基本组成 Docker Client:客户端Ddocker Daemon:守护进程Docker Images:镜像Docker Container:

Docker 之 基于容器的镜像制作

1  概述 镜像包含启动容器所需的文件系统和内容,可以理解为打包的文件,用于创建并启动docker容器. 镜像的生成途径有三个: 1.基于dockerfile实现,镜像制作的程序文件 2.基于容器实现,启动容器后,将新的操作制作为新镜像 3.docker hub automated builds 镜像文件采用分层构建机制,最底层为bootfs,上面为rootfs,rootfs上还可以有多层.位于最下层的镜像文件为父镜像(parent image),最底层为基础镜像(base image,root

Docker基础-使用Dockerfile创建镜像

1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # This dockerfile uses the ubuntu image # VERSION 2 - EDITION 1 # Author: docker_user # Command format: Instruction [arguments / command ] .. # Base image to use, this nust be set as the first line FROM ubu

docker进阶-搭建私有企业级镜像仓库Harbor

为什么要搭建私有镜像仓库 ??对于一个刚刚接触Docker的人来说,官方的Docker hub是用于管理公共镜像.既然官方提供了镜像仓库我们为什么还要去自己搭建私有仓库呢?虽然也可以托管私有镜像.我们可以非常方便的把我们自己镜像推送上去,但是Docker hub提供的私有仓库个数有限.对于个人来说Docker hub是个不错的选择,但是对于企业来说,相对于安全 ,成本和公司的架构来说搭建自己的私有镜像仓库才是正确的道路. 什么是Harbor?为什么要选择Harbor ??Harbor是一个用于存

[转]Docker基础-使用Dockerfile创建镜像

本文转自:https://www.cnblogs.com/jie-fang/p/7927643.html 1.基本结构 Dockerfile由一行行命令语句组成,并支持以#开头的注释行.例如: # This dockerfile uses the ubuntu image # VERSION 2 - EDITION 1 # Author: docker_user # Command format: Instruction [arguments / command ] .. # Base imag

Dockers镜像分层

Dockers镜像分层 1,Dockers的最小镜像 [[email protected] ~]# docker pull hello-world //下载一个最小的镜像 [[email protected] ~]# docker images //查看镜像 [[email protected] ~]# docker run hello-world //运行一下hello-world (里面是一个文本对docker运行的简单介绍) dockerfile的组成1)FROM:scratch(抓.挠)

Docker(二)——常用命令(镜像相关命令,容器相关命令:启动,拷贝,目录挂载,删除等等)

上一篇文章写的是Docker的安装和启动,启动了Docker我们可以进行镜像的安装了,镜像就是包含各种应用的操作系统. 一.镜像相关命令 1.搜索镜像 命令行的方式: docker search python #搜索关于python的镜像 在网站搜索: https://hub.docker.com/ #一般在网站上搜索方便看,搜索好之后再安装 搜索关于带python的Docker  2.下载镜像 docker pull centos:centos7.7.1908 #指定下载centos7.7.1