Most of the time, Docker just works. But sometimes, you need to be a bit clever. In my case, I want Polaris to have he permission to write to the host filesystem, not just to see it. This proved hard. These are some lessons I learned.
What's in an image?
docker save ph1ll1phenry/polaris_for_bdd:latest -o polaris_for_bdd.tar
mkdir polaris_fs
tar -xf polaris_for_bdd.tar -C polaris_fs
Then you can start untaring the blobs (where each blob is a Docker layer). In my case, I was trying to find where the bash binary was:
for BLOB in $(ls blobs/sha256/ ) ; do { echo $BLOB ; tar -vxf blobs/sha256/$BLOB | grep bash; } done
How was an image built?
You can reconstitute the steps made to create a Docker image with something like:
docker history --no-trunc apache/polaris
Restoring OS properties
docker history --no-trunc apache/polaris
Restoring OS properties
The apache/polaris Docker image had a lot of extraneous Linux binaries removed, presumably to make it smaller and more secure. However, I needed them back as I need to grant the container certain permissions on the host.
First off, the su command had been removed. You can canibalise binaries from other images in your Dockerfile like this:
FROM redhat/ubi9 AS donor
FROM apache/polaris AS final
...
COPY --from=donor /usr/bin/su /usr/bin/su
However, copying a binary over most of the time is a bit naive. Running su gave:
su: Critical error - immediate abort
Taking the parent Docker image before it was pruned, I could run:
[root@6230fb595115 ~]# ldd /usr/bin/su
linux-vdso.so.1 (0x00007fff87ae6000)
libpam.so.0 => /lib64/libpam.so.0 (0x0000733267a15000)
libpam_misc.so.0 => /lib64/libpam_misc.so.0 (0x0000733267a0f000)
libc.so.6 => /lib64/libc.so.6 (0x0000733267807000)
libaudit.so.1 => /lib64/libaudit.so.1 (0x00007332677d3000)
libeconf.so.0 => /lib64/libeconf.so.0 (0x00007332677c8000)
libm.so.6 => /lib64/libm.so.6 (0x00007332676ed000)
/lib64/ld-linux-x86-64.so.2 (0x0000733267a39000)
libcap-ng.so.0 => /lib64/libcap-ng.so.0 (0x00007332676e2000)
So, my Dockerfile had to COPY these files over too.
These libpam* shared objects refer to Linux's Pluggable Authentication Modules which is a centralized framework for permissioning arbitrary modules - eg MFA.
After a lot of faffing, I just COPYd the entire /etc/ folder from the donor to the final images. This is fine for integration tests but probably best avoided for prod :)
No comments:
Post a Comment