(开包即用,不用看代码!)借助Docker自动构建Java(Oracle)镜像

开包即用,不用看代码!

如果着急使用可以直接使用我构建的镜像,请从配置镜像源开始看

Docker中的Java

Java可能是程序员最常用的运行时环境了,
即使你不开发Java程序,大量的开发工具也需要使用Java运行时环境,
因此安装Java似乎是一个不需要专门讨论的问题。

不过在使用Docker的时候,就不那么顺利了。

使用Docker总是先从官方镜像网站搜索镜像,也就是

https://store.docker.com/ 上搜索java可以搜索到

https://store.docker.com/images/java

https://hub.docker.com/ 上搜索java可以搜索到

/java/”>https://hub.docker.com//java/

其中的路径_下划线,代表这是一个官方提供的镜像。
不过这两个页面的内容大致相同,里面都标注了DEPRECATED,查看说明,提示使用

而对于Oracle提供的JDK,给出说明

  • Ubuntu停止分发
  • RedHat要求添加仓库
  • CentOSDebianGentoo要求手工下载

OracleJDK的手工下载地址为

https://www.java.com/zh_CN/download/manual.jsp

如果Java用于Windows桌面环境,手工下载手工安装不那么麻烦。
如果用于服务器,特别是自动化部署的服务器,手工下载手工安装就很麻烦了。
由于Java是公开软件,所构建的镜像并不需要保密,
因此可以借助Docker的镜像构建服务自动构建Java镜像为公开镜像。

准备

此时可以借助于SDKMAN,首先制作SDKMAN镜像,参考

http://blog.csdn.net/hu_zhenghui/article/details/79430058

规划项目分支

https://github.com/ 上注册账号,我的账号为

https://github.com/huzhenghui

创建一个用于构建镜像的项目,本例为

https://github.com/huzhenghui/Java-Docker-Autobuild

和本例基础的自动构建SDKMAN不同,SDKMAN只需要构建最新版本即可,而Java的版本较多,
SDKMAN中查询支持的Java版本

docker run -it --rm --entrypoint /bin/bash huzhenghui/sdkman -l -c 'sdk list java'

可以看到SDKMAN支持的Java版本

================================================================================
Available Java Versions
================================================================================
     9.0.4-oracle
     9.0.1-zulu
     9.0.0-zulu
     8u161-oracle
     8u152-zulu
     8u144-zulu
     8u131-zulu
     7u141-zulu
     6u93-zulu

为此Java-Docker-Autobuild项目需要按照不同版本创建分支,本例中要构建9.0.4-oracle
在项目中创建一个名称为9.0.4-oracle的分支。此时项目包含两个分支

  • master
  • 9.0.4-oracle

master分支中包含一个用于构建镜像的文件

https://github.com/huzhenghui/Java-Docker-Autobuild/blob/master/Dockerfile

本例中不制作该镜像,因此仅放置空代码用于后面排查Docker自动构建功能。

FROM huzhenghui/sdkman

LABEL maintainer="hu@daonao.com"

9.0.4-oracle分支中也包含一个用于构建镜像的文件

https://github.com/huzhenghui/Java-Docker-Autobuild/blob/9.0.4-oracle/Dockerfile

详解镜像脚本

9.0.4-oracle分支中构建镜像的Dockerfile文件内容为

FROM huzhenghui/sdkman

LABEL maintainer="hu@daonao.com"

RUN bash -c 'source /root/.sdkman/bin/sdkman-init.sh; sdk version; echo -e "\n----------" $? "----------\n"' && \
    bash -c 'source /root/.sdkman/bin/sdkman-init.sh; echo y | sdk install java 9.0.4-oracle; echo -e "\n----------" $? "----------\n"' && \
    bash -c 'source /root/.sdkman/bin/sdkman-init.sh; export' && \
    bash -c 'source /root/.sdkman/bin/sdkman-init.sh; ${JAVA_HOME}/bin/java --version'

