2

For context, I'm building a java application compiled to GraalVM native image running on a distroless docker image in Kubernetes.

I've been trying to do something rather simple and hit a wall: I'd like to set custom heap size limits per environment via -XmxNNN. To do that, the options with which I'd like to run the application would be held in an environment variable. The problem arises due to the usage of a distroless image - which doesn't have bash and so ENTRYPOINT /application $OPTIONS doesn't work.

Is there an environment variable GraalVM supports on its own, or any other way of setting this?

I dont want to:

Inqy
  • 125
  • 1
  • 8

2 Answers2

1

I'm not sure if it will work, but you could try setting the environment variable JAVA_TOOL_OPTIONS to the desired value:

JAVA_TOOL_OPTIONS=-XmxNNN

From the documentation:

This environment variable allows you to specify the initialization of tools, specifically the launching of native or Java programming language agents using the -agentlib or -javaagent options. In the following example the environment variable is set so that the HPROF profiler is launched when > the application is started:

$ export JAVA_TOOL_OPTIONS="-agentlib:hprof"

This variable can also be used to augment the command line with other options for diagnostic purposes. For example, you can supply the -XX:OnError option to specify a script or command to be executed when a fatal error occurs.

The GraalVM documentation itself provides an example of use as well, although in a different context.

jccampanero
  • 50,989
  • 3
  • 20
  • 49
  • From my testing - I'm afraid this doesn't work. The example provided in GraalVM documentation is for launching classic Java applications with native-image-agent, where this environment variable is respected by java. It doesn't seem to be respected during native-image execution. I was looking for an equivalent that would. – Inqy Nov 29 '21 at 11:57
  • I am very sorry to hear that it doesn't work with Graalvm @Inqy. Another think you could try will be to [tune in some way](https://www.graalvm.org/reference-manual/native-image/MemoryManagement/) the _percentage_ of physical memory used. Every garbage collector provides you the necessary environment variables for that purpose: you could then rely on your physical resources and the Kubernetes resource limits to indirectly control the amount of memory used by the VM. The only drawback is that you will need to hardcode some values, although relative ones, in the `Dockerfile`. – jccampanero Nov 29 '21 at 12:13
1

You could use busybox to get a shell inside a distroless container:

FROM gcr.io/distroless/base

...

COPY --from=amd64/busybox:1.31.1 /bin/busybox /busybox/busybox
RUN ["/busybox/busybox", "--install", "/bin"]

CMD ["/bin/sh", "-c", "java -version"]

You can find an example to this kind of Dockerfile here.

But I don't think this busybox shell is necessary needed.

Altough ENTRYPOINT /application $OPTIONS does not work, this will work ENTRYPOINT ["myapp", "arguments"]

Note that distroless images by default do not contain a shell. That means the Dockerfile ENTRYPOINT command, when defined, must be specified in vector form, to avoid the container runtime prefixing with a shell.

source: github

Ervin Szilagyi
  • 14,274
  • 2
  • 25
  • 40
  • yes, with the vector form it indeed starts, but then the variables can't be dynamically defined without editing the Dockerfile, right? – Inqy Nov 29 '21 at 09:33
  • the busybox approach works great though, with only minimal increase to the image size - thanks – Inqy Nov 29 '21 at 14:19