0. 前言

本文旨在帮助读者梳理如何从0开始利用Jenkins构建Maven项目(微服务)的自动发布任务

本文目录如下:


如何完成自动部署

  • 0. 前言
  • 1. 配置工具类地址
  • 1.1 JDK
  • 1.2 Git
  • 1.3 Maven
  • 2. 安装Jenkins
  • 3. 安装额外的工具插件
  • 4. 配置必要参数
  • 4.1 配置仓库人员的用户名和密码
  • 4.2 maven及其配置文件位置
  • 4.3 服务器地址与密码
  • 4.4 开放2375远程访问端口,允许docker客户端以http请求访问私服
  • 5. 微服务部署实例
  • 5.1 新建任务,配置仓库
  • 5.2 Pre Step
  • 5.3 Build
  • 5.4 Post Step
  • 6. 总结


1. 配置工具类地址

以下内容来源于:Jenkins安装并部署Java项目完整流程

首先是在本地安装三个jenkins自动配置相关的工具

1.1 JDK

由于我们使用docker来启动jenkins,其自带有jdk,因此不需要再下载JDK,查看其容器携带的config.v2.json可发现,jdk路径为:

/opt/java/openjdk

1.2 Git

同JDK一致,docker容器中的jenkins自带有git,其路径为

/usr/bin/git

1.3 Maven

个人的Maven安装目录是/usr/bin/maven

mkdir /usr/bin/maven
cd /usr/bin/maven
wget http://mirror.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
tar xzvf apache-maven-3.6.3-bin.tar.gz

安装好后,处理一下settings.xml,配置国内镜像源:

vim /usr/bin/maven/apache-maven-3.6.3/conf/settings.xml

在内填充如下内容:

<mirror>
    <id>aliyunmaven</id>
    <mirrorOf>*</mirrorOf>
    <name>阿里云公共仓库</name>
    <url>https://maven.aliyun.com/repository/public</url>
</mirror>

设置一下本地仓库地址,这里最好设置在maven安装目录下,以保证docker容器映射后,本地仓库可查,我的设置如下:

<localRepository>/usr/bin/maven/apache-maven-3.6.3/repo</localRepository>

最后配置环境变量,保证mvn可查:

vim /etc/profile

在末尾填充:

export M2_HOME=/usr/bin/maven/apache-maven-3.6.3
PATH=$M2_HOME/bin:$PATH

然后执行source /etc/profilemvn -v能显示版本即配置成功

2. 安装Jenkins

我们使用Docker快速安装Jenkins,需要注意的是,在docker hub直接搜索Jenkins,出来的最新版也只有2.4.0版本,其界面如下所示:

jenkins go怎么打包 jenkins打包发布_docker


该版本是不友好的,由于其没有携带Localization Chinese插件,因此无法自动进行插件的安装与更新

使用以下命令在linux中安装最新版本的jenkins:

docker run \
-d --name jenkins -p 8081:8080 -p 50000:50000 \
-v /var/jenkins_home:/var/jenkins_home \
-v /usr/bin/maven/apache-maven-3.6.3:/usr/bin/maven/apache-maven-3.6.3 \
--restart=always \
jenkins/jenkins:2.404

-v /usr/bin/maven/apache-maven-3.6.3:/usr/bin/maven/apache-maven-3.6.3 这一句必须要保持一致:

  • 如果没有在创建容器时建立maven映射,jenkins将无法找到mvn执行程序
  • 如果映射路径不统一,jenkins执行mvn时将面临配置文件丢失问题

使用以下命令允许jenkins可以访问映射路径/var/jenkins_home和/usr/bin/maven:

groupadd jenkins
useradd jenkins -g jenkins
chown -R  jenkins:jenkins  /var/jenkins_home
chown -R  jenkins:jenkins  /usr/bin/maven

安装成功后,访问服务器的8081端口即可进入jenkins登录页面,登录后的新版本界面应如下所示:

jenkins go怎么打包 jenkins打包发布_微服务_02

3. 安装额外的工具插件

本部分参考文献:Jenkins常用插件汇总以及简单介绍原创

下面给出我在使用过程中认为必装的插件列表:

  • Maven Release Plug-in:该插件使得在部署SpringBoot项目时流程更清晰简便
  • Git Parameter:该插件使得可以添加Git远程仓库链接(安装后需重启Jenkins,否则会一直报Java.io异常)
  • Publish Over SSH:该插件使得构建项目时可通过远程SSH发送文件或指令,从而在jenkins中控制其他服务器构建容器

其他的插件选择性安装,安装插件的位置:系统管理–>系统配置–>插件管理–>Available Plugins

安装好后,新建任务时,你应该可以选择Maven任务,配置任务时,在源码配置部分你应该可以增加Git远程仓库,在全局设置管理你应该可以设置远程服务器连接

4. 配置必要参数

