Skip to content
This repository has been archived by the owner on Oct 23, 2019. It is now read-only.

Consider distroless java for base image #197

Closed
anuraaga opened this issue Feb 14, 2019 · 15 comments
Closed

Consider distroless java for base image #197

anuraaga opened this issue Feb 14, 2019 · 15 comments

Comments

@anuraaga
Copy link
Contributor

There's a java 11 version of distroless, which is a pretty slim docker image with JRE11. Might want to consider basing zipkin on it for better HTTP/2 support, and less gotchas thanks to using normal glibc.

GoogleContainerTools/distroless#285

@anuraaga
Copy link
Contributor Author

Tried creating an image with distroless

Current Alpine + Zuul Java 8: 144MB
Distroless Java 8: 176MB
Distroless Java 11: 246MB

I guess Java 11 is quite a bit bigger since there's been a lot of functionality added since Java 8 like modules, HTTP/2, and TLS 1.3 to name a few.

Anyways will go ahead and send a PR don't necessarily have to accept it if the size difference is too much.

@codefromthecrypt
Copy link

codefromthecrypt commented Feb 15, 2019 via email

@anuraaga
Copy link
Contributor Author

Those are the sizes of the docker images using docker images command - I think they're compressed sizes.

@codefromthecrypt
Copy link

what's the advantage of this over the similarly not-so-slim openjdk slim image? is there any liability you forsee using a google image?

@anuraaga
Copy link
Contributor Author

Main advantage is it is still way slimmer than that one

openjdk:8-slim 299MB
openjdk:11-slim 530MB

There's no OS so no systemd and similar nonsense - container security scanning also works much better since most CVEs are systemd related

The main liability I can see is how quickly they add support for a new JRE - supporting JRE11 took about half a year after release I think. The main reason for that though is they just use the debian packages - it took around that long for debian to backport JDK11 to stretch.

@codefromthecrypt
Copy link

gotcha.. I wonder though if we can make this the base image instead like before and squash it after removing the JDK part of it?

openzipkin/docker-java@8cd5043#diff-3254677a7917c6c01f55212f86c57fbfL6

Currently our services only need JRE, and that's how we originally got some space back

@shakuzen
Copy link

How about using jlink to make a minimal JRE for Zipkin in our Docker image? Seems like it can save a lot of space. Here's an article I found quickly (haven't tried it yet): https://qiita.com/h-r-k-matsumoto/items/1725fc587ce127671560

@anuraaga
Copy link
Contributor Author

The distroless images only contain JRE so nothing special to remove JDK. So as it stands, I don't think we would need to make a special base image (or are you suggesting /zipkin should also be in a base image?).

But it would make sense to have our own base image if we use jlink, which seems like a cool idea. I think we could automatically get a fully minimal JRE if we had a Java 9 modules definition, but if we have an idea of what modules are required could probably create it manually too.

@anuraaga
Copy link
Contributor Author

