别当工具人了,手摸手教会你 Jenkins !

一、Jenkins 是什么

Jenkins是一个开源软件项目,是基于java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。

简单来说,它就是一个 持续集成 的工具!

1. 持续集成

持续集成(Continuous Integration),简称 CI。频繁地将代码集成到主干之前,必须通过自动化测试,只要有一个测试用例失败,就不能集成。通过持续集成,团队可以快速从一个功能到另外一个功能。

image

好处:

  • 降低风险,由于持续集成不断去构建,编译和测试,可以很早发现问题
  • 减少重复性的工作
  • 持续部署,提供可部署单元包
  • 持续交付可供使用的版本

2. Jenkins 持续集成

image

我们先通过这张图来看到 Jenkins 在其中起到的作用:

  • 首先,开发人员将代码提交到 Git 仓库
  • 然后 Jenkins 使用 Git 插件来拉取 Git 仓库的代码,然后配合 JDK、Maven 等软件完成代码编译,测试、审查、、测试和打包等工作
  • 最后 Jenkins 将生成的 jar/war 推送到 测试/生产 服务器 ,供用户访问

整套步骤下来,作为开发人员我们只需要提交下代码,剩下的工作都交给了 Jenkins ,真是美滋滋,怎么没有早点上这个工具的车!

二、Jenkins 安装

磨刀不误砍柴工,没刀的情况下说再多都是虚的。我们就先来看下 Jenkins 是如何安装的吧!

1. 安装JDK

因为 Jenkinsjava 写的,所以要运行起来必须要配置 java 运行环境。这里就不赘诉 JDK 的安装过程了

2. 下载安装 Jenkins

  • 下载

我们可以进入下载页面选择我们要安装的版本:下载地址, 我们这里使用的版本是 :jenkins-2.190.3-1.1.noarch.rpm

  • 安装

然后把下载好的 rpm 包上传到我们的服务器,通过 rpm -ivh jenkins-2.190.3-1.1.noarch.rpm 进行安装,然后编辑 etc 目录下的 jenkins 配置文件:vim /etc/sysconfig/jenkins,需要改的地方如下(也可以选择不改):

JENKINS_USER="root"
JENKINS_PORT="8888"
复制代码
  • 启动

systemctl start jenkins

  • 访问

通过浏览器访问 http://服务器IP:8888/,看到以下页面说明启动成功了

image

然后我们在服务器上从指定文件中获取密码,进行下一步。

这一步我们可以先跳过插件安装,因为Jenkins插件需要连接默认官网下载,速度非常慢:

image

然后我们添加一个管理员账号来管理:

image

看到以下页面就说明设置成功了:

image

微信公众号关注:小菜良记 ,带你领略技术风骚!

三、Jenkins 使用

1. 插件加速

工欲善其事,必先利其器

贴心的小菜是不会让你遭受等待的痛苦的,首先我们进入 Jenkins -> Manage Jenkins -> Manage Plugins ,点击 install

image

然后我们在安装 Jenkins 的服务器上进入 /var/lib/jenkins/updates 目录,可以看到有个 default.json 文件,第一步:我们需要替换里面的部分字段,输入命令如下:

sudo sed -i 's#updates.jenkins.io/download/plugins#mirrors.tuna.tsinghua.edu.cn/jenkins/plugins#g' default.json && sudo sed -i 's#www.google.com#www.baidu.com#g' default.json
复制代码

第二步:我们进入到 /var/lib/jenkins目录,编辑 hudson.model.UpdateCenter.xm,将里面的 https://updates.jenkins.io/update-center.json修改为 http://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

最后一步: 输入以下命令进行重启 Jenkins

systemctl restart jenkins
复制代码

通过以上步骤,我们就可以愉快的安装插件了!

2. 用户管理

Jenkins 中我们也可以进行用户权限管理,这个时候我们需要借助插件 Role-based Authorization Strategy

  • 首先安装 Role-based Authorization Strategy 插件
