Can docker solve a problem of mismatched C shared

2019-08-14 20:54发布

问题:

I am trying to run some haskell code on an ubuntu (18.04) host, which was compiled on my laptop.

host: 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

laptop: 4.14.74-1-MANJARO #1 SMP PREEMPT Fri Oct 5 14:16:52 UTC 2018 x86_64 GNU/Linux

The error I get is

/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found

After doing some research I learned that this is because my laptop has version 2.28 of glibc installed, but the host only has libc6 2.27.

I did some googling and figured that maybe docker could solve this problem. However, I just created a docker image with the following Dockerfile and it didn't work (same GLIBC_2.28 error)

FROM fpco/stack-build:lts-12.9 as builder

RUN mkdir /opt/build
COPY . /opt/build
RUN cd /opt/build && stack build 

FROM ubuntu:18.04
RUN mkdir -p /opt/myapp
WORKDIR /opt/myapp
RUN apt-get update && apt-get install -y \
  ca-certificates
COPY --from=builder /opt/build/.stack-work/install/x86_64-linux-tinfo6/lts-12.9/8.4.3/bin .
CMD ["/opt/myapp/myapp-exe"]

I'm not sure what to do now. I have a few questions:

  • Why am I getting this problem in the first place? I thought I read somewhere that glibc is backwards compatible? (Is glibc the same thing as libc6..?)

  • Is there a way to use docker to get around this problem? Could i run my build process inside an ubuntu image? e.g. FROM fcpo/stack-build:lts-12.9 and ubutu:18.04, then later on creating another ubuntu image into which i copy my binary?

  • Has anybody else run into this before ? If so did you find a solution (other than just changing operating system?)?

回答1:

Why am I getting this problem in the first place? I thought I read somewhere that glibc is backwards compatible?

GLIBC is backwards compatible (programs built against old GLIBC continue to work on newer GLIBC), but the inverse is not true.

In your case, you built on a newer (GLIBC-2.28) system, and are trying to run on an older one (GLIBC-2.27). That is not guaranteed to work (although it might for sufficiently simple programs).

Is there a way to use docker to get around this problem?

You need to build against the oldest version of GLIBC that you are planning to use.

You can achieve this in multiple ways:

  • use a Linux to older Linux crosscompiler
  • use a chroot build environment
  • use a docker container with older GLIBC at build time.

Or you could run in a docker container that has the GLIBC-2.28 that your program needs.