简体   繁体   中英

ASP.NET Core with DB2 exited with code 139 on first request when running on Docker Alpine image

I'm building an ASP.NET Core 3.1 application which uses IBM.Data.DB2.Core-lnx to access the DB of a legacy application. It works when using the normal Debian images. But I'd like to use Alpine instead for smaller images. I had some errors about missing files:

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

Using the content search , I found the Alpine package which contains them. But the application shows a strange behavior: It starts and it is running until I open the website of it in the browser. After I opened it, the container exited with error code 139 and no messages:

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

I tried to replace my entrypoint with a dummy sleep command and started the app manually by opening a shell into the container with docker exec :

/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)

I have no idea why this happens. My 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"]

And the Dockerfile for the full Debian build:

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"]

As you can see, it's basically the same. I just install the missing apk packages for Alpine.

The ASP.NET Core application itself is nothing special: The VS Razor Pages template with two packages

  <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>

The IndexModel opens a DB2 connection and fetches some data from the database (its a test db, 2 rows were fetched)

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();
    }
}

I think the crash is related to IBMs DB2 lib, cause it is executed during the first request (there is no DI or something else in this test app yet, as you see above it's first initialized when the GET requeste is executed).

I'm not entirely familiar with IBM DB2, but it's likely that it is not compatible with Alpine Linux, at least in the particular version you're running.
Since you're able to confirm that DB2 itself segfaults (exit code 139 indicates SIGSEGV occured), it is very likely to be the case.

Alpine Linux is based on the musl libc library, as opposed to glibc , the GNU C library. A libc library provides the C standard library implementation and the POSIX API and as such it powers most Linux programs, and is a fundamental part of the Linux system. While musl aims to maintain compatibility with glibc, in practice there are many compatibility issues, which will prevent programs compiled on a glibc based Linux distro (such as Ubuntu, Debian, RHEL) running on musl libc based distros (such as Alpine and Void Linux), in the case they are dynamically linked. For example: the default thread stack size is 128KB on musl libc, vs. 4MB on glibc - this is a very likely cause for segfaults in complex software. There are many other subtle differences, covered here .

Googling this, I came across the following Github issue in the node-ibm_db project, with the following comment was made by an IBM project member (dated exactly 1 year ago, 20/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.

This seems to confirm that indeed, IBM DB2 does not support Alpine Linux currently.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM