dbaplus社群 2024年11月05日
你一定不知道!这个将 Docker 镜像缩小 99% 的隐藏技术
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文探讨了Docker镜像过大带来的问题,介绍了多种优化技术,如多阶段构建、层优化、使用最小基础镜像等,通过这些技术将镜像从1.2GB优化至8MB,实现部署时间缩短85%,云成本降低60%。

多阶段构建可显著减少镜像大小,将构建与运行时依赖项分开

层优化通过组合指令减少冗余层,保持镜像更干净

使用最小基础镜像,如Scratch,可使镜像针对部署进行优化

采用先进技术如Distroless镜像,仅包含运行应用所需内容

原创 Dipanshu 2024-11-04 07:15 广东

从 1.2GB 到 8MB,部署时间缩短 85%,云成本降低 60%,实在太香了!




你是否一样厌倦了与臃肿的 Docker 镜像进行抗争?这些镜像是否会占用磁盘空间并影响部署速度?值得注意的是:顶级 DevOps 团队已经将镜像大小削减了 99%。在本指南中,我将揭开他们一直保密的技术。




臃肿的 Docker 镜像的隐性成本


在我们深入研究解决方案之前,让我们先讨论一下为什么这很重要。过大的 Docker 镜像不仅会带来麻烦,还会让你付出代价:



从 1.2GB 到 8MB 的历程:案例研究


为了说明这些技术的威力,让我们看一个真实的例子。我们采用了一个基于 Python 的标准机器学习应用程序,初始 Docker 镜像大小为 1.2GB,并将其优化至仅 8MB,优化步骤如下:



起点:臃肿的镜像


这通常是你可能遇到的典型 Dockerfile


FROM python:3.9WORKDIR /appCOPY requirements.txt .RUN pip install -r requirements.txtCOPY . .CMD ["python", "main.py"]


该 Dockerfile 虽然有效,但以下原因会导致镜像尺寸较大:



现在一起看看可以优化镜像的技术:


多阶段构建:游戏规则改变者


多阶段构建是一种强大的技术,可以显著减少最终 Docker 镜像的大小,它使我们能够将构建时依赖项与运行时依赖项分开。



根据你的用例,将完整的 python 版本替换为 slim 或 alpine 版本


FROM python:3.9-slim AS builder


单阶段 Dockerfile


#  an official Python runtime as a parent imageFROM python:3.9-slim


# Install necessary build dependenciesRUN apt-get update && apt-get install -y --no-install-recommends \    build-essential \    gcc \    && rm -rf /var/lib/apt/lists/*# Set the working directoryWORKDIR /app# Copy the requirements file and install dependenciesCOPY requirements.txt ./RUN pip install --no-cache-dir -r requirements.txt# Copy the rest of the application codeCOPY . .# Compile the model (if necessary)RUN python compile_model.py# Run the inference scriptCMD ["python", "inference.py"]


构建此镜像大约需要 1.2GB,这么大的尺寸是由于这包含了所有构建工具和开发库。


多阶段 Dockerfile


第一阶段:构建阶段



# Stage 1: BuildFROM python:3.9-slim AS builder


# Install necessary build dependenciesRUN apt-get update && apt-get install -y --no-install-recommends \    build-essential \    gcc \    && rm -rf /var/lib/apt/lists/*# Set the working directoryWORKDIR /app# Copy the requirements file and install dependenciesCOPY requirements.txt ./RUN pip install --no-cache-dir -r requirements.txt# Copy the application codeCOPY . .# Compile the model (if necessary)RUN python compile_model.py# Install PyInstallerRUN pip install pyinstaller# Create a standalone executableRUN pyinstaller --onefile inference.py


第二阶段:生产阶段



# Stage 2: ProductionFROM scratch# Set the working directoryWORKDIR /app# Copy only the necessary files from the build stageCOPY --from=builder /app/dist/inference /app/inferenceCOPY --from=builder /app/model /app/model# Run the inference executableENTRYPOINT ["/app/inference"]


构建此多阶段 Dockerfile 的镜像大小约为85 MB — 减少了90%以上


层优化:每个字节都很重要


你在 Dockerfile 中写入的每条指令都会在 Docker 镜像中创建一个新层。例如 RUN、COPY 和 ADD 命令各自添加一个层,并且每个层都会添加镜像大小以及构建时间




RUN apt-get update && apt-get install -y python3-pip python3-dev && \pip3 install numpy pandas && \apt-get clean && rm -rf /var/lib/apt/lists/*


从头开始的最小基础镜像:少即是多


这是创建 Docker 镜像的最强大、但也是最具挑战性的方法。从头开始创建镜像意味着使用从头开始的基础镜像(https://hub.docker.com/_/scratch),无底层操作系统、没有依赖性、没有预先存在的数据或应用程序。把它想象成一个空的存储光盘,必须用数据填充它,因为里面什么也没有。


你放入其中的任何内容都会影响其大小,也意味着,如果你需要任何依赖项或支持应用程序或工具,你需要自己将它们安装在镜像上。


它主要在两种情况下有用:




# syntax=docker/dockerfile:1FROM scratchADD myapp /CMD ["/myapp"]


先进技术


Distroless 镜像


想象一下你正在收拾行李去旅行,你有三个选择:



Google 的 distroless 镜像介于完整发行版和临时镜像之间,这是“恰到好处”的选项,它仅包含运行应用程序所需的内容。


Distroless 镜像特点如下:



FROM gcr.io/distroless/python3-debian10COPY --from=builder /app/dist/main /app/mainCOPY --from=builder /app/model /app/modelCOPY --from=builder /app/config.yml /app/config.ymlENTRYPOINT ["/app/main"]


使用 Docker 构建工具包


Docker BuildKit 为构建 Docker 镜像提供了改进的性能、安全性和更灵活的缓存失效。启用它


DOCKER_BUILDKIT=1 docker build -t myapp .


其他技术



# Exclude large datasetsdata/


# Exclude virtual environmentvenv/# Exclude cache, logs, and temporary files__pycache__/*.log*.tmp*.pyc*.pyo*.pyd.pytest_cache.git.gitignoreREADME.md# Exclude model training checkpoints and tensorboard logscheckpoints/runs/



安全精简 Docker 镜像的基本安全实践



RUN adduser --disabled-password --gecos "" appuserUSER appuser



docker run -p 127.0.0.1:8080:8080 myimage


定期扫描 Docker 镜像是否存在已知漏洞。(考虑使用Trivy等工具定期扫描镜像是否存在漏洞)


docker scan your-image:tag



结论


实施这些技术后,我们取得了以下成果:



请记住,关键是从最小的基础镜像开始,使用多阶段构建将构建环境与运行时环境分开,并不断优化层和依赖项。通过这些方法,可以显着减小 Docker 镜像的大小!


鼓励大家在自己的项目中尝试这些优化技术,从多阶段构建开始,然后逐步应用其他技术,看看可以将 Docker 镜像制作得有多小、有多高效。Happy optimizing :)



作者丨Dipanshu    编译丨Rio

来源丨网址:https://medium.com/aws-in-plain-english/docker-pros-are-shrinking-images-by-99-the-hidden-techniques-you-cant-afford-to-miss-a70ee26b4cbf


*本文为dbaplus社群编译整理,如需转载请取得授权并标明出处!欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn


跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Docker镜像 多阶段构建 层优化 最小基础镜像
相关文章