此处的代码和一般的Dockerfile不同,解释一下其中的要点

SDKMANsdk命令

SDKMAN安装后,可以运行sdk命令,不过sdk命令不是可执行程序,也不是shell脚本文件,
查看sdk命令的类型

docker run -it --rm --entrypoint /bin/bash huzhenghui/sdkman -l -c 'type sdk'

可以看到是一个函数(函数内容省略)

sdk is a function
sdk ()
{
  ......
}

如果不加-l参数查看sdk命令的类型

docker run -it --rm --entrypoint /bin/bash huzhenghui/sdkman -c 'type sdk'

会发现不存在sdk

/bin/bash: line 0: type: sdk: not found

当然也就不能直接运行sdk命令

docker run -it --rm --entrypoint /bin/bash huzhenghui/sdkman -c 'sdk'

会发现找不到sdk命令

/bin/bash: sdk: command not found

在构建镜像中使用sdk命令

因为sdk是函数,因此运行前需要先运行初始化脚本。

docker run -it --rm --entrypoint /bin/bash huzhenghui/sdkman -c 'source /root/.sdkman/bin/sdkman-init.sh; sdk'

所以在构建镜像的时候,可以采取这样的方式

bash -c 'source /root/.sdkman/bin/sdkman-init.sh; sdk version'

先运行SDKMAN的初始化脚本,然后再运行sdk命令。

这种使用bash包裹一层,还有一个用途,也就是当sdk命令的返回值非0的时候,
如果在DockerfileRUN中直接执行,遇到sdk命令的返回值非0就直接报错退出了。
使用bash包裹一层,可以显示输出sdk命令的返回值,而bash的返回值为0,构建过程继续运行,本例中的用法如下。

bash -c 'source /root/.sdkman/bin/sdkman-init.sh; sdk version; echo -e "\n----------" $? "----------\n"'

非交互式安装

sdk命令安装语法为

sdk install [candidate] [version]

本例中要安装java9.0.4-oracle版本,也就是

sdk install java 9.0.4-oracle

不过直接运行会显示交互信息

Oracle requires that you agree with the Oracle Binary Code License Agreement
prior to installation. The license agreement can be found at:

  http://www.oracle.com/technetwork/java/javase/terms/license/index.html

Do you agree to the terms of this agreement? (Y/n):

Dockerfile中直接使用这种包含交互的命令将挂起在这里,此时可以使用一个神器的命令

yes

这个命令的功能很简单,就是不停的输出y,本例中的用法为

yes | sdk install java 9.0.4-oracle

由于当yes写入失败的时候会返回错误代码1,而Docker在遇到非0的错误代码的时候会停止,
加之本例中只需要一个y,因此可以使用

echo y | sdk install java 9.0.4-oracle

本例中的用法为:

bash -c 'source /root/.sdkman/bin/sdkman-init.sh; echo y | sdk install java 9.0.4-oracle; echo -e "\n----------" $? "----------\n"'

初始化环境变量

sdk的初始化脚本除了创建sdk函数外,还创建环境变量,直接查看环境变量

docker run -it --rm --entrypoint /bin/bash huzhenghui/sdkman -c 'export'

会看到其中不包含SDKMAN相关的环境变量

declare -x HOME="/root"
declare -x HOSTNAME="d6d4c49ca6ad"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
declare -x PWD="/"
declare -x SHLVL="1"
declare -x TERM="xterm"

运行sdk的初始化脚本后查看环境变量

docker run -it --rm --entrypoint /bin/bash huzhenghui/sdkman -c 'source /root/.sdkman/bin/sdkman-init.sh; export'

会看到其中包含SDKMAN相关的环境变量

  declare -x HOME="/root"
  declare -x HOSTNAME="173b01ea6ab2"
  declare -x OLDPWD
  declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  declare -x PWD="/"
