由于相关需求,现有的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 21
| 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://cdn.songbo.fun/sgerrand.rsa.pub && \ wget https://cdn.songbo.fun/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://cdn.songbo.fun/sgerrand.rsa.pub && \ wget https://cdn.songbo.fun/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://cdn.songbo.fun/sgerrand.rsa.pub && \ wget https://cdn.songbo.fun/glibc-2.31-r0.apk && \ wget https://cdn.songbo.fun/glibc-bin-2.31-r0.apk && \ wget https://cdn.songbo.fun/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镜像,发现很香,很多问题都不需要去考虑,直接拿来就用。
在自己制作并投入使用的时候会出现很多状况,所以我们制作镜像前后最好先了解一下有哪些坑,提前发现并且避免掉,这样才能减少错误,快速做好镜像。