docker busybox sh shell不知道任何命令

qxgroojn  于 2023-04-29  发布在  Docker
关注(0)|答案(2)|浏览(180)

总结如下:Portainer Docker容器中的Busybox“sh”中不存在命令。
细微差别,一如既往:
有一个Portainer工具图像,我想有 shell 访问。为什么我需要shell访问那里?这是因为我想通过额外的docker socket文件Map来发现连接多个docker上下文(默认上下文除外)的能力。
Portainer开发人员采取了一些措施(他们说是出于安全原因)来禁用在运行容器中获取交互式控制台的能力-没有bin/bashbin/sh等。
我从https://busybox.net/downloads/binaries/1.35.0-x86_64-linux-musl/busybox下载了Busybox
并创建了我自己的调试容器,基于原来的Portainer one:
Dockerfile:

FROM portainer/portainer-ce:2.9.3
LABEL destiny="Portainer debug"

ADD busybox busybox
ENTRYPOINT [""]
CMD [""]

执行的映像构建命令:

docker build -f Dockerfile -t portainer_debug:latest .

...并用它启动一个容器:

docker run --name ppp -it portainer_debug /busybox sh

我进入了运行容器内部的一个shell。不幸的是,我发现没有可用的命令。例如,ls命令返回:

/ # ls
sh: ls: not found
/ #

这也意味着Busybox命令(上面的sh)在容器启动时作为参数工作。我用“ls”作为参数检查了一下:

$ docker run --name ppp -it portainer_debug /busybox ls
busybox         docker-compose  kubectl         sys
data            etc             portainer       tmp
dev             helm            proc
docker          kompose         public
$

注意:“exit”命令在“sh”中工作。
与alpine image相同的练习如预期的那样工作:

/ # ls
bin      busybox  dev      etc      home     lib      media    mnt      opt      proc     root     run      sbin     srv      sys      tmp      usr      var
/ #

如果有人能提出下一步的建议来理解为什么busybox会“忘记”所有命令,我将非常高兴和感激。

nbnkbykc

nbnkbykc1#

https://busybox.net/downloads/BusyBox.html
用途
BusyBox是一个多调用二进制文件。多调用二进制文件是一种可执行程序,它执行与多个实用程序相同的作业。这意味着只有一个BusyBox二进制文件,但是这个二进制文件的作用就像是大量的实用程序。这使得BusyBox变得更小,因为所有内置的实用程序(我们称之为applet)可以共享许多常见操作的代码。
您还可以通过在命令行上发出命令作为参数来调用BusyBox。例如,输入

/bin/busybox ls

也会导致BusyBox的行为像'ls'。
当然,在每个命令中添加'/bin/busybox'会很痛苦。因此,大多数人会使用BusyBox二进制文件的链接来调用BusyBox。
例如,输入

ln -s /bin/busybox ls
    ./ls

将导致BusyBox表现为'ls'(如果'ls'命令已编译到BusyBox中)。一般来说,你不需要自己创建所有这些链接,因为BusyBox构建系统会在你运行“make install”命令时为你做这些。
如果不带参数调用BusyBox,它将为您提供一个已编译到BusyBox二进制文件中的小程序列表。
您只将二进制busybox复制到图像中。您可以执行./busybox ls或创建符号链接,并将带有符号链接的目录添加到$PATH,如果您希望shell找到它们的话。
为什么busybox“忘记”所有命令
Busybox没有“忘记”任何东西,它是无生命的,* 你 * 只是没有正确使用。
例如,下面我做:

  • 执行portainer docker image。
  • 因为我很懒,所以我不写Dockerfile,我只是将我安装在主机上的busybox可执行文件安装到docker容器中。它与容器中的COPY相同。
  • Docker容器执行/busybox sh shell
  • -c执行脚本
  • 该脚本创建目录/busybox mkdir /bin
  • busybox-for i in $(/busybox list)中每个工具脚本
  • /bin目录中创建到busybox可执行文件的符号链接-/busybox ln -s /busybox /bin/$i
  • 以上两个步骤完全如Busybox常见问题 www.example.com
  • 然后脚本执行交互式shell与我交互

由于/bin默认位于PATH中,因此在创建目录和符号链接后,所有Busybox工具都可用。请注意,所有命令都以/busybox作为前缀,以便于在PATH中使用符号链接创建目录之前调用上面文档中解释的Busybox。

$ docker run -ti --rm --entrypoint '' -v /bin/busybox:/busybox:ro portainer/portainer-ce:2.9.3 /busybox sh -c '/busybox mkdir /bin; for i in $(/busybox --list); do /busybox ln -s /busybox /bin/$i; done; sh -li'
/ # ls
bin             data            docker          etc             kompose         portainer       public          tmp
busybox         dev             docker-compose  helm            kubectl         proc            sys
/ # echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
fd3cxomn

fd3cxomn2#

ln -s /bin/busybox /bin/ash
如果ls在执行ash后工作,则执行ln -s /bin/busybox /bin/sh
我假设busybox在/bin中,但它也可能是/sbin(取决于分发决定)。

相关问题