Debian Bullseye, fluent-bit 1.9 support, shrink images #4
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Reduced image size
I noticed that the old copy commands were very inefficient. For instance a Bullseye system will have the below setup for libgnutls:
Note that
libgnutls.so.30
is a symlink tolibgnutls.so.30.29.1
(for information on why this is the case lookup "shared library soname"). However, the previous copy commands would create the following:This is because docker copy does not preserve that the file is a symlink and instead copies the file that the symlink is pointing to. This creates duplicate copies of many libs (some libraries have two separate symlinks, so three copies of the same library), significantly bloating image size.
In addition copy commands like this
COPY --from=builder /usr/lib/x86_64-linux-gnu/libssl.so* /usr/lib/x86_64-linux-gnu/
would very frequently copy static libraries (.a
files) into the image. These are completely unnecessary at runtime (they would only ever be used during compile-time if we were creating a statically linked binary) and often larger than the .so files themselves.So to solve both of these issues I went through with ld and identified every
.so
that thefluent-bit
binary was actually (recursively) linked to, and just copied those. To avoid having to do anyLD_PRELOAD
fuckery I checked for which file the binary was actually linked against (which was always thesoname
file), and just copied that file across (abusing the "docker copy dereferences symlinks" behavior that was previously mentioned).Note that the format of the copy command is now very specific. You'd think that this would work:
But instead it creates the following file:
So it's dereferencing the symlink but also carrying over the filename that the symlink points to?!?!? Very... interesting.... behavior.
So instead we need to use this form:
Which creates the expected output:
In addition, I removed the copy commands for
libssl
andlibcrypto
, as these copied shared libs from openssl which were already part of the distroless base image (the "old" copies of them stuck around in the previous layer of the docker image). I also removedlibselinux
andlibpcre
because neither showed up in the output ofld
and they are likely unnecessary (however they could be used viadlopen
on certain systems, if they are needed they can be re-added). I addedlibzstd
which is a new dependency oflibsystemd
in Bullseye.To verify that the shared library changes here work you can build the image and then run the following (note that this can be run in the debug image or the normal image, no shell is required for this):
Which will produce the following output:
This indicates that the dynamic loader was able to fully resolve all linked libraries. You would receive an error message and a non-0 output code if this wasn't true.
The image size after making all of these changes goes from
133MB
to62MB
, a 54% reduction in image size.