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 obtuve el siguiente error:
standard_init_linux.go:207: exec user process caused "no such file or directory"Según tengo entendido, probablemente tenga algo que ver con las dependencias no satisfechas, pero aún no entiendo por qué necesito todo el sistema de archivos del espacio de usuario que viene con las imágenes base solo para ejecutar un ejecutable binario. ¿No se supone que se ejecutan de forma nativa? ¿Cuál es la diferencia entre el binario que puede ejecutarse de forma independiente y uno que no?
Además, me interesa saber qué es ese archivo standard_init_linux.go . ¿El kernel de Linux contiene código go?
Encontré algunos recursos sobre imágenes base (a continuación), pero aún no brindan una respuesta directa a mi pregunta.
Recursos
El binario tiene dependencias de biblioteca compartidas. 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. Esto es lo que parece 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) Montar /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)Bibliotecas compartidas .
Los ejecutables que no están enlazados estáticamente necesitan un enlazador, un cargador y bibliotecas compartidas (como la biblioteca C estándar) con las que enlazar. Eso lo proporciona la imagen de su sistema operativo.
Java/JVM es realmente otro programa ejecutable como 'apache' o 'top'. como todos los programas, necesita un host de sistema operativo para administrar el hardware y proporcionar interfaces estandarizadas. El código binario de Java se compila contra sistemas operativos y kernels 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 del host, pero aún debe requerir una imagen del sistema operativo base sobre el kernel.