ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

docker镜像瘦身

2022-06-20 18:00:25  阅读:145  来源: 互联网

标签:server 编译 构建 build go 镜像 docker 瘦身


参考:https://mp.weixin.qq.com/s/hn8Env3e5PztLgOCAYZamA

在构建 docker 容器时,我们一般希望尽量减小镜像,以便加快镜像的分发;但是不恰当的镜像构建方式,很容易导致镜像过大,造成带宽和磁盘资源浪费,尤其是遇到 daemonset 这种需要在每台机器上拉取镜像的服务,会造成大量资源浪费;而且镜像过大还会影响服务的启动速度,尤其是处理紧急线上镜像变更时,直接影响变更的速度。如果不是刻意控制镜像大小、注意镜像瘦身,一般的业务系统中可能 90% 以上的大镜像都存在镜像空间浪费的现象(不信可以尝试检测看看)。因此我们非常有必要了解镜像瘦身方法,减小容器镜像。

 一、判断镜像是否需要瘦身

通常,我们可能都是在容器镜像过大,明显影响到镜像上传/拉取速度时,才会考虑到分析镜像,尝试镜像瘦身。此时采用的多是 docker image history 等 docker 自带的镜像分析命令,以查看镜像构建历史、镜像大小在各层的分布等。然后根据经验判断是否存在空间浪费,但是这种判断方式起点较高、没有量化,不方便自动化判断。当前,社区中也有很多镜像分析工具,其中比较流行的 dive 分析工具,就可以量化给出容器镜像有效率、镜像空间浪费率等指标。

# curl -OL https://github.com/wagoodman/dive/releases/download/v0.9.1/dive_0.9.1_linux_amd64.rpm 
# rpm -ivh dive_0.9.1_linux_amd64.rpm
# dive  mysql:lastest

采用 dive 对一个 mysql 镜像进行效率分析,发现镜像有效率只有 41%,镜像空间浪费率高达 59%,显然需要瘦身。

二、镜像瘦身方法

2.1 使用Alpine Linux

Alpine Linux是一个基于BusyBox和Musl Libc的Linux发行版,其最大的优势就是小。一个纯的基础Alpine Docker镜像在压缩后仅有2.67MB

 

2.2多阶段构建

所谓多阶段构建,实际上是允许在一个 Dockerfile 中出现多个 FROM 指令。最后生成的镜像,以最后一条 FROM 构建阶段为准,之前的 FROM 构建阶段会被抛弃。通过多阶段构建,后一个阶段的构建过程可以直接利用前一阶段的构建缓存,有效降低镜像大小。一个典型的场景是将编译环境和运行环境分离,以一个 go 项目镜像构建过程为例:

# Go语言编译环境基础镜像
FROM golang:1.16-alpine
# 拷贝源码到镜像
COPY server.go /build/
# 指定工作目录
WORKDIR /build
# 编译镜像时,运行 go build 编译生成 server 程序
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOARM=6 go build -ldflags '-w -s' -o server
# 指定容器运行时入口程序
ENTRYPOINT ["/build/server"]

这种传统的构建方式有以下缺点:

  • 基础镜像为支持编译环境,包含大量go语言的工具/库,而运行时并不需要。
  • COPY 源码,增加了镜像分层,同时有源码泄漏风险。

采用多阶段构建方式,可以将上述传统的构建方式修改如下:

## 1 编译构建阶段
#  Go语言编译环境基础镜像
FROM golang:1.16-alpine AS build
# 拷贝源码到镜像
COPY server.go /build/
# 指定工作目录
WORKDIR /build
# 编译镜像时,运行 go build 编译生成 server 程序
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOARM=6 go build -ldflags '-w -s' -o server

## 2 运行构建阶段
#  采用更小的运行时基础镜像
FROM scratch
# 从编译阶段仅拷贝所需的编译结果到当前镜像中
COPY --from=build /build/server /build/server
# 指定容器运行时入口程序
ENTRYPOINT ["/build/server"]

可以看到,使用多阶段构建,可以获取如下好处:

  • 最终镜像只关心运行时,采用了更小的基础镜像。
  • 直接拷贝上一个编译阶段的编译结果,减少了镜像分层,还避免了源码泄漏。

 2.3减少镜像分层

镜像的层就像 Git 的提交(commit)一样,用于保存镜像的当前版本与上一版本之间的差异,但是镜像层会占用空间,拥有的层越多,最终的镜像就越大。在构建镜像时,RUN, ADD, COPY 指令对应的层会增加镜像大小,其他命令并不会增加最终的镜像大小。

可以尝试合并相关指令,以减小镜像分层;COPY 指令转换合并到 RUN 指令

标签:server,编译,构建,build,go,镜像,docker,瘦身
来源: https://www.cnblogs.com/lina-2159/p/16374059.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有