一、配置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项目主页面点立即构建,马上看看报错信息吧!()
- 本文作者: reiner
- 本文链接: https://reiner.host/posts/f608275d.html
- 版权声明: 转载请注明出处,并附上原文链接