基于 busybox 将 Linux 实用程序添加到 docker 图像

Adding Linux utilities to docker image based on busybox

当我尝试 df -h busybox 容器时,我得到以下结果:

$ docker run -it busybox du -h  
# expected results

我需要的是 df -b 的输出结果:

$ docker run -it busybox du -b                                                                     
du: invalid option -- b
BusyBox v1.30.0 (2018-12-31 18:16:17 UTC) multi-call binary.

Usage: du [-aHLdclsxhmk] [FILE]...

Summarize disk space used for each FILE and/or directory

    -a  Show file sizes too
    -L  Follow all symlinks
    -H  Follow symlinks on command line
    -d N    Limit output to directories (and files with -a) of depth < N
    -c  Show grand total
    -l  Count sizes many times if hard linked
    -s  Display only a total for each argument
    -x  Skip directories on different filesystems
    -h  Sizes in human readable format (e.g., 1K 243M 2G)
    -m  Sizes in megabytes
    -k  Sizes in kilobytes (default)

由于许多标准实用程序在 busybox 图像中被修剪或不存在,因此这种行为并不奇怪。作为 dockerhub 的 busybox 页面 suggests:

FROM busybox
COPY ./my-static-binary /my-static-binary
CMD ["/my-static-binary"]

因此,我创建了一个包含以下内容的 Dockerfile,试图将我的 Ubuntu 16.04 du 二进制文件复制到图像中:

FROM busybox
COPY /usr/bin/du /bin/du
CMD ["/bin/du", "-b"]

但是当我尝试 docker build 时,出现以下错误:

$ docker build .              
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM busybox
 ---> 3a093384ac30
Step 2/3 : COPY /usr/bin/du /bin/du
COPY failed: stat /var/lib/docker/tmp/docker-builder362173879/usr/bin/du: no such file or directory

我不知道将实用程序添加到如此小的图像是否是正确的方法,但如果您告诉我实用程序(例如(完整)du、[=22] 的方式,我将不胜感激=], 等可以添加,因为没有像 apt.

这样的包管理器

由于以下限制,COPY 无法正常工作:

COPY obeys the following rules:

The path must be inside the context of the build; you cannot COPY ../something /something, because the first step of a docker build is to send the context directory (and subdirectories) to the docker daemon.

您可以在 Dockerfile documentation 中阅读更多内容。

为了使您的 busybox 图像正常工作,您应该执行以下操作:

  1. du复制到您的Dockerfile所在的目录:cp /usr/bin/du .
  2. 更新你的 Dockerfile:
FROM busybox
COPY du /du
CMD ["du", "-b"]
3. 重建你的形象:`docker build .`

根据 busybox docker documentation 你应该把复制的二进制文件直接放到 / 而不是 /bin/.

如果 just-Busybox Docker 基本映像不能满足您的需要,您可以更改 Docker 文件以基于功能更全面的 Linux 发行版。 FROM ubuntu 非常常见,包括 Unix 工具集的 GNU 版本(及其各种供应商扩展); FROM alpine 也很常见,它基于 Busybox 加上一个最小的包管理器。

另一个好的答案是将自己限制在 POSIX.1: du(1) is not required to support a -b option 中定义的功能。如果您尝试在非 Linux 的系统上编写基于 Alpine 的图像或 运行(MacOS 是当今最突出的例子),这将有所帮助。

您可能无法成功地将单个二进制文件从您的主机系统复制到 Docker 映像中,撇开路径问题不谈,因为库环境可能非常不同。如果您 运行 ldd $(which du) 在主机上,则那里列出的所有库都需要出现在图像中并且版本相似。 busybox 基本映像可能甚至不包含 libc.so.6,这是大多数动态链接二进制文件的最低要求。

您的问题的正确答案是编写一个多阶段 Docker 文件,该文件的第一阶段具有完整的 C 工具链,可构建 GNU Coreutils 的静态版本,并且然后是复制它的第二阶段。对于一个可能不是您真正想要的核心应用程序的一部分的工具来说,这是很多工作 运行。