我正在尝试在嵌入式世界中玩和学习docker的用法。 我正在使用busybox docker映像作为开始,并且尝试将C ++程序二进制文件复制到docker容器上。但是,我看到我无法在忙碌框中执行二进制文件。 我不确定我想念的是什么。繁忙的码头工人使用情况是这样吗?
这是我到目前为止尝试过的-
Dockerfile
FROM busybox:1.30
COPY ./test4.out /home/
CMD /home/test4.out
现在,这是我的c ++代码。
#include <iostream>
using namespace std;
int main()
{
return 120;
}
我已经在主机中编译了此代码-
#gcc test4.cpp -o test4.out
构建我的Docker
docker build -t abc/busybox-smarter:1.0 .
docker build -t abc/busybox-smarter:1.0 .
Sending build context to Docker daemon 12.29kB
Step 1/3 : FROM busybox:1.30
---> af2f74c517aa
Step 2/3 : COPY ./test4.out /home/
---> Using cache
---> 1d6fe02933c1
Step 3/3 : CMD /home/test4.out
---> Using cache
---> dd590ef4059d
Successfully built dd590ef4059d
Successfully tagged abc/busybox-smarter:1.0
现在,我正在运行此图像。
docker run --rm -ti abc/busybox-smarter:1.0 /bin/sh
/home # ./test4.out
/bin/sh: ./test4.out: not found
答案 0 :(得分:1)
busybox
映像包含少量静态编译的二进制文件(其中大多数实际上只是与busybox
的硬链接)。另一方面,您的gcc
命令的输出是动态链接的可执行文件:
$ g++ -o test4.out test4.cpp
$ file test4.out
test4.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=9c3a99f3baa5f699f4e32fa65acc58ac8ddc099c, not stripped
要执行,它需要适当的动态加载程序(通常为/lib64/ld-linux-x86-64.so.2
之类的东西)。
在busybox图片中不存在此错误,这会导致“未找到”错误。
除了动态加载程序之外,您的代码还具有一些其他共享库依赖项:
$ ldd prog
linux-vdso.so.1 (0x00007fff01dbb000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f566279e000)
libm.so.6 => /lib64/libm.so.6 (0x00007f566240a000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f56621f2000)
libc.so.6 => /lib64/libc.so.6 (0x00007f5661e34000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5662b30000)
您需要使所有这些共享库在映像中可用,以便您的代码运行。
您可以尝试静态编译代码。首先,您需要安排系统上所有必需库的静态版本。在我的Fedora 28环境中,这意味着我首先必须运行:
yum -y install libstdc++-static glibc-static
然后我能够生成二进制的静态版本:
$ g++ --static -o test4.out test4.cpp
$ file test4.out
test4.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=d0f3b446020e1b067ededb59ec491bff9634f550, not stripped
我可以毫无问题地在busybox
容器中运行此映像。
警告!,即使使用--static
进行编译,有些功能(通常是那些与主机名解析和用户/组有关的功能)在运行时也需要动态共享库。