首页 > 解决方案 > 为什么 java 需要基础镜像才能在 docker 上运行

问题描述

我试图理解为什么我不能在没有基本操作系统映像的情况下在 docker 容器中运行 java。
我尝试了下一个基本的 dockerfile:

FROM scratch

ADD openjdk-11.0.2_linux-x64_bin.tar.gz /java

CMD ["/java/jdk-11.0.2/bin/java", "-version" ]

并得到以下错误:

standard_init_linux.go:207: exec user process caused "no such file or directory"

据我了解,这可能与未满足的依赖关系有关,但我仍然不明白为什么我需要基础映像附带的所有用户空间文件系统来运行二进制可执行文件。他们不应该在本地运行吗?能够独立运行的二进制文件和不能独立运行的二进制文件有什么区别?

另外我很想知道那个文件是什么standard_init_linux.go?linux内核是否包含go代码?

我找到了一些关于基本图像的资源(如下),但它们仍然没有为我的问题提供直接答案。

资源

标签: linuxdocker

解决方案


该二进制文件具有共享库依赖项。如果这些依赖项不在系统中,它将不会运行。

正如您所说,很难直接检查映像,但您可以查看主机系统上的可执行文件。这是我的样子:

$ ldd java/jdk-11.0.2/bin/java
    linux-vdso.so.1 (0x00007ffc16fac000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fd839c97000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd839a78000)
    libjli.so => /home/jkugelman/from-scratch-java/java/jdk-11.0.2/bin/../lib/jli/libjli.so (0x00007fd839867000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd839663000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd839272000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fd839eb4000)

安装/lib/lib64让它运行:

$ docker run --rm -it -v /lib:/lib -v /lib64:/lib64 from-scratch-java
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

推荐阅读