如何将AI能力与大数据技术结合,助力数据分析治理等工作的效率大幅提升,优化大数据引擎的性能及成本? 了解详情
写点什么

如何给 Docker 镜像瘦身?

  • 2019-03-12
  • 本文字数:3419 字

    阅读完需:约 11 分钟

如何给Docker镜像瘦身?

在本文中,你将了解如何加快 Docker 构建周期并创建轻量级镜像。还是用比喻来说吧,给 Docker 镜像瘦身就跟我们减肥一样,减肥时期我们吃沙拉,拒绝披萨、甜甜圈和百吉饼。


这是备忘单。


FROM:指定基础(父)镜像。


标签:提供元数据。这里是包含维护者信息的好地方。


ENV:设置一个持久环境变量。


RUN:运行一个命令并创建一个图像层。用于将包安装到容器中。


COPY:将文件和目录复制到容器中。


ADD:将文件和目录复制到容器中。可以上传本地.tar 文件中。


CMD:为正在执行的容器提供命令和参数。可以覆盖参数。只能有一个 CMD。


WORKDIR:为下面的指令设置工作目录。


ARG:在构建时传递给 Docker 的变量。


ENTRYPOINT:为正在执行的容器提供命令和参数。关于这件事的争论一直在持续。


EXPOSE:公开端口。


VOLUME:创建一个目录挂载点来访问和存储持久数据。


现在让我们看看如何设计 dockerfile,以便在开发镜像和提取容器时节省时间。


缓存

Docker 的优点之一是提供缓存,帮助你更快地迭代镜像构建。


在构建映像时,Docker 按步骤遍历 Dockerfile 中的指令,按顺序执行每个指令。在检查每个指令时,Docker 会在其缓存中寻找一个可以重用的现有中间镜像,而不是创建一个新的(重复的)中间映像。


如果缓存无效,让无效的指令和所有后续 Dockerfile 指令生成新的中间镜像。一旦缓存失效,Dockerfile 中其余的指令也就失效了。


因此,从 Dockerfile 的顶部开始,如果基础镜像已经在缓存中,那么它将被重用。这将是高效命中。否则,缓存无效。



也是一击


然后将下一条指令与从该基础镜像派生的缓存中的所有子镜像进行比较。比较每个缓存的中间镜像,看指令是否在缓存命中。如果缓存失败,则缓存无效。重复相同的过程,直到到达 Dockerfile 的末尾。


大多数新指令只是简单地与中间镜像中的指令进行比较。如果匹配,则使用缓存的副本。


例如,当在 Dockerfile 中找到RUN pip install -r requiremtes .txt指令时,Docker 会在本地缓存的中间镜像中搜索相同的指令。不比较新旧 requirements.txt 文件的内容。


如果使用新包来更新 requirements.txt 文件,并使用RUN pip install并希望使用新包名称重新运行包安装,则此行为可能会出现问题。我一会儿会展示一些解决方案。


与其他 Docker 指令不同,ADD 和 COPY 指令确实需要 Docker 查看文件的内容,以确定是否存在缓存命中。将引用文件的校验和与现有中间镜像中的校验和进行比较。如果文件内容或元数据发生了更改,则缓存无效。


下面是一些有效使用缓存的技巧。


  • 可以通过传递--no-cache=Truedocker build关闭缓存。

  • 如果你要对指令进行更改,那么接下来的每一层都将频繁地重新构建。要利用缓存,请在 Dockerfile 中尽可能低地放置可能更改的指令。

  • 链接RUN apt-get updateapt-get install命令,以避免缓存丢失问题。

  • 如果你正在使用带有 requirements.txt 文件的包安装程序(如 pip),那么请遵循如下模型,以确保你不会收到带有 requirements.txt 中列出的旧包的陈旧的中间镜像。


COPY requirements.txt /tmp/RUN pip install -r /tmp/requirements.txtCOPY . /tmp/
复制代码


这些是有效使用 Docker 构建缓存的建议。


减小尺寸

Docker 镜像可能会变得很大。你想让它们尺寸变小,这样它们就可以快速拉起,使用很少的资源。让我们给你的镜像瘦身!



吃顿沙拉而不是百吉饼


Alpine base 镜像是一个完整的 Linux 发行版,没有太多其他东西。下载通常小于 5mb,但是它需要更多的时间为构建应用程序所需的依赖项编写代码。



Alpine 源自阿尔卑斯山脉


如果你的容器中需要 Python, Python Alpine 构建是一个不错的折衷方案。它包含 Linux 和 Python,你可以提供大多数其他东西。


