作者丨PavanKumar译者|恩,那就对了。我目前正在开发一个ReactJS项目,我正在其中构建一个前端应用程序。ReactJS项目没有什么新鲜事。我使用了与典型前端应用相同的package.json、相同的依赖集。现在,我决定将应用程序迁移到Kubernetes。所以我将Docker镜像推送到DockerHub并尝试在Kubernetes中部署pod。 我正在使用本地集群,pod需要5分7秒才能启动。我很惊讶。然后我将它部署到AKS集群(AzureKubernetes集群)。神奇的是,用了3分40秒。这是一个大问题。我尝试对pod进行压力测试以触发KubernetesHPA(Horizo??ntalPodAutoscaler)。新的pod需要同样的3分钟才能出现,最终应用程序被如此多的请求淹没,以至于崩溃并不断重启。经过一番调查,我发现镜像的大小是瓶颈,当然,你不会想要这么大的Docker镜像(0.5GB)。那时我意识到我必须对Docker图像大小做些什么。因此,我使用了Docker多阶段构建的概念。Docker构建:FROMnode:alpineWORKDIR/appCOPYpackage.json./COPYpackage-lock.json./COPY././RUNnpmiCMD["npm","run","start"] 这是我的初始典型ReactJS应用程序的Dockerfile。如果打开视图,您可以看到第一行代码。我使用node:alpine作为基础图像。下面是构建后的镜像大小。非多阶段构建 这是典型的镜像构建方式,写这样的Docker文件看起来很容易。但是从Kubernetes的角度来看,使用这种方式有如下一些缺点 a)image的大小直接影响Pod的启动时间。b)图片越小,Pod启动越快。Docker多阶段构建: Dockerfile中的多阶段构建功能使您能够创建具有更好缓存和更小安全足迹的更小容器映像。通过多阶段构建,您可以在Dockerfile中使用多个FROM语句。每条FROM指令都可以使用不同的基础镜像,每条FROM指令都开始构建一个新的阶段。您可以有选择地将一个阶段中构建的内容复制到另一个阶段。对于那些不需要出现在最终图像中的内容,留在前一阶段即可。 好像不一样?好吧,让我们看一下这个文件。#选择已经安装了Node的镜像FROMnode:alpineasbuildWORKDIR/codeCOPYpackage.jsonpackage.jsonCOPYpackage-lock.jsonpackage-lock.jsonRUNnpmci--production#COPY当前目录中的所有文件到ContainerCOPY中。.#安装项目依赖项,如ExpressFrameworkRUNnpmrunbuildFROMnginx:1.22-alpineasprodCOPY--from=build/code/build/usr/share/nginx/html#TellthatthisimageisgoingtoOpenaPortEXPOSE80#DefaultCommand启动ApplicationCMD["nginx","-g","daemonoff;"] 第一行称为阶段。这些阶段没有命名,您可以通过它们的整数来引用它们,从第一个FROM指令的0开始。或者,您也可以通过将AS添加到FROM指令来命名阶段。 然后其余步骤不变。一个改变游戏规则的步骤是COPY--from(第18行)。使用多阶段构建时,您可以在Dockerfile中使用多个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译者简介 崔英峰,社区小编,70后程序员,10年以上工作经验,长期从事Java开发、架构设计、容器化等相关工作。