image
  • 开启全局安全配置
image

将授权策略切换为 "Role-Based Strategy"

image
  • 创建用户

更改完授权策略,我们就可以来创建用户了,进入系统管理页面中的Manage Users

image

这里我们创建了两个用户,分别是 cbuc1cbuc2

image
  • 创建角色

创建好用户,我们就可以来创建角色了,在系统管理页面进入 Manage and Assign Roles

image

角色主要分为 Global roles(全局角色)Item roles(项目角色)

Global roles(全局角色): 管理员等高级用户可以创建基于全局的角色

Item roles(项目角色): 针对某个或者某些项目的角色

image

我们系统现在已经存在了两个用户,然后我们就可以给这两个用户绑定对应的角色

image

3. 凭证管理

什么是凭证呢? 凭证 可以用来存储需要密文保护的数据库密码,GitLab 密码信息,Docker 私有仓库的登录密码。保存了这些信息后,Jenkins 就可以和这些第三方的应用进行交互。当然,这还是得借助 Jenkins 的插件!

1)安装

首先安装 Credentials Binding 插件

image

安装好插件后,在系统首要的菜单栏中就会多了个 凭证 菜单

image

点击进去,我们可以看到可以添加的凭证有 5 种:

image
  1. Username with password :用户名和密码
  2. SSH Username with private key: 使用 SSH 用户和密钥
  3. Secret file: 需要保密的文本文件,使用时 Jenkins 会将文件复制到一个临时目录中,再将文件路径设置到一个变量中,等构建结束后,所复制的 Secret file 就会被删除
  4. Secret text: 需要保存的一个加密的文本串,如钉钉机器人或 GitHubapi token
  5. Certificate: 通过上传证书文件的方式

我们平时比较常用的类型为:Username with passwordSSH Username with private key

2)Git 凭证管理

我们如果要使用 JenkinsGitLab 拉取项目代码,我们就得使用凭证来验证。

  • 安装 Git 插件

我们需要在 Jenkins 中安装 Git插件 来拉取项目代码

image

然后我们在服务器上也需要安装 Git 工具

# 安装命令
yum install git -y
# 验证命令
git --version
复制代码
1. 方式1:用户密码类型

我们可以使用 用户密码 登录后拉取项目代码,这个时候我们需要用到 凭证的 Username with password 类型

image
image

创建成功我们就可以测试是否可用,我们先创建一个 FreeStyle 项目

image

然后在 GitLab 中复制我们项目的 URL

image

Credentials 中选择我们刚刚创建的凭证,保存配置后,我们点击 Build Now 来构建项目:

image

这个时候在控制台可以看到输出

image

然后在进入服务器的 /var/lib/jenkins/workspace 目录中看到我们拉取的项目:

image

说明我们已经成功使用 用户密码 凭证模式拉取到 Git项目了

2. 方式2:SSH密钥类型

除了用账号密码方式来验证 Git ,我们还可以用 SSH密钥 来验证,步骤流程如下:

image

从图上我们可以得知,第一步需要生成 公私钥,我们在 Jenkins服务器 上输入以下指令生成:

ssh-keygen -t rsa 输入指令后,一路回车,便可在 /root/.ssh/ 目录下生成公私钥:

image
  • id_rsa:私钥文件
  • id_rsa.pub:公钥文件

然后我们把生成的公钥放在 GitLab 中,root账户登录->点击头像->Settings->SSH Keys,复制 id_rsa.pub 中的内容,点击 "Add key"

image

然后我们再回到 Jenkins 系统页面中添加凭证,选择 SSH Username with private key ,把刚刚生成的私有文件内容复制过来

image

添加后就会生成一条凭证

image

创建成功我们就可以测试是否可用,我们先创建一个 FreeStyle 项目

image

然后在 GitLab 中复制我们项目的 URL

image

Credentials 中选择我们刚刚创建的凭证,保存配置后,我们点击 Build Now 来构建项目:

image

这个时候在控制台可以看到输出

image

然后在进入服务器的 /var/lib/jenkins/workspace 目录中看到我们拉取的项目:

image

说明我们已经成功使用 SSH Username with private key 凭证模式拉取到 Git项目了

4. 项目管理

1)Maven 安装

我们现在开发中的项目大部分都是 Maven 项目,使用 Maven 项目,我们就需要进行 依赖管理,因此我们应当在服务器上安装 Maven 来下载项目依赖。

  • 安装 Maven

我们可以从 Maven 官网上下载压缩包,然后上传到服务器上进行解压

tar -xzf apache-maven-3.6.0-bin.tar.gz

  • 配置环境变量

vim /etc/profile

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export MAVEN_HOME=/home/maven/apache-maven-3.6.2
export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin
复制代码

编辑后使配置文件生效:

source /etc/profile
复制代码

验证:

mvn -v
复制代码

然后设置 Mavensettings.xml

# 创建本地仓库目录
mkdir /data/localRepo
vim /home/maven/apache-maven-3.6.2/conf/settings.xml
复制代码

将本地仓库改为: /root/repo/

添加阿里云私服地址:alimaven aliyun maven http://maven.aliyun.com/nexus/content/groups/public/ central

  • Jenkins配置

Jenkins 我们也需要配置 JDKMaven 的关联.

进入 Jenkins -> Global Tool Configuration -> JDK

image

进入 Jenkins -> Global Tool Configuration -> Maven

image

添加全局变量

进入Manage Jenkins->Configure System->Global Properties,添加三个全局变量

JAVA_HOME、M2_HOME、PATH+EXTRA

image

然后我们进入项目中点击 configure

image

然后添加 shell 执行脚本:

image

保存后重新构建,查看控制台,可以看到 mvn 构建成功:

image

2)war 包部署

如果我们的项目是打成 war 包的形式,那么我们需要借助 tomcat 容器来运行,那么我们首先便是要先安装一个 tomcat

Tomcat 安装

我们将事先下载好的 Tomcat 安装包上传到服务器上,通过 tar -xzf apache-tomcat-8.5.47.tar.gz 解压,然后运行 bin目录下的 start.sh启动 Tomcat ,看到以下结果则说明启动成功:

image

下一步我们需要配置Tomcat用户角色权限,默认情况下Tomcat是没有配置用户角色权限的

首先我们需要修改 tomcat/conf/tomcat-users.xml 文件:

image

(复制)内容如下:

<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager-script"/>
<role rolename="manager-gui"/>
<role rolename="manager-status"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<user username="tomcat" password="tomcat" roles="manager-gui,manager-script,tomcat,admin-gui,admin-script"/>
复制代码

然后修改 /tomcat/webapps/manager/META-INF/context.xml 文件,将以下内容注释:

image

然后进入tomcat 页面,点击进入:

image

账号密码都是 tomcat

image

成功页面如下:

image

这样子我们就完成了 tomcat 的安装,然后接下来就可以进行部署了

Tomcat 部署
  • jenkins 中安装 Deploy to container 插件
  • 添加 Tomcat 凭证
image
  • 构建配置

在项目的 configure 中配置

image

然后点击构建,查看控制台输出:

image

显示已经部署成功,然后访问项目页面,可以看到 war 包项目部署成功:

image

3)jar 包部署

上面说完了 war 包项目是如何部署的,但是我们现在项目用到比较多的还是 SpringBoot ,这个时候打出来的是 jar 类型,但是 SpringBoot 里面内置了 tomcat 容器,这样子我们就不需要借助外部 tomcat 容器的使用了。

image
  • 首先我们在 Jenkins 中下载 Maven 插件,这个时候新建项目的时候会有个 Maven 项目的选项
image

然后在项目的 configure 中作如下配置:

image

Repository URL:库地址 Credentials:凭证 Branch Specifier (blank for ‘any’):分支

