docker容器详细讲解如何精简镜像减小体积

 更新时间:2021年08月31日 17:21:41   作者:iqsing  
这篇文章主要介绍了docker容器如何精简镜像减小体积,一般我们打造镜像会有几百MB,学完本文后我们将学会缩小镜像体积,从而达到做出来的镜像只有几十MB,一起来看看吧

精简镜像我们可以从两个方面切入:

减少镜像层数
缩减容量

一、减少镜像层数

1.指令合并

Dockerfile 中的每条指令都将创建一个层,不过查看官方文档中最佳实践有这样一句话:

In older versions of Docker, it was important that you minimized the number of layers in your images to ensure they were performant. The following features were added to reduce this limitation:

  • Only the instructions RUN, COPY, ADD create layers. Other instructions create temporary intermediate images, and do not increase the size of the build.

...

参考地址:Minimize the number of layers

意味着只有 RUN, COPY, ADD 三个指令会创建层,其他指令会创建一个中间镜像,并且不会影响镜像大小。这样我们说的指令合并也就是以这三个指令为主。

我们以如下Dockerfile为例

FROM debian:stable

WORKDIR /var/www
LABEL version=“v1”

RUN apt-get update
RUN apt-get -y --no-install-recommends install curl

RUN apt-get purge -y curl
RUN apt-get autoremove -y
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

构建镜像

docker build -t curl:v1 .

通过history查看构建历史

# docker history curl:v1

IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
29b721c09b67   18 seconds ago   /bin/sh -c rm -rf /var/lib/apt/lists/*          0B        
aa28ae151e59   20 seconds ago   /bin/sh -c apt-get clean                        0B        
4f733781f557   22 seconds ago   /bin/sh -c apt-get autoremove -y                989kB     
f66887372121   29 seconds ago   /bin/sh -c apt-get purge -y curl                987kB     
d458ee0de463   34 seconds ago   /bin/sh -c apt-get -y --no-install-recommend…   4.46MB    
43fdcf68018c   44 seconds ago   /bin/sh -c apt-get update                       17.6MB    
65631e8bb010   53 seconds ago   /bin/sh -c #(nop)  LABEL version=“v1”           0B        
7ef7c53b019c   53 seconds ago   /bin/sh -c #(nop) WORKDIR /var/www              0B        
8bfa93572e55   13 days ago      /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      13 days ago      /bin/sh -c #(nop) ADD file:d78d93eff67b18592…   124MB 

镜像大小

[root@localhost dockerfiles]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
curl                  v1        29b721c09b67   10 minutes ago   148MB

我们将RUN指令通过类shell操作&&合并后

RUN apt-get update && \
    apt-get -y --no-install-recommends install curl && \
    apt-get purge -y curl && \
    apt-get autoremove -y && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

查看构建历史与镜像大小

# docker history curl:v2
IMAGE          CREATED              CREATED BY                                      SIZE      COMMENT
928e12c2f57e   About a minute ago   /bin/sh -c apt-get update &&     apt-get -y …   989kB     
5a32372025fb   About a minute ago   /bin/sh -c #(nop)  LABEL version=“v2”           0B        
7ef7c53b019c   30 minutes ago       /bin/sh -c #(nop) WORKDIR /var/www              0B        
8bfa93572e55   13 days ago          /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      13 days ago          /bin/sh -c #(nop) ADD file:d78d93eff67b18592…   124MB

# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
curl                  v2        928e12c2f57e   3 minutes ago    125MB

可见只是一个简单的curl应用在通过指令合并的方式安装已经获得了约20MB的容量释放。同时使你的dockerfile文件更为易读和简约。

2.多阶段构建

在Docker17.05 中引入了多阶段构建,通过多阶段构建可以大大降低构建复杂度,同时使缩小镜像尺寸更为简单。我们来看多阶段构建的Dockerfile

#阶段1
FROM golang:1.16
WORKDIR /go/src
COPY app.go ./
RUN go build app.go -o myapp
#阶段2
FROM scratch
WORKDIR /server
COPY --from=0 /go/src/myapp ./
CMD ["./myapp"]

构建镜像

# docker build --no-cache  -t server_app:v2 .

查看构建好的镜像

# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
server_app v2 20225cb1ea6b 12 seconds ago 1.94MB

以上用例来自上篇文章《Dockerfile 多阶段构建实践》关于镜像多阶段构建具体内容可以前往查看,这里不做过多赘述。

3.启用squash特性

通过启用squash特性(实验性功能)docker build --squash -t curl:v3 . 可以构建的镜像压缩为一层。但是为了充分发挥容器镜像层共享的优越设计,这种方法不被推荐。

二、缩减容量

1. 选择小的基础镜像

每个linux发行版镜像大小相差很多,甚至相同发行版镜像也存在差异。我们以debian为例:

稳定版和瘦身版相差约40MB

# docker images 
debian                stable-slim   2aa48a485e3a   13 days ago         80.4MB
debian                stable        8bfa93572e55   13 days ago         124MB

我们将Dockerfile中基础镜像改为瘦身版debian:stable-slim

FROM debian:stable-slim

构建后的镜像尺寸更小

# docker images 
REPOSITORY            TAG           IMAGE ID       CREATED             SIZE
curl                  v4            1aab5c9bf8b3   17 seconds ago      81.4MB

当前映像基于 Debian,并包含许多二进制文件。Docker 容器应该包含一个进程,并包含运行它所需的最低限度。我们其实不需要整个操作系统。

我们可以使用基于 Alpine 的镜像 替换Debian 基础镜像。

FROM alpine

WORKDIR /var/www
LABEL version=“v5”
RUN echo -e 'https://mirrors.aliyun.com/alpine/v3.6/main/\nhttps://mirrors.aliyun.com/alpine/v3.6/community/' > /etc/apk/repositories && \
    apk update && \
    apk upgrade && \
    apk add --no-cache curl

查看镜像大小

# docker images
REPOSITORY            TAG           IMAGE ID       CREATED             SIZE
curl                  v5            7f735bb213be   11 seconds ago      10.1MB

此时我们的镜像来到了10MB。使用alpine镜像包管理工具是apk,一些软件包名可能不一样。最大的区别

2.上下文管理

我们经常会用到的COPY指令

COPY . /server/dir

COPY会把整个 构建上下文复制到镜像中,并生产新的缓存层。为了不必要的文件如日志、缓存文件、Git 历史记录被加载到构建上下文,我们最好添加.dockerignore用于忽略非必须文件。这也是精简镜像关键一步,同时能更好的保证我们构建的镜像安全性。

3.及时清理下载

我们有如下Dockerfile

..
WORKDIR /tmp
RUN curl -LO https://docker.com/download.zip && tar -xf download.zip -C /var/www 
RUN rm  -f download.zip
...

我们虽然使用了rm删除download.zip包,由于镜像分层的问题,download.zip是在新的一层被删除,上一层仍然存在。

我们要在一层中及时清理下载

RUN curl -LO https://docker.com/download.zip && tar -xf 

download.zip -C /var/www &&  rm  -f download.zip

另外在安装软件时应及时使用包管理工具清除你下载的软件依赖及缓存,比如在我们dockerfile中使用apt包管理工具做清理。

关于精简镜像的相关操作介绍到这里,更多相关docker容器 精简镜像内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • docker运行异构镜像详解

    docker运行异构镜像详解

    介绍了在不同CPU架构下运行Docker镜像时遇到的问题及解决方法,作者分享了由于银行使用鲲鹏系统(ARM架构)导致Docker容器运行失败的经历,解决方法包括启用`--platform`参数、安装`qemu-user-static`及`binfmt_misc`
    2024-12-12
  • Docker容器化部署尝试——多容器通信(node+mongoDB+nginx)

    Docker容器化部署尝试——多容器通信(node+mongoDB+nginx)

    这篇文章主要介绍了Docker容器化部署尝试——多容器通信(node+mongoDB+nginx),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Docker desktop安装mysql过程

    Docker desktop安装mysql过程

    文章介绍了如何在本地已有的Docker环境中拉取并启动MySQL容器,并详细说明了常用的环境变量参数,此外,还讨论了如何通过挂接本地磁盘来持久化MySQL数据,从而避免数据丢失
    2024-12-12
  • docker操作镜像、容器相关命令详解

    docker操作镜像、容器相关命令详解

    这篇文章主要介绍了docker操作镜像、容器相关命令,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Docker部署verdaccio搭建npm私服的实现

    Docker部署verdaccio搭建npm私服的实现

    本女王主要介绍了Docker部署verdaccio搭建npm私服的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • Vue.js中的watch属性详解

    Vue.js中的watch属性详解

    在Vue.js中,watch属性是一种非常重要的属性,它可以监听Vue实例中指定的数据变化,并在数据发生变化时执行相应的操作,本文将对 Vue.js中的watch属性进行详细的介绍,并附上相关的代码示例,需要的朋友可以参考下
    2023-06-06
  • docker-compose如何自定义network

    docker-compose如何自定义network

    文章介绍了在DockerCompose中如何通过networks配置定义和使用桥接网络,包括如何在docker-compose.yml文件中指定使用bridge网络,服务间的通信方式以及如何为服务分配特定的IP地址
    2025-01-01
  • Docker中的容器网络以及其配置说明

    Docker中的容器网络以及其配置说明

    这篇文章主要介绍了Docker中的容器网络以及其配置说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • Docker+nacos+seata1.3.0安装与使用配置教程

    Docker+nacos+seata1.3.0安装与使用配置教程

    这篇文章主要介绍了Docker+nacos+seata1.3.0安装与使用配置教程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • 详解修改docker时区及docker常用命令

    详解修改docker时区及docker常用命令

    这篇文章主要介绍了详解修改docker时区及docker常用命令,非常具有实用价值,需要的朋友可以参考下。
    2016-12-12

最新评论