关于linux:Docker – / bin / sh:< file>

Docker - /bin/sh: <file> not found - bad ELF interpreter - how to add 32bit lib support to a docker image

更新-旧问题标题:Docker-如何在Docker构建期间执行解压缩/解包/提取的二进制文件(向Docker构建上下文添加文件)

——

我一直在尝试(半天:p)执行在Docker构建期间提取的二进制文件。

我的dockerfile大致包含:

1
2
3
4
5
...
COPY setup /tmp/setup
RUN \
unzip -q /tmp/setup/x/y.zip -d /tmp/setup/a/b
...

在目录b中是一个二进制文件imcl

我得到的错误是:

1
/bin/sh: 1: /tmp/setup/a/b/imcl: not found

令人困惑的是,在尝试执行二进制文件之前,显示目录b(在dockerfile中,在构建过程中)显示了正确的文件:

1
2
3
4
5
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 noob,起初我认为这是一个权限问题(主机的根目录与容器的根目录或其他目录不同),但是在检查之后,两者的uid都是0,所以它变得更加奇怪。

Docker要求不要使用sudo,所以我尝试了su组合:

1
2
su - -c"/tmp/setup/a/b/imcl"
su - root -c"/tmp/setup/a/b/imcl"

这两个都返回了:

1
2
stdin: is not a tty
-su: /tmp/setup/a/b: No such file or directory

好吧,见鬼,我甚至不顾Docker的建议,把我的基本形象从Debian:Jessie改为Bloatish Ubuntu:14.04,这样我就可以尝试sudo:d了。

猜猜结果如何?

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

我偶然在一张Docker文档上搜索,我认为这是所有这些头疼的原因:"注意:如果文件或目录在上传的上下文中不存在,docker build将返回一个no such file or directory错误。如果没有上下文,或者指定了主机系统上其他位置的文件,则可能发生这种情况。出于安全原因,上下文仅限于当前目录(及其子目录),并确保在远程Docker主机上进行可重复的构建。这也是添加../file不起作用的原因。"

所以我的问题是:

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

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

我想我问的是类似的问题(尽管我看不到答案):如何包括Docker构建上下文之外的文件?

那我是不是走运了?

在将构建上下文发送到docker守护进程之前,我是否需要使用shell脚本解压,以使所有文件的使用与构建命令期间的使用完全相同?

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

我的问题其实是这个:Centos 64位坏ELF解释器

使用debian:jessie和ubuntu:14.04作为基础图像只会给No such file or directory错误,但尝试使用centos:7和fedora:23会给出更好的错误信息:

1
/bin/sh: /tmp/setup/a/b/imcl: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

所以我得出结论,这实际上是在64位系统上运行32位应用程序的问题。

现在,如果我启用了Internet访问和Repos,解决方案就简单了:

1
apt-get install ia32-libs

1
yum install glibc.i686

但是,我不…:

所以现在的问题是:

  • 在没有回购或互联网连接的情况下,实现相同结果的最佳方法是什么?

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

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


UPDATE:

So the question becomes now:

  • What would be the best way to achive the same result without repos or internet connection?

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

如果你不能信任他们,你可以自己建立这样一个形象,你也可以在Dockerhub上找到指导,例如:

  • f69m/ubuntu32主页上,有一个指向用于生成图像的github repo的链接;
  • hugodby/fedora32主页上,有一个用于构建图像的命令示例;
  • 等等。

或者,您可以基于一些官方图像准备自己的图像,并向其添加32位软件包。

例如,您可以使用这样的Dockerfile

1
2
3
4
FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y ia32-libs

…并将生成的图像作为基础(使用FROM指令),用于在没有互联网接入的情况下构建的图像。

您甚至可以在DockerHub上创建一个自动构建,当您的Dockerfile或主线图像(上面的示例中的debian发生更改时,它将自动重建您的图像。

无论如何获得32位支持的图像(使用现有的非官方图像或构建自己的图像),您都可以使用docker save命令将其存储到tar存档,然后使用docker load命令导入。


你真走运!您可以使用ADD命令执行此操作。博士说:

If 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.