grpc: C#: Running in Alpine Linux docker container fails with "Grpc.Core.Internal.UnmanagedLibrary Attempting to load native library "/app/libgrpc_csharp_ext.x64.so"
What version of gRPC and what language are you using?
C# and grpc 2.23
What operating system (Linux, Windows,…) and version?
Docker Alpine Linux 3.10 (tag: 3.1.0-alpine3.10)
What runtime / compiler are you using (e.g. python version or version of gcc)
dotnet core 3.1
What did you do?
Here is my dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.0-alpine3.10
RUN apk update && apk add --no-cache libc6-compat && apk add bash
WORKDIR /app
COPY ./ .
ENTRYPOINT ["dotnet", "./myapp.dll"]
Instead of libc6-compat we also tried gcompat and musl but it does not work
What did you expect to see?
My app should not crash and should be able to call my grpc services
What did you see instead?
We the application should contact a grpc service, we get the following error: D1211 15:15:26.577582 Grpc.Core.Internal.UnmanagedLibrary Attempting to load native library “/app/libgrpc_csharp_ext.x64.so”
And this: Error loading native library “/app/libgrpc_csharp_ext.x64.so”. Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /app/libgrpc_csharp_ext.x64.so)
Anything else we should know about your project / environment?
We just migrated from dotnet core 2.2 to 3.1. When we were in dotnet core 2.2 we were using Alpine 3.8 but the Microsoft Docker image for dotnet core does not support Alpine 3.8 anymore so we are kind of stuck.
I should also mention that I saw and tried the suggestions from #15605
I’ll be happy to share more information if need be.
Thanks.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 16
- Comments: 47 (9 by maintainers)
Commits related to this issue
- Adding hack to resolve issue https://github.com/grpc/grpc/issues/21446 — committed to jjdelorme/CloudRun-gRPC by deleted user 3 years ago
- Adding hack to resolve issue grpc/grpc#21446 — committed to delormej/slalom by deleted user 3 years ago
This issue still exists on .NET 5 alpine container.
Image: mcr.microsoft.com/dotnet/aspnet:5.0-alpine
Our best current workaround (in collaboration with @Belovolov)
Then in another stage:
No
libc6-compat
orglibc
necessary.Downgrading lib6-compat to 1.19 fixed this issue for me. Not sure what is impact though.
BUMP!
This issue has been open for more than a year now. The only fix opens up critical security vulnerabilities. Is there a chance to get a proper fix any time soon?
There is a little issue with the workaround
Basically, it makes the container exposed to CVE-2019-14697 with CVSS V3 9.8 CRITICAL, and CVSS V2 7.5 HIGH scores.
Yes, in fact you should be able to use the client libraries with grpc-dotnet even today (at the cost at needing a bit of glue code), by using https://www.nuget.org/packages/Google.Api.Gax.Grpc.GrpcNetClient/
A much better integration of client libraries and grpc-dotnet is planned and should land over the next few months (and on supported platforms, grpc-dotnet will actually be the default option).
I happened to bump into this issue, and since there was no way around it, had to solve it. The solution is a slight overkill, but it worked. What I did was basically build the entire grpc library right on alpine. Its a long process but quite simple:
cmake
as described here https://github.com/grpc/grpc/blob/master/BUILDING.md. usecmake
and-DBUILD_SHARED_LIBS=OFF
(default)libgrpc_csharp_ext.x64.so
note: The pre-requisites should take care of it, but you may also need to install glibc for alpine. docker syntax:
This continues to be an issue in Alpine; any chance of a long term fix for this?
Is there any chance this issue got resolved/fixed?
As workaround, I’m leveraging this https://github.com/grpc/grpc/issues/21446#issuecomment-698396812, and will soon test this other approach: https://github.com/grpc/grpc/issues/21446#issuecomment-807990690. But it would be ideal to get this fixed upstream. Thanks!
Here’s another workaround: try creating a link from /lib64 to /lib before installing libc6-compat, Alpine 3.8/musl 1.1.19 did this while Alpine 3.9/musl 1.1.20 onward have separate /lib and /lib64 with ld-linux-x86-64.so.2 in /lib64 and the rest in /lib.
This needs a real fix as mucking around with system directory structures would probably cause some other weird behaviors further down the line.
Got it! Big thank-you @elibendavid! I dug around our development/deployment setup, and found that since we build/deploy a self-contained app, the updated libgrpc_csharp_ext.so.14.0.0 had to be renamed and overwrite the file that gets automatically pulled down in the Docker publish folder.
Hopefully the issue gets an official fix in a future update as it’s a bit clumsy, but having this solution means Alpine 3.10+ should work fine with Grpc now!
I’ve been using
mcr.microsoft.com/dotnet/aspnet:6.0.1-bullseye-slim
as suggested by @rmclemente but now found an even slimmer alternative: distroless CBL-Mariner.The docker tag is not exposed on the official dockerhub page but is listed under all available tags.
Thanks @jskeet, gotcha. JFYI: I was tagging you since you asked earlier on that thread about a
minimal example
to reproduce the issue, so was just sharing to the maintainers of this repo too in case that could help. Hope we’ll get an answer/ETA from them. Thanks!@obawin This is highly dependant on your installation of .net runtime as well as your app installation. In my case it was - copy it to the exact location reported by the original error.
Looks like your originals are here (sym-links + bin):
Assuming you built on x64, you will want to rename the above file ( go for the main one not sym links ) to
libgrpc_csharp_ext.x64.so
- this is your sourceCopy it to the location reported by the original error