星空

人生不仅有眼前的苟且,还有诗和远方.

0%

docker制作jdk镜像

由于相关需求,现有的docker制作的jdk镜像是Java8早期版本的镜像,在安全性上存在较大的问题,所以计划对docker依赖的系统以及jdk进行升级操作。这其中遇到了一些问题,不过都顺利的圆满解决了,下面来具体聊一聊细节把

docker制作JDK镜像选型

为了减小容器的体积,所以考虑使用alpine的镜像,这次选择alpine没有做版本相关的限制,考虑最新版本的镜像在安全性上会有一个较大的提升,目前经过阿里云的安全扫描,相关漏洞的个数为0;

JDK选择的也是JDK8的最新长期支持版,JDK8相对来说目前使用比较广泛,而且稳定性较高。

docker制作JDK第一版的过程

由于alpine镜像作为极小型的Linux容器,它的运行环境是没法直接运行JDK的,所以需要新增一些依赖来进行相关兼容,在此过程中安装了glibc-2.31-r0.apk,该包在Github上下载的,由于服务器带宽较低,所以下载速度奇慢,所以自己将对应的包下载下来,放到了腾讯云的COS上供自己下载使用。

下面是第一版Dockerfile的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FROM alpine:latest

MAINTAINER dislazy2019@outlook.com

RUN echo http://mirrors.aliyun.com/alpine/v3.7/main > /etc/apk/repositories && \
echo http://mirrors.aliyun.com/alpine/v3.7/community >> /etc/apk/repositories

RUN apk update && apk upgrade

RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://imagecdn.bosong.online/sgerrand.rsa.pub && \
wget https://imagecdn.bosong.online/glibc-2.31-r0.apk && \
apk add glibc-bin-2.31-r0.apk


ADD jdk1.8.0_231 /usr/local
ENV JAVA_HOME=/usr/local/jdk1.8.0_231
ENV CLASSPATH=$JAVA_HOME/bin
ENV JRE_HOME=/usr/local/jdk1.8.0_231/jre
ENV PATH=$JAVA_HOME/bin:$PATH
CMD ["java","-version"]

在上面的镜像中,只安装了运行JDK所需要的相关包以及将JDK放到了容器文件中,其实在此之前有一步是需要对JDK进行内容的删减,删减一些多余的JAR包和介绍文件,来达到减少容器体积的目的。

时区问题

JDK镜像制作成功后,很顺利的推到了阿里云的镜像仓库中,并且迅速进行服务的打包部署,一切都进行的很顺利,服务也正常运行并启动。

后来在查看日志的过程中,发现服务运行日志的时差达到了8个小时,马上想到了没设置正确的时区,导致Java运行获取的当地时间不正确,这问题在生产中是致命的,然后迅速进行第二次镜像升级改造,本次主要正确设置了时区,使Java进行按照本地时间运行。

下面是第二版Dockerfile的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FROM alpine:latest

MAINTAINER dislazy2019@outlook.com

RUN echo http://mirrors.aliyun.com/alpine/v3.7/main > /etc/apk/repositories && \
echo http://mirrors.aliyun.com/alpine/v3.7/community >> /etc/apk/repositories

RUN apk update && apk upgrade && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone

RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://imagecdn.bosong.online/sgerrand.rsa.pub && \
wget https://imagecdn.bosong.online/glibc-2.31-r0.apk && \
apk add glibc-bin-2.31-r0.apk


ADD jdk1.8.0_231 /usr/local
ENV JAVA_HOME=/usr/local/jdk1.8.0_231
ENV CLASSPATH=$JAVA_HOME/bin
ENV JRE_HOME=/usr/local/jdk1.8.0_231/jre
ENV PATH=$JAVA_HOME/bin:$PATH
CMD ["java","-version"]

上面的镜像设置了时区文件,顺利解决了时区的问题。

编码问题

作为一个程序员,对乱码这个一定会异常的敏感,在大学计算机的课堂上,对于这个问题始终会强调,编码问题是数据可读性的重要保障,一个不慎,可能全盘皆输。

问题的发现比较偶然,因为我平常在工作中养成的工作习惯是日志基本使用英文,能不使用中文尽量不使用,所以一直没发现中文编码存在问题,后来因为接入了美团Cat,想试试告警效果,然后发现相关告警发送到企业微信的时候发现是乱码,此时才想到没有对乱码问题进行及时设置,此时有了第三版本的JDK镜像。

下面是第三版本的Dokcerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
FROM alpine:latest

MAINTAINER dislazy2019@outlook.com

RUN echo http://mirrors.aliyun.com/alpine/v3.7/main > /etc/apk/repositories && \
echo http://mirrors.aliyun.com/alpine/v3.7/community >> /etc/apk/repositories

RUN apk update && apk upgrade && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone

RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://imagecdn.bosong.online/sgerrand.rsa.pub && \
wget https://imagecdn.bosong.online/glibc-2.31-r0.apk && \
wget https://imagecdn.bosong.online/glibc-bin-2.31-r0.apk && \
wget https://imagecdn.bosong.online/glibc-i18n-2.31-r0.apk && \
apk add glibc-bin-2.31-r0.apk glibc-i18n-2.31-r0.apk glibc-2.31-r0.apk
#复制本地编辑的locale.md
COPY ./locale.md /locale.md
#此时设置utfu编码
RUN cat locale.md | xargs -i /usr/glibc-compat/bin/localedef -i {} -f UTF-8 {}.UTF-8

ADD jdk1.8.0_231 /usr/local
ENV JAVA_HOME=/usr/local/jdk1.8.0_231
ENV CLASSPATH=$JAVA_HOME/bin
ENV JRE_HOME=/usr/local/jdk1.8.0_231/jre
ENV PATH=$JAVA_HOME/bin:$PATH
ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US.UTF-8
CMD ["java","-version"]

为了加快镜像的构建速度,所以把必要的jar包都放到了腾讯云的COS上,以便于快速下载以及备份。

其中locale.md文件内容如下,有些不必要用到的我都给移除掉了,能大大节省镜像的构建速度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
el_CY
el_GR
en_AG
en_AU
en_BW
en_CA
en_DK
en_GB
en_HK
en_IE
en_IN
en_NG
en_NZ
en_PH
en_SG
en_US
en_ZA
en_ZM
en_ZW
es_AR
es_BO
es_CL
es_CO
es_CR
es_CU
es_DO
es_EC
es_ES
es_GT
es_HN
es_MX
es_NI
es_PA
es_PE
es_PR
es_PY
es_SV
es_US
es_UY
es_VE
et_EE
eu_ES
zh_CN
zh_HK
zh_SG
zh_TW
zu_ZA

该问题比较经典,在github上也有解决方案,主要原因就是alpine镜像本身原因没有对一些需要的特性需要支持,顺利解决了时区问题以及乱码问题,服务目前平稳运行,可以大大松口气。

结束语

以前用别人制作好的JDK镜像,发现很香,很多问题都不需要去考虑,直接拿来就用。

在自己制作并投入使用的时候会出现很多状况,所以我们制作镜像前后最好先了解一下有哪些坑,提前发现并且避免掉,这样才能减少错误,快速做好镜像。