基于 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 图像正常工作,您应该执行以下操作:
- 将
du
复制到您的Dockerfile
所在的目录:cp /usr/bin/du .
- 更新你的
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 的静态版本,并且然后是复制它的第二阶段。对于一个可能不是您真正想要的核心应用程序的一部分的工具来说,这是很多工作 运行。
当我尝试 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 图像正常工作,您应该执行以下操作:
- 将
du
复制到您的Dockerfile
所在的目录:cp /usr/bin/du .
- 更新你的
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 的静态版本,并且然后是复制它的第二阶段。对于一个可能不是您真正想要的核心应用程序的一部分的工具来说,这是很多工作 运行。