image

Run only if build succeeds:在构建成功时执行后续步骤 Add post-build step:添加构建后的步骤 Send files or execute commands over SSH:通过ssh发送文件或执行命令

  • 安装 Publish Over SSH 插件

因为我们要部署的服务器与 Jenkins 不在同一个服务器上,所以我们需要这个插件来远程部署

安装好插件后我们需要先配置远程服务器,在 Jenkins 服务器上输入 ssh-copy-id 远程服务器IP 将公钥拷贝到远程服务器上,然后在 Jenkins 系统配置中添加服务器信息,如下:

image

完成以上步骤后,我们就可以回到项目的 configure 中添加我们刚刚配置的服务器信息:

image

Name:SSH Servers中配置的服务器 Source files:源文件 Remove prefix:删除前缀 Remote directory:上传到服务器的目录 Exec command:执行的脚本

完成以上步骤,我们就可以愉快的点击 Build Now 了!

image

4)流水线项目

Jenkins 中自动构建项目的类型有很多,常用的有以下三种:

  • 自由风格软件项目(FreeStyle Project)

  • Maven 项目(Maven Project)

  • 流水线项目(Pipeline Project)

每种类型的构建其实都可以完成一样的构建过程与结果,只是在操作方式、灵活度等方面有所区别,其中流水线类型灵活度比较高,其他两种类型我们在上面的例子中都已经尝试过了,下面我们就来介绍如何构建流水线项目。

1. 概念

Pipeline 就是一套运行在 Jenkins 上的工作流框架,将原来独立运行与单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排和可视化工作

2. 优点
  • 代码Pipeline 以代码的形式实现,通常被检入源代码控制,使团队能够编辑,审查和迭代其传送流程。
  • 持久性: 无论是计划内的还是计划外的服务器重启,Pipeline 都是可恢复的
  • 可停止: Pipeline 可接收交互式输入,以确定是否继续执行 Pipeline
  • 多功能: Pipeline 支持现实世界中复杂的持续交付要求,它支持 fork/join 、循环执行、并行执行任务的功能
  • 可扩展: Pipeline 插件支持其 DSL 的自定义扩展,以及与其他插件集成的多个选项
3. 创建

创建 Pipeline 项目之前我们需要安装 Pipeline 插件:

image

然后在创建项目的时候便会多了 Pipeline 类型:

image

选择好项目类型之后我们就可以在项目中的 configure 进行配置了:

  • 首先老样子配置好 git 地址,跟上面一样,这里不多作赘诉
  • 然后配置 Pipeline 脚本

Pipeline 项目是统一通过 Pipeline 脚本来管理,这样也更好的提高灵活性

Hello World 模板:

