quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.4k stars 2.57k forks source link

Kafka Streams and Alpine linux incompatibility #6114

Open nomadgis opened 4 years ago

nomadgis commented 4 years ago

Describe the bug

There is a known issue about an incompatibility of Kafka Streams and Alpine linux, which is really seems to be a RocksDB issue. https://issues.apache.org/jira/browse/KAFKA-4988 Anyway, I don't think the Kafka Streams extension is working OOTB in Quarkus using Dockerfile.jvm with fabric8/java-alpine-openjdk8-jre as base image.

Expected behavior Normal startup and running Kafka Streams app with state store engaged.

Actual behavior The application fails to start

To Reproduce Steps to reproduce the behavior:

  1. Add kafka streams extension to quarkus project (possibly need to engage state store in app)
  2. Build docker using Dockerfile.jvm
  3. Run image in docker

Configuration

# Add your application.properties here, if applicable.

Screenshots (If applicable, add screenshots to help explain your problem.)

Environment (please complete the following information):

Additional context exec java -Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager -javaagent:/opt/agent-bond/agent-bond.jar=jmx_exporter{{9779:/opt/agent-bond/jmx_exporter_config.yml}} -XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:+ExitOnOutOfMemoryError -cp . -jar /deployments/app.jar java.lang.UnsatisfiedLinkError: /tmp/librocksdbjni4331951083922257164.so: Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /tmp/librocksdbjni4331951083922257164.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.rocksdb.NativeLibraryLoader.loadLibraryFromJar(NativeLibraryLoader.java:78) at org.rocksdb.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:56) at org.rocksdb.RocksDB.loadLibrary(RocksDB.java:64) at org.rocksdb.RocksDB.(RocksDB.java:35) at io.quarkus.kafka.streams.runtime.KafkaStreamsRecorder.loadRocksDb(KafkaStreamsRecorder.java:15) at io.quarkus.deployment.steps.KafkaStreamsProcessor$configureAndLoadRocksDb41.deploy_0(KafkaStreamsProcessor$configureAndLoadRocksDb41.zig:65) at io.quarkus.deployment.steps.KafkaStreamsProcessor$configureAndLoadRocksDb41.deploy(KafkaStreamsProcessor$configureAndLoadRocksDb41.zig:36) at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:73) at io.quarkus.runtime.Application.start(Application.java:94) at io.quarkus.runtime.Application.run(Application.java:218) at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:41) Exception in thread "main" java.lang.RuntimeException: Failed to start quarkus at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:193) at io.quarkus.runtime.Application.start(Application.java:94) at io.quarkus.runtime.Application.run(Application.java:218) at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:41) Caused by: java.lang.UnsatisfiedLinkError: /tmp/librocksdbjni4331951083922257164.so: Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /tmp/librocksdbjni4331951083922257164.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.rocksdb.NativeLibraryLoader.loadLibraryFromJar(NativeLibraryLoader.java:78) at org.rocksdb.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:56) at org.rocksdb.RocksDB.loadLibrary(RocksDB.java:64) at org.rocksdb.RocksDB.(RocksDB.java:35) at io.quarkus.kafka.streams.runtime.KafkaStreamsRecorder.loadRocksDb(KafkaStreamsRecorder.java:15) at io.quarkus.deployment.steps.KafkaStreamsProcessor$configureAndLoadRocksDb41.deploy_0(KafkaStreamsProcessor$configureAndLoadRocksDb41.zig:65) at io.quarkus.deployment.steps.KafkaStreamsProcessor$configureAndLoadRocksDb41.deploy(KafkaStreamsProcessor$configureAndLoadRocksDb41.zig:36) at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:73) ... 3 more

gsmet commented 4 years ago

/cc @gunnarmorling

Not sure we will want to change our default image for that.

nomadgis commented 4 years ago

I would suspect not -- perhaps offering an alternative base image would provide a working solution for Kafka Streams apps.

gunnarmorling commented 4 years ago

In the quickstart example we use fabric8/java-centos-openjdk8-jdk. Is there an UBI Java image by now? If so, that'd be a nice alternative.

If you don't want to switch the default image, it'd need mentioning in the Kafka Streams reference guide.

That said I was surprised by the choice of Alpine as a base image. It's using musl as libc implementation and in the past there were discussions around this not being a 100% satisfying glibc alternative for OpenJDK (there's Portola, an ongoing project to port OpenJDK to Alpine), so people tended to recommend against this. Are these concerns addressed by now?

gunnarmorling commented 4 years ago

So, on UBI Java, that's what Drools currently is doing:

FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
RUN microdnf install java-1.8.0-openjdk-headless && microdnf clean all

I like that. I can send a PR for updating the existing example and also add a mention to the guide.

gsmet commented 4 years ago

/cc @cescoffier who is the master of the images.

My opinion is that I would prefer to use UBI everywhere rather than Alpine.

cescoffier commented 4 years ago

Yes, UBI is better for our purpose. In addition, Alpine is musl based, and we need glibc in native mode.

gunnarmorling commented 4 years ago

The native image already uses ubi-minimal. But as mentioned above, I'm doubtful about musl-based Alpine for OpenJDK, too.