Graylog2 / graylog-docker

Official Graylog Docker image
https://hub.docker.com/r/graylog/graylog/
Apache License 2.0
361 stars 133 forks source link

Create Graylog image using Java 11 #172

Closed malcyon closed 3 years ago

malcyon commented 3 years ago

Description

This creates new graylog and graylog-enterprise docker images using Java 11. This is a multiarch image that supports linux/amd64 and linux/arm64.

It is tagged the same way as the other images, with a -jre11 appended at the end. This is also using the Jenkins pipeline to build the image and not Docker Hub.

Java Option Changes

In the current published image, these Java options are set:

echo "export GRAYLOG_SERVER_JAVA_OPTS='-Djdk.tls.acknowledgeCloseNotify=true -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:NewRatio=1 -XX:MaxMetaspaceSize=256m -server -XX:+ResizeTLAB -XX:+UseConcMarkSweepGC -XX:+CMSConcurrentMTEnabled -XX:+CMSClassUnloadingEnabled -XX:+UseParNewGC -XX:-OmitStackTraceInFastThrow'" >> /etc/profile.d/graylog.sh

The UseCGroupMemoryLimitForHeap Java flag is deprecated in Java 11. Graylog won't even start when it is set. So, I removed it. The UseContainerSupport flag is defaulted to true even in Java 8, so we should be okay as far as memory usage in containers.

If these flags are set in Java 15, Graylog won't start. But they do still work in Java 11:

This flag doesn't exist at all in Java 11:

Fixes #152

Notes for Reviewers

malcyon commented 3 years ago

I found that the Garbage Collection JAVA_OPTS were hardcoded into the image, and they need to be different between different Java versions. I understand that we don't want to go changing those settings out from under people without a good reason. But I also want people to be able to configure their own GC if they want.

It's kinda hard to do both of these at once. The method I thought of was to use a feature flag, So if you set GRAYLOG_DOCKER_DISABLE_CMS_GC, it will not set the java flags for the Concurrent Mark Sweep garbage collector. Then, the user can specify whatever they want via GRAYLOG_SERVER_JAVA_OPTS. If they don't set that flag, it'll work the same as it always has. Except for UseParNewGC, which apparently doesn't exist in Java 11, so that will be silently dropped if it's not available.

Let me know if that is an acceptable compromise, or if there's anything I haven't thought of. It's definitely nice to have one Dockerfile for both versions of the image, but I don't want to cause chaos or anything, either.

malcyon commented 3 years ago

Also note that JAVA_VERSION_MAJOR has to be at the very top of the Dockerfile, or it can't be used in the FROM statement at all. And it also has to be duplicated later on in the Dockerfile, or it can't be used in the second stage.

malcyon commented 3 years ago

Building the Java 8 image locally:

docker build --build-arg GRAYLOG_VERSION=4.1.3 --tag graylog:4.1.3 --file docker/oss/Dockerfile .

Building the Java 11 image locally:

docker build --build-arg GRAYLOG_VERSION=4.1.3 --build-arg JAVA_VERSION_MAJOR=11 --tag graylog:4.1.3 --file docker/oss/Dockerfile .