dotnet发布与新的隐式dockerfile特性使用NuGet microt.net . build . contai



我正在试用新的NuGet包Microsoft.NET.Build.Containers允许使用dotnet publish创建docker镜像。.

Microsoft Docs: https://learn.microsoft.com/en-us/dotnet/core/docker/publish-as-container?view=vs-2022

它在本地机器上正常工作,但在GitLab cicd中失败。

项目(在sln文件中添加以下内容):

# create a new project and move to its directory
dotnet new mvc -n my-awesome-container-app
cd my-awesome-container-app
# add a reference to a (temporary) package that creates the container
dotnet add package Microsoft.NET.Build.Containers
# publish your project for linux-x64
dotnet publish --os linux --arch x64 -c Release -p:PublishProfile=DefaultContainer
# run your app using the new container
docker run -it --rm -p 5010:80 my-awesome-container-app:1.0.0

蔡先生管道:

image: mcr.microsoft.com/dotnet/sdk:7.0
stages:          # List of stages for jobs, and their order of execution
- publish
build-job:       # This job runs in the build stage, which runs first.
stage: publish
script:
- dotnet publish --os linux --arch x64 --configuration Release -p:PublishProfile=DefaultContainer

产生的错误(省略repo):

MSBuild version 17.4.1+9a89d02ff for .NET
Determining projects to restore...
Restored /builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj (in 827 ms).
my-awesome-container-app -> /builds/.../dotnetpublishdockerimage/my-awesome-container-app/bin/Release/net7.0/linux-x64/my-awesome-container-app.dll
my-awesome-container-app -> /builds/.../dotnetpublishdockerimage/my-awesome-container-app/bin/Release/net7.0/linux-x64/publish/
Building image 'my-awesome-container-app' with tags 1.0.0 on top of base image mcr.microsoft.com/dotnet/aspnet:7.0
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: The "CreateNewImage" task failed unexpectedly. [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018: System.AggregateException: One or more errors occurred. (An error occurred trying to start process 'docker' with working directory '/builds/.../dotnetpublishdockerimage/my-awesome-container-app'. No such file or directory) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:  ---> System.ComponentModel.Win32Exception (2): An error occurred trying to start process 'docker' with working directory '/builds/.../dotnetpublishdockerimage/my-awesome-container-app'. No such file or directory [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at System.Diagnostics.Process.ForkAndExecProcess(ProcessStartInfo startInfo, String resolvedFilename, String[] argv, String[] envp, String cwd, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderrFd, Boolean usesTerminal, Boolean throwOnNoExec) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at Microsoft.NET.Build.Containers.LocalDocker.Load(Image x, String name, String tag, String baseName) in D:a_work1sMicrosoft.NET.Build.ContainersLocalDocker.cs:line 19 [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    --- End of inner exception stack trace --- [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at System.Threading.Tasks.Task.Wait() [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Execute() in D:a_work1sMicrosoft.NET.Build.ContainersCreateNewImage.cs:line 243 [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]
/root/.nuget/packages/microsoft.net.build.containers/0.2.7/build/Microsoft.NET.Build.Containers.targets(124,9): error MSB4018:    at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [/builds/.../dotnetpublishdockerimage/my-awesome-container-app/my-awesome-container-app.csproj]

寻找一个可能的解决方案,我遇到了它的文章GitHub的行动,它也在那里工作。还有我在这个问题项目中使用的例子。

文章:https://devblogs.microsoft.com/dotnet/announcing-builtin-container-support-for-the-dotnet-sdk/

同时GitLab运行器正在使用Docker执行器。也许它在容器中不起作用。GitHub的文章显示了ubuntu-latest,但我不知道它是否在下面的容器中运行。

有谁知道发生了什么并有解决方案吗?

进一步研究,我发现了问题和解决方案。

这里有两个问题。

  1. 为了构建映像(dotnet发布的一部分)需要docker-in-docker (dind)。
  2. .net sdk映像不提供dind支持

要解决第一个问题,需要进行一些更改。

首先将did作为服务添加到cicd:

services:
- docker:dind

下一步分配docker主机变量:

variables:
DOCKER_HOST: tcp://docker:2375/

最后在docker运行器(config.toml)上启用特权模式:

[[runners]]
...
[runners.docker]
...
privileged = true
...

可能需要重新启动docker运行器。

tls也可能存在问题。可以通过向cicd:

添加空的certs dir来忽略它(尽管不建议在特权模式下)。
variables:
DOCKER_TLS_CERTDIR: ""

解决第二个问题的另一种方法是使用镜像'docker',它提供了dind支持。从这里有2个选项:

  1. 安装。net sdk:
before_script:
- apk add dotnet7-sdk
官方文档:https://learn.microsoft.com/en-us/dotnet/core/install/linux-alpine
  1. 在安装了sdk的docker基础上创建一个新的docker镜像,然后在管道中使用这个镜像

可能有其他更优雅的方法来解决这个问题,但它将作为一个变通的方法。

一个示例cicd管道,包括发布到注册表:

stages: 
- publish
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_TLS_CERTDIR: ""
services:
- docker:dind
docker_test:
stage: publish
image: docker
before_script:
- apk add dotnet7-sdk
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- dotnet publish --os linux --arch x64 --configuration Release -p:PublishProfile=DefaultContainer
- IMAGE_ID=$(docker images --format='{{.ID}}' | head -1)
- docker tag $IMAGE_ID $CI_REGISTRY_IMAGE/my-image:1.0.0
- docker push $CI_REGISTRY_IMAGE/my-image:1.0.0

最新更新