一、使用更精简的镜像

常用的Linux系统镜像一般有 Debian、Ubuntu、CentOS和Alpine,其中Alpine是面向安全的轻量级Linux发行版本。Docker的Alpine镜像仅有不到5M的大小,非常适合作为基础镜像。

Alpine使用ash这个轻量级的shell,而上述其他Linux发行版默认使用bash作为其shell。另外,Aline使用apk作为其包管理工具,软件安装包的名字可能与其他发行版不同,可以在https://pkgs.alpinelinux.org/packages搜索确定安装包的名字。

二、压缩RUN语句&清理不必要的文件和程序

1、压缩RUN语句

Docker镜像是分层的,Dockerfile中的每一条RUN语句都会增加一层镜像,导致镜像非常臃肿。多个RUN命令应尽量用一条RUN命令完成,用“&&”和“\”串联每一条命令。

比如下面的两条RUN命令

RUN apt-get update
RUN apt-get install -y git

可以压缩成一条

RUN apt-get update && \
apt-get install -y git

2、清理不必要的程序和文件

另外,在用apt安装软件包时,我们可以使用--no-install-recommends参数来避免安装非必须的文件,从而减小镜像的体积;安装完成之后rm -rf /var/lib/apt/lists/* ,清理apt缓存,进一步缩小镜像。

RUN apt-get update && \
apt-get install -y --no-install-recommends git && \
rm -rf /var/lib/apt/lists/*

使用apk安装软件包时,我们可以使用--no-cache参数达到同样的目的,或者在安装完软件包后使用rm -rf /var/cache/apk/*。

RUN apk -U --no-cache add git
或者
RUN apk -U add git && \
rm -rf /var/cache/apk/*

要注意的是,安装软件包和清理缓存需要在同一条RUN语句中执行,因为每一条RUN语句都会增加一层,这样把apt-get和rm -rf /var/lib/apt/lists/*分开的话,就不能清理apt-get产生的缓存;apk也是同理。

# 正确
RUN apt-get update && \
apt-get install -y --no-install-recommends git && \
rm -rf /var/lib/apt/lists/*
# 错误
RUN apt-get update && \
apt-get install -y --no-install-recommends git && \
RUN rm -rf /var/lib/apt/lists/*

在构建镜像的时候,我们在编译阶段可能会下载一些依赖的头文件和用于编译的程序,或者其他相关程序(比如git),这些在程序运行时完全不需要,可以删除掉。

RUN apt-get update && \
apt-get install -y git make gcc libssl-dev && \
……
# 编译完成后,清理编译环境和跟程序运行无关的软件
apt-get purge -y git make gcc libssl-dev
……

三、多段构建

从Docker 17.05开始,一个Dockerfile文件可以使用多条FROM语句,每条FROM语句可以使用不同的镜像。这样我们可以把Docker的构建阶段分层多个阶段,以两个FROM语句为例,我们可以使用一个镜像编译我们的程序;另一个镜像使用更精简的镜像,拷贝上一阶段的编译的结果。

在使用FROM语句时,我们可以用AS为不同的镜像起别名,方便后续操作。用COPY命令从其他镜像拷贝文件时,我们可以用--from=alias src dst从别的阶段复制文件;如果没有为镜像起别名,第一个镜像的ID为0,第二个为1,我们可以用ID从别的阶段拷贝文件,--from=0 src dst

FROM golang:1.9-alpine as builder
RUN apk --no-cache add git
WORKDIR /go/src/github.com/go/helloworld/
RUN go get -d -v github.com/go-sql-driver/mysql
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest as prod
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/go/helloworld/app .
CMD ["./app"]

四、压缩镜像

1.使用docker export和docker import

docker export是用来保存一个容器的,所以我们需要有一个正在运行的容器才能使用此命令。

docker export <CONTAINER ID> > export.tar

docker import用来加载保存的容器,但是不能恢复成一个容器,而是变成一个镜像

docker import export.tar <IMAGE NAME>:[TAG]

可以用一条命令实现

docker export <容器ID> | docker import - <镜像名>[:标签]

使用export和import后得到的镜像不会保存镜像的历史,所以镜像会变小。

docker save是用来保存一个镜像的,docker save <IMAGE ID> > save.tar;然后可以用docker load加载我们保存的镜像,docker load < save.tar。使用docker save和load恢复后的镜像依然会保存镜像的历史。

test镜像未经过压缩的,test/import镜像是经过压缩的镜像,可以看到已经变小了一些

2.使用docker-squash

github地址:https://github.com/jwilder/docker-squash

docker save <image id> | sudo docker-squash -t newtag | docker load

参考文章:

https://www.cnblogs.com/kuku0223/p/8421964.html

https://zhuanlan.zhihu.com/p/42815689

https://stackoverflow.com/questions/49118579/alpine-dockerfile-advantages-of-no-cache-vs-rm-var-cache-apk

https://www.cnblogs.com/zhangmingcheng/p/7122386.html

https://www.jianshu.com/p/1d889800cdfe

https://tuhrig.de/flatten-a-docker-container-or-image/

精简Docker镜像的几个方法的更多相关文章

  1. 精简Docker镜像的五种通用方法

    http://dockone.io/article/8163 精简Docker镜像的好处很多,不仅可以节省存储空间和带宽,还能减少安全隐患.优化镜像大小的手段多种多样,因服务所使用的基础开发语言不同而 ...

  2. 精简你的 docker 镜像

    精简你的 docker 镜像 Intro 现在 docker 的使用越来越普遍,今天来谈一下如何精简你的 docker 镜像 为什么要精简 docker 首先来说说为什么要精简 docker 镜像,减 ...

  3. 将iso镜像转换为docker镜像

    为什么不用官方的镜像? 不是不想使用,而是官方镜像提供的功能实在是太少了,不信的话,你pull一个ubuntu:latest的进行,你看有没有wget.curl.ssh这些功能,就连最简单的ifcon ...

  4. 多阶段构建Golang程序Docker镜像

    Docker简介 Docker是基于Linux容器技术(LXC),使用Go语言实现的开源项目,诞生于2013年,遵循Apache2.0协议.Docker自开源后,受到广泛的关注和讨论. Docker在 ...

  5. web项目docker化的两种方法

    标题所讲的两种方法其实就是创建docker镜像的两种方法 第一种:启动镜像后进入容器中操作,将需要的软件或者项目移动到容器中,安装或者部署,然后退出即可 第二种:编写dockerfile,将需要的镜像 ...

  6. docker镜像的创建

    获得更多资料欢迎进入我的网站或者 csdn或者博客园 昨天讲解了docker的安装与基本使用,今天给大家讲解下docker镜像的创建的方法,以及push到Docker Hub docker安装请点击右 ...

  7. Docker 镜像针对不同语言的精简策略

    导航: 这里分为几个部分. 相关转载云原生:米开朗基杨 1.Docker减小镜像体积 2.Docker镜像针对不同语言的精简策略 对于刚接触容器的人来说,他们很容易被自己制作的 Docker 镜像体积 ...

  8. Docker 下载镜像慢的问题解决方法

    让你火箭般的速度下载docker镜像! 的冷漠度 百家号17-11-1713:09 因为有墙的原因所以在国内下载docker镜像的速度非常慢,有时候是几kb每秒,那个蛋疼的等待,真是谁等谁知道!下面我 ...

  9. docker(三)docker镜像和镜像发布方法

    一.从公网docker hub 拉取image ~ # 搜索docker search centos~ » docker pull centos admin@steven- Using default ...

随机推荐

  1. Hibernate4教程二:基本配置(2)

    <hibernate-mapping>元素 这个元素是xxx.hbm.xml配置的根元素,定义如下: java代码: <hibernate-mapping schema=" ...

  2. [转载]Redux原理(一):Store实现分析

    写在前面 写React也有段时间了,一直也是用Redux管理数据流,最近正好有时间分析下源码,一方面希望对Redux有一些理论上的认识:另一方面也学习下框架编程的思维方式. Redux如何管理stat ...

  3. VS Code的使用

    之前一直使用的是WebStorm来学习web前端开发,最近开始使用VSCode,很多方面和WebStorm不一样,需要一段时间适应,以下是我初次使用VSCode进行web前端开发学习所遇到的一些问题以 ...

  4. PHP内置函数parse_str会自动进行urldecode(URL解码)

    用法:void parse_str ( string $str [, array &$arr] ) parse_str用来解析(分离)URL中的查询字符串(Query String),所谓查询 ...

  5. Spring-DI控制反转和IOC依赖注入

    Spring-DI控制反转和IOC依赖注入 DI控制反转实例 IDEAJ自动导入Spring框架 创建UserDao.java接口 public interface UserDao { public ...

  6. 前端每日实战:69# 视频演示如何用纯 CSS 创作一个单元素抛盒子的 loader

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/qKwXbx 可交互视频 此视频是可 ...

  7. 苹果的AR赌注仍然有很多需要证明的

    苹果公司为开发者主题发布会做准备,其中一个更大的公告很可能是其增强现实平台的新变化.自从去年宣布ARKit以来,这家科技巨头几乎对其对AR的潜力抱有信心. 在很多讨论背后,人们都相信技术的实用性,但在 ...

  8. 09.事务管理、整合jpa、整合mybatis

    事务管理 spring-boot-starter-jdbc会自动默认注入DataSourceTransactionManager spring-boot-starter-data-jpa会自动默认注入 ...

  9. python实现简单接口

    接口实现 import flask,json server=flask.Flask(__name__)#__name__代表当前的python文件.把当前的python文件当做一个服务启动 @serv ...

  10. vagrant up ----失败 问题解决

    命令行启动提示信息 there was an error while executing `vboxmanage`, a cli used by vagrant for controlling vir ...