Py学习  »  docker

在Docker上编译OpenJDK 8

Docker • 4 年前 • 461 次点击  

以前曾经试过在VMware上安装Linux,但是每次都不顺利,例如Linux环境,预装依赖软件,OpenJDK源码的选择等环境都会遇到问题,一旦失败再重新开始挺费时间的,现在用Docker就省事多了,镜像和容器的创建和删除都比较简单干净,专心做好Dockerfile就行,下面我们一起来实践一下吧。

本次实战用到的所有文件,已经打包到GitHub上,路径是git@github.com:zq2599/centos7buildopenjdk8.git,欢迎您来使用(git clone git@github.com:zq2599/centos7buildopenjdk8.git)

本次编译实战的基本步骤如下: 


编写的Dockerfile中要做的如下的事情:

  1. 安装依赖的软件;

  2. 把OpenJDK的源码复制到镜像中;


在编写Dockerfile之前要做三个重要的选择,如下:

  1. Linux:我选择了CentOS 7,之前试过Ubuntu 16.04,但是在Configure的时候提示"freetype"没有安装,我按照提示去装了,再次Configure的时候继续提示"freetype"没有安装......(此问题现在还没解决,如果您解决过相同问题,请您告诉一下解决方法,谢谢了!)

  2. OpenJDK源码,这次要编译的是OpenJDK 8,源码的下载地址在这里[1]。

  3. Bootstrap JDK:即编译时要用到的JDK,下载了OpenJDK的源码后,解压开可以看到“README-builds.html”这个文件,里面有对Bootstrap JDK的描述:


看得出,需要安装JDK 7来编译OpenJDK 8的源码。

OK,关键问题都已确认,即将开始Dockerfile制作,不过制作之前还有个小问题需要先想好:本次我打算把制作镜像所需的Dockerfile和依赖文件都放到GitHub上去,这样做的好处有两个:

  1. 读者们从Git上clone下来之后直接执行Docker build就能在本地构建镜像;

  2. daocloud.io网站上支持通过执行GitHub目录的方式在线构建镜像,后面我们会实践在daocloud.io上构建镜像并部署到腾讯云或者阿里云服务器上。


上传到GithHub时,除了Dockerfile,还要上传的文件有两个:JDK 1.7和OpenJDK 8源码,都超过了100M,如下图: 


这就麻烦了,GitHub上传文件的时候,单个文件不能超过100M,否则push的时候会被服务器拒绝,解决这个问题有两个办法:

1、构建镜像的时候不要把这两个文件复制到镜像中了,改为在Dockerfile中通过执行wget命令将这两个文件分别下载到镜像中,OpenJDK的下载路径是:http://www.java.net/download/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03mar2014.zip,而OpenJDK 1.7的下载路径就难办了,Oracle上下载历史版本的时候,是要做登录操作的,这个在Dockerfile中难以实现,找到了一个下载地址:https://mirror.its.sfu.ca/mirror/CentOS-Third-Party/NSG/common/x86_64/jdk-7u80-linux-x64.rpm,但是下载速度很慢,最少一个小时以上了,所以wget这种方法看似简单,但下载文件耗时实在太长;

2、第二种方法比较简单易用,就是在Mac或者Linux上先用split命令将文件分割成多个,再上传到GitHub上,在Dockerfile中有对应的命令将分割后的文件恢复成分割前的原文件,具体的分割命令如下:

  1. split -b 50m jdk-7u71-linux-x64.rpm jdkrpm-


这个命令是将jdk-7u71-linux-x64.rpm分割成不超过50m的多个文件,分割后的文件以jdkrpm-作为文件名的前缀,如下图: 


OpenJDK的源码用如下命令分割:

  1. split -b 50m openjdk-8-src- b132-03_mar_2014.zip openjdksrc-


Dockerfile中,从分割文件恢复以上两个原文件的命令为:

  1. cat jdkrpm-* > jdk-7u71-linux-x64.rpm

  2. cat openjdksrc-* > openjdk-8-src-b132-03_mar_2014.zip


以上就是两种处理大文件的方法,本文用的是第二种,即先分割上传到Git,在Dockerfile中将已分割文件恢复成原文件再使用。

好了,前期的准备工作已经做完了,现在可以编写Dockerfile文件了,整个文件中要做的事情列出如下:

1、安装依赖软件,例如libXtst-devel,libXt-devel等等,这些都是编译前的Configure命令要检查的,检查不过无法进行编译;

2、把分割后的OpenJDK源码复制到镜像文件中,再合成,再解压;

3、安装JDK 7,把分割后的安装文件复制到镜像中合成,然后安装;

4、为了方便用户进入容器后快速开始编译,我们做了一个shell脚本start_make.sh,把这个脚本也要复制到镜像中,内容如下:

  1. #!/bin/bash

  2. $WORK_PATH/$OPENJDK_SRC_DIR/configure

  3. echo "start make"

  4. cd $WORK_PATH/$OPENJDK_SRC_DIR

  5. make all ZIP_DEBUGINFO_FILES=0 DISABLE_HOTSPOT_OS_VERSION_CHECK=OK


5、清理无用的文件,例如OpenJDK源码的压缩文件,JDK 7的安装文件等;

