docker - 为什么可以在 Docker 映像中手动运行 Java 程序,但不能作为 ENTRYPOINT
问题描述
我创建了一个 openjdk-11 alpine docker 映像并将我的 jar 复制到其中。我的 Dockerfile 是这样的:
FROM pwittchen/alpine-java11
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} /opt/app.jar
ENTRYPOINT ["java", "-jar", "/opt/app.jar"]
如果我运行:
docker run -it image
然后
Error loading shared library libjli.so: No such file or directory (needed by /usr/local/share/jdk-11/bin/java)
Error relocating /usr/local/share/jdk-11/bin/java: JLI_Launch: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_PreprocessArg: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_ReportMessage: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_StringDup: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_MemFree: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_InitArgProcessing: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_AddArgsFromEnvVar: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_List_add: symbol not found
Error relocating /usr/local/share/jdk-11/bin/java: JLI_List_new: symbol not found
但如果:
docker run -it --entrypoint /bin/sh image
然后我可以直接在shell中执行:
$ java -jar /opt/app.jar
并且有效。
为什么以 ENTRYPOINT 运行会使 libjli.so 库隐藏并尝试重新定位 JLI*?
解决方案
问题出在肌肉上。当您直接从 shell 执行时,musl 能够读取库路径,但是当您使用 CMD 和/或 ENTRYPOINT 执行时,musl 无法解析库路径。
在阅读和 openjdk8-alpine 中已经解决的旧问题后,我能够找到这个。那么这是一个回归。
https://github.com/docker-library/openjdk/issues/77
要解决,首先创建一个文件ld-musl-x86_64.pat指定 musl 所需的库在哪里。文件内容如下所示:
/lib
/usr/lib
/usr/local/lib
/usr/local/share/jdk-11/lib/jli
在构建阶段将文件复制到 docker 映像。我的新 Dockerfile 如下所示:
FROM pwittchen/alpine-java11
VOLUME /tmp
ARG JAR_FILE
#Copy the configuration file with the Library path!
COPY ld-musl-x86_64.path /etc/ld-musl-x86_64.pat
COPY ${JAR_FILE} /opt/app.jar
ENTRYPOINT ["java", "-jar", "/opt/app.jar"]
终于工作了。
推荐阅读
- javascript - 使用钩子的 react-sortable-tree Crud 操作
- java - java 8 日期/时间 API:使用通用日期/时间格式解析以提取自纪元以来的毫秒数
- php - PHP7 +中的任何方式通过方括号将对象视为数组?
- jenkins - 从詹金斯发送黄瓜关于松弛的报告
- python - 无法启动 ipython 内核 Python 3.8.5
- r - 如果返回错误,如何在 R 中的循环中跳过一个项目?
- javascript - 返回函数的函数,即在其中声明的函数
- javascript - 如何在反应中注入javascript变量?
- mediawiki - 如何在 EnsiWiki 上以优雅的方式解析参考书目
- docker - 将假的 nvidia 运行时添加到 docker 运行时