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 && sudo apt update && sudo apt install libc6:i386
【参考方案1】:
更新:
那么问题就变成了:
在没有 repos 或 Internet 连接的情况下获得相同结果的最佳方法是什么?
您可以使用DockerHub上提供的各种非官方32位镜像,搜索debian32
、ubuntu32
、fedora32
等。
如果你不能信任他们,你可以自己构建这样的镜像,你也可以在 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你很幸运!您可以使用ADD
命令执行此操作。 The docs说:
如果
<src>
是可识别压缩格式的本地 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: 未找到