docker - 在 Docker Alpine 镜像上运行时,带有 DB2 的 ASP.NET Core 在首次请求时退出并显示代码 139

标签 docker asp.net-core dockerfile asp.net-core-3.1 alpine-linux

我正在构建一个 ASP.NET Core 3.1 应用程序,它使用 IBM.Data.DB2.Core-lnx访问遗留应用程序的数据库。当使用普通的 Debian 镜像时它可以工作。但我想使用 Alpine 来代替较小的图像。我遇到了一些关于丢失文件的错误:

Error loading shared library libpam.so.0: No such file or directory (needed by /app/clidriver/lib/liblibdb2.so)

使用content search ,我找到了包含它们的 Alpine 包。但该应用程序显示了一个奇怪的行为:它启动并运行,直到我在浏览器中打开它的网站。我打开它后,容器退出,错误代码为 139,没有消息:

db2_test_1  | info: Microsoft.Hosting.Lifetime[0]
db2_test_1  |       Now listening on: http://0.0.0.0:5000
db2_test_1  | info: Microsoft.Hosting.Lifetime[0]
db2_test_1  |       Application started. Press Ctrl+C to shut down.
db2_test_1  | info: Microsoft.Hosting.Lifetime[0]
db2_test_1  |       Hosting environment: Development
db2_test_1  | info: Microsoft.Hosting.Lifetime[0]
db2_test_1  |       Content root path: /app
db2test_db2_test_1 exited with code 139

我尝试用虚拟 sleep 命令替换入口点,并通过使用 docker exec 在容器中打开 shell 来手动启动应用程序:

/app # dotnet DB2Test.dll
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {53574556-0fee-4926-b1f3-6c57cdfd395a} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://0.0.0.0:5000
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app
Segmentation fault (core dumped)

我不知道为什么会发生这种情况。我的 Dockerfile:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS sdk-image
WORKDIR /app
COPY DB2Test.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Debug -o /publish

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine AS runtime-image
WORKDIR /app
COPY --from=sdk-image /publish .
#RUN apk add libxml2-dev openssl-dev zlib zlib-dev libressl libressl-dev libc6-compat linux-pam
RUN apk add libxml2-dev libc6-compat linux-pam

ARG ASPNETCORE_ENVIRONMENT=Development
ENV ASPNETCORE_URLS=http://0.0.0.0:5000
ENV ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/app/clidriver/lib"

ENTRYPOINT ["dotnet", "DB2Test.dll"]

以及完整 Debian 构建的 Dockerfile:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS sdk-image
WORKDIR /app
COPY DB2Test.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Debug -o /publish

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime-image
WORKDIR /app
COPY --from=sdk-image /publish .
RUN apt-get update \
    && apt-get install -y libxml2-dev

ARG ASPNETCORE_ENVIRONMENT=Development
ENV ASPNETCORE_URLS=http://0.0.0.0:5000
ENV ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT}
# https://gist.github.com/StevenLiekens/dacbd8cdef93d20bf7fcfc2bdafbce43
ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/app/clidriver/lib"

ENTRYPOINT ["dotnet", "DB2Test.dll"]

正如你所看到的,基本上是一样的。我只是安装 Alpine 缺少的 apk 包。

ASP.NET Core 应用程序本身没有什么特别的:带有两个包的 VS Razor Pages 模板

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Dapper" Version="2.0.78" />
    <PackageReference Include="IBM.Data.DB2.Core" Version="3.1.0.400" Condition="'$(OS)' == 'WINDOWS_NT'"/>
    <PackageReference Include="IBM.Data.DB2.Core-lnx" Version="3.1.0.400" Condition="'$(OS)' == 'UNIX'"/>
  </ItemGroup>

</Project>

IndexModel 打开 DB2 连接并从数据库中获取一些数据(它是一个测试数据库,获取了 2 行)

public class IndexModel : PageModel {
    private readonly ILogger<IndexModel> _logger;
    public List<Community> Communities { get; private set; }

    public IndexModel(ILogger<IndexModel> logger) {
        _logger = logger;
    }

    public void OnGet() {
        String MyDb2ConnectionString = "Server=cnx-db2:50000;database=SNCOMM;uid=lcuser;pwd=xx;";
        DB2Connection db = new DB2Connection(MyDb2ConnectionString);
        db.Open();
        Communities = db.Query<Community>(@"SELECT COMMUNITY_UUID as Uid, NAME, LOWER_NAME AS LowerName, DESCRIPTION FROM SNCOMM.COMMUNITY")
            .ToList();
    }
}

我认为崩溃与 IBM 的 DB2 库有关,因为它是在第一个请求期间执行的(此测试应用程序中还没有 DI 或其他内容,正如您在上面看到的,它是在执行 GET 请求时首次初始化的) .

最佳答案

我并不完全熟悉 IBM DB2,但它可能与 Alpine Linux 不兼容,至少在您运行的特定版本中是这样。
由于您能够确认 DB2 本身存在段错误(退出代码 139 表示发生了 SIGSEGV),因此情况很可能是这样。

Alpine Linux 基于musl libc库,而不是 glibc ,GNU C 库。 libc 库提供了 C 标准库实现和 POSIX API,因此它为大多数 Linux 程序提供支持,并且是 Linux 系统的基本组成部分。虽然 musl 旨在保持与 glibc 的兼容性,但实际上存在许多兼容性问题,这将阻止在基于 glibc 的 Linux 发行版(例如 Ubuntu、Debian、RHEL)上编译的程序在基于 musl libc 的发行版(例如 Alpine 和 Void Linux)上运行),在它们是动态链接的情况下。例如:musl libc 上的默认线程堆栈大小为 128KB,而 glibc 上的默认线程堆栈大小为 4MB - 这很可能是复杂软件中出现段错误的原因。还有许多其他细微差别,已涵盖 here .

谷歌搜索,我发现了以下内容Github issuenode-ibm_db项目,IBM 项目成员发表了以下评论(日期正好是 1 年前,2020 年 2 月 20 日):

node-ibm_db works on Linux-x86-64 images of amazonlinux, ubuntu and debian. It can not work on alpine as IBM Db2 Client Installers are not compiled on alpine linux using musl libc. So, none of the IBM Driver for Db2 will work on alpine linux.

这似乎证实了 IBM DB2 目前确实不支持 Alpine Linux。

关于docker - 在 Docker Alpine 镜像上运行时,带有 DB2 的 ASP.NET Core 在首次请求时退出并显示代码 139,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66285841/

相关文章:

django - 通过Nginx代理HTTPS向docker-compose中的gunicorn django提供静态文件

docker - 从官方 docker 镜像启动时,payara 完整应用服务器的管理控制台的默认用户名和密码是什么?

node.js - Docker 容器中的平均应用程序

c# - 无法读取 Startup.cs 中 JSON 文件的设置

amazon-web-services - 当我尝试运行 Docker 文件时抛出错误 "AH00111: Config variable ${APACHE_RUN_DIR} is not defined"

docker - docker 上的沙发数据库 : open console

asp.net-mvc - 有没有办法为每个 Controller 方法添加虚拟方法行为? (即记录)

mono - Kestrel 命令抛出无法加载 libuv。确保 libuv 已安装并可用作 libuv.so.1

docker - 已成功安装magento2,但未找到管理页面抛出错误

linux - 为 Docker 容器创建共享包缓存文件夹