jenkins自动构建并发布Maven项目的流程梳理:

  • 从Git仓库拉取代码至本地工作空间:/var/jenkins_home/workspace/[project_name]
  • 执行preBuild工作,一般包括以下步骤:
  • 清理工作空间中可能存在的target目录
  • 清理私服中前一次的微服务打包镜像
  • 根据pom.xml文件以及docker_build插件,执行微服务打包–>生成镜像–>上传镜像的一系列流程(docker_build是不安全的,其要求docker开放远程操作端口且无需验证
  • 执行Build工作:指定父工程pom.xml
  • 执行postBuild工作:运行docker容器

根据流程,我们可梳理出各个流程中需要配置的重要参数:

  • 拉取代码:配置仓库人员的用户名和密码(也可采用令牌访问的方式)
  • preBuild:
  • 清理target目录需要mvn命令支持,因此需要配置maven及其配置文件位置
  • 清理私服中前一次打包镜像,需要使用到docker命令,这里有两种实现选择:(1)直接访问docker远程端口;(2)通过SSH向远程服务器(私服服务器)发送指令,后者更为安全,这里选用后者,其需要配置服务器地址以及密码
  • 调用docker_build插件,需要开放docker远程访问端口2375,以及允许docker私服被docker客户端以http请求访问。因此,此处涉及到两个配置:开放2375远程访问端口;允许docker客户端以http请求访问私服
  • Build:无需额外配置
  • postBuild:无需额外配置

4.1 配置仓库人员的用户名和密码

jenkins go怎么打包 jenkins打包发布_jenkins_03


生成项目时,在Git的Credentials处点击添加以配置

4.2 maven及其配置文件位置

全局工具配置中,将第一部分安装好的maven路径配置过来(由于已经在生成容器时映射了该路径,因此该路径下的文件可查)

首先是配置maven配置文件路径:

jenkins go怎么打包 jenkins打包发布_jenkins go怎么打包_04


然后配置maven路径:

jenkins go怎么打包 jenkins打包发布_微服务_05


由此,我们保证了jenkins调用mvn时,以下内容可查(均为映射路径):

  • 配置文件可查
  • 本地仓库可查

此处顺带配置一下JDK和Git的地址,如第一部分所给出的:

jdk: /opt/java/openjdk
git: /usr/bin/git

4.3 服务器地址与密码

在系统配置下,找到Publish over SSH配置项,配置服务器的Name(自定义,如aliyun), Hostname(主机地址,如192.168.0.1),Username(用户名,如root),在高级配置中选择使用密码验证,并在Password输出密码。配置好后应如下图所示:

jenkins go怎么打包 jenkins打包发布_jenkins_06


此时,在使用SSH发送指令时,即可指定该远程服务器(这也是在不同服务器部署不同微服务容器的基础)

4.4 开放2375远程访问端口,允许docker客户端以http请求访问私服

以下内容来源于:Docker开启远程安全访问

简单总结一下步骤:

  • 要部署微服务的服务器上编辑docker.service文件:vim /usr/lib/systemd/system/docker.service
  • 找到 文件中的[Service] 节点,修改 ExecStart 属性,增加 -H tcp://[Jenkins部署地址]:2375 --insecure-registry [Jenkins部署地址]:5000,前者开放docker远程访问,允许Jenkins以tcp请求访问2375端口,后者允许Jenkins以http请求访问私服(必须注意docker远程连接一定不能允许任一ip访问,也就是写成0.0.0.0,否则将造成严重的服务器风险
  • 运行:systemctl daemon-reload && systemctl restart docker

运行成功后即配置成功

这里有一个特殊的示例,如果你准备在同一台服务器部署jenkins,并利用该台服务器创建私服并启动微服务,那么,这里的[Jenkins部署地址]可以直接填docker的虚拟网关172.17.0.1

以上就是建立项目前需要做好的配置工作,接下来我将以一个微服务部署的例子介绍如何编写自动部署项目的流程

5. 微服务部署实例

以黑马程序员的学成在线项目为实例,挑选了其中五个微服务进行部署,分别是:system, gateway, auth, content, media(其余的则是打包时的依赖),项目结构如下

jenkins go怎么打包 jenkins打包发布_maven_07


其中,system,content,media采用api–>service–>model三层架构,最终在父工程中打包并以api生成微服务,如下图所示:

jenkins go怎么打包 jenkins打包发布_maven_08

5.1 新建任务,配置仓库

首先,在jenkins中新建一个任务,配置好源码仓库

jenkins go怎么打包 jenkins打包发布_docker_09

5.2 Pre Step

正如之前所述,Pre Step要完成以下工作:

  • 调用SSH向私服远程发送清理残余镜像指令,指令如下:
docker stop junxianghui-gateway 
docker rm junxianghui-gateway 
docker exec registry rm -rf /var/lib/registry/docker/registry/v2/repositories/junxianghui-gateway
docker stop junxianghui-user
docker rm junxianghui-user
docker exec registry rm -rf /var/lib/registry/docker/registry/v2/repositories/junxianghui-user
docker stop junxianghui-log
docker rm junxianghui-log
docker exec registry rm -rf /var/lib/registry/docker/registry/v2/repositories/junxianghui-log
docker stop junxianghui-pay
docker rm junxianghui-pay
docker exec registry rm -rf /var/lib/registry/docker/registry/v2/repositories/junxianghui-pay
docker stop junxianghui-cashback
docker rm junxianghui-cashback
docker exec registry rm -rf /var/lib/registry/docker/registry/v2/repositories/junxianghui-cashback
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml

其中,命令行

docker exec registry rm -rf /var/lib/registry/docker/registry/v2/repositories/junxianghui-gateway

是为了清理私服的镜像目录

命令行

docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml

是为了清理私服的镜像文件,二者缺一不可,否则均会导致镜像无法更新

这里我们建议在宿主机中通过.sh文件的方式批量执行上述命令,放在jenkins中执行上述命令可能会导致服务器内存爆炸(亲身经历)

  • 调用mvn指令清理target目录,并重构maven项目
  • 首先是整体清理以及重构父工程pom,自动下载项目的所有依赖至本地仓库
  • 然后分别对五个微服务,调用docker_builder插件,完成打包–>生成镜像–>上传的一系列流程

    这里顺便贴一个docker_builder插件的pom配置方式:
<build>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>${spring-boot.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.2.2</version>
            <configuration>
                <!--修改imageName节点的内容,改为私有仓库地址和端口,再加上镜像id和 TAG,我们要直接传到私服-->
                <!--配置最后生成的镜像名,docker images里的,我们这边取项目名:版本-->
                <!--<imageName>${project.artifactId}:${project.version}</imageName>-->
                <imageName>[请填入你的docker私服ip,示例:172.17.0.1]:5000/${project.artifactId}:${project.version}</imageName>
                <!--也可以通过以下方式定义image的tag信息。 -->
                <!-- <imageTags>
                     <imageTag>${project.version}</imageTag>
                     <!–build 时强制覆盖 tag,配合 imageTags 使用–>
                     <forceTags>true</forceTags>
                     <!–build 完成后,push 指定 tag 的镜像,配合 imageTags 使用–>
                     <pushImageTag>true</pushImageTag>
                 </imageTags>-->
                <baseImage>java:8u20</baseImage>
                <maintainer>docker_maven docker_maven@email.com</maintainer>
                <workdir>/root</workdir>
                <cmd>["java", "-version"]</cmd>
                <!--来指明Dockerfile文件的所在目录,如果配置了dockerDirectory则忽略baseImage,maintainer等配置-->
                <!--<dockerDirectory>./</dockerDirectory>-->
                <!--2375是docker的远程端口,插件生成镜像时连接docker,这里需要指定docker远程端口,前缀http不可删除,否则jenkins报错-->
                <dockerHost>http://[请填入你的docker私服ip,示例:172.17.0.1]:2375</dockerHost>
                <!--入口点,project.build.finalName就是project标签下的build标签下 的filename标签内容,testDocker-->
                <!--相当于启动容器后,会自动执行java -jar ...-->
                <entryPoint>["java", "-Dfile.encoding=utf-8","-jar", "/root/${project.build.finalName}.jar"]</entryPoint>
                <!--是否推送到docker私有仓库,旧版本插件要配置maven的settings文件。 -->
                <pushImage>true</pushImage>
                <registryUrl>[请填入你的docker私服ip,示例:172.17.0.1]:5000</registryUrl>  <!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
                <resources>
                    <resource>
                        <targetPath>/root</targetPath>
                        <directory>${project.build.directory}</directory>
                        <!--把哪个文件上传到docker,相当于Dockerfile里的add app.jar /-->
                        <include>${project.build.finalName}.jar</include>
                    </resource>
                </resources>
            </configuration>
        </plugin>
    </plugins>
</build>

至此,Pre Step已为我们准备好docker容器运行的镜像

5.3 Build

Build只需要设置root pom即可,具体该设计的目的此处不明

jenkins go怎么打包 jenkins打包发布_jenkins_10

5.4 Post Step

Post Step只需通过SSH远程向服务器发送运行docker容器的命令即可

运行命令整理如下:

docker run -p 63070:63070 --name xuecheng-plus-auth -idt 172.21.74.125:5000/xuecheng-plus-auth:0.0.1-SNAPSHOT
docker run -p 63010:63010 --name xuecheng-plus-gateway -idt 172.21.74.125:5000/xuecheng-plus-gateway:0.0.1-SNAPSHOT
docker run -p 63110:63110 --name xuecheng-plus-system -idt 172.21.74.125:5000/xuecheng-plus-system-api:0.0.1-SNAPSHOT
docker run -p 63040:63040 --name xuecheng-plus-content -idt 172.21.74.125:5000/xuecheng-plus-content-api:0.0.1-SNAPSHOT
docker run -p 63050:63050 --name xuecheng-plus-media -idt 172.21.74.125:5000/xuecheng-plus-media-api:0.0.1-SNAPSHOT

成型配置如下:

jenkins go怎么打包 jenkins打包发布_微服务_11

6. 总结

本文从0开始,一步步介绍了如何利用Jenkins来构建Maven项目(微服务)并自动发布,其中有很多的细节需要读者耐心阅读,如有疑问欢迎留言!

最后,SSH远程指令的形式将是未来进行多机微服务部署的基础与关键,其为jenkins提供了丰富多彩的操作远程服务器的支持,需要读者花费精力去领悟它!