前言:该系列文章,围绕持续集成:Jenkins+Docker+K8S 相关组件,实现自动化管理源码编译、打包、镜像构建、部署等操作; 本篇文章主要描述 Jenkins 基础用法 。

一、Jenkins 安装

 

1、环境部署

下载 Jenkins 包

注意这里直接下载 war 文件,以 Java 服务的形式启动。

  • 环境:war 运行

  • 版本:2.289.3

  • 类型:Generic Java package (.war)

启动命令

java -jar jenkins.war --httpPort=8090

复制代码

启动日志

Jenkins is fully up and running

复制代码

访问本地端口:8090

该页面会提示初始登录密码的位置,查看该文件中初始密码,并完成登录。

/.jenkins/secrets/initialAdminPassword

复制代码

安装推荐插件

登录之后先把推荐的插件装上。

创建用户

插件安装完成之后会提示创建用户。

账号:admin  密码:admin

复制代码

这样初始化完成。

重新启动:restart

Jenkins_url/restart

复制代码

2、配置与插件

基础配置

打开: Manage-Jenkins 选项,配置 Global-Tool-Configuration 选项:

 

 

- 查看JDK安装目录/usr/libexec/java_home -V
- 查看Git安装目录which git
- 查看Maven安装目录mvn -v

复制代码

配置组件:JDK、Git、Maven,采用开发环境的组件版本;

插件安装

安装如下插件:

1、Maven插件Maven Integration plugin
2、Pipeline插件Pipeline Utility Steps

复制代码

二、本地 Git 打包

简介:基于 Jenkins 完成本地的 Git 仓库项目打包;

1、新建 Item

  • 任务名称:MavLoc,处理本地 maven 工程;

  • 任务类型:选择构建 maven 项目;

2、构建记录管理

保持构建的天数:3 天,保持构建的最大个数:10 个;

3、构建过程

前置 Pre-Steps 步骤,这里执行一次 maven 版本查看:

构建 Build 步骤,这里直接写项目的 pom 路径,注意执行的 maven 命令:

clean package -Dmaven.test.skip=true

复制代码

后置 Post Steps 步骤,注意选择构建成功后才执行,自行忽略这里 shell 语法的不入流组合:

#!/bin/bash
BUILD_ID=dontKillMe
# 定义目录AUTO_PATH=/项目路径/butte-auto-parent/
# 移动Jar包cd $AUTO_PATH/auto-client/target/pwdmv auto-client-1.0-SNAPSHOT.jar $AUTO_PATH
cd $AUTO_PATH/auto-serve/target/pwdmv auto-serve-1.0-SNAPSHOT.jar $AUTO_PATH
# 启动服务cd $AUTO_PATH
nohup java -jar auto-client-1.0-SNAPSHOT.jar &echo "run auto-client ..."
sleep 20s
nohup java -jar auto-serve-1.0-SNAPSHOT.jar &echo "run auto-serve ..."

复制代码

4、执行构建

上述配置完成后,打开任务页面,执行如下操作:

  • Build Now:执行上面的构建任务;

  • 构建 #ID:查看控制台输出的日志;

这样就可以通过 jenkins 完成本地项目的打包和启动了。

三、API 触发任务

1、用户令牌

简介:通过配置用户 API 访问的 token 令牌,脱离 jenkins 控制台,直接触发构建任务;

进入用户面板的设置选项,配置 API Token :

注意这里生成令牌后要立刻复制下来,页面会提示 token 无法复现。

2、任务令牌

任务配置的构建触发器模块,设置远程构建的令牌:

 

 

上面已经给到 token 的使用方式。

3、脚本触发

通过如下方式,直接触发上述构建任务的流程:

curl http://用户:令牌@Jenkins_Url/job/MavLoc/build?token=任务令牌

复制代码

这里通过脚本直接请求 URL 的方式触发流程。

四、打包 Git 项目

1、配置仓库

创建 MavGit 任务,这里不做过多的配置,与本地仓库相比,只是把仓库地址换成 Gitee 地址,只配置仓库 url 和分支即可,其他采用默认:

 

因为是开放的仓库地址,所以不用配置账号密码,默认指定 master 分支,然后执行 build 构建。

2、查看空间

上面流程执行完后,查看 MavGit 的工作空间: /.jenkins/workspace/MavGit :

这里可以明显发现,仓库的代码已经被 pull 下来,并且完成了自动打包流程,后续结合 shell 脚本完成 jar 启动管理即可。

五、Webhook 原理

Pipeline 流水线任务通常情况下都是自动触发的,在 Git 仓库中配置源码改动后通知的地址即可。

例如在 Gitee 仓库中,基于 WebHook 的配置,可以在向仓库 push 代码后,自动回调预先设定的请求地址,从而触发代码更新后的打包动作,基本流程如下:

这里涉及到两个核心配置:

  • Gitee 回调:即仓库接收到 push 请求后的通知地址;在仓库管理的 WebHooks 选项中;

  • Jenkins 流程:编写流水线任务,处理代码提交后的自动化流程;这里需要 Jenkins 地址可以在外网访问,网上的组件很多,自行选择搭建即可;

