精简docker镜像的建议

精简docker镜像的建议

作者: 张首富
时间: 2019-05-03
个人博客: www.zhangshoufu.com
QQ群: 895291458

前提

因为公司业务需求,需要到客户现场部署我们代码的离线环境,因为各大银行和运营商所提供的底层系统各不相同,代码不一定能运行的起来,所以我们就采用了docker版的离线部署方式,报我们所有的应用全打成docker包,然后再到客户现场部署.
但是这又引发了另外一个问题,因为我们的客户一般都是银行和运营商,所以我们要拷贝个东西到他们的系统里面是很费劲的,因为全是docker包,因为我们打包没有精简,导致打出来的docker非常庞大,传输文件到客户服务器里面往往需要大半天时间或者更久.
为了提高工作效率,缩短传输包的时间,我们决定对docker镜像进行精简

精简docker镜像的必要性

1,我们大家都知道docker镜像是分层存储的,镜像层依赖于一系列底层技术(FileSystem,copy-on-wirte,union mounts联合挂载),而docker镜像最多有127层,当超过127层的时候docker镜像打包就会失败.
2,精简docker镜像大小能减少我们的构建时间,只装必须使用的包,不需要的就不装
3,减少磁盘使用量
4,因为包含的文件少,所以漏洞如果就少
5,传输速度,部署速度加快

精简docker镜像的建议

a, 选择基础镜像

当我们编写Dockerfile FROM的时候选择最合适的最小的基础镜像,我们在这个基础上安装我们必须的安装包.
常用的 Linux 系统镜像一般有 Ubuntu、CentOs、Alpine,其中 Alpine 更推荐使用。大小对比如下:

Alpine 是一个高度精简又包含了基本工具的轻量级 Linux 发行版,基础镜像只有 4.41M,各开发语言和框架都有基于 Alpine 制作的基础镜像,强烈推荐使用它。

查看上面的镜像尺寸对比结果,你会发现最小的镜像也有 4.41M,那么有办法构建更小的镜像吗?答案是肯定的,例如 gcr.io/google_containers/pause-amd64:3.1 镜像仅有 742KB。为什么这个镜像能这么小?在为大家解密之前,再推荐两个基础镜像:

1) scratch 镜像

scratch 是一个空镜像,只能用于构建其他镜像,比如你要运行一个包含所有依赖的二进制文件,如centos 7.5镜像,他就是基于scratch来构建的,他的Dockerfile文件来构建的

FROM scratch
ADD centos-7-docker.tar.xz /

LABEL org.label-schema.schema-version = "1.0"     org.label-schema.name="CentOS Base Image"     org.label-schema.vendor="CentOS"     org.label-schema.license="GPLv2"     org.label-schema.build-date="20180531"

CMD ["/bin/bash"]

centos镜像使用了scratch 作为基础镜像,这个镜像本身是不占空间的,使用它构建的镜像大小几乎和二进制文件本身一样大,所以镜像非常小。

2) busybox 镜像

scratch 是个空镜像,如果希望镜像里可以包含一些常用的 Linux 工具,busybox 镜像是个不错选择,镜像本身只有 1.16M,非常便于构建小镜像。

b, 串联 DOckerfile 指令

大家在定义 Dockerfile 时,如果太多的使用 RUN 指令,经常会导致镜像有特别多的层,镜像很臃肿,而且甚至会碰到超出最大层数(127层)限制的问题,遵循 Dockerfile 最佳实践,我们应该把多个命令串联合并为一个 RUN(通过运算符&&和/ 来实现),每一个 RUN 要精心设计,确保安装构建最后进行清理,这样才可以降低镜像体积,以及最大化的利用构建缓存。
下面是一个优化前 Dockerfile:
下面的例子只是做个测试,正常来讲没有人会这样构建docker镜像
docker镜像打包比对

