为了提高镜像的上传和分发速度,我们通常会努力把自己的镜像做得尽量小!
Java开发的jar包应用需要运行在JDK上(实际只需要JRE里的java运行工具和JVM,JDK中包含了JRE),而java运行工具和JVM又需要运行在操作系统上!而容器镜像正是这样从底层操作系统开始一层一层构建出来的,换句话说一个简单的Hello World镜像要能成功在容器中运行,它需要基于JDK镜像和操作系统镜像才能跑起来,JDK和操作系统都是非常大的。特别是操作系统,那么操作系统有没有小巧一点的呢?在Linux的众多发行版中还真有一款以小巧、简单和安全标榜的操作系统——Alpine Linux(https://www.alpinelinux.org/),下面是它的官网截图:
它的发行包基本都在10M以下!如果以它为底层操作系统构建的镜像包应该可以大副底缩小体积!其实业界在大规模集群中基本都是用它做镜像的基础操作系统的,因此在各大公开镜像仓库中基本都有它的镜像包!因此你可以不用自己制作操作系统这层的镜像了(其实基于它的JDK镜像包也很多了!),特别是Alpine Linux 3.10.0版本基本上都会有:
#将 alpine:3.10 镜像拉取到本地Docker仓库中备用 (这步拉不到的话,你可能需要换一下本地Docker的镜像源)
[root@master1 ~]# docker pull alpine:3.10 3.10: Pulling from library/alpine 3.10: Pulling from library/alpine 396c31837116: Already exists Digest: sha256:451eee8bedcb2f029756dc3e9d73bab0e7943c1ac55cff3a4861c52a0fdd3e98 Status: Downloaded newer image for alpine:3.10 docker.io/library/alpine:3.10
接下来我们就基于该版本的alpine制作一下我们自己的JDK镜像:
首先,准备一个制作JDK镜像所需文件的存放目录:
[root@master1 ~]# mkdir alpinejdk [root@master1 ~]# cd alpinejdk/
alpine能够如此小巧是因为它没有集成一些普通的Linux库,比如跑Java应用必须依赖的glibc相关的包,所以得像平常在Linux安装应用一样先为alpine安装这些包。主要需要的依赖包有 glibc、glibc-bin 和 glibc-i18n,这里我们选用 glibc 2.29-r0版本的。glibc是Git上的开源库,仓库地址为 https://github.com/sgerrand/alpine-pkg-glibc/releases,FQ上去选择你需要的版本下载就好(最好不要太新)!下面是我下载好的版本:
#将 glibc 相关包准备好备用
[root@master1 alpinejdk]# ls glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk
然后,我们将需要的JDK也下载好,下面是我下载好的版本:
#将 JDK 包准备好备用
[root@master1 alpinejdk]# ls glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk jdk-8u201-linux-x64.tar.gz
接着,我们在alpinejdk 目录创建一个Dockerfile文件(第一个字母D是大写),该文件是指导Docker制作镜像的,可以理解为Docker的输入参数:
#指明制作当前镜像将基于的基础镜像 FROM alpine:3.10 #指定所制作镜像的维护者和联系方式 MAINTAINER xurm "[email protected]" #指定制像制作过程中的工作目录,后面的命令都在此目录下执行 WORKDIR /material #将需要的包添加的上一步的工作目录,添加分ADD和COPY两种,ADD会复制并解压 ADD jdk-8u201-linux-x64.tar.gz /material COPY glibc-2.29-r0.apk /material COPY glibc-bin-2.29-r0.apk /material COPY glibc-i18n-2.29-r0.apk /material #更换安装过程中的工具包下载源(否则下载后面的工具会非常的慢) RUN echo http://mirrors.aliyun.com/alpine/v3.10/main/ > /etc/apk/repositories RUN echo http://mirrors.aliyun.com/alpine/v3.10/community/ >> /etc/apk/repositories RUN apk update #安装必要工具 RUN apk --no-cache add ca-certificates wget #下载alpine-pkgs.sgerrand公钥 RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub #安装必要的依赖 RUN apk add glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk #清理缓存和工作目录不必要的包,保留JDK解压目录即可 RUN rm -rf /var/cache/apk/* glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk #设置时区 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo 'Asia/Shanghai' >/etc/timezone #配置环境变量 ENV JAVA_HOME=/material/jdk1.8.0_201 ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV PATH=$PATH:$JAVA_HOME/bin #指定容器启动时需要执行的命令(需要的话就把注释#去掉) #CMD ["java","-version"]
编辑完Dockerfile并保存好后,使用以下命令构建镜像:
#注意最后空格后有个点 . docker build -t alpinejdk:1.8.0_201 .
docker build的用法:docker build [OPTIONS] PATH | URL | - ,我们上面将 [OPTIONS] 设为了 -t ,表示设置 “name:tag” 格式的镜像名称,最后的点 . 用于批定镜像构建过程中的上下文环境目录。
整个构建过程如下所示:
[root@master1 alpinejdk]# docker build -t alpinejdk:1.8.0_201 . Sending build context to Docker daemon 202.5MB Step 1/19 : FROM alpine:3.10 ---> e7b300aee9f9 Step 2/19 : MAINTAINER xurm "[email protected]" ---> Using cache ---> 5fdb5b434cf9 Step 3/19 : WORKDIR /material ---> Using cache ---> f60af4742012 Step 4/19 : ADD jdk-8u201-linux-x64.tar.gz /material ---> Using cache ---> 056cc34aa581 Step 5/19 : COPY glibc-2.29-r0.apk /material ---> Using cache ---> 6b80010726b4 Step 6/19 : COPY glibc-bin-2.29-r0.apk /material ---> Using cache ---> 965c150d5513 Step 7/19 : COPY glibc-i18n-2.29-r0.apk /material ---> Using cache ---> aaaf184fbea2 Step 8/19 : RUN echo http://mirrors.aliyun.com/alpine/v3.10/main/ > /etc/apk/repositories ---> Running in 9e536725e205 Removing intermediate container 9e536725e205 ---> ab94b7352898 Step 9/19 : RUN echo http://mirrors.aliyun.com/alpine/v3.10/community/ >> /etc/apk/repositories ---> Running in c769b9f58d1c Removing intermediate container c769b9f58d1c ---> e6317fbd2407 Step 10/19 : RUN apk update ---> Running in 43e2446a425a fetch http://mirrors.aliyun.com/alpine/v3.10/main/x86_64/APKINDEX.tar.gz fetch http://mirrors.aliyun.com/alpine/v3.10/community/x86_64/APKINDEX.tar.gz v3.10.9-43-g3feb769ea3 [http://mirrors.aliyun.com/alpine/v3.10/main/] v3.10.6-10-ged79a86de3 [http://mirrors.aliyun.com/alpine/v3.10/community/] OK: 10344 distinct packages available Removing intermediate container 43e2446a425a ---> dba92f8c55fa Step 11/19 : RUN apk --no-cache add ca-certificates wget ---> Running in c69ba952343b fetch http://mirrors.aliyun.com/alpine/v3.10/main/x86_64/APKINDEX.tar.gz fetch http://mirrors.aliyun.com/alpine/v3.10/community/x86_64/APKINDEX.tar.gz (1/2) Installing ca-certificates (20191127-r2) (2/2) Installing wget (1.20.3-r0) Executing busybox-1.30.1-r5.trigger Executing ca-certificates-20191127-r2.trigger OK: 7 MiB in 16 packages Removing intermediate container c69ba952343b ---> afdd9b63380b Step 12/19 : RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub ---> Running in 92b39bf34ca2 Removing intermediate container 92b39bf34ca2 ---> 6627f29c92f3 Step 13/19 : RUN apk add glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk ---> Running in a48462bce6d7 (1/4) Installing glibc (2.29-r0) (2/4) Installing libgcc (8.3.0-r0) (3/4) Installing glibc-bin (2.29-r0) (4/4) Installing glibc-i18n (2.29-r0) Executing glibc-bin-2.29-r0.trigger OK: 38 MiB in 20 packages Removing intermediate container a48462bce6d7 ---> 86d6c3d16f1d Step 14/19 : RUN rm -rf /var/cache/apk/* glibc-2.29-r0.apk glibc-bin-2.29-r0.apk glibc-i18n-2.29-r0.apk ---> Running in 79fc0134cc8f Removing intermediate container 79fc0134cc8f ---> 5affb242a852 Step 15/19 : RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ---> Running in cb29bfb56c79 Removing intermediate container cb29bfb56c79 ---> 045155cdff08 Step 16/19 : RUN echo 'Asia/Shanghai' >/etc/timezone ---> Running in 9aadbce04dfb Removing intermediate container 9aadbce04dfb ---> 99d77f7cd687 Step 17/19 : ENV JAVA_HOME=/material/jdk1.8.0_201 ---> Running in 335a2f9f17f1 Removing intermediate container 335a2f9f17f1 ---> a5db569b86f0 Step 18/19 : ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ---> Running in 0dd5ade516b9 Removing intermediate container 0dd5ade516b9 ---> 683ad1d9cb79 Step 19/19 : ENV PATH=$PATH:$JAVA_HOME/bin ---> Running in 7d88e1bfde25 Removing intermediate container 7d88e1bfde25 ---> 07a302bdf267 Successfully built 07a302bdf267 Successfully tagged alpinejdk:1.8.0_201
构建完后,我们查看下本地Docker镜像列表中是否有刚刚构建的镜像 alpinejdk:1.8.0_201 :
[root@master1 alpinejdk]# docker images | grep alpinejdk alpinejdk 1.8.0_201 07a302bdf267 37 seconds ago 447MB
看到有447MB,也是蛮大的,不过比起基于其他Linux镜像的就会小得多了!
最后我们使用刚刚新制作的镜像创建并启动容器,再进入容器内部验证一下:
# alpinejdkContainer 为自定义的容器名称,alpinejdk:1.8.0_201是启动容器使用的镜像,/bin/sh 是进入容器后执行的命令
[root@master1 alpinejdk]# docker run -it --name alpinejdkContainer alpinejdk:1.8.0_201 /bin/sh /material # java -version java version "1.8.0_201" Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode) /material # pwd /material /material # ls jdk1.8.0_201 /material #
你也可以将上述步骤分开来做:
#使用镜像创建容器,会返回容器ID [root@master1 alpinejdk]# docker create -it alpinejdk:1.8.0_201 cf3365896871e9f301374e97e02374789d06d512f37374434ef5037f4ac5b3ff #使用容器ID启动容器,会返回启动后的容器ID [root@master1 alpinejdk]# docker start cf3365896871e9f301374e97e02374789d06d512f37374434ef5037f4ac5b3ff cf3365896871e9f301374e97e02374789d06d512f37374434ef5037f4ac5b3ff #进入启动后的容器,进行验证 [root@master1 alpinejdk]# docker exec -it cf3365896871e9f301374e97e02374789d06d512f37374434ef5037f4ac5b3ff /bin/sh /material # java -version java version "1.8.0_201" Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode) /material # pwd /material /material # ls jdk1.8.0_201 /material # ls jdk1.8.0_201/ COPYRIGHT bin man LICENSE include release README.html javafx-src.zip src.zip THIRDPARTYLICENSEREADME-JAVAFX.txt jre THIRDPARTYLICENSEREADME.txt lib /material #
至此,我们就完成了基于Alpine Linux镜像制作小体积JDK镜像和基本验证的全部操作!以后可以基于该镜像制作jar包应用的镜像了!
标签:r0,JDK,glibc,---,apk,2.29,Linux,镜像 From: https://www.cnblogs.com/xuruiming/p/17144416.html