这里仅仅说明一下在企业应用的两种简单实践,并不包含自动化这套东西。这里说的两种实践,是我在工作中不同公司使用的两种部署方式,仅供大家参考。
第一种:是把环境和app都一起打成一个镜像,每次部署都重新打一个镜像,然后启动容器;
第二种:仅仅把环境打成一个镜像,每次部署的时候,通过容器数据卷的方式,将app复制到容器中;
app: springboot的jar文件,里面加入了日志
java环境:jdk1.8
目录安排:
日志目录:/logs/
应用目录:/code/
我在这里准备了jdk-8u261-linux-x64.tar.gz 这个jdk文件:
内容如下:
FROM centos:7.6.1810
LABEL \
author="lxc" \
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
docker build -t donkey/java8:1.0.0 .
镜像打包物料放在了/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拷贝进去,然后执行命令。
执行构建命令:
docker build -t donkey/docker-demo:1.0.0 .
我在/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
curl http://127.0.0.1:8070
在/data/docker/java8_1我放了一个Dockerfile文件
内容如下:
FROM donkey/java8:1.0.0
ENTRYPOINT ["sh", "entry.sh"]
其实就是在基础镜像上加了一个命令执行。
构建
docker build -t donkey/java8_1:1.0.0 .
docker run -d -p 8071:8080 -v /www/demo_2:/code -v /logs:/logs --name demo_2 fa14c12a02c1
curl http://127.0.0.1:8071
我这里介绍的都是手工操作的处理,文章描述的可能不是很完全,实际上我们用jenkins或者云效等流水线来部署,还是比较方便的。我想说的是,这两种部署方式,在企业中我都是用过,只不过说把应用不打进镜像中的方式有点脱离docker的思想。
我在实际工作使用中,这种将代码和环境分离的方式还挺好用的。这里我说一下原因:
1.如果部署比较频道,特别是我们开发测试环境,如果将app+环境打成一个镜像,那么每次部署都要重新打包,然后上传远程仓库,然后再启动,那么这就会导致部署时间较长,因为打包时间和上传时间都比较长;
2.由于基础环境镜像本身就比较大,然后再加上app,这样打出来的镜像就更大,每个镜像都会占用磁盘空间,你会发现,随着工作的继续,我们的磁盘空间消耗很大,因为镜像文件很多很大;
3.对于一些java这种app,如果我只是改个页面,那么我也必须要重新打包镜像,上传远程仓库、启动容器,而实际上我并不需要重启容器,只需要把html文件替换就好了;
4.有人说这样把app和基础环境分开,你回滚就比较困难,但我想说的是,我的代码是用git来管理的,直接回滚到之前的代码版本就好了,不需要回滚镜像(当然不如回滚镜像快)。
在自动化部署中:
第一种app+环境,我们只需要在代码文件中创建Dockerfile和entry.sh两个文件,每次从基础镜像来构建出app+基础环境的镜像,然后执行启动脚本就行了;
第二种app和环境分开,我们只需要在代码文件中创建entry.sh文件,甚至我们都不需要创建任何关于docker启动的文件,因为是一类的应用,我们直接在服务器上放置一个默认的entry.sh脚本文件就行,每次都一个基础镜像直接运行容器就行了,这样镜像的管理也简单的很。
当然使用哪种方式,可以根据自己的需求来进行。这里仅仅是我的一点个人观点。