按照以上步骤,最终写出的Dockerfile文件如下:

  1. # Docker image of compile and build enviroment for openjdk8

  2. # VERSION 0.0.1

  3. # Author: bolingcavalry


  4. #基础镜像使用CentOS 7

  5. FROM centos:centos7


  6. #作者

  7. MAINTAINER BolingCavalry <zq2599@gmail.com>


  8. #定义工作目录

  9. ENV WORK_PATH /usr/local


  10. #定义JDK 1.7的文件名

  11. ENV JDK_RPM_FILE jdk-7u71-linux-x64.rpm


  12. #定义OpenJDK源码的文件名

  13. ENV OPENJDK_SRC_ZIP openjdk-8- src-b132-03_mar_2014.zip


  14. #定义解压缩后的文件名

  15. ENV OPENJDK_SRC_DIR openjdk


  16. #yum更新

  17. RUN yum -y update


  18. #安装工具集

  19. RUN yum -y groupinstall "Development Tools"


  20. #安装即将用到的软件

  21. RUN yum -y install unzip libXtst-devel libXt-devel libXrender-devel cups-devel freetype-devel alsa-lib-devel which


  22. #把分割过的JDK 1.7安装文件复制到工作目录

  23. COPY ./jdkrpm-* $WORK_PATH/


  24. #用本地分割过的文件恢复原有的JDK 1.7的安装文件

  25. RUN cat $WORK_PATH/jdkrpm-* > $WORK_PATH/$JDK_RPM_FILE


  26. #本地安装JDK 1.7

  27. RUN yum -y localinstall $WORK_PATH/$JDK_RPM_FILE


  28. #把分割过的OpenJDK 8的源码压缩包复制到工作目录

  29. COPY ./openjdksrc-* $WORK_PATH/


  30. #用本地分割过的文件恢复原有的OpenJDK 8的源码压缩包

  31. RUN cat $WORK_PATH/openjdksrc-* > $WORK_PATH/ $OPENJDK_SRC_ZIP


  32. #解压缩源码

  33. RUN unzip $WORK_PATH/$OPENJDK_SRC_ZIP -d $WORK_PATH


  34. #复制启动编译的shell

  35. COPY ./start_make.sh $WORK_PATH/$OPENJDK_SRC_DIR/


  36. #给执行文件增加可执行权限:Configure文件

  37. RUN chmod a+x $WORK_PATH/$OPENJDK_SRC_DIR/configure


  38. #给执行文件增加可执行权限:启动编译文件

  39. RUN chmod a+x $WORK_PATH/$OPENJDK_SRC_DIR/start_make.sh


  40. #删除分割文件

  41. RUN rm $WORK_PATH/jdkrpm-*


  42. #删除分割文件

  43. RUN rm $WORK_PATH/openjdksrc-*


  44. #删除JDK安装包文件

  45. RUN rm $WORK_PATH/$JDK_RPM_FILE


  46. #删除OpenJDK源码压缩文件

  47. RUN rm $WORK_PATH/$OPENJDK_SRC_ZIP


至此,镜像文件制作所需的材料都已经齐全了,如下图: 


现在让我们开始制作镜像吧,打开终端,进入Dockerfile所在目录,执行命令:

  1. docker build -t bolingcavalryopenjdk:0.0.1 .


因为要在线安装不少的软件,所以可能耗时会略长,和网络带宽有关,我在住处用家庭网络大概10分钟左右构建成功,执行目录docker images查看镜像,新的镜像文件已经生成了,如下图: 


现在启动一个容器试试吧:

  1. docker run --name=jdk001 -idt bolingcavalryopenjdk:0.0.1


容器已经启动,再执行以下命令进入容器:

  1. docker exec -it jdk001 /bin/bash


进去后,直接到/usr/local/openjdk目录下,执行./start_make.sh,开始编译了,整个过程的耗时和当前电脑的硬件配置有关,我用i7处理器的Mac Pro 15大约要用20多分钟,编译结束后会有类似下图的输出: 


这时候去/usr/local/openjdk目录下看看,发现多了一个build目录,这里面就是编译好的结果,如下图: 


build目录下只有一个linux-x86_64-normal-server-release目录,再进去就能看到JDK目录了,如下图: 


进入/usr/local/openjdk/build/linux-x86_64-normal-server-release/jdk/bin目录,会发现里面有Java文件,执行./java -version输出如下: 


新的JDK信息已经打印出来了,OpenJDK Runtime Enviroment信息已经说明了这是个最新构建的JDK环境。

至此我们的本次实战就结束了,面对如此干净的编译环境和现成的源码,读者您是否有一种改动一番源码的冲动,然后构建一个个性化的属于自己的JDK,建议您自己动手修改和编译OpenJDK源码,以加深对JVM的认识。

相关链接:

  1. http://www.java.net/download/openjdk/jdk8/promoted/b132/openjdk-8-src-b132-03_mar_2014.zip


Kubernetes实战培训


Kubernetes实战培训将于2019年6月28日在深圳开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:云原生介绍、微服务;Docker基础、Docker工作原理、镜像、网络、存储、数据卷、安全;Kubernetes架构、核心组件、常用对象、网络、存储、认证、服务发现、调度和服务质量保证、日志、监控、告警、Helm、实践案例等,点击下方图片或者点击阅读原文了解详情。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/35086
 
461 次点击