我用最新的 Python Alpine 构建的带有打印脚本(“hello world”)的镜像大小为 78.5 MB。下面是 Dockerfile:


FROM python:3.7.2-alpine3.8COPY . /appENTRYPOINT [“python”, “./app/my_script.py”, “my_var”]
复制代码


在 Docker Hub 上,基础镜像的大小为 29MB,当构建子镜像时,需要下载并安装 Python,尺寸就变得很大。


除了使用 Alpine 基础镜像,另一种减小镜像大小的方法是使用多级构建。这种技术还会增加 Dockerfile 的复杂性。


多级构建



一个舞台+另一个舞台=多级舞台


多阶段构建使用多个 FROM 指令。你可以有选择地将文件(称为构建工件)从一个阶段复制到另一个阶段。你可以在最终的镜像中扔掉任何你不想要的东西。这种方法可以减少整体镜像的大小。


每个 FROM 指令


  • 开始构建的新阶段

  • 去掉在之前阶段留下的任何状态

  • 可以用不同的基础镜像


下面是Docker文档中经过修改的多级构建示例:


FROM golang:1.7.3 AS buildWORKDIR /go/src/github.com/alexellis/href-counter/RUN go get -d -v golang.org/x/net/html  COPY app.go .RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .FROM alpine:latest  RUN apk --no-cache add ca-certificatesWORKDIR /root/COPY --from=build /go/src/github.com/alexellis/href-counter/app .CMD ["./app"]
复制代码


注意,我们通过给 FROM 指令增加一个名字来命名第一阶段。然后,被命名的阶段会通过COPY --from=指令引用到 Dockerfile 中。


在制造大量容器的情况下,多级构建是有意义的。多级构建可以帮助你从镜像大小中挤出每一寸空间。然而,有时多阶段构建会增加复杂性,使镜像更难维护,因此你可能不会在大多数构建中使用它们。参见此处对折衷高级模式的进一步讨论。


相反,每个人都应该使用.dockerignore 文件来帮助保持 Docker 镜像的简洁。


.dockerignore

如果你对 Docker 了解得足够多,那么*.dockerignore*就是一些你应该知道的东西。


.dockerignore 类似于.gitignore。它是一个包含 Docker 模式列表的文件,Docker 在生成镜像时需要匹配文件名并排除这些模式。



来.dockerignore 一下


将.dockerignore 文件与 Dockerfile 和构建上下文的其余部分放在同一个文件夹中。


运行 docker build 创建镜像时,docker 检查.dockerignore 文件。如果找到一个,则逐行检查文件并使用 Go 的filepath。匹配规则——以及Docker自己的一些规则——以匹配文件名以进行排除。想想 unix 风格的 glob 模式,而不是正则表达式。


因此*.jpg将排除扩展名为.jpg 的文件。并且视频将排除视频文件夹及其内容。


您可以使用以#开头的注释来解释您在.dockerignore 中所做的事情。


使用.dockerignore 从 Docker 镜像中排除不需要的文件是个好主意。


  • 帮助你保守秘密。没有人想在镜像中使用密码。

  • 减少镜像大小。更少的文件意味着更小、更快的镜像。

  • 减少构建缓存失效。如果日志或其他文件正在发生变化,而你的镜像缓存因此而失效,则会减慢构建周期。


这就是使用.dockerignore 文件的原因。


尺寸检查

让我们看看如何从命令行找到 Docker 镜像和容器的大小。


  • 要查看正在运行的容器的大致大小,可以使用docker container ls -s命令。

  • 运行docker image ls显示镜像的大小。

  • 要查看组成镜像的中间镜像大小,请使用docker image history my_image:my_tag

  • 运行Docker image inspect my_image:tag:该标签将显示跟镜像有关的信息,包括每个层的大小。图层与构成镜像略有不同。但是你可以把它们看成是一样的。

  • 安装和使用dive可以很容易地看到你的层内容。


现在,让我们来看看一些最佳实践来给镜像瘦身。


减少镜像大小和构建时间的八个最佳实践

  1. 尽可能使用正式的基础镜像。官方镜像定期更新,比非官方镜像更安全。

  2. 在可能的情况下使用不同的 Alpine 镜像,以保持你的镜像轻量级。


3.如果使用 apt,请在同一指令中将 RUN apt-get update 与 apt-get install 结合使用。然后在该指令中链接多个包。用\字符在多行上按字母顺序列出包。例如:


RUN apt-get update && apt-get install -y \    package-one \    package-two  && rm -rf /var/lib/apt/lists/*
复制代码


这种方法减少了要构建的层的数量,并保持简洁。


  1. 在运行指令的末尾包含&& rm -rf /var/lib/apt/lists/*,以清理 apt 缓存,使其不存储在层中。

  2. 聪明地使用缓存,将可能发生更改的指令放在 Dockerfile 中。

  3. 使用.dockerignore 文件将不需要的和不必要的文件从镜像中删除。

  4. 查看dive——它的一个非常酷的工具,可以检查你的 Docker 镜像层,并帮助你削减多余的部分。

  5. 不要安装你不需要的软件包。唉!但这种现象很常见。


总结

现在你知道了如何使 Docker 镜像快速构建、快速下载,并且不占用太多空间。和健康饮食一样,知道是成功的一半。享受你的蔬菜。



健康和美味


查看英文原文链接:https://towardsdatascience.com/slimming-down-your-docker-images-275f0ca9337e


2019-03-12 15:007465
用户头像

发布了 124 篇内容, 共 39.9 次阅读, 收获喜欢 173 次。

关注

评论 5 条评论

发布
用户头像
图片再次丢失
2021-03-04 14:51
回复
用户头像
配图已挂!!
2019-03-13 14:21
回复
已修复。
2019-03-13 15:14
回复
用户头像
骷髅图和沙拉不太搭配啊。。。
2019-03-12 21:06
回复
非礼勿听、非礼勿言、非礼勿视?
2019-03-13 15:15
回复
没有更多了
发现更多内容

索信达控股:探寻金融数字化转型契机下的高增长“密码”

索信达控股

直播时各种背景是怎么实现的?聊一聊虚拟背景背后的技术

阿里云视频云

阿里云 计算机视觉 视频会议 虚拟背景 人像抠图

发布两小时,霸榜GitHub!Spring Boot实战文档

java小李

Spring Boot

IT自动化运维工具就用行云管家!省心省力省事!

行云管家

云管平台 IT运维 行云管家 自动化运维

企业上云是什么意思?企业上云的好处是什么?

行云管家

云计算 软件 云服务 企业上云 IDC

java并发编程

十二万伏特皮卡丘

抖音获客APP开发,抖音获客系统开发(成功案例),抖音获客系统源码

系统开发咨询1357O98O718

技术分析| 即时通讯和实时通讯的区别

anyRTC开发者

音视频 WebRTC 即时通讯 实时通讯 实时消息

短视频SEO软件系统开发资料

Tensorflow serving with docker

毛显新

tensorflow Docker

贝丽美牙系统开发(开发案例),贝丽美牙源码设计

系统开发咨询1357O98O718

双特新零售系统开发(开发模式),双特新零售现成源码

系统开发咨询1357O98O718

短视频SEO营销系统软件开发资料

妙视亮眼贴系统开发案例分析,妙视亮眼贴开发源码

系统开发咨询1357O98O718

逆袭成功,不愧是阿里内部面试参考指南,已帮我拿下了8个大厂的offer

Java 程序员 架构 面试 计算机

一周信创舆情观察(7.19~7.25)

统小信uos

只出现一次的数字

Memorys

Java 面试 算法

抖音获客系统开发(软件开发),抖音获客源码模式

系统开发咨询1357O98O718

GitHub万人斩!Java系列面试宝典,我拿到之后直接反杀了面试官

java小李

git cherry-pick

WebAssembly正逐渐成为FaaS的主力

DisonTangor

Docker Faas webassembly

短视频SEO获客系统软件开发简介

后端开发-Reactor设计模式

Linux服务器开发

reactor 设计模式 网络编程 线程池 epoll

通过创建GeoLine给地图添加烟花图效果

森友小锘

大前端 地图 物联网 可视化

从简历被拒到收割8个大厂offer,我用了3个月成功破茧成蝶

java小李

面试

直呼内行!靠着这份阿里10w字面试总结,我成功收到了4个大厂offer

Java 程序员 架构 面试 计算机

仅仅上线一小时,下载量就破10W!阿里内部Java性能优化实战手册

java小李

面试 JVM

【共识专栏】共识的分类(上)

趣链科技

区块链 联盟共识 共识机制 共识算法

短视频询盘软件系统开发内容

花朵分类(一)

毛显新

深度学习 tensorflow keras

南山二脂系统开发功能,南山二脂源码案例设计

系统开发咨询1357O98O718

如何给Docker镜像瘦身?_容器_Jeff Hale_InfoQ精选文章