不满足的链接错误:/tmp/snappy-1.1.4-libsnappyjava.so 加载共享库 ld-linux-x86-64.so.2 时出错:没有那个文件或目录。

37

我正在尝试在Kubernetes中运行一个Kafka Streams应用程序。当我启动Pod时,会出现以下异常:

Exception in thread "streams-pipe-e19c2d9a-d403-4944-8d26-0ef27ed5c057-StreamThread-1"
java.lang.UnsatisfiedLinkError: /tmp/snappy-1.1.4-5cec5405-2ce7-4046-a8bd-922ce96534a0-libsnappyjava.so: 
Error loading shared library ld-linux-x86-64.so.2: No such file or directory 
(needed by /tmp/snappy-1.1.4-5cec5405-2ce7-4046-a8bd-922ce96534a0-libsnappyjava.so)
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
        at java.lang.Runtime.load0(Runtime.java:809)
        at java.lang.System.load(System.java:1086)
        at org.xerial.snappy.SnappyLoader.loadNativeLibrary(SnappyLoader.java:179)
        at org.xerial.snappy.SnappyLoader.loadSnappyApi(SnappyLoader.java:154)
        at org.xerial.snappy.Snappy.<clinit>(Snappy.java:47)
        at org.xerial.snappy.SnappyInputStream.hasNextChunk(SnappyInputStream.java:435)
        at org.xerial.snappy.SnappyInputStream.read(SnappyInputStream.java:466)
        at java.io.DataInputStream.readByte(DataInputStream.java:265)
        at org.apache.kafka.common.utils.ByteUtils.readVarint(ByteUtils.java:168)
        at org.apache.kafka.common.record.DefaultRecord.readFrom(DefaultRecord.java:292)
        at org.apache.kafka.common.record.DefaultRecordBatch$1.readNext(DefaultRecordBatch.java:264)
        at org.apache.kafka.common.record.DefaultRecordBatch$RecordIterator.next(DefaultRecordBatch.java:563)
        at org.apache.kafka.common.record.DefaultRecordBatch$RecordIterator.next(DefaultRecordBatch.java:532)
        at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.nextFetchedRecord(Fetcher.java:1060)
        at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.fetchRecords(Fetcher.java:1095)
        at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.access$1200(Fetcher.java:949)
        at org.apache.kafka.clients.consumer.internals.Fetcher.fetchRecords(Fetcher.java:570)
        at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:531)
        at org.apache.kafka.clients.consumer.KafkaConsumer.pollOnce(KafkaConsumer.java:1146)
        at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1103)
        at org.apache.kafka.streams.processor.internals.StreamThread.pollRequests(StreamThread.java:851)
        at org.apache.kafka.streams.processor.internals.StreamThread.runOnce(StreamThread.java:808)
        at org.apache.kafka.streams.processor.internals.StreamThread.runLoop(StreamThread.java:774)
        at org.apache.kafka.streams.processor.internals.StreamThread.run(StreamThread.java:744)

之前,我曾尝试使用Docker容器来启动Kafka和kafka-streams-app,并且它们能够完美地运行。这是我第一次尝试使用Kubernetes。

这是我的DockerFile StreamsApp

FROM openjdk:8u151-jdk-alpine3.7

COPY /target/streams-examples-0.1.jar /streamsApp/

COPY /target/libs /streamsApp/libs

CMD ["java", "-jar", "/streamsApp/streams-examples-0.1.jar"]
我该怎么才能解决这个问题呢?请帮帮我。 编辑:
/ # ldd /usr/bin/java 
    /lib/ld-musl-x86_64.so.1 (0x7f03f279a000)
Error loading shared library libjli.so: No such file or directory (needed by /usr/bin/java)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f03f279a000)
Error relocating /usr/bin/java: JLI_Launch: symbol not found

我认为这是关于CPU架构问题。你是否检查了Java和Linux,确保操作系统和Java都是相同的架构,例如32位或64位? - tommybee
请提供此 Docker 内部执行 ldd /usr/bin/java 命令的输出,以便进行进一步的诊断。 - d0bry
@d0bry 我已编辑了问题。 - el323
8个回答

41

在我的情况下,安装丢失的libc6-compat没有起作用。应用程序仍然会抛出java.lang.UnsatisfiedLinkError

然后我在docker中发现/lib64/ld-linux-x86-64.so.2存在,并且是指向/lib/libc.musl-x86_64.so.1的链接,但是/lib只包含ld-musl-x86_64.so.1而不是ld-linux-x86-64.so.2

所以我在/lib目录中添加了一个名为ld-linux-x86-64.so.2的文件,链接到ld-musl-x86_64.so.1,问题得到解决。

我使用的Dockerfile:

FROM openjdk:8-jre-alpine
COPY entrypoint.sh /entrypoint.sh
RUN apk update && \
  apk add --no-cache libc6-compat && \
  ln -s /lib/libc.musl-x86_64.so.1 /lib/ld-linux-x86-64.so.2 && \
  mkdir /app && \
  chmod a+x /entrypoint.sh
