如何使用 Docker 和 Kaniko 减少 .NET Core 应用程序的构建时间?
How can I reduce the build time for a .NET Core application using Docker and Kaniko?
我的 .NET Core 2.2 控制台应用程序中有以下 Dockerfile。
FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["TaikunBillerPoller.csproj", ""]
RUN dotnet restore "TaikunBillerPoller.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "TaikunBillerPoller.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "TaikunBillerPoller.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TaikunBillerPoller.dll"]
我的 .dockerignore 文件看起来像
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.vs
**/.vscode
**/*.*proj.user
**/azds.yaml
**/charts
**/bin
**/obj
**/Dockerfile
**/Dockerfile.develop
**/docker-compose.yml
**/docker-compose.*.yml
**/*.dbmdl
**/*.jfm
**/secrets.dev.yaml
**/values.dev.yaml
**/.toolstarget
我们正在使用 GitLab 和 Kaniko 构建 gitlab-ci.yml 文件。
构建此控制台应用程序需要 7 分钟,但另一个使用 Go 语言编写的应用程序需要 40 秒。
如何减少此应用程序的构建时间?
您的第一行 FROM 完全未使用。而是将 FROM base
行更改为 FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim
这个问题可能是因为 Kaniko **/someDir .dockerignore 模式没有被正确观察到。我注意到 /obj、/bin、.idea (rider) 和 .git 文件夹都被复制了。
https://github.com/GoogleContainerTools/kaniko/issues/1396
您也没有使用基于 alpine 的 sdk 和运行时映像。
在 dotnet restore command
中,您可以使用 --no-cache
标志,因为 docker 层缓存会处理它。
dotnet publish
进行构建,因此您可以跳过调用 dotnet build
。如果你想执行测试,你可以调用 dotnet test
然后
您明确调用了 dotnet restore
,因此在所有后续 dotnet
命令中您可以使用 --no-restore
选项。
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS base
#Add whatever tools you need to the base image
RUN apk add --update --no-cache git bash curl zip; \
export PATH="$PATH:/root/.dotnet/tools"; \
dotnet tool install --global dotnet-xunit-to-junit --version 1.0.2
FROM base AS restore
WORKDIR /src
COPY ["TaikunBillerPoller.csproj", ""]
RUN dotnet restore --no-cache "TaikunBillerPoller.csproj"
COPY . .
FROM restore as publish
ARG VERSION="0.0.0"
RUN dotnet test "TaikunBillerPoller.csproj" --configuration Release --no-restore
RUN dotnet publish "TaikunBillerPoller.csproj" --output /app --configuration Release --no-restore /p:Version=$VERSION
FROM mcr.microsoft.com/dotnet/core/runtime:2.2-alpine AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TaikunBillerPoller.dll"]
在 2015 年 Mac 我有一个 asp.net 微服务,它使用正常的 docker build
构建、测试、发布和创建 beanstalk_bundle zip,时间如下:
- 51s 无缓存
- 22s 代码更改
- <1s 无代码更改(管道 yml 更改)
Kaniko 增加了开销,因为层缓存是远程完成到某个存储库(通常)。
这一次将在很大程度上取决于您如何配置 Kaniko 缓存和安装的卷。这是我在本地机器上用于调试的东西。
#!/bin/bash
# Assuming this is either not an ephemeral machine, or the ephemeral machine
# maps the cache directory to permanent volume.
# We cache images into the local machine
# so that the Kaniko container, which is ephemeral, does not have to pull them each time.
docker run -v $(pwd):/workspace gcr.io/kaniko-project/warmer:latest \
--cache-dir=/workspace/cache \
--image=mcr.microsoft.com/dotnet/core/sdk:2.2-alpine \
--image=mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine
docker run -it --rm \
-v `pwd`:/workspace \
-v `pwd`/kaniko-config.json:/kaniko/.docker/config.json:ro \
-v `pwd`/reports:/reports \
-v `pwd`/beanstalk_bundle:/beanstalk_bundle \
gcr.io/kaniko-project/executor:latest \
--dockerfile "buildTestPublish.Dockerfile" \
--destination "registry.gitlab.com/somePath/theImageName:theVersion" \
--skip-unused-stages \
--cache \
--cache-dir=/workspace/cache \
--verbosity=trace
我的 .NET Core 2.2 控制台应用程序中有以下 Dockerfile。
FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-stretch AS build
WORKDIR /src
COPY ["TaikunBillerPoller.csproj", ""]
RUN dotnet restore "TaikunBillerPoller.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "TaikunBillerPoller.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "TaikunBillerPoller.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TaikunBillerPoller.dll"]
我的 .dockerignore 文件看起来像
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.vs
**/.vscode
**/*.*proj.user
**/azds.yaml
**/charts
**/bin
**/obj
**/Dockerfile
**/Dockerfile.develop
**/docker-compose.yml
**/docker-compose.*.yml
**/*.dbmdl
**/*.jfm
**/secrets.dev.yaml
**/values.dev.yaml
**/.toolstarget
我们正在使用 GitLab 和 Kaniko 构建 gitlab-ci.yml 文件。
构建此控制台应用程序需要 7 分钟,但另一个使用 Go 语言编写的应用程序需要 40 秒。
如何减少此应用程序的构建时间?
您的第一行 FROM 完全未使用。而是将 FROM base
行更改为 FROM mcr.microsoft.com/dotnet/core/runtime:2.2-stretch-slim
这个问题可能是因为 Kaniko **/someDir .dockerignore 模式没有被正确观察到。我注意到 /obj、/bin、.idea (rider) 和 .git 文件夹都被复制了。
https://github.com/GoogleContainerTools/kaniko/issues/1396
您也没有使用基于 alpine 的 sdk 和运行时映像。
在 dotnet restore command
中,您可以使用 --no-cache
标志,因为 docker 层缓存会处理它。
dotnet publish
进行构建,因此您可以跳过调用 dotnet build
。如果你想执行测试,你可以调用 dotnet test
然后
您明确调用了 dotnet restore
,因此在所有后续 dotnet
命令中您可以使用 --no-restore
选项。
FROM mcr.microsoft.com/dotnet/core/sdk:2.2-alpine AS base
#Add whatever tools you need to the base image
RUN apk add --update --no-cache git bash curl zip; \
export PATH="$PATH:/root/.dotnet/tools"; \
dotnet tool install --global dotnet-xunit-to-junit --version 1.0.2
FROM base AS restore
WORKDIR /src
COPY ["TaikunBillerPoller.csproj", ""]
RUN dotnet restore --no-cache "TaikunBillerPoller.csproj"
COPY . .
FROM restore as publish
ARG VERSION="0.0.0"
RUN dotnet test "TaikunBillerPoller.csproj" --configuration Release --no-restore
RUN dotnet publish "TaikunBillerPoller.csproj" --output /app --configuration Release --no-restore /p:Version=$VERSION
FROM mcr.microsoft.com/dotnet/core/runtime:2.2-alpine AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "TaikunBillerPoller.dll"]
在 2015 年 Mac 我有一个 asp.net 微服务,它使用正常的 docker build
构建、测试、发布和创建 beanstalk_bundle zip,时间如下:
- 51s 无缓存
- 22s 代码更改
- <1s 无代码更改(管道 yml 更改)
Kaniko 增加了开销,因为层缓存是远程完成到某个存储库(通常)。 这一次将在很大程度上取决于您如何配置 Kaniko 缓存和安装的卷。这是我在本地机器上用于调试的东西。
#!/bin/bash
# Assuming this is either not an ephemeral machine, or the ephemeral machine
# maps the cache directory to permanent volume.
# We cache images into the local machine
# so that the Kaniko container, which is ephemeral, does not have to pull them each time.
docker run -v $(pwd):/workspace gcr.io/kaniko-project/warmer:latest \
--cache-dir=/workspace/cache \
--image=mcr.microsoft.com/dotnet/core/sdk:2.2-alpine \
--image=mcr.microsoft.com/dotnet/core/aspnet:2.2-alpine
docker run -it --rm \
-v `pwd`:/workspace \
-v `pwd`/kaniko-config.json:/kaniko/.docker/config.json:ro \
-v `pwd`/reports:/reports \
-v `pwd`/beanstalk_bundle:/beanstalk_bundle \
gcr.io/kaniko-project/executor:latest \
--dockerfile "buildTestPublish.Dockerfile" \
--destination "registry.gitlab.com/somePath/theImageName:theVersion" \
--skip-unused-stages \
--cache \
--cache-dir=/workspace/cache \
--verbosity=trace