使用Jenkins + docker 自动化部署Spring Cloud微服务的采坑之路 其三【使用maven插件dockerfile-maven-plugin自动构建镜像】

一、配置pom.xml

上一章里我们已经配置好了jenkins,接下来配置maven项目插件,pom.xml如下:

<plugin> 
			<groupId>com.spotify</groupId> 
			<artifactId>dockerfile-maven-plugin</artifactId> 
			<version>1.4.9</version> 
			<!-- 运行mvn 打包命令时会自动打包镜像并推送  -->
			<executions>
				<execution> 
					<id>default</id> 
					<goals> 
					<goal>build</goal>
					<!-- 推送 -->
					<goal>push</goal>
					</goals>
				</execution>
			</executions>
			<configuration> 
				<skip>${dockerfile.skip}</skip>
                <!-- docker连接地址 -->
				<dockerHost>http://http://192.168.2.55:2375/</dockerHost>
				<!-- 测试推送到docker hub的仓库 -->
				<repository>yourAccount/${project.artifactId}</repository>
				
				<username>yourAccount</username>
				<password>****</password>
				<!-- 从master/target目录build  -->
				<buildDirectory>${session.executionRootDirectory}/target/</buildDirectory>
				<!-- push镜像需要在maven中配置镜像地址,目录测试服务器的maven路径是/root/.jenkins/tools/hudson.tasks.Maven_MavenInstallation/maven-3.6.0/conf -->
				<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
                  <!-- 这个是你要在dockerfile里使用的maven变量,在此处配置后可在dockerfile里使用该 变量 -->
				<buildArgs>
					<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
					<SERVER_PORT>${dockerfile.port}</SERVER_PORT>
				</buildArgs> 
			</configuration> 
		</plugin>

 

该插件能帮助我们完成:

 1、自动构建docker镜像

 2、自动将docker镜像推送到远程库

 3、半自动启动docker容器

 

二、添加dockerfile

在你的项目根目录新建一个dockerfile文件(名字就叫dockerfile,没有后缀),编辑内容,配置以下:

FROM java:8-jre-alpine
#FROM 使用java环境镜像
#设置挂载目录,使用项目名作为日志文件夹,所有项目的日志统一都是spring.log,因此使用文件夹区分
VOLUME /usr/docker/logs
ARG JAR_FILE
#将该项目的JAR添加到镜像中
ADD ${JAR_FILE} app.jar
#RUN bash -c 'touch app.jar'
#配置该项目要映射出去的端口,目前和项目配置文件中端口不一样是为了测试用,生产请修改为一致的端口,如需使用配置文件中的端口,把--server.port=删除,并将EXPOSE修改为项目配置文件对应的端口
EXPOSE 8399
#jar运行命令
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar","--spring.profiles.active=test","--server.port=8399"]

该文件可以看作是docker容器的运行配置,其中FROM JAVA:8 配置了java环境的docker镜像,该镜像的版本号是:8-jre-alpine,远程镜像可以从duckerhub搜索,如果仅仅是运行java代码的项目,那么java镜像足以。

PS:如果是结构的maven项目,那么每个maven子项目都需要一个dockerfile,运行maven打包命令时要跳过parent项目打包,因为parent是一个空项目仅仅是用于配置通用的pom.xml  , pom.xml插件配置中有这么一段:

<skip>${dockerfile.skip}</skip>    ,表示是否跳过打包,在所有的parent 项目的pom.xml中添加如下配置即可:

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<dockerfile.skip>true</dockerfile.skip>
	</properties>

这样打包插件就不会打包parent项目了。

 

三、编写docker镜像的自动启动shell命令

 

新建一个run.sh文件(该文件是用于jenkins执行完打包命令后自动运行docker命令时用),添加以下代码:

declare -A map=(["service1"]="8399:8399" ["service2"]="8201:8201" ["service3"]="8206:8206")
#API_PORT="8888"
# 进入target目录并
cd $WORKSPACE/target
for file in *
do
#只要jar文件 
if [ "${file##*.}"x = "jar"x ];then 
#Jenkins中编译好的jar名称 
jar_name=${file%-*.*.*-SNAPSHOT.jar}
#截取jar包的名称作为镜像名
IMAGE_NAME="yourAccount/$jar_name"
CONTAINER_NAME="$jar_name"
# 构建Docker镜像(maven插件已做)
#docker build -t $IMAGE_NAME .
# 推送Docker镜像
#docker push $IMAGE_NAME
# 判断镜像存在才启动容器
cid=$(docker images | grep $IMAGE_NAME |awk '{print $3}')
if [ x"$cid" != x ]
then
#获取map中的值     --entrypoint=["java","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar","--spring.profiles.active=test","--server.port=${START_PORT}"] --expose=${START_PORT}
PORT_VAL=${map[$jar_name]}
#截取:前的端口号作为启动端口
START_PORT=${PORT_VAL%%:*}
# 启动Docker容器 大写P表示随机端口, --link分别是eureka、gateway的IP和端口,如果有多个eureka配置host并使用hostname.-link 可以让两个容器之间互相通信             -v xx:xx 设置映射目录,这样容器被删除该文件夹下日志也不会被删
RUN_SHELL="docker run -d -p ${PORT_VAL} -v /usr/docker/logs:/logs --name=$CONTAINER_NAME $IMAGE_NAME "
echo $RUN_SHELL
$RUN_SHELL
fi
fi 
done

上述的shell命令是遍历了maven项目target下所有jar文件,通过截取jar文件的名称用作docker镜像名,并通过docker命令判断镜像是否已经存在,如果存在才调用 docker应用启动命令,这一段shell命令其实就是一段启动docker容器的命令。

然后关于第一条代码declare -A map=(["service1"]="8399:8399" ["service2"]="8201:8201"    有必要说明 下,因为docker镜像里的端口和宿主机的端口是独立分开的,如果启动时让docker自动随机分配端口,那么注册中心就会找不到这个服务,因为服务启动的时候是在docker镜像里启动的,而docker镜像的端口和映射到宿主机的端口是不一样的就会访问不到,举例:service1 在docker镜像中启动了,启动端口为:8080,那么要访问它则必须将它的端口映射出来,如果让docker随机分配比如分配了4567,那么如果你要访问service1的url则是 http:localhost:4567  而不是8080,因此只有端口映射统一注册中心才能找得到该 服务。

 

四、编写自动删除镜像的shell代码

在每次打包maven项目时该插件都会重新打包并推送docker镜像,如果之前已经打包过了Dockers镜像,那么这次执行它会生成一个字句叫"null"的镜像(因为重名了),所有需要在打包之前清除之前的Docker镜像:

#此sh用于在构建前删除已经存在的镜像
# 进入target目录并   $WORKSPACE是jenkins变量,表示当前项目所在的位置
cd $WORKSPACE/target
for file in *
do 
#只要jar文件 
if [ "${file##*.}"x = "jar"x ];then 
#Jenkins中编译好的jar名称 
jar_name=${file%-*.*.*-SNAPSHOT.jar}
#截取jar包的名称作为镜像名
IMAGE_NAME="yourAccount/$jar_name"
CONTAINER_NAME="$jar_name"
# 构建Docker镜像(maven插件已做)
#docker build -t $IMAGE_NAME .
# 推送Docker镜像
#docker push $IMAGE_NAME
# 删除Docker容器
cid=$(docker ps | grep $CONTAINER_NAME |awk '{print $1}')
if [ x"$cid" != x ]
    then
    echo $CONTAINER_NAME
    docker rm -f $cid
fi
# 删除Docker镜像
tid=$(docker images | grep $IMAGE_NAME |awk '{print $3}')
if [ x"$tid" != x ]
    then
    echo $IMAGE_NAME
    docker rmi -f $tid
fi

fi 
done

上述代码是通过截取jar文件名称 然后调用 docker命令判断容器、镜像是否存在 ,如果 已经存在则删除.

 

五、配置jenkins

准备工作已经完成,接下来完成最后的配。

基础的配置保持不变(如第二章:点击查看,除了post step那步不需要)。

 1、在jenkins执行打包命令之前执行clean.sh(jenkins的配置名称好像是post before??总之大概是这个意思啦)

     在该Jenkins配置输入框里输入 sh clean.sh就行了,别忘记把clean.sh放在项目根目录

2、在post setp(也就是执行完成打包命令之后的配置),填入sh run.sh,同样记得把run.sh放入项目根目录。

好了,终于配完了,接下来点保存配置,再回到jenkins项目主页面点立即构建,马上看看报错信息吧!(

 

文章新地址:https://reiner.host/posts/f608275d.html

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值