COPY build/libs/*.jar /app
ENTRYPOINT ["/entrypoint.sh"]

总之:

RUN apk update && apk add --no-cache libc6-compat
ln -s /lib/libc.musl-x86_64.so.1 /lib/ld-linux-x86-64.so.2

37
安装 gcompat 即可替代安装 libc6-compat,后者提供 /lib/ld-linux-x86-64.so.2。链接 https://pkgs.alpinelinux.org/contents?file=ld-linux-x86-64.so.2&path=&name=&branch=edge。 - HenningCash
救了我的命,谢谢。因为库已经存在了,我只是添加了符号链接。 - Willa

34

错误消息显示*libsnappyjava.so无法找到ld-linux-x86-64.so.2。这是glibc动态加载程序,而Alpine镜像不使用glibc。您可以在Dockerfile中安装libc6-compat软件包来尝试运行它,例如:

RUN apk update && apk add --no-cache libc6-compat

5
这并没有解决问题,我仍然遇到了UnsatisfiedLinkError错误。@HenningCash提出的解决方案解决了这个问题。 - Pat

26

这个问题有两种解决方案:

  1. 您可以使用其他预装了snappy-java库的基础镜像,例如openjdk:8-jre-slim对我来说效果很好。

  2. 另一种解决方案是仍然使用openjdk:8-jdk-alpine镜像作为基础镜像,但手动安装snappy-java库:

FROM openjdk:8-jdk-alpine
RUN apk update && apk add --no-cache gcompat
...

你建议使用Slim对我确实起了作用。非常感谢! - Vitaly Sazanovich
1
如果您的基础镜像是 openjdk:8-alpine,第二种解决方案也适用。 - Bruno Gasparotto

3

在使用Alpine内核的Docker中

运行apk update && apk add --no-cache libc6-compat gcompat是我的救命稻草


1
如果您通过build.sbt添加Docker文件,则正确的方法是:
dockerfile in docker := {
  val artifact: File = assembly.value
  val artifactTargetPath = s"/app/${artifact.name}"

  new Dockerfile {
    from("openjdk:8-jre-alpine")
    copy(artifact, artifactTargetPath)
    run("apk", "add", "--no-cache", "gcompat")
    entryPoint("java", "-jar", artifactTargetPath)
  }

安装gcompat将实现您的目的。

0
我不需要在dockerFile中添加libc6-compat
因为/lib/libc.musl-x86_64.so.1文件已经存在于我的容器中。
在dockerFile中只需添加:
run ln -s /lib/libc.musl-x86_64.so.1 /lib/ld-linux-x86-64.so.2

我的容器在消费经过Snappy压缩的消息时没有出现错误。
Exception in thread "streams-pipe-e19c2d9a-d403-4944-8d26-0ef27ed5c057-StreamThread-1"
java.lang.UnsatisfiedLinkError: /tmp/snappy-1.1.4-5cec5405-2ce7-4046-a8bd- 
922ce96534a0-libsnappyjava.so: 
Error loading shared library ld-linux-x86-64.so.2: No such file or directory 
(needed by /tmp/snappy-1.1.4-5cec5405-2ce7-4046-a8bd-922ce96534a0-libsnappyjava.so)
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)

0

看起来很奇怪,但似乎你使用的docker镜像 - openjdk:8u151-jdk-alpine3.7 不一致, 一些动态加载的对象未包含在软件包中,或者您需要在此镜像中运行“ldconfig -v”以更新共享对象的映射, 或者最后,有一个/etc/ld.so.conf文件,其中包含操作系统正在查找.so对象的路径。如果您不想浪费时间进行调试,请考虑使用提供Java二进制文件的另一个docker镜像。 最后但同样重要的是,在alpine论坛上寻求解决方案。


谢谢回答。还有一个问题,Kafka的docker镜像有可能出了问题吗? - el323
1
很难说。需要进一步调查才能找到问题所在。我认为你可以尝试使用另一个开发者的Docker镜像来使Kafka正常工作。 - d0bry

0

我已经实现了一个Docker镜像,其中运行了一个Spring Boot微服务和一个完美工作的Kafka Strean拓扑。

在这里,我分享Dockerfile文件。

FROM openjdk:8-jdk-alpine
# Add Maintainer Info
LABEL description="Spring Boot Kafka Stream IoT Processor"
# Args for image
ARG PORT=8080

RUN apk update && apk upgrade && apk add --no-cache gcompat
RUN ln -s /bin/bash /usr/bin
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app


COPY resources/wait-for-it.sh  wait-for-it.sh
COPY target/iot_processor.jar app.jar

RUN dos2unix wait-for-it.sh
RUN chmod +x wait-for-it.sh
RUN uname -a
RUN pwd
RUN ls -al

EXPOSE ${PORT}

CMD ["sh", "-c", "echo 'waiting for 300 seconds for kafka:9092 to be accessable before 
starting application' && ./wait-for-it.sh -t 300 kafka:9092 -- java -jar app.jar"]

希望它能帮助到某人


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接