Well initial experimentation using a similar command to that article results in a huge JRE :(

root@3067589752d7:/# jlink --module-path /usr/lib/jvm/java-11-openjdk-amd64/jmods --compress=2 --add-modules java.base,java.logging      --no-header-files      --no-man-pages      --output /opt/jdk-11-mini-runtime
root@3067589752d7:/# cd /opt/jdk-11-mini-runtime/
root@3067589752d7:/opt/jdk-11-mini-runtime# du -h
356K	./lib/security
312M	./lib/server
332K	./lib/jli
328M	./lib
16K	./conf/security/policy/limited
12K	./conf/security/policy/unlimited
36K	./conf/security/policy
88K	./conf/security
104K	./conf
76K	./legal/java.base
4.0K	./legal/java.logging
84K	./legal
44K	./bin
328M	.

vs default openjdk:11-jre-slim JVM directory

root@18ff7fb1f259:/# cd /usr/lib/jvm/java-11-openjdk-amd64/
root@18ff7fb1f259:/usr/lib/jvm/java-11-openjdk-amd64# ls
bin  conf  docs  legal	lib  man
root@18ff7fb1f259:/usr/lib/jvm/java-11-openjdk-amd64# du -h
4.0K	./lib/security
35M	./lib/server
72K	./lib/jli
178M	./lib
16K	./conf/security/policy/limited
12K	./conf/security/policy/unlimited
32K	./conf/security/policy
36K	./conf/security
4.0K	./conf/management
44K	./conf
4.0K	./legal/java.compiler
4.0K	./legal/jdk.jstatd
4.0K	./legal/jdk.sctp
4.0K	./legal/jdk.jdi
4.0K	./legal/jdk.jfr
4.0K	./legal/java.management
4.0K	./legal/jdk.internal.vm.compiler.management
4.0K	./legal/jdk.rmic
4.0K	./legal/jdk.hotspot.agent
4.0K	./legal/jdk.internal.jvmstat
4.0K	./legal/java.management.rmi
4.0K	./legal/java.se
4.0K	./legal/java.sql.rowset
4.0K	./legal/jdk.management.jfr
4.0K	./legal/jdk.attach
4.0K	./legal/jdk.jartool
24K	./legal/jdk.javadoc
32K	./legal/java.desktop
4.0K	./legal/jdk.security.jgss
4.0K	./legal/java.scripting
4.0K	./legal/jdk.jdwp.agent
4.0K	./legal/jdk.xml.dom
4.0K	./legal/jdk.editpad
4.0K	./legal/jdk.pack
4.0K	./legal/java.datatransfer
4.0K	./legal/java.transaction.xa
4.0K	./legal/jdk.compiler
4.0K	./legal/jdk.jsobject
4.0K	./legal/jdk.scripting.nashorn.shell
4.0K	./legal/jdk.net
4.0K	./legal/java.instrument
48K	./legal/java.xml
4.0K	./legal/java.security.sasl
4.0K	./legal/jdk.httpserver
4.0K	./legal/jdk.internal.vm.compiler
4.0K	./legal/jdk.management
4.0K	./legal/jdk.aot
4.0K	./legal/jdk.naming.rmi
4.0K	./legal/jdk.accessibility
8.0K	./legal/jdk.dynalink
4.0K	./legal/jdk.internal.ed
12K	./legal/jdk.scripting.nashorn
4.0K	./legal/jdk.charsets
4.0K	./legal/jdk.jcmd
4.0K	./legal/jdk.jconsole
12K	./legal/jdk.crypto.cryptoki
16K	./legal/java.xml.crypto
4.0K	./legal/jdk.unsupported
4.0K	./legal/jdk.jlink
4.0K	./legal/jdk.naming.dns
4.0K	./legal/jdk.internal.vm.ci
4.0K	./legal/java.rmi
4.0K	./legal/jdk.jdeps
36K	./legal/jdk.crypto.ec
8.0K	./legal/jdk.localedata
4.0K	./legal/jdk.management.agent
8.0K	./legal/java.smartcardio
4.0K	./legal/jdk.unsupported.desktop
52K	./legal/java.base
4.0K	./legal/java.logging
4.0K	./legal/java.net.http
8.0K	./legal/jdk.internal.opt
4.0K	./legal/jdk.security.auth
4.0K	./legal/java.naming
4.0K	./legal/jdk.zipfs
4.0K	./legal/jdk.jshell
4.0K	./legal/java.security.jgss
8.0K	./legal/jdk.internal.le
4.0K	./legal/java.prefs
4.0K	./legal/java.sql
504K	./legal
212K	./bin
84K	./man/man1
84K	./man/ja_JP.UTF-8/man1
88K	./man/ja_JP.UTF-8
176K	./man
179M	.

@shakuzen
Copy link

That's probably docker-library/openjdk#217

@anuraaga
Copy link
Contributor Author

anuraaga commented Feb 15, 2019

Urgh nice find. Indeed, with that, just java.base,java.logging goes down to 31M.

I'd leave it to @adriancole on whether it's a good idea at all to trim down the JVM, or which modules are needed (java.base,java.logging,java.sql come to mind but no clue if it's enough), as he probably has an idea of all the various usage of this base image :)

@codefromthecrypt
Copy link

codefromthecrypt commented Feb 15, 2019 via email

@codefromthecrypt
Copy link

codefromthecrypt commented Feb 15, 2019 via email

@anuraaga
Copy link
Contributor Author

Yeah agree we would want to first try a different image and then try trimming it down. And I understand the compose issue now - I'd need to migrate the other folders in this repo to distroless too so they all share the same base image. I don't mind doing it if it seems worth trying.

And yeah, I don't think we should create a java11-specific uberjar or anything, just update the JRE which still can have other benefits like TLS updates.

So we just need to decide, do we think migrating to Java 11 is worth having a larger image for a little while until we potentially trim it down again. And whether we migrate all these Dockerfiles at the same time. @adriancole what do you think?

@codefromthecrypt
Copy link

codefromthecrypt commented Feb 15, 2019 via email

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants