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
- Docker: imagen base
- Contenedores de arquitectura Parte 1: Por qué es importante entender el espacio del usuario frente al espacio del núcleo
- ¿Cuál es la relación entre el sistema operativo host del acoplador y el sistema operativo de imagen base del contenedor?
3 respuestas
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)
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.
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.
Preguntas relacionadas
Nuevas preguntas
linux
Las preguntas de Linux deben estar relacionadas con la programación. Use esta etiqueta solo si su pregunta se relaciona con la programación utilizando API de Linux o un comportamiento específico de Linux, no solo porque ejecuta su código en Linux. Si necesita soporte para Linux, puede probar https://unix.stackexchange.com o el sitio específico de Stack Exchange de la distribución de Linux como https://askubuntu.com o https://elementaryos.stackexchange.com/