我正在尝试用我的二进制文件(用Rust编写)创建一个图像,但是我得到了不同的错误。这是我的Dockerfile
:
FROM scratch
COPY binary /
COPY .env /
COPY cert.pem /etc/ssl/
ENV RUST_BACKTRACE 1
CMD /binary
建筑物完好无损,但是当我尝试运行时,我得到了这个:
$ docker run binary
docker: Error response from daemon: OCI runtime create failed: container_linux.go:348: starting container process caused "exec: \"/bin/sh\": stat /bin/sh: no such file or directory": unknown.
ERRO[0000] error waiting for container: context canceled
而且:
$ docker run binary /binary
standard_init_linux.go:195: exec user process caused "no such file or directory"
我不知道该怎么做。错误消息对我来说很奇怪。根据{{3}}它必须有效。
系统信息:最新的Arch Linux和Docker:
Docker version 18.02.0-ce, build fc4de447b5
我使用C ++程序进行了测试,它的工作正常,包括clang和gcc。
它不适用于基于scratch
,alpine
,busybox
或bash
的图片,但它适用于postgresql
,{{1 }和ubuntu
图片。确切的问题是Rust和轻量级docker图像有关 - 否则一切正常。
答案 0 :(得分:10)
正如@Oleg Sklyar指出的那样,问题是Rust二进制文件是动态链接的。
这可能有点令人困惑,因为许多听说过Rust的人也听说过Rust二进制文件是静态链接的,但这是指板条箱中的Rust代码:crate是静态链接的,因为它们目前都是已知的编译这并不是指程序可能链接到的现有C动态库,例如libc和其他必备库。通常,这些库也可以构建为静态链接的工件(请参阅本文末尾)。要检查您的程序或库是否动态链接,您可以使用ldd
实用程序:
$ ldd target/release/t
linux-vdso.so.1 (0x00007ffe43797000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fa78482d000)
librt.so.1 => /usr/lib/librt.so.1 (0x00007fa784625000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fa784407000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fa7841f0000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fa783e39000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fa784ca2000)
您的Docker镜像中需要这些库。你还需要翻译;要获得其路径,您可以使用objdump
实用程序:
$ LANG=en objdump -s -j .interp target/release/t
target/release/t: file format elf64-x86-64
Contents of section .interp:
0270 2f6c6962 36342f6c 642d6c69 6e75782d /lib64/ld-linux-
0280 7838362d 36342e73 6f2e3200 x86-64.so.2.
将文件复制到预期的目录中,一切正常。
还有第二个选项是使用rust-musl-builder
泊坞窗图像。 postgresql
和diesel
存在一些问题,但对于大多数项目而言,它会很好。它的工作原理是生成一个静态链接的可执行文件,您可以复制和使用它。如果您希望提供较小的docker镜像并且没有所有无用的额外数据(如解释器,未使用的库等),则此选项比使用解释器和动态库更受欢迎。
答案 1 :(得分:0)
就我而言,问题是我传递了一个无效的可执行文件名:
CMD ["liquidator"]
liquidator
是 Docker 镜像的名称,但我需要这个:
CMD ["hifi-liquidator"]
基本上 CMD 必须与 Cargo.toml
文件中的“名称”字段相同。