Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native-image i.e. GraalVM builds of Zookeeper and CLIs #29

Merged
merged 83 commits into from
Jul 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
2e5d50e
A way to generate native-image config json
solsson Apr 6, 2020
d8bc54b
Start from the generated nativeagent dockerfile
solsson Apr 7, 2020
dfe86a9
Hand edited to explore native-image command variations
solsson Apr 7, 2020
3345348
Now failing on a java.lang.ref.SoftReference
solsson Apr 7, 2020
d874c70
native-image passes when Quarkus' kafka-client is in the classpath
solsson Apr 7, 2020
d8a5e9d
Output to a writable location
solsson Apr 7, 2020
863d300
distroless with support for unchanged ./bin/*.sh commands
solsson Apr 8, 2020
fb1d666
In practice we'll often do scripting
solsson Apr 8, 2020
62838d8
The reflect config I had in kafka-unwrap, plus the Loader that was mi…
solsson Apr 8, 2020
6a9adc7
Adds a naming convention to build native with Docker Hub,
solsson Apr 8, 2020
d3306a3
Adds topics list command to verify create, and actually merge configs
solsson Apr 8, 2020
319e6c2
Folder rename
solsson Apr 8, 2020
6add1be
The reflect config I had in kafka-unwrap, plus the Loader that was
solsson Apr 8, 2020
6885b71
Start from manually maintained native resources json
solsson Apr 8, 2020
7a7095f
I get an NPE after every kafka-topics run with the original reflect c…
solsson Apr 8, 2020
9d8f908
We should version all config resource results
solsson Apr 8, 2020
6d05c9c
Adds an image that can combine command line tools and scripts
solsson Apr 8, 2020
b9726c4
Fixes kafka-topics support for --zookeeper
solsson Apr 8, 2020
bf2a7ec
Tracking kafka and zk native-agent results, for the fun of it
solsson Apr 8, 2020
98100a2
Removes the old native base image, not included in build hooks
solsson Apr 9, 2020
3a4f669
Use current build's (in the ./hooks/build sequence) graalvm image
solsson Apr 9, 2020
171ed8a
Build nativebase always, but don't push; use in subsequent builds
solsson Apr 9, 2020
3241d34
native-cli needs to support scripting
solsson Apr 9, 2020
e9e0cd5
Adds utilities and entrypoint to native-cli
solsson Apr 10, 2020
54cbb4f
Avoids useradd because it results in a ~25 MB layer
solsson Apr 11, 2020
7c1caa2
WIP another zookeeper
solsson Apr 9, 2020
39897cf
Zookeeper native-image passes when classpath is minimized,
solsson Apr 8, 2020
81a5c85
WIP zookeeper logging at INFO level
solsson Apr 8, 2020
ebab223
More zookeeper config
solsson Apr 11, 2020
cbea571
Declarative FTW, but 3 zk instances made no difference to native conf
solsson Apr 11, 2020
dde254b
zookeeper build working, but not the resulting binary
solsson Apr 11, 2020
3934e25
Merge branch 'native-zookeeper' into native
solsson Apr 11, 2020
6fa9780
Got different zookeeper config results now
solsson Apr 12, 2020
382f2aa
Adds kafka-configs use cases
solsson Apr 12, 2020
f5f512c
Adds kafka-consumer-groups
solsson Apr 12, 2020
c8cc6b8
Adds kafka-configs and kafka-consumer-groups to native build,
solsson Apr 12, 2020
987c9a9
Failing to configure log4j in native, again
solsson Apr 12, 2020
98d11b3
Had forgotten to add the new steps
solsson Apr 12, 2020
e1c6f7b
Zookeeper without log4j again, static INFO level logging
solsson Apr 12, 2020
7867e84
kafka-topics matching -configs and -consumer-groups
solsson Apr 12, 2020
4ca8964
The two new builds had the same log4j classnotfound that kafka-topics…
solsson Apr 12, 2020
6c5842c
Zookeeper runs now, with some jmx error
solsson Apr 12, 2020
c48a9f7
nativeagent rerun
solsson Apr 12, 2020
afbd828
Adds a second broker
solsson Apr 12, 2020
b0f16b4
AdoptOpenJDK 11.0.7
solsson Apr 21, 2020
fdd96fb
Merge remote-tracking branch 'origin/master' into native
solsson Apr 24, 2020
cd82586
Interestingly zookeeper resulted in log4j reflects now
solsson Apr 24, 2020
a2d3f56
There were two containers with the sane native-config folder
solsson May 12, 2020
415cee7
Documents the two issues with native-image zookeeper
solsson May 18, 2020
3ced8f2
Tries native-image zookeeper with log4j
solsson May 18, 2020
291fd01
Runs graal 20.1 prerelease because of an issue compiling 2.5.0
solsson May 19, 2020
1e7bbb4
These workarounds weren't needed
solsson May 19, 2020
ab41bf6
Current distroless build
solsson May 19, 2020
be144bd
Since 2.5.0 builds the entrypoints have wildcard classpaths
solsson Apr 24, 2020
e72396e
This way to remove jars also get "zip END header not found"
solsson Apr 24, 2020
f9f4f13
WIP There seems to be compile time dependencies to log4j2
solsson Apr 26, 2020
eb945a4
Qurrent Quarkus
solsson May 19, 2020
422fe08
Avoid expanded classpath, modify classpath in a way that supports non…
solsson May 19, 2020
a51fc58
Names the stage now with the new classpath mod strategy
solsson May 19, 2020
062d626
Fixes permission error for usecases containers' native agent
solsson May 19, 2020
6bc3bbf
Using static logging config now
solsson May 19, 2020
0e91446
A fresh nativeagent run (see README.md)
solsson May 19, 2020
87026d9
There's compile time dependencies to log4j, but we can still replace
solsson May 19, 2020
34326a8
Revert "Using static logging config now"
solsson May 19, 2020
e2695a3
Fails to resolve UnresolvedElementException: Discovered unresolved
solsson May 19, 2020
9c702d5
For when class loading fails towards the edges of our use cases
solsson May 19, 2020
44c32bc
Reuse a single dockerfile for all cli applications
solsson May 19, 2020
213d17a
Builds pass locally now (:native, see README.md)
solsson May 19, 2020
df6ad4a
Fixes a documentation mistake
solsson May 19, 2020
f43548a
Need to use a variable in build ARG to get kafka's .sh names
solsson May 20, 2020
9f85435
Logging isn't great with CLIs, in particular when used in scripts
solsson May 20, 2020
6740685
GraalVM 20.1 has been released
solsson Jun 16, 2020
8e3e989
Apparently there's a new prefix to the download version
solsson Jun 16, 2020
6d1552f
Enables the new graalvm feature to pass on termination signals
solsson Jun 17, 2020
d10b342
Quarkus 1.6.0 officially supports graalvm 20.1.0,
solsson Jul 10, 2020
35c4501
Refreshes runtime images
solsson Jul 10, 2020
4e61120
Gotcha in hooks/build: ./native is built to :nativebase
solsson Jul 12, 2020
45f82b8
The official zk image supports JMXDISABLE=true but we must keep sed'ing
solsson Jul 12, 2020
4d41551
Merge branch 'master' into native
solsson Jul 12, 2020
70e76a3
wip
solsson Jul 12, 2020
4b23d8a
Use named layers for copy, in case we add more layers
solsson Jul 12, 2020
03ca0e5
Static logging for zookeeper, to avoid log4j's reflection
solsson Jul 12, 2020
fa81999
We'll probably stick with kafka's bundled zookeeper until KIP-500
solsson Jul 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,27 @@ We've kept the repository name to avoid breaking the automated build of solsson/

For legacy Dockerfiles from this repo (if you navigated to here from a Docker Hub [solsson](https://hub.docker.com/u/solsson/) image),
see https://github.com/solsson/dockerfiles/tree/misc-dockerfiles.

## Native builds

Very experimental.

```
NOPUSH=true IMAGE_NAME=solsson/kafka:nativeagent ./hooks/build
docker-compose -f native/docker-compose.yml down
docker run --rm --entrypoint chown -v $(pwd)/native/configs:/configs busybox -R $(id -u) /configs
NOPUSH=true IMAGE_NAME=solsson/kafka:native ./hooks/build
```

To test the native images reuse the usecases script:

```
for build in kafka-topics kafka-configs kafka-consumer-groups zookeeper-server-start; do
docker tag solsson/kafka:native-$build solsson/kafka:nativeagent-$build
done
./native/native-usecases.sh
docker-compose -f native/docker-compose.yml down
git restore --source=HEAD --staged --worktree -- native/configs/
# The cli image should simply combine the supported commands
docker run --rm --entrypoint sh solsson/kafka:native-cli -c 'ls ./bin/'
```
61 changes: 57 additions & 4 deletions hooks/build
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ set -e
PUSH=""

[ -z "$IMAGE_NAME" ] && echo "IMAGE_NAME is required" && exit 1;

# Nativeagent is a prerequisite of native, but meant to run locally with result json and Dockerfiles commited
# NOPUSH=true IMAGE_NAME=solsson/kafka:nativeagentagent ./hooks/build
[ -z "$NATIVEAGENT" ] && echo $IMAGE_NAME | grep 'nativeagent$' && NATIVEAGENT=true
# Docker Hub builds with tags ending with "native"
[ -z "$NATIVE" ] && echo $IMAGE_NAME | grep 'native$' && NATIVE=true

function imagename {
buildname=$1
case $IMAGE_NAME in
Expand All @@ -21,13 +28,16 @@ PUSH="$PUSH $jre"
docker build -t solsson/kafka -t "$IMAGE_NAME" ./kafka
PUSH="$PUSH $IMAGE_NAME"

nonroot=$(imagename nonroot)
docker build -t solsson/kafka:nonroot -t "$nonroot" ./kafka-nonroot
PUSH="$PUSH $nonroot"

graalvm=$(imagename graalvm)
docker build -t solsson/kafka:graalvm -t "$graalvm" ./jdk-adoptopenjdk-graalvm
PUSH="$PUSH $graalvm"

nonroot=$(imagename nonroot)
docker build -t solsson/kafka:nonroot -t "$nonroot" ./kafka-nonroot
PUSH="$PUSH $nonroot"
nativeagent=$(imagename nativebase)
docker build -t solsson/kafka:nativebase -t "$nativeagent" ./native

initutils=$(imagename initutils)
docker build -t solsson/kafka:initutils -t "$initutils" ./initutils
Expand All @@ -45,6 +55,10 @@ PUSH="$PUSH $cmak"
entrypoints=$(imagename entrypoints)
docker build -t $entrypoints ./kafka-entrypoints

[ "$NATIVEAGENT" = "true" ] && {
mkdir -p ./native/kafka-entrypoints
}

function entrypoint_gen {
echo "# $@"
script=$1; shift
Expand All @@ -66,6 +80,15 @@ function entrypoint_gen {
echo '"]' >> $dfile
docker build -t $image -f $dfile ./kafka-entrypoints
PUSH="$PUSH $image"

[ "$NATIVEAGENT" != "true" ] || {
cp $dfile native/$dfile
sed -i "s|FROM .*|FROM $nativeagent|" native/$dfile
sed -i 's| , "-cp" \\| , "-agentpath:/opt/graalvm/lib/libnative-image-agent.so=config-merge-dir=/home/nonroot/native-config" \\\
, "-cp" \\|' native/$dfile
docker build -t $image -f native/$dfile ./native
}

}

entrypoint_gen ./bin/kafka-server-start.sh /etc/kafka/server.properties
Expand All @@ -76,7 +99,37 @@ entrypoint_gen ./bin/kafka-consumer-groups.sh
entrypoint_gen ./bin/kafka-reassign-partitions.sh
entrypoint_gen ./bin/kafka-leader-election.sh

# Entrypoints done
# Entrypoints done, run native build stuff

[ "$NATIVEAGENT" != "true" ] || {
./native/native-usecases.sh
}

[ "$NATIVE" != "true" ] || {
# Don't push anything else with native builds because those images would also get a "native" tag
PUSH=""
for cli in \
kafka-topics:kafka.admin.TopicCommand \
kafka-configs:kafka.admin.ConfigCommand \
kafka-consumer-groups:kafka.admin.ConsumerGroupCommand; do
command=$(echo $cli | cut -d: -f1)
mainclass=$(echo $cli | cut -d: -f2)
nativename=$(imagename $command)
echo "Buildig admin CLI $command $mainclass ..."
cat native/admincmd.Dockerfile | sed "s|{{command}}|$command|g" | sed "s|{{mainclass}}|$mainclass|g" | \
docker build -t solsson/kafka:native-$command -t "$nativename" -f - native/
PUSH="$PUSH $nativename"
done
for nativebuild in \
zookeeper-server-start \
cli; do
nativename=$(imagename $nativebuild)
docker build -t solsson/kafka:native-$nativebuild -t "$nativename" -f native/$nativebuild.Dockerfile native/
PUSH="$PUSH $nativename"
done
}

# Push results

echo "PUSH list contains: $PUSH"
[ -z "$NOPUSH" ] || exit 0
Expand Down
3 changes: 0 additions & 3 deletions kafka-native-base-jre/Dockerfile

This file was deleted.

2 changes: 0 additions & 2 deletions kafka-native-base/Dockerfile

This file was deleted.

3 changes: 3 additions & 0 deletions native/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

# These are only used for ./native/native-usecases.sh, and the result is ./native/config resources
kafka-entrypoints
9 changes: 9 additions & 0 deletions native/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM solsson/kafka:graalvm

# Should be identical to kafka-nonroot's user
RUN echo 'nonroot:x:65532:65534:nonroot:/home/nonroot:/usr/sbin/nologin' >> /etc/passwd && \
mkdir -p /home/nonroot && touch /home/nonroot/.bash_history && chown -R 65532:65534 /home/nonroot
USER nonroot:nogroup

COPY --from=solsson/kafka:nonroot /opt/kafka /opt/kafka
COPY --from=solsson/kafka:nonroot /etc/kafka /etc/kafka
59 changes: 59 additions & 0 deletions native/admincmd.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
FROM adoptopenjdk:11.0.7_10-jdk-hotspot-bionic@sha256:c2ce12d7530d957f2d44dd33339eeeafa3b889c27af0824b186c4afef1f843ef \
as nonlibs
RUN echo "class Empty {public static void main(String[] a){}}" > Empty.java && javac Empty.java && jar --create --file /empty.jar Empty.class

FROM curlimages/curl@sha256:aa45e9d93122a3cfdf8d7de272e2798ea63733eeee6d06bd2ee4f2f8c4027d7c \
as extralibs

USER root
RUN curl -sLS -o /slf4j-nop-1.7.30.jar https://repo1.maven.org/maven2/org/slf4j/slf4j-nop/1.7.30/slf4j-nop-1.7.30.jar
RUN curl -sLS -o /quarkus-kafka-client-1.6.0.Final.jar https://repo1.maven.org/maven2/io/quarkus/quarkus-kafka-client/1.6.0.Final/quarkus-kafka-client-1.6.0.Final.jar

FROM solsson/kafka:nativebase as native

ARG classpath=/opt/kafka/libs/extensions/*:/opt/kafka/libs/*

COPY --from=extralibs /*.jar /opt/kafka/libs/extensions/

# docker run --rm --entrypoint ls solsson/kafka -l /opt/kafka/libs/ | grep log
COPY --from=nonlibs /empty.jar /opt/kafka/libs/slf4j-log4j12-1.7.30.jar

COPY configs/{{command}} /home/nonroot/native-config

RUN native-image \
--no-server \
--install-exit-handlers \
-H:+ReportExceptionStackTraces \
--no-fallback \
-H:IncludeResourceBundles=joptsimple.HelpFormatterMessages \
-H:IncludeResourceBundles=joptsimple.ExceptionMessages \
-H:ConfigurationFileDirectories=/home/nonroot/native-config \
# When testing the build for a new version we should remove this one, but then it tends to come back
--allow-incomplete-classpath \
--report-unsupported-elements-at-runtime \
# -D options from entrypoint
-Djava.awt.headless=true \
-Dkafka.logs.dir=/opt/kafka/bin/../logs \
-cp ${classpath} \
-H:Name={{command}} \
{{mainclass}} \
/home/nonroot/{{command}}

FROM gcr.io/distroless/base-debian10:nonroot@sha256:78f2372169e8d9c028da3856bce864749f2bb4bbe39c69c8960a6e40498f8a88

COPY --from=native \
/lib/x86_64-linux-gnu/libz.so.* \
/lib/x86_64-linux-gnu/

COPY --from=native \
/usr/lib/x86_64-linux-gnu/libzstd.so.* \
/usr/lib/x86_64-linux-gnu/libsnappy.so.* \
/usr/lib/x86_64-linux-gnu/liblz4.so.* \
/usr/lib/x86_64-linux-gnu/

WORKDIR /usr/local

ARG command=
COPY --from=native /home/nonroot/{{command}} ./bin/{{command}}.sh

ENTRYPOINT [ "/usr/local/bin/{{command}}.sh" ]
3 changes: 3 additions & 0 deletions native/cli-scripts/cli-list.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

(cd /usr/local/bin && ls -l)
8 changes: 8 additions & 0 deletions native/cli-scripts/kafka-topics_ifnotexists.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
# Utility for --create to replace --if-not-exists until that flag ceases to require zookeeper
log=$(mktemp)
kafka-topics "$@" | tee $log
result=${PIPESTATUS[0]}
grep "already exists" $log && exit 0
rm $log
exit $result
27 changes: 27 additions & 0 deletions native/cli.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM ubuntu:20.04@sha256:c844b5fee673cd976732dda6860e09b8f2ae5b324777b6f9d25fd70a0904c2e0

WORKDIR /usr/local
COPY --from=solsson/kafka:native-kafka-topics /usr/local/bin/* /usr/local/bin/
COPY --from=solsson/kafka:native-kafka-configs /usr/local/bin/* /usr/local/bin/
COPY --from=solsson/kafka:native-kafka-consumer-groups /usr/local/bin/* /usr/local/bin/

RUN set -ex; \
export DEBIAN_FRONTEND=noninteractive; \
runDeps='ca-certificates netcat-openbsd libsnappy1v5 liblz4-1 libzstd1 kafkacat jq'; \
apt-get update && apt-get install -y $runDeps $buildDeps --no-install-recommends; \
\
rm -rf /var/lib/apt/lists; \
rm -rf /var/log/dpkg.log /var/log/alternatives.log /var/log/apt /root/.gnupg

COPY cli-scripts/* /usr/local/bin/

RUN for sh in $(find /usr/local/bin/ -name *.sh); do \
ln -s $sh $(echo -n $sh | sed 's/\.sh$//'); \
done

# Should be identical to kafka-nonroot's user
RUN echo 'nonroot:x:65532:65534:nonroot:/home/nonroot:/usr/sbin/nologin' >> /etc/passwd && \
mkdir -p /home/nonroot && touch /home/nonroot/.bash_history && chown -R 65532:65534 /home/nonroot
USER nonroot:nogroup

ENTRYPOINT [ "cli-list" ]
11 changes: 11 additions & 0 deletions native/configs-manual-additions/kafka-configs/reflect-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"name": "org.apache.log4j.helpers.Loader"
},
{
"name": "sun.security.provider.ConfigFile",
"methods": [
{ "name": "<init>", "parameterTypes": [] }
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"name": "org.apache.log4j.helpers.Loader"
},
{
"name": "sun.security.provider.ConfigFile",
"methods": [
{ "name": "<init>", "parameterTypes": [] }
]
}
]
14 changes: 14 additions & 0 deletions native/configs-manual-additions/kafka-topics/reflect-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"name": "org.apache.log4j.helpers.Loader"
},
{
"name": "io.netty.util.internal.logging.Log4J2Logger"
},
{
"name": "sun.security.provider.ConfigFile",
"methods": [
{ "name": "<init>", "parameterTypes": [] }
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
2 changes: 2 additions & 0 deletions native/configs/kafka-configs/jni-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
2 changes: 2 additions & 0 deletions native/configs/kafka-configs/proxy-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
Loading