1.介绍
1.1 说明
这里仅仅说明一下在企业应用的两种简单实践,并不包含自动化这套东西。这里说的两种实践,是我在工作中不同公司使用的两种部署方式,仅供大家参考。
1.2 两种部署方式
第一种:是把环境和app都一起打成一个镜像,每次部署都重新打一个镜像,然后启动容器;
第二种:仅仅把环境打成一个镜像,每次部署的时候,通过容器数据卷的方式,将app复制到容器中;
1.3 两种部署方式的物料说明
app: springboot的jar文件,里面加入了日志
java环境:jdk1.8
目录安排:
日志目录:/logs/
应用目录:/code/
2.构建java环境基础镜像
2.1 准备jdk的文件
我在这里准备了jdk-8u261-linux-x64.tar.gz 这个jdk文件:
2.2 编写的Dockerfile:
内容如下:
FROM centos:7.6.1810
LABEL \
author="lxc<xincasso.lvxss@126.com>" \
createTime="2023-09-24 10:20"
RUN yum -y install vim
RUN yum -y install net-tools
RUN yum -y install initscripts
# 安装lib库
RUN yum -y install glibc.i686
ADD jdk-8u261-linux-x64.tar.gz /usr/local/
ENV JAVA_HOME=/usr/local/jdk1.8.0_261
ENV JRE_HOME=$JAVA_HOME/jre
ENV CLASSPATH=$JAVA_HOME/lib/dt.jar:$JRE_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH=$PATH:$JAVA_HOME/bin
RUN mkdir -p /code
RUN mkdir -p /logs
WORKDIR /code
2.3 构建java8的基础镜像
docker build -t donkey/java8:1.0.0 .
3.上线部署
3.1 环境和app都一起打成一个镜像,上线部署
3.1.1 物料准备
镜像打包物料放在了/data/docker/docker-demo 这个目录下
其中有docker-demo-0.0.1-SNAPSHOT.jar、Dockerfile其中docker-demo-0.0.1-SNAPSHOT.jar代表我们生成的app应用代码,Dockerfile镜像构建文件。
Dockerfile文件内容如下:
FROM donkey/java8:1.0.0
COPY docker-demo-0.0.1-SNAPSHOT.jar /code/app.jar
ENTRYPOINT ["sh", "entry.sh"]
这个文件比较简单,就是基于java的基础镜像,把我们的app拷贝进去,然后执行命令。
3.1.2 构建镜像
执行构建命令:
docker build -t donkey/docker-demo:1.0.0 .
3.1.3 启动容器
我在/www/demo_1 这个目录下,当了一个entry.sh脚本
脚本内容很简单,就是启动app.jar
#!/bin/sh
java -jar app.jar
然后启动容器
docker run -d -p 8070:8080 -v /www/demo_1/entry.sh:/code/entry.sh -v /logs:/logs --name demo_1 38af11626649
包括端口映射、容器数据卷挂载。
3.1.4 验证
curl http://127.0.0.1:8070
查看日志:
3.2 将app以数据卷挂载的形式运行容器
3.2.1 重新构建java基础镜像
在/data/docker/java8_1我放了一个Dockerfile文件
内容如下:
FROM donkey/java8:1.0.0
ENTRYPOINT ["sh", "entry.sh"]
其实就是在基础镜像上加了一个命令执行。
构建
docker build -t donkey/java8_1:1.0.0 .
3.2.2 放置应用app服务器指定目录
这里我放到了/www/demo_2下
3.2.3 运行容器
docker run -d -p 8071:8080 -v /www/demo_2:/code -v /logs:/logs --name demo_2 fa14c12a02c1
3.2.4 验证
curl http://127.0.0.1:8071
4.小结
4.1 小小说明
我这里介绍的都是手工操作的处理,文章描述的可能不是很完全,实际上我们用jenkins或者云效等流水线来部署,还是比较方便的。我想说的是,这两种部署方式,在企业中我都是用过,只不过说把应用不打进镜像中的方式有点脱离docker的思想。
4.2我的观点
我在实际工作使用中,这种将代码和环境分离的方式还挺好用的。这里我说一下原因:
1.如果部署比较频道,特别是我们开发测试环境,如果将app+环境打成一个镜像,那么每次部署都要重新打包,然后上传远程仓库,然后再启动,那么这就会导致部署时间较长,因为打包时间和上传时间都比较长;
2.由于基础环境镜像本身就比较大,然后再加上app,这样打出来的镜像就更大,每个镜像都会占用磁盘空间,你会发现,随着工作的继续,我们的磁盘空间消耗很大,因为镜像文件很多很大;
3.对于一些java这种app,如果我只是改个页面,那么我也必须要重新打包镜像,上传远程仓库、启动容器,而实际上我并不需要重启容器,只需要把html文件替换就好了;
4.有人说这样把app和基础环境分开,你回滚就比较困难,但我想说的是,我的代码是用git来管理的,直接回滚到之前的代码版本就好了,不需要回滚镜像(当然不如回滚镜像快)。
在自动化部署中:
第一种app+环境,我们只需要在代码文件中创建Dockerfile和entry.sh两个文件,每次从基础镜像来构建出app+基础环境的镜像,然后执行启动脚本就行了;
第二种app和环境分开,我们只需要在代码文件中创建entry.sh文件,甚至我们都不需要创建任何关于docker启动的文件,因为是一类的应用,我们直接在服务器上放置一个默认的entry.sh脚本文件就行,每次都一个基础镜像直接运行容器就行了,这样镜像的管理也简单的很。
当然使用哪种方式,可以根据自己的需求来进行。这里仅仅是我的一点个人观点。