+ declare -x SDKMAN_CANDIDATES_DIR="/root/.sdkman/candidates"
+ declare -x SDKMAN_CURRENT_API="https://api.sdkman.io/2"
+ declare -x SDKMAN_DIR="/root/.sdkman"
+ declare -x SDKMAN_LEGACY_API="https://api.sdkman.io/1"
+ declare -x SDKMAN_PLATFORM="Linux64"
+ declare -x SDKMAN_VERSION="5.6.1+290"
  declare -x SHLVL="1"
  declare -x TERM="xterm"

本例中在使用SDKMAN安装Java后,通过环境变量查看安装情况。

bash -c 'source /root/.sdkman/bin/sdkman-init.sh; export'

可以看到JAVA相关的环境变量。

declare -x JAVA_HOME="/root/.sdkman/candidates/java/current"
declare -x PATH="/root/.sdkman/candidates/java/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

创建镜像仓库

https://hub.docker.com 上注册账号,我的账号为

https://hub.docker.com/r/huzhenghui/

创建一个用于保存镜像的仓库,本例为

https://hub.docker.com/r/huzhenghui/java/

按照Docker网站上创建仓库时的说明设置自动构建,完成后可在此看到相关信息
(本页面仅限于自己访问,请将链接中的用户名和仓库名替换为你自己的用户名和仓库名)

https://cloud.docker.com/app/huzhenghui/repository/docker/huzhenghui/java/general

配置自动构建镜像仓库

前面讨论过本例按照不同的版本创建不同的分支,
Docker上的默认自动构建配置无法满足多分支,因此需要配置成为自动构建不同版本。
查看配置(本页面仅限于自己访问,请将链接中的用户名和仓库名替换为你自己的用户名和仓库名)

https://cloud.docker.com/app/huzhenghui/repository/docker/huzhenghui/java/builds

编辑配置(本页面仅限于自己访问,请将链接中的用户名和仓库名替换为你自己的用户名和仓库名)

https://cloud.docker.com/app/huzhenghui/repository/docker/huzhenghui/java/builds/edit

编辑其中的BUILD RULES

Source Type Source Docker Tag Dockerfile location Build Context
Branch /^[-0-9a-z.]+$/ version-{sourceref} Dockerfile /

测试镜像仓库配置

设置成功后,每次向 https://github.com/huzhenghui/Java-Docker-Autobuild 提交代码,
即会自动触发构建。构建成功后,可以在镜像仓库中看到公开的信息。

https://hub.docker.com/r/huzhenghui/java

查看标签列表可以看到对应于源代码分支的两个标签

Tag Name Compressed Size
version-9.0.4-oracle 1 GB
version-master 68 MB

配置镜像源

从标签列表中可以看到,version-9.0.4-oracle版本的尺寸高达1GB
直接拉取镜像可能很慢,此时可以使用更快捷的镜像源。
比较方便的是中国科学技术大学提供的镜像源,文档为

http://mirrors.ustc.edu.cn/help/dockerhub.html

本例中使用的是Boot2Docker,配置镜像源需要编辑文件

vi /var/lib/boot2docker/profile

在如下位置增加行

  EXTRA_ARGS='
  --label provider=hyperv
+ --registry-mirror=https://docker.mirrors.ustc.edu.cn
  '
  CACERT=/var/lib/boot2docker/ca.pem
  DOCKER_HOST='-H tcp://0.0.0.0:2376'
  DOCKER_STORAGE=aufs
  DOCKER_TLS=auto
  SERVERKEY=/var/lib/boot2docker/server-key.pem
  SERVERCERT=/var/lib/boot2docker/server.pem

修改后如下所示

EXTRA_ARGS='
--label provider=hyperv
--registry-mirror=https://docker.mirrors.ustc.edu.cn
'
CACERT=/var/lib/boot2docker/ca.pem
DOCKER_HOST='-H tcp://0.0.0.0:2376'
DOCKER_STORAGE=aufs
DOCKER_TLS=auto
SERVERKEY=/var/lib/boot2docker/server-key.pem
SERVERCERT=/var/lib/boot2docker/server.pem

