ICode9

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

dockerfile多阶段构建的优缺点

2022-06-14 15:01:52  阅读:220  来源: 互联网

标签:testapi 宿主机 优缺点 publish 构建 dotnet 镜像 dockerfile


一直以来,公司的CI/CD环境都是在Jenkins的工作节点中编译,再将编译打包好的目标程序直接使用dockerfile构建镜像。

以.NET程序来做例子,其dockerfile是这样的

FROM mcr.microsoft.com/dotnet/aspnet:3.1-focal
WORKDIR /app
COPY ./publish /app
CMD ["dotnet", "testapi.dll"]

Jenkins的shell脚本则直接执行

dotnet dotnet publish -o ./publish
docker build -t testapi .

 

以上做法是不符合docker的理念的,因为工作节点(docker的宿主机)还需要安装对应程序的sdk才可以进行程序的编译打包。

所以我决定对其进行一点改造,通过Dockerfile的多阶段构建,使程序的编译也依赖于docker镜像,这样工作节点就无需自己去安装SDK了,以后扩展多个工作节点也方便很多。

还是以.NET程序为例,改造后的dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:3.1-focal AS base

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["testapi/testapi.csproj", "testapi/"]
COPY ["testapi.Infrastructure/testapi.Infrastructure.csproj", "testapi.Infrastructure/"]
COPY ["testapi.Core/testapi.Core.csproj", "testapi.Core/"]
COPY ["testapi.Model/testapi.Model.csproj", "testapi.Model/"]
COPY ["testapi.SocketServer/testapi.SocketServer.csproj", "testapi.SocketServer/"]
RUN dotnet restore "testapi/testapi.csproj"
COPY . .
WORKDIR "/src/testapi"

FROM build AS publish
RUN dotnet publish -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "testapi.dll"]

 

OK,简单的改造完成了,Jenkins执行脚本中省去pubilsh的步骤,直接

docker build -t testapi .

但是!但是!但是!但是!

执行下来结构却并不如意,因为这执行一趟下来,耗时4分30秒,而之前只需10多秒整个流程完成了。

查看日志发现,主要耗时在dotnet restore这一步中,总耗时3分多。而直接在工作节点宿主机中进行编译的话,因为之前还原的nuget包保存在硬盘中,所以不需要再次下载,所以我这次把宿主机中项目的文件全部删除,再次使用在没改造前的方式(在宿主机中编译)构建一次,这次耗时1分30秒多,可以发现,同样是执行dotnet restore,在dockerfile中执行会比宿主机中执行慢很多,要还原的nuget包越多就越慢。

当然,耗时这么多的执行过程,只限于第一次构建或者程序的.csproj有改动的情况,因为dockerfile分阶段构建,会留下缓存,体现在docker images会出现一个名称和tag皆为<none>的镜像,这个镜像就是dotnet编译过程中下产生的依赖包缓存了,所以这就出现第二个问题了,随着程序的改动,其他程序的编译,执行次数的增多,会有越来越多的<none>镜像出现(没错,每一次nuget包的变动都会有一个新的none镜像),虽然有命令可以批量删除,但是删除之后再次构建dockerfile就又会很慢,而且这些<none>镜像不好管理,size又普遍很大,占用磁盘空间。dotnet程序还好说,前端程序的module包都是1G2G的。。。

另外,在本地环境中,构建的镜像一般都不打版本号,每次tag都是latest,这也会导致<none>镜像的出现,所以公司有一个定时任务专门去清理这些<none>镜像。。

 

 

 

综上所述,在dockerfile中编译的缺点:

1、编译速度没有宿主机快

2、下载程序的依赖包比在宿主机中直接下载更加耗时

3、会产生none镜像,占用磁盘空间

 优点:

1、不需要在宿主机中安装各种SDK

2、有缓存(none镜像),且程序依赖没有改变的情况下,比在宿主机直接打包快

 

 

参考资料:

关于<none>空悬镜像

 

标签:testapi,宿主机,优缺点,publish,构建,dotnet,镜像,dockerfile
来源: https://www.cnblogs.com/arthaslcm/p/16374065.html

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

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

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

ICode9版权所有