pipeline {
    agent any
    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
复制代码

stages: 代表整个流水线的所有执行阶段,通常 stages 只有1个,里面包含多个 stage

stage: 代表一个阶段内需要执行的逻辑,steps 里面是 shell 脚本,git 拉取代码,ssh 远程发布等任意内容

声明式 Pipeline 模板:

pipeline {
    agent any
    stages {
        stage('拉取代码') {
            steps {
                echo '拉取代码'
            }
        }
        stage('编译构建') {
            steps {
                echo '编译构建'
            }
        }
        stage('项目部署') {
            steps {
                echo '项目部署'
            }
        }
    }
}
复制代码

你也完全不用担心不会书写 Pipeline 脚本,我们可以点击 [Pipeline Syntax] 跳转到 Pipeline 代码生成页面

image
image

书写好脚本后点击构建,可以看到整个构建过程:

image

如果我们需要部署到不同环境,比如生产环境和开发环境,我们还可以在项目的 configure 中进行配置:

  • 首先需要安装 Extended Choice Parameter 插件
  • 然后在配置中添加 Extended Choice Parameter 参数
image

完成以上配置后,点击保存,这个时候我们就可以在构建的时候选择需要部署的服务器了

image

然后我们就可以从 Pipeline 脚本中读取我们选择的参数,贴上该项目的构建脚本,如下:

image
node {
    //git凭证ID
    def git_auth = "7fdb3fa3-74eb-4862-b36f-c03701f71250"
    //git的url地址
    def git_url = "git@192.168.100.131:cbuc_group/cbuc_web.git"
    //获取当前选择的服务器名称
    def selectedServers = "${publish_server}".split(",")

    stage('开始拉取代码') {
        checkout([$class: 'GitSCM', branches: [[name: '*/v3.0']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: git_auth, url: git_url]]])
    }
    stage('开始打包') {
        sh "mvn -Dmaven.test.skip=true clean package"
    }
    stage('开始远程部署') {
        //遍历所有服务器,分别部署
        for(int j=0;j<selectedServers.length;j++){
            //获取当前遍历的服务器名称
            def currentServerName = selectedServers[j]
            //生产环境部署目录
            def pro_address = "/home/pro/java"
            //开发环境部署目录
            def dev_address = "/home/dev/java"

            //根据不同的profile来部署服务器
            if(currentServerName=="pro"){
                sshPublisher(publishers: [sshPublisherDesc(configName: 'pro_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'sh build.sh', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: pro_address, remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/cbuc_web-0.0.1-SNAPSHOT.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }else if(currentServerName=="dev"){
                sshPublisher(publishers: [sshPublisherDesc(configName: 'dev_server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "sh build.sh", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: dev_address, remoteDirectorySDF: false, removePrefix: 'target', sourceFiles: 'target/cbuc_web-0.0.1-SNAPSHOT.jar')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }
    }
}
复制代码

还有一种情况就是如果部署 Jenkins 的服务器宕机了,这个时候就会丢失 Pipeline 脚本文件,重新书写是一件很麻烦的事情,那么我们就可以将脚本文件放到我们的项目的根目录下,然后在 configure 中配置 Pipeline 脚本文件的位置:

image
image

然后我们点击构建,可以看到结果也是成功的:

image

5)构建触发器

上面我们讲完了几种项目的构建方式,其中都是通过手动点击构建进行构建的,我们也可以通过触发器来构建

image

常用的有:

1. Build After Other Projects Are Built
image

其他工程构建后触发。在选项中填写我们关注的项目,其中也支持3个选择以供选择:

Trigger only if build is stable: 仅在项目稳定构建时执行

Trigger even if the build is unstable: 即使项目构建不稳定也执行

Trigger even if the build fails: 即使项目构建失败也执行

2. Build Periodically
image

定时构建。语法类型如 cron 表达式,定时字符串从左往右分别为: 分 时 日 月 周

3. Poll SCM

轮询 SCM。指定时间扫描本地代码仓库的代码是否有变更,如果代码有变更就触发项目构建。

image
4. Trigger builds remotely
image

远程触发构建。通过使用我们定义的密钥,然后访问构建地址:http://192.168.100.131:8888/job/test01/build?token=123123

5. 自动触发构建

刚才我们看到在Jenkins的内置构建触发器中,轮询SCM可以实现Gitlab代码更新,项目自动构建,但是该方案的性能不佳。那有没有更好的方案呢? 有的。就是利用Gitlabwebhook实现代码push到仓库,立即触发项目自动构建。

image

完成自动触发构建我们需要在 Jenkins 安装插件:GitLab HookGitLab

image

然后我们在 Build Trigger 中就可以看到多了一个选项:

image

复制这串 WebHook 地址,跟着到 GitLab 页面进行设置:

路径步骤:Admin Area -> Settings -> Network

image

然后我们在对应的项目中进行设置:

image

最后再回到 Jenkins 页面中做以下配置:Manage Jenkins->Configure System

image

做完以上配置,我们就可以愉快的代码进行自动触发构建了!

END

看完不赞,都是坏蛋
原文链接:https://juejin.cn/post/6905688958575837191
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容