看我如何将Docker镜像大小缩减95%

译文 精选
开发
使用Docker多阶段构建的概念

作者丨Pavan Kumar

译者 | 崔莹峰

策划丨诺亚

  编写Dockerfile看起来很容易,除非你最终编写了大小为0.5GB的Docker镜像。是的,没错。我最近在做一个ReactJS项目,在那里我正在构建一个前端应用程序。React JS项目没有什么新鲜的。我使用了与典型前端应用程序相同的package.json,相同的依赖集。现在,我决定将应用程序迁移到Kubernetes。所以我将Docker镜像推送到DockerHub并尝试在Kubernetes部署Pod。

  我使用的是一个本地集群,Pod花了5分零7秒启动。我很惊讶。然后我将其部署到AKS集群(Azure Kubernetes集群)。令人惊讶的是,它花了3分40秒。这可是件大事。我尝试对Pod进行压测以触发Kubernetes HPA(Horizontal Pod Autoscaler)。新的Pod需要同样的3分钟才能出现,最终应用程序被太多的请求淹没,不堪重负以致崩溃不断重启。经过调查,我发现镜像的大小是瓶颈,当然,你不会想要如此巨大的Docker镜像(0.5GB)。那时我意识到我必须对Docker镜像大小做些什么。因此,我使用了Docker多阶段构建的概念。

Docker构建:

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
CMD ["npm", "run", "start"]

  这是我最初的一个Dockerfile,它是为一个典型的ReactJS应用程序提供的。如果你打开查看,你就可以看到第一行代码,我使用了node:alpine作为基础镜像,如下是镜像构建完成后的尺寸。

图片

非多阶段构建

  这是构建镜像的典型方法,编写这样的Docker文件似乎很容易。但是从Kubernetes的角度来看,使用这种方法存在一些缺点如下

  a)镜像的大小直接影响Pod启动时间。

      b)镜像越小,Pod启动越快。

Docker多阶段构建:

  Dockerfile中的多阶段构建特性使你能够创建具有更好缓存和占用更小安全空间的较小容器镜像。使用多阶段构建,你可以在Dockerfile中使用多个FROM语句。每个FROM指令可以使用不同的基础镜像,并且每个FROM指令都会开始构建一个新的阶段。你可以有选择地将一个阶段构建好的内容复制到另一个阶段,对于那些不需要出现在在最终镜像里的内容就留在上一个阶段好了。

  似乎不一样?好吧,让我们了解一下这个文件。

# Choose the Image which has Node installed already
FROM node:alpine as build
WORKDIR /code
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci --production
# COPY all the files from Current Directory into the Container
COPY . .
# Install the Project Dependencies like Express Framework
RUN npm run build
FROM nginx:1.22-alpine as prod
COPY --from=build /code/build /usr/share/nginx/html
# Tell that this image is going to Open a Port
EXPOSE 80
# Default Command to launch the Application
CMD ["nginx", "-g", "daemon off;"]

  第一行称为阶段。这些阶段没有命名,你通过它们的整数来引用它们,从0开始表示第一条FROM指令。或者,你也可以通过向FROM指令添加AS来命名阶段。

  然后其余的步骤保持不变。改变游戏规则的一个步骤是COPY——来自(第18行)。使用多阶段生成时,可以在Docker文件中使用多个FROM语句。每个FROM指令都可以使用不同的基础镜像,并且每个指令都开始构建一个新的阶段。你可以有选择地将一个阶段构建好的内容复制到另一个阶段,对于那些不需要出现在在最终镜像里的内容就留在上一个阶段好了。

  现在让我们开始构建镜像。

图片

多阶段构建镜像尺寸

  哇,是的!图像大小压缩了95%。图像大小现在是27.2MB。

  我的本地集群花了25秒来拉取镜像并开始使用。我的AKS集群花了10秒钟来拉取镜像并开始使用。

  这就是如何利用Docker中的多阶段构建来压缩Docker镜像的大小。

  原文链接:

  ​​https://levelup.gitconnected.com/how-i-reduced-the-size-of-my-docker-image-by-95-520a05439300​

译者简介

  崔莹峰,51CTO社区编辑,一名70后程序员,拥有10多年工作经验,长期从事 Java开发,架构设计,容器化等相关工作。

责任编辑:张洁 来源: 51CTO技术栈
相关推荐

2023-11-06 13:11:22

Docker映像Builkit

2019-07-15 10:00:53

DockerJava容器

2023-12-29 07:04:28

Go项目Docker编写

2019-07-15 16:00:24

Docker架构容器

2009-02-19 16:59:10

虚拟化VMware虚拟磁盘

2020-08-23 11:52:10

Docker容器技术

2009-08-26 18:05:25

ViewState持久

2024-11-01 12:10:57

2024-01-15 08:59:31

Docker优化

2011-05-18 14:51:43

2018-06-12 15:07:57

IT

2023-02-17 12:07:45

ChatGPTPython

2017-01-05 09:18:12

容器Docker

2011-11-08 15:15:40

路由器复位

2012-11-07 15:57:34

OSSECMYSQL

2015-10-28 14:59:26

JAVA插件Chrome

2009-06-11 10:50:27

netbeans配置

2009-03-04 10:27:50

Provisionin桌面虚拟化Xendesktop

2021-12-22 10:45:56

Docker RegiHarborLinux

2011-05-04 09:29:22

点赞
收藏

51CTO技术栈公众号