Estoy tratando de entender por qué no puedo ejecutar Java dentro del contenedor Docker sin tener una imagen base del sistema operativo.
Probé el siguiente dockerfile básico:

FROM scratch

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

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

Y obtuvo el siguiente error:

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

Según tengo entendido, eso probablemente tenga algo que ver con dependencias insatisfechas, pero aún no entiendo por qué necesito todo el sistema de archivos de espacio de usuario que viene con imágenes base solo para ejecutar un ejecutable binario. ¿No se supone que deben correr de forma nativa? ¿Cuál es la diferencia entre el binario que puede ejecutarse de forma independiente y uno que no lo hace?

Además, me interesa saber qué es ese archivo standard_init_linux.go. Qué contiene el kernel de Linux?

He encontrado algunos recursos sobre imágenes base (a continuación), pero aún no proporcionan una respuesta directa a mi pregunta.

Recursos

3
matanper 10 may. 2019 a las 21:55

3 respuestas

La mejor respuesta

El binario ha compartido dependencias de la biblioteca. Si esas dependencias no están en el sistema, no se ejecutará.

Como dijiste, es difícil inspeccionar la imagen directamente, pero puedes echar un vistazo al ejecutable en tu sistema host. Así es como se ve en el mío:

$ 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)

El montaje /lib y /lib64 hace que se ejecute:

$ 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)
4
John Kugelman 10 may. 2019 a las 19:27

Bibliotecas compartidas .

Los ejecutables que no están vinculados estáticamente necesitan un vinculador, un cargador y bibliotecas compartidas (como la biblioteca C estándar) con los que se vinculan. Eso es proporcionado por su imagen del sistema operativo.

1
Charles Duffy 10 may. 2019 a las 19:17

Java / JVM es realmente solo otro programa ejecutable como 'apache' o 'top'. Al igual que todos los programas, necesita un host del sistema operativo para administrar el hardware y proporcionar interfaces estandarizadas. El código binario de Java se compila contra sistemas operativos y núcleos específicos.

Más fundamentalmente, tengo curiosidad por saber si el contenedor Docker se ejecutaría sin una imagen base del sistema operativo. El contenedor debe usar el Kernel host, pero aún debe requerir una imagen base del sistema operativo en la parte superior del kernel.

-2
David Lightman 10 may. 2019 a las 19:12