pho*_*360 16 java aspose aspose.words docker kubernetes
我们有一个 Java 应用程序,它使用 3rd 方(Asposee,但我认为这并不重要)生成 word 文档。该应用程序是从一个简单的 Docker 文件构建的:
FROM openjdk:10-jdk-slim
COPY target/*.jar /opt/
CMD $JAVA_HOME/bin/java $JAVA_OPTS -jar /opt/*.jar
Run Code Online (Sandbox Code Playgroud)
当我们在本地构建应用程序(mvn package
然后docker build
)并在其中运行应用程序k8s
时效果很好。
但是,当我们使用 Jenkins 在 CI/CD 管道中构建映像时,在运行显然需要额外字体的特定进程时,我们会遇到运行时异常:
Caused by: java.lang.NullPointerException: null
at java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1288)
at java.desktop/sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:225)
at java.desktop/sun.awt.FontConfiguration.init(FontConfiguration.java:107)
at java.desktop/sun.awt.X11FontManager.createFontConfiguration(X11FontManager.java:765)
at java.desktop/sun.font.SunFontManager$2.run(SunFontManager.java:440)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.desktop/sun.font.SunFontManager.<init>(SunFontManager.java:385)
at java.desktop/sun.awt.FcFontManager.<init>(FcFontManager.java:35)
at java.desktop/sun.awt.X11FontManager.<init>(X11FontManager.java:56)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,项目是在 Jenkins 中构建的,由 docker image 编译maven:3.5.4-jdk-10-slim
。
我已经检查了两个 jar 文件(本地和来自 jenkins)并且类文件是相同的(如预期的那样)。
在这两种情况下,它是相同的基本图像,所以我不明白有什么区别。在本地构建与在另一个 Docker 容器中构建时 Docker 中的内容有什么不同吗?
编辑
我们查看了两个 docker 镜像,发现了以下差异。
由于本地构建的图像ls -l /usr/lib
返回:
drwxr-xr-x 2 root root 4096 May 3 2017 X11
drwxr-xr-x 5 root root 4096 Apr 26 00:00 apt
drwxr-xr-x 2 root root 4096 May 26 08:31 binfmt.d
drwxr-xr-x 2 root root 4096 Jun 6 01:50 cgmanager
drwxr-xr-x 2 root root 4096 Jun 6 01:50 dbus-1.0
drwxr-xr-x 2 root root 4096 Jun 6 01:51 dconf
drwxr-xr-x 3 root root 4096 Jun 6 01:51 debug
drwxr-xr-x 3 root root 4096 Apr 20 10:08 dpkg
drwxr-xr-x 2 root root 4096 Jun 6 01:50 environment.d
drwxr-xr-x 3 root root 4096 Apr 25 04:56 gcc
drwxr-xr-x 2 root root 4096 Jun 6 01:51 glib-networking
drwxr-xr-x 2 root root 4096 Apr 26 00:00 init
drwxr-xr-x 1 root root 4096 Jun 6 01:51 jvm
drwxr-xr-x 3 root root 4096 Jun 6 01:50 kernel
lrwxrwxrwx 1 root root 20 Mar 4 09:49 libnih-dbus.so.1 -> libnih-dbus.so.1.0.0
-rw-r--r-- 1 root root 34824 Mar 4 09:49 libnih-dbus.so.1.0.0
lrwxrwxrwx 1 root root 15 Mar 4 09:49 libnih.so.1 -> libnih.so.1.0.0
-rw-r--r-- 1 root root 92184 Mar 4 09:49 libnih.so.1.0.0
drwxr-xr-x 3 root root 4096 Mar 29 19:47 locale
drwxr-xr-x 3 root root 4096 Jun 6 01:50 lsb
drwxr-xr-x 1 root root 4096 Jul 21 2017 mime
drwxr-xr-x 2 root root 4096 Jun 6 01:50 modprobe.d
drwxr-xr-x 2 root root 4096 May 26 08:31 modules-load.d
-rw-r--r-- 1 root root 198 Jan 13 23:36 os-release
drwxr-xr-x 3 root root 4096 Jun 6 01:51 ssl
drwxr-xr-x 1 root root 4096 Jun 6 01:50 systemd
drwxr-xr-x 2 root root 4096 Jun 6 01:50 sysusers.d
drwxr-xr-x 2 root root 4096 Jul 21 2017 tar
drwxr-xr-x 15 root root 4096 Feb 11 20:06 terminfo
drwxr-xr-x 1 root root 4096 Jun 6 01:50 tmpfiles.d
drwxr-xr-x 1 root root 4096 Apr 26 00:00 udev
drwxr-xr-x 1 root root 16384 Jun 6 01:51 x86_64-linux-gnu
Run Code Online (Sandbox Code Playgroud)
但在 Jenkins 内部构建的图像ls -l /usr/lib
返回:
drwxr-xr-x 5 root root 4096 Jun 25 00:00 apt
drwxr-xr-x 3 root root 4096 Jul 3 01:00 debug
drwxr-xr-x 3 root root 4096 Apr 20 10:08 dpkg
drwxr-xr-x 3 root root 4096 Jun 17 03:36 gcc
drwxr-xr-x 2 root root 4096 Jun 25 00:00 init
drwxr-xr-x 1 root root 4096 Jul 3 01:00 jvm
drwxr-xr-x 1 root root 4096 Jul 12 11:00 locale
drwxr-xr-x 3 root root 4096 Jul 3 01:00 lsb
drwxr-xr-x 1 root root 4096 May 16 07:47 mime
-rw-r--r-- 1 root root 198 Jan 13 23:36 os-release
drwxr-xr-x 3 root root 4096 Jul 3 01:00 ssl
drwxr-xr-x 3 root root 4096 Apr 20 10:08 systemd
drwxr-xr-x 2 root root 4096 May 16 07:47 tar
drwxr-xr-x 15 root root 4096 May 21 08:54 terminfo
drwxr-xr-x 2 root root 4096 Jun 25 00:00 tmpfiles.d
drwxr-xr-x 3 root root 4096 Jun 25 00:00 udev
drwxr-xr-x 2 root root 4096 May 3 2017 X11
drwxr-xr-x 1 root root 4096 Jul 3 01:00 x86_64-linux-gnu
Run Code Online (Sandbox Code Playgroud)
这真的很令人费解,因为我认为 Docker 总是会从相同的 Dockerfile 生成相同的图像
Jua*_*cio 14
使用 openjdk:8u111-jdk-alpine,安装 dejavu 解决问题:
例如:
Dockerfile:
FROM openjdk:8u111-jdk-alpine
# Needed to fix 'Fontconfig warning: ignoring C.UTF-8: not a valid language tag'
ENV LANG en_GB.UTF-8
# JRE fails to load fonts if there are no standard fonts in the image; DejaVu is a good choice,
# see https://github.com/docker-library/openjdk/issues/73#issuecomment-207816707
RUN apk add --update ttf-dejavu && rm -rf /var/cache/apk/*
VOLUME /tmp
COPY /target/*.jar app.jar
ENTRYPOINT ["java","-Xmx100m","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Run Code Online (Sandbox Code Playgroud)
只需在 Dockerfile 中添加以下内容即可
RUN apk add --no-cache fontconfig ttf-dejavu
Run Code Online (Sandbox Code Playgroud)
小智 5
安装libfontconfig1
为我解决了这个问题(来源):
RUN apt-get install -y libfontconfig1 && rm -rf /var/lib/apt/lists/*
Run Code Online (Sandbox Code Playgroud)
我想我们发现了问题。
在 Jenkins 上运行时,我们使用(Docker inside docker)Docker 映像在构建中docker:dind
提供命令。docker
该镜像基于Alpine
linux。运行时docker info
我们得到以下信息:
在苹果机上:
Kernel Version: 4.9.87-linuxkit-aufs
Operating System: Docker for Mac
Run Code Online (Sandbox Code Playgroud)
关于詹金斯:
Kernel Version: 4.4.115-k8s
Operating System: Alpine Linux v3.7 (containerized)
Run Code Online (Sandbox Code Playgroud)
Alpine
linux 肯定缺少这些字体。我们通过手动将它们安装在以下位置解决了问题Dockerfile
:
RUN apt-get update \
&& apt-get install --assume-yes apt-utils \
&& apt-get install --assume-yes software-properties-common \
&& apt-get install --assume-yes dbus \
&& apt-get install --assume-yes cgmanager \
&& apt-get install --assume-yes glib-networking \
&& apt-get install --assume-yes libnih-dbus-dev \
&& apt-get install --assume-yes dconf-cli \
&& apt-get install --assume-yes fontconfig
Run Code Online (Sandbox Code Playgroud)
不确定这是最低要求的库,但这些库成功了:D
归档时间: |
|
查看次数: |
11669 次 |
最近记录: |