上一章节,主要是介绍了下
Dockerfile
的一些经常使用命令的说明。咱们知道,利用Dockerfile
能够构建一个新的镜像,好比运行Java
环境,就须要一个JDK
环境的镜像,但直接使用公共的镜像时,通常上大小都比较大。因此本章节就主要结合Dockerfile
文件及commit
方式,构建属于本身的镜像,同时对镜像进行压缩和优化,同时也是对Dockerfile
知识的一个实践。html
做为一个
java
后端开发,这里就直接以构建一个Oracle官方jre
环境来示例。java
因为在Linux中,
JVM
主要是调用系统的C语言库,Oracle的官方JRE,使用的是libc,也就是glibc
,这意味着你要运行任何Java程序,都须要先装好glibc
。因此咱们直接去https://hub.docker.com
找一个基于glibc
的基础镜像(固然了,你们也可直接选定好比CensOS
这些Linux的发行版本了)。linux
咱们之类直接选择默认排在第一个的alpine-glibc
做为咱们的基础镜像,比较这个大小也才12M左右呀!spring
题外话:你们做为实验性质时,为了获取更小的基础镜像,能够选择alpine
这个基础镜像,比较这个只有5M大小,够精简了!docker
这里咱们直接去Oracle官网选择
jre
版本,这里选择的是jre-8u181-linux-x64
版本(因为对linux命令不是很熟悉,为了避免必要的时间浪费,这里直接下载了镜像了,熟悉的各位能够直接使用wget
进行下载的)。后端
# 基础镜像 FROM frolvlad/alpine-glibc LABEL MAINTAINER oKong <499452441@qq.com> # 将JRE添加至镜像中,add 命令在源文件为压缩文件时,会自动解压的 ADD jre-8u181-linux-x64.tar.gz /opt/docker/java/jre8 # 设置JAVA环境变量 # 这里须要注意下,解压后有个目录的,为jre1.8.0_181,一开始没注意,启动时报了:exec: "java": executable file not found in $PATH: unknown 后才发现。 ENV JAVA_HOME /opt/docker/java/jre8/jre1.8.0_181 ENV CLASSPATH=$JAVA_HOME/bin ENV PATH=.:$JAVA_HOME/bin:$PATH # 这里无实际意义,只是在容器启动时,输出jre版本信息,验证是否安装成功 CMD ["java","-version"]
利用build
命令,构建镜像,同时指定tag
:tomcat
docker build -t lqdev.cn/jre8:0.1 .
注意:后面有个.
的。springboot
Sending build context to Docker daemon 81.19MB Step 1/7 : FROM frolvlad/alpine-glibc ---> d3bc626306a1 Step 2/7 : LABEL MAINTAINER oKong <499452441@qq.com> ---> Running in e788d29cd1e1 Removing intermediate container e788d29cd1e1 ---> 5d95db4ae169 Step 3/7 : ADD jre-8u181-linux-x64.tar.gz /opt/docker/java/jre8 ---> 0f4bb83df722 Step 4/7 : ENV JAVA_HOME /opt/docker/java/jre8/jre1.8.0_181 ---> Running in 57a1e1ef00ed Removing intermediate container 57a1e1ef00ed ---> 6f2b543a91b7 Step 5/7 : ENV PATH ${PATH}:${JAVA_HOME}/bin ---> Running in 2d75c88f97fb Removing intermediate container 2d75c88f97fb ---> 92a7a0f9926c Step 6/7 : WORKDIR /opt/docker/java/jre8/jre1.8.0_181 ---> Running in 7b9a69efc980 Removing intermediate container 7b9a69efc980 ---> 158c08c995c3 Step 7/7 : CMD ["java","-version"] ---> Running in 9ab517f8292a Removing intermediate container 9ab517f8292a ---> 9c8606ac315a Successfully built 9c8606ac315a Successfully tagged lqdev.cn/jre8:0.1
而后查看下镜像列表,bash
docker images
说明已经构建成功了,咱们来运行下:app
docker run -it -d --name myfirstjre lqdev.cn/jre8:0.1
查看下容器列表:
docker ps -a
因为Dockerfile
中使用CMD
命令覆盖了本来的/bin/sh
,容器已启动就中止了。因此咱们看下日志,就知道是否jre
安装成功。
docker logs -f c6873a97ff49
输出了版本信息了,说明已经安装成功了。
如今咱们就能够基于这个jre镜像进行实际的jar包部署了。
Dockerfile
文件方式:
# 基于咱们自定义构建的镜像 FROM lqdev.cn/jre8:0.1 VOLUME /opt/tmp # 这是jar 可自行选择,这里直接使用了原先讲解springboot十四章节:基于Docker部署时的jar包 ADD chapter-14-0.0.1-SNAPSHOT.jar app.jar # -Djava.security.egd=file:/dev/./urandom 可解决tomcat可能启动慢的问题 # 具体可查看:https://www.cnblogs.com/mightyvincent/p/7685310.html ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] # 对外端口 EXPOSE 8080
而后构建新镜像,并运行,同时查看日志输出
docker run -it -d --name springboot lqdev.cn/springboot:0.1
日志控制台:
运行的容器列表:
说明咱们已经成功了,jar也启动了。如今访问下部署的jar服务:
在第三章讲解
Docker
经常使用命令时,有说到,利用commit
可从容器中构建一个新的镜像。因此这里简单讲解下利用此命令进行自动镜像的构建过程。
构建思路:咱们启动一个基础镜像,同时运行,而后咱们进入容器,下载所须要的jre版本,并配置其环境变量。以后退出容器进行保存操做。这里就不直接下载了,咱们直接拷贝jre到容器里
启动基础镜像:
docker run -it -d --name commitImages frolvlad/alpine-glibc
拷贝jre到容器中。
docker cp /opt/docker/java/jre-8u181-linux-x64.tar.gz b0d354b9453a:/opt/docker/java/jre8
这里会提示,说目录不存在,可利用exec命令,进入容器建立目录下,这里就不演示了。
No such container:path: b0d354b9453a:/opt/docker/java
如今咱们进入容器:
docker exec -it b0d354b9453a /bin/sh
进入,/opt/docker/java/jre8
目录,进行常规linux下的jre安装:
cd /opt/docker/java/jre8 # 解压 tar -xzvf jre-8u181-linux-x64.tar.gz # 配置环境变量,vi /etc/profile 末尾加入 export JAVA_HOME=/opt/docker/java/jre8/jre1.8.0_181 export CLASSPATH=$JAVA_HOME/bin export PATH=.:$JAVA_HOME/bin:$PATH # 生效配置 source /etc/profile # 验证是否成功 java -version 输出: java version "1.8.0_181" Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode) # 这里有个坑,生效配置后退出容器后又失效了,搜索了后,把环境变量放在### ~/.bashrc 或者在~/.bashrc里面加一句source /etc/profile 可是仍是未生效。。。。我放弃了。。 直接写个sh脚本启动 时加入吧。。
而后咱们退出容器,利用commit
命令进行构建新镜像:
docker commit b0d354b9453a lqdev.cn/jre8:0.2
而后查看:
运行jar,验证下是否正常,这里直接在启动的时候拷贝jar到镜像。
docker run -it -d -p 1234:8080 -v /opt/docker/java:/opt/docker/java/app.jar --name springboot2 lqdev.cn/jre8:0.2
而后进入容器运行下java 命令
# 进入容器 docker exec -it 583d0f387555 /bin/sh # 生效配置 source etc/profile # 运行jar nohup java -Djava.security.egd=file:/dev/./urandom -jar /opt/docker/java/app.jar >log.txt &
退出后,访问宿主的1234端口服务,就能看见部署成功了:
其实比较好的作法是:建立一个sh
脚本,脚本里设置了环境生效命令及java命令便可,你们可自行尝试下,这里就不演示了。
上一章节,咱们利用Dockerfile
和commit
的方式生成镜像。如今咱们看下,镜像文件大小:
两种方式,commit还多了80M多。这里咱们本着精简的原则,对镜像大小进行优化下。
首先,镜像文件是按
镜像层(Layers)
进行叠加的。总的来讲就是:每一条指令都会建立一个镜像层,继而会增长总体镜像的大小。
一个基础镜像的大小直接决定了新镜像的大小,因此能够选择尽可能小的精简的镜像。本文就使用了alpine-glibc
做为基础镜像,大小12.8M。
多个RUN时,可经过 && 和 / 支持将命令串联在一块儿
# 举例 RUN yum -y install java-1.7.0-openjdk-devel && yum clean all
不少镜像大部分都是经过此方式进行RUN方式编写的。官网:https://hub.docker.com/里面的大部分镜像都是以下写法
好比jre
包中就有不少的文档及说明文件是非必要的,这些就能够删除了。如下只是个参考,你们能够自行删减,能够在Dockerfile
编写时,解压后,使用RUN
命令进行操做也能够直接把压缩包里删除后在拷贝:
rm -rf COPYRIGHT LICENSE README release THIRDPARTYLICENSEREADME-JAVAFX.txtTHIRDPARTYLICENSEREADME.txt Welcome.html #删除其余无用文件 rm -rf lib/plugin.jar \ lib/ext/jfxrt.jar \ bin/javaws \ lib/javaws.jar \ lib/desktop \ plugin \ lib/deploy* \ lib/*javafx* \ lib/*jfx* \ lib/amd64/libdecora_sse.so \ lib/amd64/libprism_*.so \ lib/amd64/libfxplugins.so \ lib/amd64/libglass.so \ lib/amd64/libgstreamer-lite.so \ lib/amd64/libjavafx*.so \ lib/amd64/libjfx*.so
对比下,确实少了不少了。
固然对于大小不关心的,也就无需理会了,毕竟如今存储空间都很大的,也就可能传输的时候慢点,哈哈~
镜像优化的你们可看看如下几篇文章或者自行搜索下相关资料:
本章节主要是介绍如何利用
Dockerfile
或者commit
方式构建自定义镜像。经过这两种方式,咱们就能根据本身的实际业务须要进行个性化改造、优化,最终构建一个通用镜像。在构建本身的镜像时,尽可能仍是选择本身熟悉的、稳定的基础环境镜像进行构建,毕竟出了问题找起来也熟门熟路点。一般,运维部门或者实施部门,制定的镜像属于资产,通常不会上送至Docker
远程仓库的,有了镜像,咱们就须要有个地方去存储。下一章节,就重点讲解下如何构建私有仓库,管理本身的镜像文件!
若文中有错误或者遗漏之处,还望指出,共同进步!
499452441
lqdevOps
我的博客:http://blog.lqdev.cn