注意:可以先随意设置回调地址,在请求日志中直接拷贝请求参数,在 postman 中去触发 Jenkins 任务,这样在测试时会方便很多。

这里结合 Gitee 的帮助文档,去分析不同 push 动作的参数标识,可以判断分支的创建、推送、删除等操作,例如:

<code data-type="codeline">"after": "1c50471k92owjuh37dsadfs76ae06b79b6b66c57",</code><code data-type="codeline">"before": "0000000000000000000000000000000000000000",</code>

复制代码

创建分支:before 字符都是 0;删除分支:after 字符都是 0;

六、流水线配置

1、插件安装

在 Jenkins 插件管理中,安装 Generic-Webhook-Trigger 插件,流水线 pipeline 相关组件在 Jenkins 初始化的时候已经安装了。

2、创建流水线

新建 Item,输入任务名称,选择 pipeline 选项即可:

选择 Webhook 选项,页面提示了触发的方式。

3、触发流水线

http://用户名:密码@JENKINS_URL/generic-webhook-trigger/invoke

复制代码

基于如上方式通过认证,触发流水线执行,会生成任务日志,即流程是通顺的。

七、Pipeline 语法

1、结构语法

  • triggers:基于 hook 模式触发流水线任务;

  • environment:声明全局通用的环境变量;

  • stages:定义任务步骤,即流程分段处理;

  • post.always:最终执行的动作;

常规流程中的整体结构如下:

<code data-type="codeline">pipeline {</code><code data-type="codeline">    agent any</code><code data-type="codeline">    triggers {}</code><code data-type="codeline">    environment {}</code><code data-type="codeline">    stages {}</code><code data-type="codeline">    post { always {}}</code><code data-type="codeline">}</code>

复制代码

把各个节点下的脚本配置进去,就会生成一个自动化的流水线任务。注意这里 不勾选 使用Groovy沙盒 选项。

2、参数解析

这里说的参数解析是指,Gitee 通过 hook 机制请求 Jenkins 服务携带的参数,这里主要解析 post 参数即可,解析方式看说明:

这里从 hook 回调的参数中选了几个流程中使用的参数,下面看具体解析方式,在上图中点击新增:

{    "ref":"refs/heads/master",    "repository":{        "name":"butte-auto-parent",        "git_http_url":"仓库地址-URL"    },    "head_commit":{        "committer":{            "user_name":"提交人名称",        }    },    "before":"277bf91ba85996da6c",    "after":"178d56ae06b79b6b66c"}

复制代码

把上述参数依次做好配置即可,这样在工作流中就可以使用这些参数。

3、触发器节点

这里即 triggers 模块配置,核心作用是加载触发流程的一些参数,后续在脚本中使用,其他相关配置按需选择即可,注意这里的参数需要在上个步骤中配置:

<code data-type="codeline">triggers {</code><code data-type="codeline">    GenericTrigger(</code><code data-type="codeline">        genericVariables: [</code><code data-type="codeline">            [key: 'ref', value: '$.ref'],</code><code data-type="codeline">            [key: 'repository_name', value: '$.repository.name'],</code><code data-type="codeline">            [key: 'repository_git_url', value: '$.repository.git_http_url'],</code><code data-type="codeline">            [key: 'committer_name', value: '$.head_commit.committer.user_name'],</code><code data-type="codeline">            [key: 'before', value: '$.before'],</code><code data-type="codeline">            [key: 'after', value: '$.after']</code><code data-type="codeline">        ],</code><code data-type="codeline">        // causeString: ' Triggered on $ref' ,</code><code data-type="codeline">        // printContributedVariables: true,</code><code data-type="codeline">        // 打印请求参数</code><code data-type="codeline">        // printPostContent: true</code><code data-type="codeline">    )</code><code data-type="codeline">}</code>

复制代码

4、环境变量

声明一些全局的环境变量,也可以直接定义,在流程中用 ${变量} 的方式引用:

<code data-type="codeline">environment {</code><code data-type="codeline">    branch = env.ref.split("/")[2].trim()</code><code data-type="codeline">    is_master_branch = "master".equals(branch)</code><code data-type="codeline">    is_create_branch = env.before.replace('0','').trim().equals("")</code><code data-type="codeline">    is_delete_branch = env.after.replace('0','').trim().equals("")</code><code data-type="codeline">    is_success = false</code><code data-type="codeline">}</code>

复制代码

这里根据 hook 请求参数,解析出分支的操作类型:是否创建、是否删除、是否主干分支,以及定义一个 is_success 流程是否成功的标识。

5、分段流程

这里主要分为五个步骤:解析数据、拉取分支、处理 Pom 文件、分支推送、项目打包;

<code data-type="codeline">stages {</code><code data-type="codeline">    // 解析仓库信息</code><code data-type="codeline">    stage('Parse') {</code><code data-type="codeline">        </code><code data-type="codeline">        steps {</code><code data-type="codeline">            echo "仓库分支 : ${branch} \n仓库名称 : ${repository_name} \n仓库地址 : ${repository_git_url} \n提交用户 : ${committer_name}"</code><code data-type="codeline">            script {</code><code data-type="codeline">                if ("true".equals(is_master_branch)) {</code><code data-type="codeline">                    echo "保护分支 : ${branch}"</code><code data-type="codeline">                }</code><code data-type="codeline">                if ("true".equals(is_create_branch)) {</code><code data-type="codeline">                    echo "创建分支 : ${branch}"</code><code data-type="codeline">                }</code><code data-type="codeline">                if ("true".equals(is_delete_branch)) {</code><code data-type="codeline">                    echo "删除分支 : ${branch}"</code><code data-type="codeline">                }</code><code data-type="codeline">            }</code><code data-type="codeline">        }</code><code data-type="codeline">    }</code><code data-type="codeline">        </code><code data-type="codeline">    // 拉取仓库分支</code><code data-type="codeline">    stage('GitPull') {</code><code data-type="codeline">        steps {</code><code data-type="codeline">            script {</code><code data-type="codeline">                if ("false".equals(is_delete_branch)) {</code><code data-type="codeline">                    echo "拉取分支 : ${branch}"</code><code data-type="codeline">                    git branch: "${branch}",url: "${repository_git_url}"</code><code data-type="codeline">                }</code><code data-type="codeline">            }</code><code data-type="codeline">        }</code><code data-type="codeline">    }</code><code data-type="codeline">        </code><code data-type="codeline">    // 解析仓库Pom文件</code><code data-type="codeline">    stage('MvnPom') {</code><code data-type="codeline">        steps {</code><code data-type="codeline">            script {</code><code data-type="codeline">                // 解析Pom文件内容</code><code data-type="codeline">                def pom = readMavenPom file: 'pom.xml'</code><code data-type="codeline">                def version = "${pom.version}"</code><code data-type="codeline">                def encode = pom.getProperties().get("project.build.sourceEncoding")</code><code data-type="codeline">                echo "Pom版本 : "+ version</code><code data-type="codeline">                echo "Pom编码 : "+ encode</code><code data-type="codeline">                def devVersion = "${branch}-"+version</code><code data-type="codeline">                def jarName = "${branch}-"+version+".jar"</code><code data-type="codeline">                echo "Now版本 : "+ devVersion</code><code data-type="codeline">                echo "Jar名称 : "+ jarName</code><code data-type="codeline">                </code><code data-type="codeline">                // 修改Pom文件内容</code><code data-type="codeline">                // pom.getProperties().put("dev.version","${devVersion}".trim().toString())</code><code data-type="codeline">                // writeMavenPom file: 'pom.xml', model: pom</code><code data-type="codeline">                </code><code data-type="codeline">                echo "update pom success"</code><code data-type="codeline">            }</code><code data-type="codeline">        }</code><code data-type="codeline">    }</code><code data-type="codeline">        </code><code data-type="codeline">    // 推送仓库分支</code><code data-type="codeline">    stage('GitPush') {</code><code data-type="codeline">        steps {</code><code data-type="codeline">            script {</code><code data-type="codeline">                echo "git push success"</code><code data-type="codeline">            }</code><code data-type="codeline">        }</code><code data-type="codeline">    }</code><code data-type="codeline">        </code><code data-type="codeline">    // 本地打包流程</code><code data-type="codeline">    stage('Package') {</code><code data-type="codeline">        steps {</code><code data-type="codeline">            script {</code><code data-type="codeline">                sh 'mvn clean package -Dmaven.test.skip=true'</code><code data-type="codeline">                is_success = true</code><code data-type="codeline">            }</code><code data-type="codeline">        }</code><code data-type="codeline">    }</code><code data-type="codeline">}</code>

复制代码

  • 解析数据:解析并输出部分参数信息;

  • 拉取分支:结合 Git 命令,拉取分支代码;

  • 处理 Pom 文件:对 pom 文件的读取和修改;

  • 分支推送:结合 Git 命令,推送分支代码;

  • 项目打包:结合 Mvn 命令,完成项目打包;

注意:这里在本地测试流程时,并没有推送代码;在项目打包完成后,结合 shell 脚本完成服务的启动发布。

6、消息通知

在流程的最后,识别任务的执行标识 is_success ,通知相关人员是否打包成功,这里的通知方式可以选择邮件或者其他 API 推送的通知类型,不过多描述:

<code data-type="codeline">post {</code><code data-type="codeline">    always {</code><code data-type="codeline">        script {</code><code data-type="codeline">            echo "notify : ${committer_name} , pipeline is success : ${is_success}"</code><code data-type="codeline">        }</code><code data-type="codeline">    }</code><code data-type="codeline">}</code>

复制代码

7、执行日志

完成上面 pipeline 流水线脚本开发后,通过 postman 工具不断发送请求,完成脚本调试:

这里也可以点击流程里的不同模块,查看该模块下的日志信息:

 

本内容为合法授权发布,文章内容为作者独立观点,不代表开发云立场,未经允许不得转载。

CSDN开发云