Docker | 第五章:构建自定义镜像
前言
上一章节,主要是介绍了下
Dockerfile
的一些常用命令的说明。我们知道,利用Dockerfile
可以构建一个新的镜像,比如运行Java
环境,就需要一个JDK
环境的镜像,但直接使用公共的镜像时,一般上大小都比较大。所以本章节就主要结合Dockerfile
文件及commit
方式,构建属于自己的镜像,同时对镜像进行压缩和优化,同时也是对Dockerfile
知识的一个实践。
利用Dockerfile构建自定义镜像
作为一个
java
后端开发,这里就直接以构建一个Oracle官方jre
环境来示例。
选定基础镜像
由于在Linux中,
JVM
主要是调用系统的C语言库,Oracle的官方JRE,使用的是libc,也就是glibc
,这意味着你要运行任何Java程序,都需要先装好glibc
。所以我们直接去https://hub.docker.com
找一个基于glibc
的基础镜像(当然了,大家也可直接选定比如CensOS
这些Linux的发行版本了)。
我们之类直接选择默认排在第一个的alpine-glibc
作为我们的基础镜像,比较这个大小也才12M左右呀!
题外话:大家作为实验性质时,为了获取更小的基础镜像,可以选择alpine
这个基础镜像,比较这个只有5M大小,够精简了!
准备JRE版本
这里我们直接去Oracle官网选择
jre
版本,这里选择的是jre-8u181-linux-x64
版本(由于对linux命令不是很熟悉,为了不必要的时间浪费,这里直接下载了镜像了,熟悉的各位可以直接使用wget
进行下载的)。
编写Dockerfile
# 基础镜像
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
:
docker build -t lqdev.cn/jre8:0.1 .
注意:后面有个.
的。
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
然后查看下镜像列表,
docker images
说明已经构建成功了,我们来运行下:
docker run -it -d --name myfirstjre lqdev.cn/jre8:0.1
查看下容器列表:
docker ps -a
由于Dockerfile
中使用CMD
命令覆盖了原本的/bin/sh
,容器已启动就停止了。所以我们看下日志,就知道是否jre
安装成功。
docker logs -f c6873a97ff49
输出了版本信息了,说明已经安装成功了。
实践:运行SpringBoot的jar包
现在我们就可以基于这个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服务:
利用commit命令构建自定义镜像
在第三章讲解
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时,可通过 && 和 / 支持将命令串联在一起
# 举例
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
对比下,确实少了很多了。
当然对于大小不关心的,也就无需理会了,毕竟现在存储空间都很大的,也就可能传输的时候慢点,哈哈~
参考资料
镜像优化的大家可看看以下几篇文章或者自行搜索下相关资料:
- https://blog.csdn.net/qq_36763896/article/details/53293088
- https://my.oschina.net/shyloveliyi/blog/1627020
- https://blog.csdn.net/chenyufeng1991/article/details/78766123
总结
本章节主要是介绍如何利用
Dockerfile
或者commit
方式构建自定义镜像。通过这两种方式,我们就能根据自己的实际业务需要进行个性化改造、优化,最终构建一个通用镜像。在构建自己的镜像时,尽量还是选择自己熟悉的、稳定的基础环境镜像进行构建,毕竟出了问题找起来也熟门熟路点。通常,运维部门或者实施部门,制定的镜像属于资产,一般不会上送至Docker
远程仓库的,有了镜像,我们就需要有个地方去存储。下一章节,就重点讲解下如何构建私有仓库,管理自己的镜像文件!
最后
若文中有错误或者遗漏之处,还望指出,共同进步!
老生常谈
- 个人QQ:
499452441
- 微信公众号:
lqdevOps
个人博客:http://blog.lqdev.cn
Docker | 第五章:构建自定义镜像的更多相关文章
- Docker学习(六)Dockerfile构建自定义镜像
Docker学习(六)Dockerfile构建自定义镜像 前言 通过前面一篇文章可以知道怎么去使用一个镜像搭建服务,但是,如何构造自己的一个镜像呢,docker提供了dockerfile可以让我们自己 ...
- docker构建自定义镜像
docker构建自定义镜像 要构建一个镜像,第一步准备所需要的文件,第二步编写Dockerfile文件,比如我现在构建一个java web镜像 第一步:准备java web工程的war包文件(这里假设 ...
- 五十四.自定义镜像及仓库、持久化存储 、 Docker网络架构
1. 制作自定义镜像(base基础镜像,搭建共性环境) 基于centos镜像使用commit创建新的镜像文件 基于centos镜像使用Dockerfile文件创建一个新的镜像文件 1.1 使用镜像 ...
- Docker入门3------手动编辑自定义镜像
手动编辑自定义镜像 查看本地现有镜像: 基于centos创建一个,会自动下载centos最新原始镜像 docker run -it --name=web centos /bin/bash 然后在容器内 ...
- Docker学习之4——构建NGINX镜像
Nginx是一个高性能的Web和反向代理服务器,它具有很多非常优越的特性:1.作为Web服务器.2.作为负载均衡服务器.3.作为邮件代理服务器.4.安装及配置简单.接下来我们介绍在docker构建ng ...
- Dockerfile详解,以及构建自定义镜像
Dockerfile使用 前面的操作我们一直下载下载官方已经构建好的镜像,直接下载后就可以run,如果我们想要在镜像中添加自己的应用,比如在tomcat中添加自己的app,构建一个自定义的镜像,那么我 ...
- docker使用centos7系统构建tomcat镜像
FROM shansongxian/centos-oraclejdk8:latest #此镜像使用centos7系统,精简jdk,只运行java程序,无法编译/构建 MAINTAINER huqian ...
- docker使用alpine系统构建tomcat镜像
FROM frolvlad/alpine-oraclejdk8 #此镜像使用alpine-glibc系统,精简jdk,只运行java程序,无法编译/构建 MAINTAINER huqiang:2018 ...
- java并发编程实战:第十四章----构建自定义的同步工具
一.状态依赖性管理 对于单线程程序,某个条件为假,那么这个条件将永远无法成真 在并发程序中,基于状态的条件可能会由于其他线程的操作而改变 可阻塞的状态依赖操作的结构 acquire lock on o ...
随机推荐
- linux命令学习 查找文件和文件夹
1: 查找根目录下查找文件夹名称叫XXXX的目录地址 find / -name XXXX -d 2: 查找/var/www/目录下叫index.php的文件 find /var/www/ -name ...
- 微服务学习一 微服务session 管理
集群和分布式架构中: session管理有三种方法: 1: Cookie: 将Session对象保存在Cookie,保存在浏览器端.浏览器发送请求的时候,会把整个session放在请求里一起发送到se ...
- 关于导入excel报错的处理(xls,xlsx)
关于导入excel报错的处理(xls,xlsx) 最近在做一个将excel导入到dataGriview中的小功能在做的过程中遇到以下问题: 链接excel的链接串是这样写的 string strCon ...
- Thinkphp通过phpqrcode实现网址验证码
第一步: phpqrcode下载第三方扩展包,http://phpqrcode.sourceforge.net/ 第二步: 将扩展包放到/ThinkPHP/Library/Vendor/下的Phpqr ...
- 常用转义字符例如&的含义
&中的amp就是英文ampersand的缩写,该词的意思是&这个符号& 是 HTML 中 & 的表示方法.即在html中用&表示&符号
- Ubuntu16.4下安装Chrome浏览器以及Chromedriver
一.Chrome浏览器的安装 对于谷歌Chrome32位版本,使用如下链接: wget https://dl.google.com/linux/direct/google-chrome-stable_ ...
- CentOS7 LVM磁盘扩容
1:创建磁盘分区(注意红色命令部分) [root@hongyin-test- ~]# fdisk /dev/sda Welcome to fdisk (util-linux ). Changes wi ...
- VIM命令图---可定制版
近期闲来无事,便自己用PS制作了一份VIM命令助记图,之前看到网上有类似的图片,可是有些解释感觉不太好,并有一些错误的地方,所以就自己做了一份,并且保留了PS源文件,为了方便会PS的网友可以对本图进行 ...
- python之05 操作系统用户密码修改
ubuntu的操作系统修改密码的操作方法: 一.在系统启动时按住shift键,出现下图的界面 二.按下e进入命令行,找到下图红色框中的文字并修改成rw init=/bin/bash 然后按F10启动, ...
- 51nod1315(位运算)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1315 题意:中文题诶- 思路:位或(|)运算是二进制位有一个 ...