查询镜像源

修改后重新启动Docker主机,使用如下命令查询Docker主机信息。

docker info

在输出结果的底部寻找刚才设置的镜像源。

  Containers: 2
   Running: 1
   Paused: 0
   Stopped: 1
  Images: 106
  Server Version: 18.01.0-ce
  Storage Driver: aufs
   Root Dir: /mnt/sda1/var/lib/docker/aufs
   Backing Filesystem: extfs
   Dirs: 151
   Dirperm1 Supported: true
  Logging Driver: json-file
  Cgroup Driver: cgroupfs
  Plugins:
   Volume: local
   Network: bridge host macvlan null overlay
   Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
  Swarm: inactive
  Runtimes: runc
  Default Runtime: runc
  Init Binary: docker-init
  containerd version: 89623f28b87a6004d4b785663257362d1658a729
  runc version: b2567b37d7b75eb4cf325b77297b140ea686ce8f
  init version: 949e6fa
  Security Options:
   seccomp
    Profile: default
  Kernel Version: 4.4.111-boot2docker
  Operating System: Boot2Docker 18.01.0-ce (TCL 8.2.1); HEAD : 0bb7bbd - Thu Jan 11 16:32:39 UTC 2018
  OSType: linux
  Architecture: x86_64
  CPUs: 1
  Total Memory: 987.2MiB
  Name: s1c1g1
  ID: UISY:2IP3:SOM7:I4MZ:ZKDX:GXIF:HNS5:DDQA:OEY3:QUMS:E7MM:GH6F
  Docker Root Dir: /mnt/sda1/var/lib/docker
  Debug Mode (client): false
  Debug Mode (server): true
   File Descriptors: 26
   Goroutines: 46
   System Time: 2018-03-05T16:45:18.962920098Z
   EventsListeners: 0
  Registry: https://index.docker.io/v1/
  Labels:
   provider=hyperv
  Experimental: false
  Insecure Registries:
   127.0.0.0/8
+ Registry Mirrors:
+  https://docker.mirrors.ustc.edu.cn/
  Live Restore Enabled: false

拉取镜像

速度快到飞起来

docker pull huzhenghui/java:version-9.0.4-oracle

查看环境变量

docker run -it --rm --entrypoint /bin/bash huzhenghui/java:version-9.0.4-oracle -c 'source /root/.sdkman/bin/sdkman-init.sh; export'

可以看到Java相关环境变量

  declare -x HOME="/root"
  declare -x HOSTNAME="d3bf9cd90d9e"
+ declare -x JAVA_HOME="/root/.sdkman/candidates/java/current"
  declare -x OLDPWD
+ declare -x PATH="/root/.sdkman/candidates/java/current/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  declare -x PWD="/"
  declare -x SDKMAN_CANDIDATES_DIR="/root/.sdkman/candidates"
  declare -x SDKMAN_CURRENT_API="https://api.sdkman.io/2"
  declare -x SDKMAN_DIR="/root/.sdkman"
  declare -x SDKMAN_LEGACY_API="https://api.sdkman.io/1"
  declare -x SDKMAN_PLATFORM="Linux64"
  declare -x SDKMAN_VERSION="5.6.1+290"
  declare -x SHLVL="1"
  declare -x TERM="xterm"

测试镜像

使用环境变量运行Java查看效果

docker run -it --rm --entrypoint /bin/bash huzhenghui/java:version-9.0.4-oracle -c 'source /root/.sdkman/bin/sdkman-init.sh; ${JAVA_HOME}/bin/java --version'

输出如下内容表示可以正常运行了

java 9.0.4
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
发布了1058 篇原创文章 · 获赞 107 · 访问量 290万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 撸撸猫 设计师: 设计师小姐姐

分享到微信朋友圈

×

扫一扫,手机浏览