上次配完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源又很慢,很有必要换成国内的
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/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 发现了官方版本
---------------------------------------------------------------------------------------------------后记-----------------------------------------------------------------------------------------------------
后来项目组要搭建jdk17运行环境,经过一番研究搭建完成了,这里记录下
jdk17运行环境包括两部分:
1.包含jdk17的jenkins编译环境
2.包含jre17的docker jre17基础镜像
一、包含jdk17的jenkins编译环境
这个很好配置,主要是下载途径
这里推荐使用 Eclipse temurin
https://adoptium.net/zh-CN/temurin/archive/?version=17
参考文档:https://blog.csdn.net/lanwp5302/article/details/86612197
jdk包下载下来之后,上传jenkins服务器,并在jenkins中配置编译环境即可
二、包含jre17的docker jre17基础镜像
去dockerhub 的openjdk项目找过,并没有找到比较新的jdk17版本,还是决定自己搭建
最早的也是两年前了
其实用上面的jre8 dockerfile改编下即可
首先贴出dockerfile
FROM debian:bookworm-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-17-jre-amd64 ENV JAVA_DEBIAN_VERSION=17.0.12.0.0+7 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-17-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
dockerfile 详解:
1.FROM debian:bookworm-slim
看 dockerhub上的openjdk项目已用到了debian:bookworm-slim,我们也果断跟进
2.ENV JAVA_HOME=/usr/lib/jvm/temurin-17-jre-amd64
这里temurin-17-jre-amd64要根据需要修改
3.ENV JAVA_DEBIAN_VERSION=17.0.12.0.0+7
这里还是老方法,搜索package文件中的17-jre字段,找到最新版本号
这个版本号正好和上面下载的jdk版本号对应起来
4.apt-get install -y temurin-17-jre="$JAVA_DEBIAN_VERSION"
这里同样安装命令适配 jre17包名,其实包名在上面的截图里也能看到
-------------------------------------------------------------------------后记2------------------------------------------------------------------------
后来同事做项目遇到了生成图片里中文显示乱码问题
经过一番排查原因是:docker容器里没有字体所致,装上中文字体,和程序里配置的对应一致即可
正好jre8要升级了,一起做了
FROM debian:bookworm-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.432.0.0+6 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" ttf-wqy-zenhei && 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
其实升级点主要是三部分
FROM debian:bookworm-slim:如果系统太老旧需要换成新版本
ENV JAVA_DEBIAN_VERSION=8.0.432.0.0+6:这个是jre的小版本号,最好半年更新一次,更新到最新版apt-get install -y temurin-8-jre="$JAVA_DEBIAN_VERSION" ttf-wqy-zenhei :这里除了安装jre之外还安装了 ttf-wqy-zenhei 中文字体
开发在代码里同样配置成 ttf-wqy-zenhei 字体即可
参考文档:
https://blog.csdn.net/weixin_55518591/article/details/130730408
https://blog.csdn.net/number1110/article/details/129797876
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性