Docker - /bin/sh: <file> 未找到 - 错误的 ELF 解释器 - 如何向 docker 图像添加 32 位库支持
Docker - /bin/sh: <file> not found - bad ELF interpreter - how to add 32bit lib support to a docker image
更新 – 旧问题标题:
Docker - 如何在 docker 构建期间执行 unzipped/unpacked/extracted 二进制文件(将文件添加到 docker 构建上下文)
--
我一直在尝试(半天 :P)执行 docker 构建期间提取的二进制文件。
我的 docker 文件大致包含:
...
COPY setup /tmp/setup
RUN \
unzip -q /tmp/setup/x/y.zip -d /tmp/setup/a/b
...
在目录 b
中是一个二进制文件 imcl
我遇到的错误是:
/bin/sh: 1: /tmp/setup/a/b/imcl: not found
令人困惑的是,在尝试执行二进制文件之前显示目录 b
(在 docker 文件内,在构建期间),显示了正确的文件:
RUN ls -la /tmp/setup/a/b/imcl
-rwxr-xr-x 1 root root 63050 Aug 9 2012 imcl
RUN file /tmp/setup/a/b/imcl
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped`
起初我是一个 Unix 菜鸟,我认为这是一个权限问题(主机的根目录与容器的根目录或其他东西不同)但是,在检查之后,两者的 UID 都是 0,所以它变得更奇怪了。
Docker 询问 not to use sudo 所以我尝试使用 su 组合:
su - -c "/tmp/setup/a/b/imcl"
su - root -c "/tmp/setup/a/b/imcl"
这两个都返回了:
stdin: is not a tty
-su: /tmp/setup/a/b: No such file or directory
好吧,我什至违抗了 Docker 的建议,并将我的基本图像从 debian:jessie 更改为 bloatish ubuntu:14.04 所以我可以尝试使用 sudo :D
猜猜结果如何?
sudo: unable to execute /tmp/setup/a/b/imcl: No such file or directory
随机谷歌搜索我偶然发现了一个 piece of Docker docs 我相信这是所有这些头撞的原因:
"Note: docker build will return a no such file or directory error if the file or directory does not exist in the uploaded context. This may happen if there is no context, or if you specify a file that is elsewhere on the Host system. The context is limited to the current directory (and its children) for security reasons, and to ensure repeatable builds on remote Docker hosts. This is also the reason why ADD ../file will not work."
所以我的问题是:
- 有解决办法吗?
- 有没有办法在构建期间(在 docker 文件中)将提取的文件添加到 docker 构建上下文?
哦,我正在构建的机器没有连接到互联网...
我想我问的和这个类似(虽然我没有看到答案):
How to include files outside of Docker's build context?
所以我运气不好?
在将构建上下文发送到 Docker 守护程序之前,我是否需要使用 shell 脚本解压缩,以便所有文件都完全按照构建命令期间的原样使用?
更新:
嗯,构建上下文实际上不是问题。我对此进行了测试,并能够在 docker 构建期间执行解压的二进制文件。
我的问题其实是这个:
CentOS 64 bit bad ELF interpreter
使用 debian:jessie 和 ubuntu:14.04 作为基础图像只会出现 No such file or directory
错误,但尝试使用 centos:7 和 fedora:23 会给出更好的错误消息:
/bin/sh: /tmp/setup/a/b/imcl: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
所以这让我得出结论,这实际上是 运行 64 位系统上的 32 位应用程序的问题。
现在,如果我可以访问互联网并启用回购协议,解决方案就会很简单:
apt-get install ia32-libs
或
yum install glibc.i686
但是,我不...:[
那么现在的问题就变成了:
- 在没有回购协议或互联网连接的情况下获得相同结果的最佳方法是什么?
根据 IBM,我需要的准确库是 gtk2.i686 和 libXtst.i686,可能还有 libstdc++
[root@localhost]# yum install gtk2.i686
[root@localhost]# yum install libXtst.i686
[root@localhost]# yum install compat-libstdc++
你走运了!您可以使用 ADD
命令执行此操作。 The docs 说:
If <src>
is a local tar archive in a recognized compression format
(identity, gzip, bzip2 or xz) then it is unpacked as a directory... When a directory is
copied or unpacked, it has the same behavior as tar -x
: the result is
the union of:
- Whatever existed at the destination path and
- The contents of the
source tree, with conflicts resolved in favor of “2.” on a
file-by-file basis.
UPDATE:
So the question becomes now:
- What would be the best way to achive the same result without repos or internet connection?
您可以使用 DockerHub 上可用的各种 non-official 32 位映像,搜索 debian32
、ubuntu32
、fedora32
等
如果你不相信他们,你可以自己构建这样的镜像,你也可以在 DockerHub 上找到说明,例如:
- on
f69m/ubuntu32
home page, there is a link to GitHub repo 用于生成图像;
- 在
hugodby/fedora32
主页上,有一个用于构建映像的命令示例;
- 等等。
或者,您可以根据一些官方镜像准备自己的镜像,并在其中添加 32 位包。
说,你可以像这样使用 Dockerfile
:
FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y ia32-libs
...并使用生成的图像作为基础(使用 FROM
指令)您在没有互联网访问的情况下构建的图像。
您甚至可以在 DockerHub 上创建一个 automated build,当您的 Dockerfile
(例如,在 GitHub 上发布)或主线映像(debian
在上面的例子中)改变。
无论您是如何获得支持 32 位的图像(使用现有的 non-official 图像或构建您自己的图像),您都可以使用 [=20] 将其存储到 tar 存档=] 命令,然后使用 docker load
命令导入。
更新 – 旧问题标题:
Docker - 如何在 docker 构建期间执行 unzipped/unpacked/extracted 二进制文件(将文件添加到 docker 构建上下文)
--
我一直在尝试(半天 :P)执行 docker 构建期间提取的二进制文件。
我的 docker 文件大致包含:
...
COPY setup /tmp/setup
RUN \
unzip -q /tmp/setup/x/y.zip -d /tmp/setup/a/b
...
在目录 b
中是一个二进制文件 imcl
我遇到的错误是:
/bin/sh: 1: /tmp/setup/a/b/imcl: not found
令人困惑的是,在尝试执行二进制文件之前显示目录 b
(在 docker 文件内,在构建期间),显示了正确的文件:
RUN ls -la /tmp/setup/a/b/imcl
-rwxr-xr-x 1 root root 63050 Aug 9 2012 imcl
RUN file /tmp/setup/a/b/imcl
ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped`
起初我是一个 Unix 菜鸟,我认为这是一个权限问题(主机的根目录与容器的根目录或其他东西不同)但是,在检查之后,两者的 UID 都是 0,所以它变得更奇怪了。
Docker 询问 not to use sudo 所以我尝试使用 su 组合:
su - -c "/tmp/setup/a/b/imcl"
su - root -c "/tmp/setup/a/b/imcl"
这两个都返回了:
stdin: is not a tty
-su: /tmp/setup/a/b: No such file or directory
好吧,我什至违抗了 Docker 的建议,并将我的基本图像从 debian:jessie 更改为 bloatish ubuntu:14.04 所以我可以尝试使用 sudo :D
猜猜结果如何?
sudo: unable to execute /tmp/setup/a/b/imcl: No such file or directory
随机谷歌搜索我偶然发现了一个 piece of Docker docs 我相信这是所有这些头撞的原因: "Note: docker build will return a no such file or directory error if the file or directory does not exist in the uploaded context. This may happen if there is no context, or if you specify a file that is elsewhere on the Host system. The context is limited to the current directory (and its children) for security reasons, and to ensure repeatable builds on remote Docker hosts. This is also the reason why ADD ../file will not work."
所以我的问题是:
- 有解决办法吗?
- 有没有办法在构建期间(在 docker 文件中)将提取的文件添加到 docker 构建上下文?
哦,我正在构建的机器没有连接到互联网...
我想我问的和这个类似(虽然我没有看到答案):
How to include files outside of Docker's build context?
所以我运气不好?
在将构建上下文发送到 Docker 守护程序之前,我是否需要使用 shell 脚本解压缩,以便所有文件都完全按照构建命令期间的原样使用?
更新:
嗯,构建上下文实际上不是问题。我对此进行了测试,并能够在 docker 构建期间执行解压的二进制文件。
我的问题其实是这个: CentOS 64 bit bad ELF interpreter
使用 debian:jessie 和 ubuntu:14.04 作为基础图像只会出现 No such file or directory
错误,但尝试使用 centos:7 和 fedora:23 会给出更好的错误消息:
/bin/sh: /tmp/setup/a/b/imcl: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
所以这让我得出结论,这实际上是 运行 64 位系统上的 32 位应用程序的问题。
现在,如果我可以访问互联网并启用回购协议,解决方案就会很简单:
apt-get install ia32-libs
或
yum install glibc.i686
但是,我不...:[
那么现在的问题就变成了:
- 在没有回购协议或互联网连接的情况下获得相同结果的最佳方法是什么?
根据 IBM,我需要的准确库是 gtk2.i686 和 libXtst.i686,可能还有 libstdc++
[root@localhost]# yum install gtk2.i686
[root@localhost]# yum install libXtst.i686
[root@localhost]# yum install compat-libstdc++
你走运了!您可以使用 ADD
命令执行此操作。 The docs 说:
If
<src>
is a local tar archive in a recognized compression format (identity, gzip, bzip2 or xz) then it is unpacked as a directory... When a directory is copied or unpacked, it has the same behavior astar -x
: the result is the union of:
- Whatever existed at the destination path and
- The contents of the source tree, with conflicts resolved in favor of “2.” on a file-by-file basis.
UPDATE:
So the question becomes now:
- What would be the best way to achive the same result without repos or internet connection?
您可以使用 DockerHub 上可用的各种 non-official 32 位映像,搜索 debian32
、ubuntu32
、fedora32
等
如果你不相信他们,你可以自己构建这样的镜像,你也可以在 DockerHub 上找到说明,例如:
- on
f69m/ubuntu32
home page, there is a link to GitHub repo 用于生成图像; - 在
hugodby/fedora32
主页上,有一个用于构建映像的命令示例; - 等等。
或者,您可以根据一些官方镜像准备自己的镜像,并在其中添加 32 位包。
说,你可以像这样使用 Dockerfile
:
FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y ia32-libs
...并使用生成的图像作为基础(使用 FROM
指令)您在没有互联网访问的情况下构建的图像。
您甚至可以在 DockerHub 上创建一个 automated build,当您的 Dockerfile
(例如,在 GitHub 上发布)或主线映像(debian
在上面的例子中)改变。
无论您是如何获得支持 32 位的图像(使用现有的 non-official 图像或构建您自己的图像),您都可以使用 [=20] 将其存储到 tar 存档=] 命令,然后使用 docker load
命令导入。