FROM centos:7.5.1804
COPY ./*.repo /etc/yum.repos.d/
RUN yum -y install nginx
RUN yum -y install mariadb*
CMD nginx
FROM centos:7.5.1804
COPY ./*.repo /etc/yum.repos.d/
RUN yum -y install nginx  mariadb*
CMD nginx
FROM centos:7.5.1804
COPY ./*.repo /etc/yum.repos.d/
RUN yum -y install nginx  mariadb* &&     yum clean all
CMD nginx
REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
test                                                 V3.0                4ce16d6e1859        6 seconds ago       586MB
test                                                 V2.0                6cb5da7d6afc        26 minutes ago      685MB
test                                                 V1.0                49738c7042d6        31 minutes ago      805MB

通过上面的实验,我们可以看出,将yum命令分成两个RUN来写远远比卸载一个RUN里面节省空间大小的多。
两个镜像所安装的软件全是一模一样,但是一个RUN和两个RUN有本质的区别,因为每多一个RUN镜像就会多一层

c,使用多阶段构建

Dockerfile 中每个指令都会为镜像增加一个镜像层,并且你需要在移动到下一个镜像层之前清理不需要的组件,实际上,有一个Dockerfile用于开发,(其中
包含构建应用程序所需的所有内容)以及一个用于生产的瘦客户端,它只包含您的应用程序以及运行它所需的内容,“这被称为建造者模式”。Dockerfile 17.05.0-ce 版本
以后支持多阶段构建,使用多阶段构建,你可以在Dockerfile中使用多个FROM 语句,每条 FROM 指令可以使用不同的基础镜像,这样可以选择性的将服务组件从一个阶段
COPY到另一个阶段,最终只保留镜像中需要的内容。

d, 构建业务镜像的技巧

1,把依赖的库和代码分成COPY,因为docker镜像打包的时候回去中心仓库(server端)对比有没有相同的层,有相同的层直接拿来使用,所以我们尽量把不会改变成东西
放在一层,这样我们打包速度就会很快了
2,使用代码本身的启动,不要安装一些无所谓的东西来辅助启动,因为我发现有好多开发会把代码使用Supervisor的方式去启动他的代码,这种方式是违法了docker本身
的理念的,因为这种可能造成docker启动没问题,但是里面的服务不正常

e,其他优化方法

1,使用yum 或者apt安装完软件之后删除缓存的安装数据
2, apt-get install 可以添加 --no-install-recommends参数来不安装非必须的依赖
3,能用一条命令RUN完的就不要写两条

原文地址:https://blog.51cto.com/13447608/2388498

时间: 2024-08-29 21:24:50

精简docker镜像的建议的相关文章

Docker镜像构建的优化总结

Docker镜像构建的优化总结 随着我们对docker镜像的持续使用,在此过程中如果不加以注意并且优化,镜像的体积会越来越多.很多时候我们在使用docker部署应用时,会发现镜像的体积至少有1G以上.镜像体积的增大,不单单会增加磁盘资源与网络资源的开销,也会影响应用的部署效率,使得应用的部署时间会越来越长.因此我们需要减少部署镜像的体积以加快部署效率,降低资源的开销.而对于镜像的优化,可以通过对dockerfile的优化来实现. 一.镜像最小化 1.选择最精简的基础镜像 选择体积最小的基础镜像可

docker镜像与容器的联系、存储驱动

2.1 docker镜像与容器的联系.存储驱动什么是镜像?简单说,docker镜像是一个不包含Linux内核而又精简的Linux操作系统.镜像从哪里来?Docker hub是由docker公司负责维护的公共注册中心,包含了大量的容器镜像,docker工具默认从这个公共镜像库下载镜像:https://hub.docker.com/explore默认是国外的源,下载会慢,建议配置国内镜像仓库:[[email protected] ~]# vim /etc/docker/daemon.json{"re

Docker 镜像加速器

Docker 镜像加速器 我们使用Docker的第一步,应该是获取一个官方的镜像,例如mysql.wordpress,基于这些基础镜像我们可以开发自己个性化的应用.我们可以使用Docker命令行工具来下载官方镜像.但是因为网络原因,我们下载一个300M的镜像需要很长的时间,甚至下载失败.因为这个原因,阿里云容器Hub服务提供了官方的镜像站点加速官方镜像的下载速度. 使用镜像加速器 在不同的系统下面,配置加速器的方式有一些不同,所以我们介绍主要的几个操作系统的配置方法.关于加速器的地址,你只需要登

Dockerfile创建自定义Docker镜像以及CMD与ENTRYPOINT指令的比较

1.概述 创建Docker镜像的方式有三种 docker commit命令:由容器生成镜像: Dockerfile文件+docker build命令: 从本地文件系统导入:OpenVZ的模板. 关于这三种方式的大致说明请参考yeasy/docker_practice的创建镜像. 最近学习了Dockerfile文件的相关配置,这里做一下简单的总结,并对之前一直感到有些迷惑的CMD和ENTRYPOINT指令做个差异对比. 2.Dockerfile文件总结 Dockerfile 由一行行命令语句组成,

如何交互式地创建一个Docker镜像

今天我们来学习如何使用一个docker镜像交互式地创建一个Docker镜像.当我们从镜像中启动一个Docker进程,Docker就会获取该镜像及其父镜像,并重复这个过程,直到到达基础镜像.然后联合文件系统(UFS)会在其顶层添加一个读写层.读写层被称之为容器,它包含了一些关于父镜像信息及一些其他的信息,如唯一ID,网络配置和资源限制等.容器是有状态的,其状态可以从 运行态 切换到 退出态.一个处于 运行态的容器包含了在CPU上面运行的进程树,于其它在该主机上运行的进程相隔离,而退出态是指文件系统

如何将应用打包成为 Docker 镜像

容器是镜像的实例,先声明镜像,再创建容器,所以容器可以有多个. 虽然 DockerHub 提供了大量的镜像,但是由于企业环境的多样性,并不是每个应用都能在 DockerHub 找到对应的镜像来使用.那就要求企业的运维人员掌握制作 Docker 镜像的技能.在开始打包应用前,你首先要明白这两件事: 第一件事是选择适合你的方式来生成镜像: 1. 通过 Dockerfile 来自动编译生成镜像,实现构建镜像的需求. 2.通过容器内操作,并进行 Commit 来实现打包生成镜像. 第一种思路多用于用户交

将 ASP.NET 5 应用作为 docker 镜像发布 (Linux版)

将 ASP.NET 5 应用作为 docker 镜像发布 (Linux版)? 提示 本文更新时间:2015年12月20日. 注解 如果你需要将 docker 镜像运行在Windows平台,或者使用在 Visual Studio 2015 上,请看稍后的一片博文(目前未发布) 将 ASP.NET 5 应用作为 docker 镜像发布 (Windows版) 创建 ASP.NET 5 项目? 首先,你需要一个已经完成的 ASP.NET 5 应用,如果还没有的话,可以参考 在 Mac OS 上创建的 A

Docker 镜像加速器(如何加速下载)

https://yq.aliyun.com/articles/29941 Docker 镜像加速器 我们使用Docker的第一步,应该是获取一个官方的镜像,例如mysql.wordpress,基于这些基础镜像我们可以开发自己个性化的应用.我们可以使用Docker命令行工具来下载官方镜像.但是因为网络原因,我们下载一个300M的镜像需要很长的时间,甚至下载失败.因为这个原因,阿里云容器Hub服务提供了官方的镜像站点加速官方镜像的下载速度. 使用镜像加速器 在不同的系统下面,配置加速器的方式有一些不

理解Docker(2):Docker 镜像

对于每个软件,除了它自身的代码以外,它的运行还需要有一个运行环境和依赖.不管这个软件是象往常一样运行在物理机或者虚机之中,还是运行在现在的容器之中,这些都是不变的.在传统环境中,软件在运行之前也需要经过 代码开发->运行环境准备 -> 安装软件 -> 运行软件 等环节,在容器环境中,中间的两个环节被镜像制作过程替代了.也就是说,镜像的制作也包括运行环境准备和安装软件等两个主要环节,以及一些其他环节.因此,Docker 容器镜像其实并没有什么新的理论,只是这过程有了新的方式而已. 镜像(i