关于在GitLab的CI/CD中用docker buildx本地化多架构打包dotnet应用的问题

关于在GitLab的CI/CD中用docker buildx本地化多架构打包dotnet应用的问题

这是一个DevOps综合性问题

网络上的方案都是细分的领域,未见一个集成了GitLab+docker+dotnet的多架构DevOps方案。由此,才产生了这篇文章,来说一说,我在自动化持续交付的过程中遇到的问题,以及解决方案。

docker buildx多架构打包.NET应用的问题

关于多架构构建,可以参考使用Docker buildx 为 .NET 构建多平台镜像这篇博文。

用QEMU模拟多架构环境打包

我与他不同的是,我的客户环境是信创,服务器无法连接公网,需要本地化打包成.tar包,而不是pushDocker Hub上。

但由于客户服务器是arm64架构的CPU,我本地没有相同架构的机器,于是我尝试在公司的amd64架构服务器上用QEMU模拟arm64的docker环境来编译。

shell命令如下:

bash 复制代码
docker buildx build --platform linux/arm64 -t demo:v1.0.0-linux-arm64 -o type=docker,dest=demo-linux-arm64.tar -f src/Demo/Dockerfile .

Dockerfile如下:

bash 复制代码
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src

COPY ["Demo/Demo.csproj", "Demo/Demo.csproj"]

RUN dotnet restore "Demo.csproj" -r linux-arm64
COPY . .

WORKDIR "/src/Demo"
RUN dotnet build "Demo.csproj" -r linux-arm64 --no-restore -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "Demo.csproj" -r linux-arm64 --no-restore -c Release -o /app/publish

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

RUN dotnet restore "Demo.csproj" -r linux-arm64还原时报错:

bash 复制代码
MSBUILD : error : This is an unhandled exception in MSBuild -- PLEASE UPVOTE AN EXISTING ISSUE OR FILE A NEW ONE AT https://aka.ms/msbuild/unhandled
MSBUILD : error :     System.NullReferenceException: Object reference not set to an instance of an object.

这个报错很明显是MSBUILD的错误,由于我程序在调试编译时是没问题的,所以想到应该是架构不同引发的问题。在网上查找一番,发现-a这个参数可以指定架构,于是改成了RUN dotnet restore "Demo.csproj" -a arm64

这次编译成功了,有点得意,拿去客户服务器部署,却还是报错Exec format error

此时查看docker镜像确实是arm64架构的。

说明,虽然编译成功,镜像也是arm64架构了,但MSBUILD生成的dll文件的格式还是amd64架构的。

这就犯难了,明明用了QEMU模拟arm64的docker环境,镜像也成功打包成了arm64架构的,那是dotnet与QEMU环境无法兼容?

于是,就查到了[Unhandled Exception]: System.NullReferenceException: Object reference not set to an instance of an object.

注意到这句话:This is dotnet/runtime#78340 which is likely rooted to https://gitlab.com/qemu-project/qemu/-/issues/249.

dotnet/runtime#78340页面中找到了相关内容:

至此,通过模拟arm64架构环境来打包的方式以失败告终。

相关推荐
努力买辣条39 分钟前
基于 Docker 的高可用 WordPress 集群部署:分布式 Nginx + Keepalived、MySQL 主从复制与 ProxySQL 读写分离
分布式·nginx·docker
CTRA王大大4 小时前
【golang】制作linux环境+golang的Dockerfile | 如何下载golang镜像源
linux·开发语言·docker·golang
@寄居蟹9 小时前
Docker 命令大全
docker·容器·eureka
运维开发王义杰9 小时前
GitLab CI:Auto DevOps 全解析,告别繁琐配置,拥抱自动化未来
ci/cd·gitlab·devops
运维开发王义杰10 小时前
GitLab CI:深度解析 Runner的Shell与Docker执行器
ci/cd·docker·gitlab
qq_3643717210 小时前
Docker 常见命令
运维·docker·容器
小白不想白a16 小时前
【K8s】整体认识K8s之Docker篇
docker·容器·kubernetes
Agome9917 小时前
Docker之nginx安装
java·nginx·docker
努力买辣条1 天前
基于Docker的高可用WordPress集群部署:Nginx负载均衡+Mysql主从复制+ProxySQL读写分离
nginx·docker·负载均衡
记忆不曾留1 天前
unbuntu 20.04 docker 部署wordpress
运维·docker·容器·wordpress·独立站建站