As a summary:
No commands exist in Busybox "sh" in a Portainer Docker container.
Nuances, as always:
There is a Portainer tool image I’d like to have shell access in.
Why I need shell access there? It’s because I’d like to discover the ability to connect more than one docker context (other than default)
via additional docker socket file mapping.
Portainer developers take some steps (they say for security reasons) to disable the ablity to get an interactive console inside the running container – there are no bin/bash
, bin/sh
etc.
I’ve downloaded Busybox from
https://busybox.net/downloads/binaries/1.35.0-x86_64-linux-musl/busybox
and created my own debug container based on th original Portainer one:
Dockerfile:
FROM portainer/portainer-ce:2.9.3
LABEL destiny="Portainer debug"
ADD busybox busybox
ENTRYPOINT [""]
CMD [""]
Executed image build command:
docker build -f Dockerfile -t portainer_debug:latest .
… and started a container with it:
docker run --name ppp -it portainer_debug /busybox sh
I entered into a shell inside of the running container.
Unfortunately, I found that there are no commands available.
For example, ls
command returns:
/ # ls
sh: ls: not found
/ #
It also means that Busybox commands (sh
above) work as a parameter at container start. I checked it with "ls" as a paramater:
$ docker run --name ppp -it portainer_debug /busybox ls
busybox docker-compose kubectl sys
data etc portainer tmp
dev helm proc
docker kompose public
$
Note: "exit" command works inside "sh".
The same excercise with alpine image works as expected:
/ # ls
bin busybox dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
/ #
I’d be glad and very thankful if somebody could suggest the next steps to understand why busybox "forgets" all commands.
2
Answers
From https://busybox.net/downloads/BusyBox.html :
You only copied the binary
busybox
into the image. You can do./busybox ls
or create the symlink, and add the directory with symlinks to$PATH
if you want shell to find them.Busybox didn’t "forget" anything, it is inanimate, you just haven’t correctly used.
For example, below I do:
Dockerfile
, I just mount busybox executable that I have installed on my host to inside the docker container. It’s the same as COPY in container./busybox sh
shell-c
which executes a script/busybox mkdir /bin
for i in $(/busybox list)
/bin
directory –/busybox ln -s /busybox /bin/$i
Because
/bin
is by default in PATH, after creating the directory and symlinks, all Busybox tools are available. Note that all commands are prepended with/busybox
to facilitate the Busybox invoking explained in the documentation above, before the creation of directory in PATH with symlinks.ln -s /bin/busybox /bin/ash
if ls works after executing ash, then do
ln -s /bin/busybox /bin/sh
I assume busybox is in
/bin
but it may be/sbin
(depending on distribution decisions) as well.