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

目录

  • 一、减少镜像层数
    • 1.指令合并
    • 2.多阶段构建
    • 3.启用squash特性
  • 二、缩减容量
    • 1. 选择小的基础镜像
    • 2.上下文管理
    • 3.及时清理下载
精简镜像我们可以从两个方面切入:
减少镜像层数
缩减容量


一、减少镜像层数

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 三个指令会创建层,其他指令会创建一个中间镜像,并且不会影响镜像大小。这样我们说的指令合并也就是以这三个指令为主。
【docker容器详细讲解如何精简镜像减小体积】我们以如下Dockerfile为例
FROM debian:stableWORKDIR /var/wwwLABEL version=“v1”RUN apt-get updateRUN apt-get -y --no-install-recommends install curlRUN apt-get purge -y curlRUN apt-get autoremove -yRUN apt-get cleanRUN rm -rf /var/lib/apt/lists/*

构建镜像
docker build -t curl:v1 .

通过history查看构建历史
# docker history curl:v1IMAGECREATEDCREATED BYSIZECOMMENT29b721c09b6718 seconds ago/bin/sh -c rm -rf /var/lib/apt/lists/*0Baa28ae151e5920 seconds ago/bin/sh -c apt-get clean0B4f733781f55722 seconds ago/bin/sh -c apt-get autoremove -y989kBf6688737212129 seconds ago/bin/sh -c apt-get purge -y curl987kBd458ee0de46334 seconds ago/bin/sh -c apt-get -y --no-install-recommend…4.46MB43fdcf68018c44 seconds ago/bin/sh -c apt-get update17.6MB65631e8bb01053 seconds ago/bin/sh -c #(nop)LABEL version=“v1”0B7ef7c53b019c53 seconds ago/bin/sh -c #(nop) WORKDIR /var/www0B8bfa93572e5513 days ago/bin/sh -c #(nop)CMD ["bash"]0B13 days ago/bin/sh -c #(nop) ADD file:d78d93eff67b18592…124MB

镜像大小
[root@localhost dockerfiles]# docker imagesREPOSITORYTAGIMAGE IDCREATEDSIZEcurlv129b721c09b6710 minutes ago148MB

我们将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:v2IMAGECREATEDCREATED BYSIZECOMMENT928e12c2f57eAbout a minute ago/bin/sh -c apt-get update &&apt-get -y …989kB5a32372025fbAbout a minute ago/bin/sh -c #(nop)LABEL version=“v2”0B7ef7c53b019c30 minutes ago/bin/sh -c #(nop) WORKDIR /var/www0B8bfa93572e5513 days ago/bin/sh -c #(nop)CMD ["bash"]0B13 days ago/bin/sh -c #(nop) ADD file:d78d93eff67b18592…124MB# docker imagesREPOSITORYTAGIMAGE IDCREATEDSIZEcurlv2928e12c2f57e3 minutes ago125MB

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

2.多阶段构建

在Docker17.05 中引入了多阶段构建,通过多阶段构建可以大大降低构建复杂度,同时使缩小镜像尺寸更为简单。我们来看多阶段构建的Dockerfile
#阶段1FROM golang:1.16WORKDIR /go/srcCOPY app.go ./RUN go build app.go -o myapp#阶段2FROM scratchWORKDIR /serverCOPY --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 debianstable-slim2aa48a485e3a13 days ago80.4MBdebianstable8bfa93572e5513 days ago124MB

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

构建后的镜像尺寸更小
# docker images REPOSITORYTAGIMAGE IDCREATEDSIZEcurlv41aab5c9bf8b317 seconds ago81.4MB

当前映像基于 Debian,并包含许多二进制文件。Docker 容器应该包含一个进程,并包含运行它所需的最低限度。我们其实不需要整个操作系统。
我们可以使用基于 Alpine 的镜像 替换Debian 基础镜像。
FROM alpineWORKDIR /var/wwwLABEL 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 imagesREPOSITORYTAGIMAGE IDCREATEDSIZEcurlv57f735bb213be11 seconds ago10.1MB

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

2.上下文管理

我们经常会用到的COPY指令
COPY . /server/dir

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

3.及时清理下载

我们有如下Dockerfile
..WORKDIR /tmpRUN 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容器 精简镜像内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读