Jenkins基础CI实践

6,029 阅读3分钟

前面我们搭建好了基本的jenkins环境,是时候借助jenkins的构建任务将推送到gitlab的项目源码拉取过来进行基础的CI构建了。开干!

gitlab创建项目

spring boot项目

首先我们在本地用idea向导创建一个基于gradle构建的spring boot项目:

image.png

项目路径:E:\study\spring_boot\code\cicd\hello\hello

这是一个最简单的hello world应用,代码就省略了。

创建gitlab项目

登录gitlab后,New Project -> 创建一个空白项目

image.png

点创建项目即可。

git客户端

安装与设置

下载地址:git-scm.com/downloads

安装向导中,勾选添加到桌面,选择editor:

image.png

后续安装默认即可。

全局设置用户、邮箱,在终端中运行:

git config --global user.name "xiaojuan"
git config --global user.email "1372569394@qq.com"

生成和配置key

桌面右键

image.png

执行操作命令:

# 进入用户目录
cd ~/
# 创建.ssh目录
mkdir .ssh
cd .ssh

# 键入下面的命令后点几次回车
ssh-keygen -t rsa -C "1372569394@qq.com"

把id_rsa.pub里的内容粘贴到gitlab密钥中

image.png

进入项目首页

image.png

进入地址:http://192.168.0.113:8929/-/profile/keys

image.png

点击Add Key。

commit和push源码

使用idea自带的git工具进行图形化的操作。

创建本地仓库

image.png

image.png

选中hello项目,项目右键 -> Git -> 提交目录

全部勾选,写下提交信息,点提交

image.png

接下来进行push操作,先在gitlab项目页clone下,地址:ssh://git@192.168.0.114:2224/root/hello.git

项目右键-> Git -> Push

点Define remote,输入URL:ssh://git@192.168.0.114:2224/root/hello.git

最后直接点push按钮即可。

这样看到最终把项目push到gitlab上了。

后续改了代码可以commit并push:

image.png

基础CI流程

配置全局凭据

先配置全局jenkins用户的ssh登录凭据

image.png

把本地.ssh目录下的id_rsa文件内容拷贝到private key的填写域中。

同时配置在全局安全策略中不验证host key

image.png

创建任务拉取代码

在Jenkins的Dashboard页面左侧点新建任务,输入任务名test01,选自由风格的任务,确定。

添加git仓库地址:

image.png

最后保存。

然后点立即构建,看到控制台输出,拉取到gitlab仓库中项目的最新代码:

image.png

进入jenkins容器的内部查看下拉取的源码目录:

[root@dev-1 jenkins]# docker exec -it jenkins bin/bash

image.png

执行gradle构建

找到任务的项目配置:

image.png

image.png

设置完点击保存。

构建后,输出的信息:

image.png

推送可执行jar

继续将gradle构建好的可执行jar包推送到实现配置好的服务器test-1上。

image.png

注意,这里推送后的路径要删除前缀的路径,因为我们不希望在服务器上也创建这样的目录。

远程部署和启动应用

要执行spring boot的远程构建,我们可以先通过jenkins构建后把构建好的jar包传到目标服务器,在把要执行的docker相关的命令也传过去,进行执行。现在我们将采用另一种方式,通过在工程中增加gradle的docker插件来直接支持远程打包,在目标服务器上生成构建好的image,然后再发送启动容器的命令,把目标服务启动起来。

gradle的docker插件

首先在工程中增加如下gradle的docker插件配置:

plugins {
    ...
    id 'com.bmuschko.docker-spring-boot-application' version '6.7.0'
}

...

docker {
    url = 'tcp://192.168.0.115:2375'
    springBootApplication {
        baseImage = 'openjdk:8-jre-slim'
        maintainer = 'xiaojuan'
        ports = [8082]
        images = "hello:${PROJECT_VERSION}"
        jvmArgs = ['-Dspring.profiles.active=test']
    }
}
...

然后刷新gradle后,看到要执行的目标任务:

image.png

远程docker服务设置

执行会发现,目标服务拒绝请求,这里要修改下远程服务器的docker中的配置:

在服务器中打开文件:/lib/systemd/system/docker.service,修改的内容:

# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

重启下docker

systemctl daemon-reload
systemctl restart docker

确保本地可以执行下面命令:

curl 192.168.0.115:2375
{"message":"page not found"}

dockerBuildImage任务

先在目标服务器上pull基础镜像:

docker image pull daocloud.io/library/java:8u40-jdk

然后执行dockerBuildImage任务,可以看到目标服务器上构建好的image:

image.png

当修改了源码后,重新构建后,会发现生成新的image,而原来的image变为废弃的null,这些是我们考虑要清理的。

image.png

提交修改后的build.gradle的代码,进行Jenkins的构建,修改gradle要执行的目标任务:

image.png

可以看到gradle构建的目标的任务:

image.png

说明Jenkins的构建任务执行了docker远程构建image的插件任务。

启动服务

这里我们将通过docker-compose来启动spring boot应用,先在工程中增加docker-compose.yml的定义:

image.png

提交git后,修改Jenkins中hello项目构建任务的配置,ssh传输设置改为如下,舍弃原来传jar包的方式:

image.png

再执行下Jenkins的构建,看到最终在test-1服务器上构建了image(如果代码有更新的话,会重新构建image),同时会把工程中的docker/docker-compose.yml文件传到基准路径/usr/local/test下的hello/下。如果这个docker-compose后续不经常改,也可以手动在test-1上建下,不要维护到git上,每次jenkins拉取后都要执行后续的传文件,就没这个必要了,只要关注服务的重新启动。再看下我们要对远程服务器执行的构建命令:

image.png

这样我们就可以对有变更的构建重启服务了,并且会把作废的image清理掉。

基于tag的构建

在我们的代码库中通常我们会以打tag的形式来标注一个项目或者模块当前开发的功能版本分支,同样在jenkins构建和部署应用时也要能对特定的tag所代表的分支进行构建。这一小节,一起来实践下。

Jenkins参数化构建设置

选择参数化构建:

image.png

image.png

在gradle构建之前,增加执行shell的步骤:

image.png

把新增的shell框挪到gradle构建之前,

image.png

最后保存

设置gitlab tag

image.png

image.png

image.png

这样在每次改了代码提交后,可以在新的时间点上设置新的tag。

维护gradle构建的版本

gitlab上打的标签,在jenkins中执行构建时,可以从环境参数获取git参数传过来的信息,也就是这里的tag参数:

build.gradle中获取环境参数:

ext.PROJECT_VERSION = System.getenv('tag')

docker-compose.yml中获取环境参数:

...
services:
  hello:
    image: hello:${tag}
    ...

按指定tag的版本启动服务

当gradle的docker插件按tag打出版本后,要在目标服务器上启动相应版本的应用,这里需要在docker-compose up时指定一个tag相关的环境变量,而在jenkins服务器发送命令时,可以这样传递环境变量:

image.png

对于同一个tag,如果要更新功能,可以先在gitlab上删除tag,提交代码后重新再打相同的tag,再jenkins构建该tag,此时docker image prune -f会清理废弃的image。

Jenkins构建时指定源码的tag版本即可:

image.png