上次配完trivy之后,扫描java项目发现很多漏洞,具体分析了下,大部分居然是制作docker的基础镜像java:8造成的

于是更新 java8 镜像就提上日程了,上docker hub上看了下,最新版的java 8镜像还是6年前。。

https://hub-stage.docker.com/_/java/tags

 

无奈只能自己制作了,首先看一下当时java 镜像的 dockerfile

#添加debian基础镜像
ADD file:89ecb642d662ee7edbb868340551106d51336c7e589fdaca4111725ec64da957 in /
CMD ["/bin/bash"]
#更新apt源并下载安装必须组件(--no-install-recommends是最小化安装),完成后删除apt缓存
/bin/sh -c apt-get update && apt-get install -y --no-install-recommends ca-certificates curl wget && rm -rf /var/lib/apt/lists/*
/bin/sh -c apt-get update && apt-get install -y --no-install-recommends bzip2 unzip xz-utils && rm -rf /var/lib/apt/lists/*
#新增包含java的apt源 
/bin/sh -c echo 'deb http://deb.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list
#设置utf8编码
ENV LANG=C.UTF-8
#编写java_home检测脚本
/bin/sh -c { echo '#!/bin/sh'; echo 'set -e'; echo; echo 'dirname "$(dirname "$(readlink -f "$(which javac || which java)")")"'; } > /usr/local/bin/docker-java-home && chmod +x /usr/local/bin/docker-java-home
#设置java安装参数
ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre
ENV JAVA_VERSION=8u111
ENV JAVA_DEBIAN_VERSION=8u111-b14-2~bpo8+1
ENV CA_CERTIFICATES_JAVA_VERSION=20140324
#更新apt源,安装java,删除apt源缓存,检查环境java_home和预期是否一致
/bin/sh -c set -x && apt-get update && apt-get install -y openjdk-8-jre-headless="$JAVA_DEBIAN_VERSION" ca-certificates-java="$CA_CERTIFICATES_JAVA_VERSION" && rm -rf /var/lib/apt/lists/* && [ "$JAVA_HOME" = "$(docker-java-home)" ]
#java 证书配置
/bin/sh -c /var/lib/dpkg/info/ca-certificates-java.postinst configure

 

下面是我的搭建过程

1.首先要找个最新版本的debian源

首先当然是看docker hub官方镜像了:https://hub-stage.docker.com/_/debian/tags

最新版居然和java一样是6年前。。

就在无奈时,我看了nginx的镜像:https://hub-stage.docker.com/_/nginx/tags

nginx是有更新的

 点进去一看,基础镜像不就是debian吗,虽然不知道他是哪来的,但是nginx作为官方镜像,有理由相信这也是官方的,至少是经过官方认可的

 ok,基础镜像找到了,那就用它了: debian:12-slim

 

2.调试步骤

有了基础镜像之后,下面就是调试了,运行一个debian容器,然后在里面对照官方脚本一步一步安装,一点一点排除报错,把所有步骤和命令调试完成就ok了

#运行debian镜像
docker run -dit debian:12-slim
#进入debian镜像
docker exec -it 容器名 /bin/bash

 

3.apt源替换

首先就是需要替换debian源,由于dodcker镜像是最小化安装的缘故,后期按需安装工具是必须的,而国外的apt源又很慢,很有必要换成国内的

参考文档:https://mp.weixin.qq.com/s?__biz=MzI4MTg5MjU4Nw==&mid=2247485184&idx=2&sn=99e4f5da26e970b71e197bc4bdda3da8&chksm=eba30484dcd48d92f597fda92ed59d13ed022b8192e8f9a0a1990b5269201cfe2677282e9928&scene=27

sed -i "s@http://deb.debian.org@https://mirrors.163.com@g" /etc/apt/sources.list
或者
sed -i 's/security-cdn.debian.org/mirrors.aliyun.com' /etc/apt/sources.list

如果使用的https源,则需要执行apt install apt-transport-https,再执行apt update更新源索引

经过实测,网易云的速度只有100k出头,阿里云还不错,这里果断用阿里云

另外,我看原来镜像地址就是http,所以还是用的http地址

 

4.java版本的选择和下载途径

 首先就是OpenJDK和JDK区别

1 主要不同

OpenJDK Font Renderer(字体栅格化引擎) 和Oracle JDK Flight Recorder(飞行记录仪) 是Oracle JDK和OpenJDK之间明显的主要区别. —— 存疑, 尚未求证.

OpenJDK使用的是开源免费的FreeType, 可以按照GPL v2许可证使用.

Oracle JDK采用了商业实现, 其中的Flight Recorder和MissionControl都是从JRockit中改造而来的.

JRockit是Oracle的JVM, 从Java SE 7开始, HotSpot和JRockit合并为一个JVM.

2 授权协议的不同

OpenJDK采用GPL V2协议放出, 而Oracle JDK则采用JRL(Java Research License, Java研究授权协议) 放出. 两种者虽然都是开放源代码的, 但在使用上却要注意:

GPL V2允许在商业上使用;

JRL只允许个人研究使用, 要获得Oracle JDK的商业许可证, 需要联系Oracle的销售人员进行购买.

3 OpenJDK不包含Deployment功能

部署的功能包括: Browser Plugin、Java Web Start、Java Mission Control, 这些功能OpenJDK都没有.

4 OpenJDK源码不完整

在采用GPL协议的OpenJDK中, SUN JDK的一部分源码因为产权问题无法提供给OpenJDK使用, 其中最主要的是JMX中的可选元件SNMP部份的代码, 因此这些不能开放的源码将它作成plug, 以供 OpenJDK编译时使用.

 

参考文档:https://www.cnblogs.com/wangzfChina/p/13065902.html

从授权协议这一点,就可以排除JDK了,果断用OpenJDK

其次就是JDK 和JRE 的区别

JDK
Java Development Kit,被称为Java开发包或Java开发工具。大体上可以理解为
JDK = JRE + 某些工具文件。在可以 运行的基础上增加了相对应的工具。

JRE
JAVA Runtime Environment,JRE是支持Java程序运行的标准环境.
参考文档:https://blog.csdn.net/weixin_45837168/article/details/125046377

 

我只是运行程序,那就选JRE就够了

好了现在可以确定要下载 openjdk 的JRE版本

 

然后是下载途径的问题,其实也找了好久,debian版本变了,要找适合新版本的包含java的源还是挺难的

其实有个偷懒的方法就是下载java包到本地,然后通过ADD 从本地添加至镜像,但也许是技术人的倔强,我不甘于此

 直到看到这篇文章:https://blog.csdn.net/u014454538/article/details/130735582

 清华的Open JDK下载镜像  Adoptium 很符合要求~

我这个版本的deb源是bookworm,仔细翻了下,找到这个

https://mirror.tuna.tsinghua.edu.cn/Adoptium/deb/dists/bookworm/main/binary-amd64/

 下载下来看了下,都是他所提供的java包,搜8-jre,找到了最新版,这就是我想要的!

Package: temurin-8-jre
Version: 8.0.382.0.0+5
Architecture: amd64
Maintainer: Eclipse Adoptium Package Maintainers <temurin-dev@eclipse.org>
Installed-Size: 106133
Depends: adoptium-ca-certificates, fonts-dejavu, java-common, libasound2, libc6, libfontconfig1, libfreetype6, libx11-6, libxext6, libxi6, libxrender1, libxtst6, zlib1g
Recommends: fonts-dejavu-core, fonts-dejavu-extra
Provides: java-runtime, java-runtime-headless, java2-runtime, java2-runtime-headless, java5-runtime, java5-runtime-headless, java6-runtime, java6-runtime-headless, java7-runtime, java7-runtime-headless, java8-runtime, java8-runtime-headless
Section: java
Priority: optional
Description: Eclipse Temurin 8 JRE
 Eclipse Temurin JRE is an OpenJDK-based runtime environment to execute
 Java applications and services.
Filename: pool/main/t/temurin-8/temurin-8-jre_8.0.382.0.0+5_amd64.deb
SHA1: 102d36ccd154dabb29b46966a65f4685c08b699c
SHA256: 9da988d25f8ea53fe9730f357735b96e88cd84a521ac9c5ef164d8179512da68
Size: 28927200

 

 

好了,后面是添加源的问题了,本来是手动添加的,但是在apt-get update步骤报错:“the following signatures couldn’t be verified because the public key is not available”

找了个方法:https://codess.cc/archives/413.html

 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010

 有警告:Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).

官方不推荐用这种方法

而且关键参数 recv-keys 哪来呢,也是个问题,我那个key是报错之后抛出来的,总不能docker build的时候获取报错吧,不现实

就在我一筹莫展的时候,找到了这个https://mirror.tuna.tsinghua.edu.cn/help/adoptium/

 

Debian/Ubuntu 用户

首先请安装依赖:

 

apt-get update && apt-get install -y wget apt-transport-https

然后信任 GPG 公钥:

 

wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | tee /etc/apt/keyrings/adoptium.asc

随后执行以下命令来添加 apt 存储库:

 

echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://mirrors.tuna.tsinghua.edu.cn/Adoptium/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list

再执行

 

apt-get update

之后可以使用 apt-get install temurin-<version>-jdk 安装软件包,例如 temurin-17-jdk 和 temurin-8-jdk

 

太贴心了,有木有,清华的学子就是不一样~

记得按需匹配脚本

 

5.研读脚本,基于脚本的改造

rm -rf /var/lib/apt/lists/

这个是删除apt缓存的,我觉得没必要每步都删,会加重下面步骤的下载负担,所以只在最后安装步骤加上了他

 

/bin/sh -c { echo '#!/bin/sh'; echo 'set -e'; echo; echo 'dirname "$(dirname "$(readlink -f "$(which javac || which java)")")"'; } > /usr/local/bin/docker-java-home && chmod +x /usr/local/bin/docker-java-home

这步是做了一个检测本地java_home的脚本,可以下载java:openjdk-8u111-jre镜像,运行并进入,执行echo $(docker-java-home) ,即可看出效果

linux set -e原理可以参考这篇:https://blog.csdn.net/Dontla/article/details/132072054

 

[ "$JAVA_HOME" = "$(docker-java-home)" ]

这一步其实困扰了我好久,docker build执行到这步就报错,找了半天才发现 ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre/  这最后多了一个/,$(docker-java-home) 这个是不带斜杠的,真囧

那这步的作用就不言而喻了,就是检查java_home是否和预期一致

 

6.证书配置

 java8其实对于https的支持并不好,证书配置还是挺重要的

原脚本用的是 /bin/sh -c /var/lib/dpkg/info/ca-certificates-java.postinst configure 和ENV CA_CERTIFICATES_JAVA_VERSION=20140324

我到现在也没参透这步的用意,有大神知道的话麻烦留个言,感谢

我到相同目录下查找没有ca-certificates-java.postinst ,不过找到了

 

 结合那个package  java文档,感觉应该是这个adoptium-ca-certificates

 

 

 

好了最后放上我的脚本,为了让镜像体积尽可能小,很多脚本做了叠加处理,减少层数

FROM debian:12-slim

RUN sed -i "s@http://deb.debian.org@http://mirrors.aliyun.com@g" /etc/apt/sources.list.d/debian.sources && apt-get update && apt-get install -y --no-install-recommends ca-certificates apt-transport-https curl wget bzip2 unzip xz-utils

ENV LANG=C.UTF-8 

ENV JAVA_HOME=/usr/lib/jvm/temurin-8-jre-amd64

ENV JAVA_DEBIAN_VERSION=8.0.382.0.0+5

RUN wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | tee /etc/apt/trusted.gpg.d/adoptium.asc && echo "deb [signed-by=/etc/apt/trusted.gpg.d/adoptium.asc] https://mirrors.tuna.tsinghua.edu.cn/Adoptium/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list && { echo '#!/bin/sh'; echo 'set -e'; echo; echo 'dirname "$(dirname "$(readlink -f "$(which javac || which java)")")"'; } > /usr/local/bin/docker-java-home && chmod +x /usr/local/bin/docker-java-home && set -x && apt-get update && apt-get install -y temurin-8-jre="$JAVA_DEBIAN_VERSION" && rm -rf /var/lib/apt/lists/* && [ "$JAVA_HOME" = "$(docker-java-home)" ] && /var/lib/dpkg/info/adoptium-ca-certificates.postinst configure && mv /etc/localtime /etc/localtime_bak && ln -s  /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai > /etc/timezone

其实RUN本来用的是 /bin/sh -c ,无奈老报错,改用RUN了

 

经过扫描,只有两个高危,漏洞基本符合预期

 

后记:

就在自己制作镜像没多久,我就发现了,大厂都有自己的openjdk。。

阿里:

项目名称:Dragonwell11

阿里开源项目:https://opensource.alibaba.com/project

使用指南:https://github.com/dragonwell-project/dragonwell11/wiki/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Dragonwell11%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97

下载地址:https://github.com/dragonwell-project/dragonwell11/releases

jdk8:https://github.com/dragonwell-project/dragonwell8

jdk17:https://github.com/dragonwell-project/dragonwell17

腾讯:

项目名称:TencentKona-8

腾讯开源项目:https://opensource.tencent.com/projects 

使用指南:https://github.com/Tencent/TencentKona-8/wiki/%E5%AE%89%E8%A3%85%E8%AF%B4%E6%98%8E

下载地址:https://github.com/Tencent/TencentKona-8/releases

#可以通过docker下载最新版
docker pull konajdk/konajdk:8

#查看jdk版本号
docker run -it --rm  镜像id java -version

jdk11:https://github.com/Tencent/TencentKona-11

jdk17:https://github.com/Tencent/TencentKona-17 

 

 

另外在这个项目https://github.com/alibaba/SREWorks/blob/main/paas/openjdk8-jre/Dockerfile 发现了

FROM adoptopenjdk/openjdk8:alpine-jre

经过实测也是可用的

 

最后附上temurin-jdk的官方git:https://github.com/adoptium/temurin-build

 

后来发现docker官方也是有openjdk的

首先docker serach java发现了openjdk

 

 然后 docker search openjdk 发现了官方版本

 

posted on 2023-09-27 11:18  06  阅读(1605)  评论(0编辑  收藏  举报