Docker - /bin/sh: <file> not found - 错误的 ELF 解释器 - 如何将 32 位 lib 支持添加到 docker 映像

Posted

技术标签:

【中文标题】Docker - /bin/sh: <file> not found - 错误的 ELF 解释器 - 如何将 32 位 lib 支持添加到 docker 映像【英文标题】:Docker - /bin/sh: <file> not found - bad ELF interpreter - how to add 32bit lib support to a docker image 【发布时间】:2016-04-19 01:08:22 【问题描述】:

UPDATE - 旧问题标题:Docker - 如何在 docker build 期间执行解压缩/解压缩/提取的二进制文件(将文件添加到 docker build context)

--

我一直在尝试(半天:P)执行在 docker build 期间提取的二进制文件。

我的 dockerfile 大致包含:

...
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(在 dockerfile 中,在构建期间)显示了正确的文件:

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 更改为 bloatishubuntu:14.04,所以我可以尝试使用 sudo :D

猜猜结果如何?

sudo: unable to execute /tmp/setup/a/b/imcl: No such file or directory

我偶然在谷歌上搜索到了piece of Docker docs,我相信这是所有这些头疼的原因: "注意:如果文件或目录在上传的上下文中不存在,docker build 将返回 no such file or directory 错误。如果没有上下文,或者您指定的文件位于主机系统。出于安全原因,上下文仅限于当前目录(及其子目录),并确保在远程 Docker 主机上可重复构建。这也是 ADD ../file 不起作用的原因。”

所以我的问题是:

有解决办法吗? 有没有办法在构建期间(在 dockerfile 中)将提取的文件添加到 docker 构建上下文?

哦,我正在建造的机器没有连接到互联网......

我想我的问题与此类似(尽管我没有看到答案):How to include files outside of Docker's build context?

所以我运气不好?

在将构建上下文发送到 Docker 守护程序之前,我是否需要使用 shell 脚本解压缩,以便所有文件都完全按照构建命令期间的方式使用?

更新: 嗯,构建上下文实际上不是问题。我对此进行了测试,并且能够在 docker build 期间执行解压缩的二进制文件。

我的问题实际上是这个: 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

但是,我不... :[

所以问题变成了现在:

在没有 repos 或 Internet 连接的情况下获得相同结果的最佳方法是什么?

根据IBM,我需要的精确库是 gtk2.i686 和 libXtst.i686,可能还有 libstdc++

[root@localhost]# yum install gtk2.i686
[root@localhost]# yum install libXtst.i686
[root@localhost]# yum install compat-libstdc++

【问题讨论】:

On Debian/Ubuntu 18.04: sudo dpkg --add-architecture i386 &amp;&amp; sudo apt update &amp;&amp; sudo apt install libc6:i386 【参考方案1】:

更新:

那么问题就变成了:

在没有 repos 或 Internet 连接的情况下获得相同结果的最佳方法是什么?

您可以使用DockerHub上提供的各种非官方32位镜像,搜索debian32ubuntu32fedora32等。

如果你不能信任他们,你可以自己构建这样的镜像,你也可以在 DockerHub 上找到说明,例如:

f69m/ubuntu32首页,有一个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 位的映像(使用现有的非官方映像或自己构建的),您都可以使用 docker save 命令将其存储到 tar 存档,然后使用 docker load 导入命令。

【讨论】:

在在线机器上的 64 位基础映像上构建自己的映像,并在 64 位基础映像上添加 32 位库,并使用 docker save + docker load 将映像传输到离线机器,现在我为什么不认为我自己...看到这是我在传输普通基础图像时使用的确切方法:D 管理构建映像并在容器内安装 32 位软件,并添加了 32 位库的自定义基础映像。但是,我在构建后尝试运行容器时遇到了问题。似乎是 32 位库在尝试执行 64 位脚本时导致了问题,例如:无法启动容器 XXX:[8] 系统错误:exec:“/IBM/WebSphere8/AppServer/profiles/std/bin/startServer.sh ...” : stat 没有这样的文件或目录。 ...话虽如此,我强烈建议与系统相比,获得匹配的 32/64 位安装可执行文件/二进制文件。【参考方案2】:

你很幸运!您可以使用ADD 命令执行此操作。 The docs说:

如果&lt;src&gt; 是可识别压缩格式的本地 tar 存档 (identity, gzip, bzip2 or xz) 然后它被解压为一个目录...当一个目录是 复制或解包,它的行为与tar -x 相同:结果是 联合:

    目标路径中存在的任何内容和 的内容 源树,解决了有利于“2”的冲突。在一个 逐个文件。

【讨论】:

我自己也遇到过这种情况...太糟糕了,我的格式是 .zip :P 我想我需要在初始构建上下文中解压缩并中继解压缩文件。 对不起,这毕竟不是真正的答案,我已经更新了这个问题。此外,在 Docker 构建期间,解压缩文件的二进制执行似乎很有可能。 很高兴知道。我会保留这个答案,因为它包含有用的上下文

以上是关于Docker - /bin/sh: <file> not found - 错误的 ELF 解释器 - 如何将 32 位 lib 支持添加到 docker 映像的主要内容,如果未能解决你的问题,请参考以下文章

docker alpine /bin/sh script.sh 未找到

Docker - /bin/sh: nodemon: 未找到

Docker 镜像错误:“/bin/sh: 1: [python,: not found”

Docker Alpine /bin/sh apk 未找到

docker进入式 执行sh

Docker / bin / sh:1 ::找不到miniconda3