jenkins持续集成

2023年 10月 6日 48.3k 0

jenkins持续集成

 
image.png

课程目标

  • 了解CI、CD的基本概念
  • 掌握Jenkins的主从集群搭建
  • 掌握Jenkins角色权限配置、分组配置、全局配置等核心配置的使用
  • 掌握Jenkins的持久化原理及目录结构、文件备份与恢复
  • 掌握pipeline声明式语法
  • 熟练使用pipeline语法配置进行微服务项目基于docker容器的持续集成部署

 

相关理论

基本概念

持续集成

(Continuous Intergration)

持续集成的重点在于构建编译及测试,开发人员每天要提交很多次代码到分支,在分支合并到主干前,需要通过编译和测试识别出问题。持续集成的流程就是通过自动化的构建(主要是构建编译、自动化测试)来验证,从而尽早地发现集成错误。

持续集成的核心意义:通过自动化测试尽早的发现代码的问题。

image.png

持续交付

(Continuous Delivery):

持续交付指的是将产品尽可能快的发布上线的过程。持续交付是在持续集成基础上的扩展,也就是说除了自动化编译、自动化测试,为了尽快上线我们还需要自动化发布流程,整个流程实现后,根据实际需要,可以周期性的进行产品上线发布,上线方式为人工点击部署实现快速上线。部署环境的先后部署顺序,一般在公司都是开发环境、测试环境、预发布环境(类生产环境)和正式生产环境,如果代码在预发布环境测试通过,那么就可通过手动的方式部署生产环境实现上线的目的。

持续交付的核心意义:尽快的将最终的产品发布到线上环境,给用户使用。持续交付是每个企业追求的目标,我们常说的CI/CD里的CD一般指的就是持续交付。

image.png

 

持续部署

(Continuous Deployment):

持续部署就是在持续交付的基础上,将编译、测试、打包部署到生产环境的过程做成自动化。

持续部署的核心意义:持续的将迭代的需求自动化的方式部署到生产环境。一般来说,非生产环境的持续部署基本都能实现。但生产环境的持续部署并不是每个企业都能做到,主要原因是受限于各种系统功能依赖、自动化测试不完善等因素,自动化一旦部署到生产,将可能造成严重生产事故。

image.png

说明:无论是持续集成、持续交付还是持续部署,如果要实现整个流程,基本上离不开CI服务器。

 

持续集成

特点
  • 快速定位错误,测试环节可以及时暴露问题;
  • 避免大幅度偏离主干,借助统一的代码库;
  • 减少不必要的成本投入,可以自动化解决重复乏味的事情,节省人力和时间;
工作流程

image.png

工作阶段

持续集成工作流程大体包括这么几个阶段:

  • 初始化CI流程

    基本的CI流程的配置,比如脚本、定时任务等。

  • 拉取最新代码

    从源码仓库拉取最新代码到构建服务器磁盘上。

  • 构建

    一般源码仓库自包含构建,可通过配置的脚本触发执行构建。比如Java的构建一般基于Maven或Gradle。

  • 执行测试

    测试阶段一般包含单元测试和集成测试。Java中的单元测试常指JUnit。

  • 结果处理

    CI流程执行的最后结果要么是成功,要么是失败,结果需要通知给对应的人员,一般的通知方式有邮件、钉钉、短信。

集成工具
  • Travis CI
  • Bamboo
  • TeamCity
  • CircleCI
  • Gitlab CI
  • Jenkins

DevOps

概念

DevOps这个词,其实就是Development(开发)和Operation(运维)两个词的组合。

DevOps 不是一项技术,也不是一套流程和方法论,更不是一套简单的工具产品。DevOps的维基百科定义是这样的:DevOps是一组过程、方法与系统的统称,用于促进开发、技术运营(运维)和质量保证(QA)部门之间的沟通、协作与整合。

通过实践 DevOps,可以将开发、测试、运维之间的工作串联起来,以持续构建、自动化测试、持续发布为目标,将所有流程全部自动化,最大化减少重复性的人力投入。同时,基础环境的自动化构建也降低了由于人的原因带来的意外风险。下图为DevOps所包含的流程:

image.png

 

 

DevOps 这个词是Patrick Debois 于2009 年创造的。出生于比利时的Patrick 先生曾经是一名苦闷的IT 咨询师,饱受开发和运维相互割裂及伤害之苦。2009 年他参加了一个技术大会,在会上听了名为10+ Deploys Per Day: Dev and Ops Cooperation at Flickr 的演讲,深受启发,并创造了DevOps 这个词。

目前,DevOps处于高速增长的阶段。尤其是在大企业中,DevOps受到了广泛的欢迎。越大的企业,越喜欢DevOps。包括Adobe、Amazon、Apple、Airbnb、Ebay、Etsy、Facebook、LinkedIn、Netflix、NASA、Starbucks、Walmart、Sony等公司,都在采用DevOps。

 

工具链

由于DevOps是一种跨职能的工作模式,因此实践过程需要使用不同的工具集(被称为 "工具链"),而不是单一的工具集。这些工具链应该符合以下一个或多个类别,这些类别反映了开发和交付过程中的关键环节:

  • 编码---代码开发和审查、源代码管理工具、代码合并
  • 构建---持续集成工具,构建状态
  • 测试---持续测试工具,提供快速、及时的业务风险反馈
  • 发布---变更管理、发布审批、发布自动化
  • 配置---基础设施配置和管理,基础设施作为代码工具的基础设施
  • 监控---应用性能监控、终端用户体验

DevOps生态圈工具链图:

image.png

常用工具

DevOps 需要要通过技术工具链完成持续集成、持续交付、用户反馈和系统优化的整合。工具链包括版本控制&协作开发工具、自动化构建和测试工具、持续集成&交付工具、部署工具、维护工具、监控,警告&分析工具等等。

  • 版本控制&协作开发:GitHub、GitLab、BitBucket、SubVersion、Coding、Bazaar
  • 自动化构建和测试:Apache Ant、Maven 、Selenium、PyUnit、QUnit、JMeter、Gradle、PHPUnit
  • 持续集成&交付:Jenkins、Capistrano、BuildBot、Fabric、Tinderbox、Travis CI、flow.ci Continuum、LuntBuild、CruiseControl、Integrity、Gump、Go
  • 容器平台:Docker、Rocket、Ubuntu(LXC)、第三方厂商如(AWS/阿里云)
  • 配置管理:Chef、Puppet、CFengine、Bash、Rudder、Powershell、RunDeck、Saltstack、Ansible
  • 微服务平台:OpenShift、Cloud Foundry、Kubernetes、Mesosphere
  • 服务开通:Puppet、Docker Swarm、Vagrant、Powershell、OpenStack Heat
  • 日志管理:Logstash、CollectD、StatsD
  • 监控,警告&分析:Nagios、Ganglia、Sensu、zabbix、ICINGA、Graphite、Kiban

 

DevOps的目标
  • 更快的上市时间
  • 提高部署频率
  • 更短的修复时间
  • 降低发布失败率
  • 更快的平均恢复时间

总结来说DevOps的目标是最大限度地提高运营流程的可预测性、效率、安全性和可维护性。

 

小结

两者关系
  • 由DevOps的流程和工具链我们可以得知,DevOps 是持续集成思想的延伸
  • 持续集成/部署是 DevOps 的技术核心,在没有自动化测试、持续集成/部署之下,DevOps就是空中楼阁。

 

 

jenkins环境搭建

Jenkins介绍

背景

Jenkins,之前叫做Hudson,由SUN公司启动,2010年oracle收购SUN导致hudson商标归oracle保留,hudson的主要贡献者基于hudson 更名为jenkins并持续更新。很长一段时间内Jenkins和Hudson继续作为两个独立的项目,每个都认为对方是自己的分支。目前Hudson已经停止开发,最新的版本发布于2016年,而Jenkins的社区和开发却异常活跃。Jenkins是目前市场上使用最多的CI/CD工具。

  • Jenkins是基于Java开发的一种持续集成工具。
  • Jenkins作为持续集成工具,持续集成是其核心功能,在核心功能基础之上可扩展实现强大的CD功能。
特点
  • 开源免费
  • 易于安装(基本上算是所有CI工具里安装配置最简单的)
  • 多平台支持(windows/linux/macos)
  • 主从分布式架构
  • 提供web可视化配置管理页面
  • 安装配置简单
  • 插件资源丰富
应用场景
  • 集成svn/git客户端实现源代码下载检出
  • 集成maven/ant/gradle/npm等构建工具实现源码编译打包单元测试
  • 集成sonarqube对源代码进行质量检查(坏味道、复杂度、新增bug等)
  • 集成SaltStack/Ansible实现自动化部署发布
  • 集成Jmeter/Soar/Kubernetes/…..
  • 可以自定义插件或者脚本通过jenkins传参运行
  • 可以说Jenkins比较灵活,插件资源丰富,日常运维工作都可以自动化
版本
  • Jenkins 1.x:不支持pipeline
  • Jenkins 2.x:支持pipeline(主流)
  • Jenkins X:基于k8s的持续集成(趋势)

 

主从集群

jenkins支持主从模式,这将会把构建任务分发到多个从节点去执行,这样就可以支撑起多个项目的大量构建任务,提升构建效率。同时,你可以提供多种环境(如:开发环境、生产环境)来对同一个项目进行测试和构建。

 

部署方式
  • 服务器直接运行war
  • 服务器通过 yum命令下载jenkins安装包进行安装运行
  • docker容器运行

 

本课程采用第一种方式,服务器直接运行war,因为它更符合我们的启动习惯。

环境说明
  • centos7
  • jdk1.8
  • maven3.x.x
  • git1.8.3
  • jenkins最新版本:mirrors.jenkins-ci.org/war/latest/
  • Master主机 : 假设主机名叫 linux30
  • Slave从机 : 假设主机名叫 linux31

 

安装Master

登录master服务器

环境准备

root用户执行命令

安装JDK

将压缩包上传到/opt目录下,进行解压

# 配置Java环境变量
[root@linux30 opt]# vi /etc/profile


# java环境变量
export JAVA_HOME=/opt/jdk1.8.0_301
export JRE_HOME=/opt/jdk1.8.0_301/jre


export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin


# 使用source命令,使其生效
[root@linux30 opt]# source /etc/profile


# 验证安装成功
[root@linux30 opt]# java -version
java version "1.8.0_301"
Java(TM) SE Runtime Environment (build 1.8.0_301-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.301-b09, mixed mode)
[root@linux30 opt]# javac -version
javac 1.8.0_301
安装git
[root@linux30 opt]# yum install -y git


# 验证是否安装成功
[root@linux30 opt]# git --version
git version 1.8.3.1
安装sshpass

远程连接工具

[root@linux30 opt]# yum install sshpass -y

后续备份恢复会使用

安装wget
[root@linux30 opt]# yum install wget -y
安装axel(可选)

多线程下载工具

[root@linux30 opt]# wget http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/a/axel-2.4-9.el7.x86_64.rpm


[root@linux30 opt]# rpm -ivh axel-2.4-9.el7.x86_64.rpm
创建jenkins用户
# 创建jenkins用户
[root@linux30 opt]# useradd -d /home/jenkins -m -s /bin/bash jenkins


# 设置密码为12345678
[root@linux30 opt]# passwd jenkins
更改用户 jenkins 的密码 。
新的 密码:
无效的密码: 密码未通过字典检查 - 过于简单化/系统化
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
下载安装maven

maven下载页面:maven.apache.org/download.cg…

  • 上传压缩包,解压到/opt目录下

    # 配置maven环境变量
    [root@linux30 opt]# vi /etc/profile
    
    
    # java环境变量
    export JAVA_HOME=/opt/jdk1.8.0_301
    export JRE_HOME=/opt/jdk1.8.0_301/jre
    # maven环境变量
    export MAVEN_HOME=/opt/apache-maven-3.8.5
    # path环境变量设置
    export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin:$MAVEN_HOME/bin
    
    
    # 执行source命令,使其生效
    [root@linux30 opt]# source /etc/profile
    
    
    # 验证是否安装成功
    [root@linux30 opt]# mvn -v
    Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0)
    Maven home: /opt/apache-maven-3.8.5
    Java version: 1.8.0_301, vendor: Oracle Corporation, runtime: /opt/jdk1.8.0_301/jre
    Default locale: zh_CN, platform encoding: UTF-8
    OS name: "linux", version: "3.10.0-1160.62.1.el7.x86_64", arch: "amd64", family: "unix"
    
  • 配置镜像加速

    maven下的 conf/settings.xml 找到和标签,在其中添加如下内容(镜像加速):

    [root@linux30 opt]# vi /opt/apache-maven-3.8.5/conf/settings.xml
    
    
        
        
         alimaven
         alimaven
         http://maven.aliyun.com/nexus/content/groups/public/
         central
        
    
  • 注意,注意,注意:如果配置本地仓库的地址,譬如:/usr/local/maven/repository, 一定要赋予该目录其他用户可读写的权限

     

    安装rsync(可选)

    跨机器文件同步工具

    [root@linux30 opt]# yum install rsync -y
    
    关闭防火墙
    [root@linux30 opt]# systemctl stop firewalld
    # 永久关闭防火墙
    [root@linux30 opt]# systemctl disable firewalld
    

     

    安装Jenkins
    创建安装目录

    进入该目录后下载jenkins

    # 创建jenkins安装目录
    [root@linux30 opt]# mkdir /opt/jenkins
    
    
    # 该目录为jenkins用户授权
    [root@linux30 opt]# chown -R jenkins:jenkins /opt/jenkins
    
    
    # 切换jenkins用户
    [root@linux30 opt]# su jenkins
    
    下载Jenkins

    下载jenkins安装包,

    下载页:www.jenkins.io/download/

    各版本war索引页:mirrors.jenkins-ci.org/war/

  • 最新版本安装下载

    # 下载最新版
    [jenkins@linux30 jenkins]$ axel -n 20 http://mirrors.jenkins-ci.org/war/latest/jenkins.war
    
  • 指定版本下载

    # 指定版本
    [jenkins@linux30 jenkins]$ axel -n 20 http://mirrors.jenkins-ci.org/war/2.345/jenkins.war
    [jenkins@linux30 jenkins]$ ll
    总用量 89220
    -rw-rw-r-- 1 jenkins jenkins 91354985 4月  28 10:34 jenkins.war
    
  • 下载不成功若报错:Too many redirects

    使用如下方式下载,版本选择 > 2.340

    [jenkins@linux30 jenkins]$ wget https://mirrors.jenkins-ci.org/war/2.355/jenkins.war --no-check-certificate
    

     

    编辑启动脚本

    登录jenkins用户后创建启动脚本

    # 创建jenkins启动脚本
    [jenkins@linux30 jenkins]$ vi jenkins.sh
    

    脚本具体内容如下

    #!/bin/bash
    args=$1
    #注意修改jenkinswar包的目录
    jenkins_war_path="/opt/jenkins"
    #jenkins开放端口
    jenkins_http_port="8888"
    #java安装路径
    java_home="/opt/jdk1.8.0_301"
    function isRuning(){
            local jenkinsPID=`ps -ef|grep jenkins.war|grep -v grep|awk '{print $2}'`
            if [ -z ${jenkinsPID} ];then
                    echo "0"
            else
                    echo ${jenkinsPID}
            fi
    }
    
    
    #停止jenkins
    function stop(){
            local runFlag=$(isRuning)
            if [ ${runFlag} -eq "0" ];then
                    echo "Jenkins is already stoped."
            else
                    `kill -9 ${runFlag}`
                    echo "Stop jenkins success."
            fi
    }
    
    
    #启动jenkins
    function start(){
            local runFlag=$(isRuning)
            echo "${runFlag}"
            if [ ${runFlag} -eq "0" ];then
                    `${java_home}/bin/java -jar ${jenkins_war_path}/jenkins.war --httpPort=${jenkins_http_port} &` > /dev/null
                    if [ $? -eq 0 ];then
    
    
                            echo "Start jenkins success."
                            exit
                    else
                            echo "Start jenkins fail."
                    fi
            else
                    echo  "Jenkins is running now."
            fi
    }
    
    
    #重启jenkins
    function restart(){
            local runFlag=$(isRuning)
            if [ ${runFlag} -eq "0" ];then
                    echo "Jenkins is already stoped."
                    exit
            else
                    stop
                    start
                    echo "Restart jenkins success."
            fi
    }
    
    
    #根据输入的参数执行不同的动作
    #参数不能为空
    if [ -z ${args} ];then
            echo "Arg can not be null."
            exit
    #参数个数必须为1个
    elif [ $# -ne 1 ];then
            echo "Only one arg is required:start|stop|restart"
    #参数为start时启动jenkins
    elif  [ ${args} = "start" ];then
            start
    #参数为stop时停止jenkins
    elif [ ${args} = "stop" ];then
            stop
    #参数为restart时重启jenkins
    elif [ ${args} = "restart" ];then
            restart
    else
            echo "One of following args is required: start|stop|restart"
            exit 0
    fi
    

     

    启动jenkins
    [jenkins@linux30 jenkins]$ sh jenkins.sh start
    

    image.png
     

    镜像加速

    jenkins默认镜像地址:updates.jenkins.io/update-cent…

    镜像地址列表

    常见的jenkins镜像地址有以下地址

    镜像名 镜像地址
    清华大学 mirrors.tuna.tsinghua.edu.cn/jenkins/upd…
    华为 mirrors.huaweicloud.com/jenkins/upd…
    xmission mirror.xmission.com/jenkins/upd…

    也可参见官方网站提供的可用镜像地址:mirrors.jenkins-ci.org/status.html

    配置加速

    修改jenkins配置(插件站点更新,加速联网)

    [jenkins@linux30 ~]$ vi /home/jenkins/.jenkins/hudson.model.UpdateCenter.xml
    

    将XML内的url的值替换为:mirror.xmission.com/jenkins/upd…

    
    
      
        default
        http://mirror.xmission.com/jenkins/updates/update-center.json
      
    
    

    image.png

    也可进入到web-ui界面的Manage Jenkins->manage plugins->Advanced -> Update Site进行修改

    image.png

    访问Jenkins

    浏览器访问jenkins,端口8888

    http://192.168.10.30:8888/

    获取管理员密码

    登录后需要输入解锁密码才能够继续访问jenkins

    通过如下命令可以从jenkins安装目录中获取管理员密码

    [jenkins@linux30 ~]$ cat /home/jenkins/.jenkins/secrets/initialAdminPassword
    2b10023d16a040729fa78b71d760a656
    
    跳过插件安装

    输入密码后点击继续,并跳过插件安装界面

    进入jenkins主页

    点击开始使用就会来到jenkins的主页面

    image.png

    修改管理员密码

    修改管理员密码为123456,具体操作为点击页面左上角jenkins->people->admin->configure进行修改

    image.png

    点击save保存即可,回跳到登录页进行重新登录

    image.png

    安装插件

    jenkins运行需要安装很多插件,下面我们介绍下如何安装插件,下面我们以Role-based Authorization Strategy插件为例介绍下如何安装插件

    插件安装
    • 点击manage Jenkins-> manager Plugins 进入插件管理页面

    • 点击available进入可用的插件页面,搜索Role-based Authorization Strategy,点击下载后在重启

    image.png

    • 进入下载插件界面,在该界面稍等就会出现下载完成信息

    image.png

     

    重启jenkins

    这里我们使用手动重启jenkins,在jenkins用户下进行重启

    如果有多个插件安装,可下载完所有插件后再重启

    [jenkins@linux30 jenkins]$ sh jenkins.sh restart
    
    验证插件安装成功

    image.png

    插件列表

    本课程需要安装:ssh、Pipeline、Role-based Authorization Strategy、Git、Gitee、Git Parameter、thinBackup 鉴于课题下载速度比较慢,已提前安装完成

    image.png

    插件名 作用
    Pipeline 流水线部署项目
    Role-based Authorization Strategy 提供了一种基于角色(Role)的用户权限管理策略,支持创建global角色、Project角色、Slave角色,以及给用户分配这些角色。这款插件是最常用的Jenkins权限策略和管理插件
    Git 支持使用Github、GitLab、Gerrit等系统管理代码仓库,创建普通job时会用到
    Gitee Gitee Jenkins Plugin 是Gitee基于 GitLab Plugin 开发的 Jenkins 插件。用于配置 Jenkins 触发器,接受Gitee平台发送的 WebHook 触发 Jenkins 进行自动化持续集成或持续部署,并可将构建状态反馈回Gitee平台。
    Git Parameter 可用于把git的tag branch当作构建参数传进来,方便使用branch构建
    Extended Choice Parameter 参数化构建
    Maven Integration 这个插件为Maven 2 / 3项目提供了高级集成功能
    SonarQube Scanner 代码扫描
    Email Extension 扩展了发送告警邮件的控制力度。可以定义邮件触发器、邮件内容、收件人
    Workspace Cleanup 每次build之前删除workspace目录下指定的文件
    Monitoring 监控Jenkins节点的CPU、系统负载、平均响应时间和内存使用
    Build Monitor View 将Jenkins项目以一块看板的形式呈现
    ThinBackup 备份与恢复
    jacoco 单元测试覆盖率
    Generic Webhook Trigger webohook

     

    配置jenkins

    上面我们已经完成了jenkins的插件安装以及访问,我们需要对jenkins做一些配置

    前往 Jenkins -> Manage Jenkins -> Configure System 进入系统配置页面

    image.png

    配置码云地址

    如下输入码云的地址,具体配置项如下:

    • 链接名:输入你想要的名字,这个名字无所谓,后面只是做显示作用
    • Gitee 域名 URL:输入码云完整URL地址,gitee.com(码云私有化客户输入部署的域名),一般填gitee.com即可
    • Advanced:可配置是否忽略 SSL 错误(适您的Jenkins环境是否支持),并可设置链接超时时间(适您的网络环境而定),我是忽略掉的了。
    • 测试连接:选择创建的令牌,并点击测试连接,如果显示成功则说明码云配置成功

    image.png

    令牌配置

    证书令牌:右边选项点击add,选择jenkins,详细配置如下

    • Domain:选择全局凭据(Global credentials)
    • 类型(Kind):选择Gitee API 令牌(Gitee API Token)
    • 范围(Scope):根据你个人想要这个凭据在哪个范围可使用,我选的是全局
    • Gitee APIV5 私人令牌(Gitee API Token):输入你的码云私人令牌,获取地址gitee.com/profile/per…
    • ID和描述:自己随便填,也是作为显示使用而已添加完成后,选择刚自己添加的这个令牌
    Gitee API V5 的私人令牌:ee765478006dfed0b79f54a7a77a15c9
    ID:gitee-api-token
    Description:gitee-api-token-descrition
    

     

    工具
    重启Jenkins

    这里是个小技巧,具体为在页面重启jenkins的方式,在jenkins地址后加上/restart即可,比如在本课程中具体的重启地址可以为:

    http://ip:8888/restart

    示例:http://192.168.10.30:8888/restart

    全局工具配置

    非pipeline的Java项目如果要构建成功,全局工具的环境需要配置好

    • 配置入口:Manage Jenkins->Global Tool Configuration
    • 配置方式:指定服务器上已经安装好的服务位置(不需要勾选自动安装)
    • 配置前提:服务器已经安装好jdk、maven、git

    image.png

    image.png

    image.png

     

    添加slave

    slave无需再次安装jenkins,但是需要保证主机从机能够连通

    image.png

    环境准备

    登录到从机器安装环境

    wget、axel、sshpass、jdk、git、maven、等步骤参考前文

    image.png

    创建jenkins

    同样需要新建jenkins用户

    # 新建jenkins用户
    [root@linux31 opt]# useradd jenkins --home-dir /home/jenkins --shell /bin/bash
    # 设置密码为 12345678
    [root@linux31 opt]# passwd jenkins
    更改用户 jenkins 的密码 。
    新的 密码:
    无效的密码: 密码未通过字典检查 - 过于简单化/系统化
    重新输入新的 密码:
    passwd:所有的身份验证令牌已经成功更新。
    
    配置ssh免密登录

    免密登录指的是master可以不用密码直接登录到slave

    # 切换到jenkins用户
    [root@linux30 ~]# su jenkins
    
    
    # 进入jenkins目录
    [jenkins@linux30 root]$ cd /home/jenkins/
    
    
    # 生成sshkey,执行下面命令后一直回车完成即可
    [jenkins@linux30 ~]$ ssh-keygen
    

    image.png

    拷贝主机的公钥文件到从机器,执行命令后输入从机jenkins 的用户密码即可

    # linux31表示你从机,slave那台机器的ip,或者主机名
    [jenkins@linux30 ~]$ ssh-copy-id jenkins@linux31
    

    image.png

    安装ssh插件

    登录jenkins,安装ssh插件,安装完成后重启jenkins

    image.png

     

    添加从节点slave

    image.png

    image.png

    上图中点击OK后,配置信息

    image.png

    说明:

    • of executors:并发构建数量为2
    • Remote Root Directory:从节点的工作目录为 /home/jenkins
    • Labels:标签名为 jenkins-slave,多个node可以共用一个标签,那么创建job的时候,可以指定标签,在这些node运行
    • Usage:常选择“尽可能多的使用此节点”

     

    添加用户名密码

    如果add按钮点击失效,则需要添加凭证

    image.png

     

    选择刚才加的jenkins用户

    image.png

     

    • 上图点击保存后,slave就创建完毕,master会执行连接slave

      如果配置完等待一会master没连接上slave,那么图中左边导航处会出现断开的图标

      可以进行重连,或者刷新状态,多试几次。

    注意:如果连接失败,需要检查JavaPath选项,该值为:/opt/jdk1.8.0_301/bin/java

    测试slave可用性
    安装pipeline插件

    image.png

    检查发现该插件已经安装成功

    创建pipeline方式的测试job

    image.png

    job配置

    image.png

    脚本内容:

    pipeline {
       agent{
           label "jenkins-slave"
       }
    
    
       stages {
          stage('Hello') {
             steps {
                echo 'Hello World'
             }
          }
       }
    }
    
    构建job

    image.png

    查看job构建日志

    image.png

    可以看到,由于我们脚本配置了jenkins-slave,所以,最终执行任务是在jenkins-slave1节点机器上执行的

    image.png

    角色&权限(选学)

    权限控制

    本文重点介绍核心配置:节点管理、用户管理、角色管理、分组管理、插件管理

    创建用户

    点击manage Jenkins-> manager users -> create user

    image.png

    输入完成信息后就可以创建用户了

    用户管理

    为方便接下来的演示,新建如下账号,开发共计两个账号,运维、测试、负责人各一个账号。

    账号名 密码 说明
    java01 java01 某Java工程师账号
    web01 web01 某前端工程师账号
    test01 test01 某测试工程师账号
    ops01 ops01 某运维工程师账号
    leader01 leader01 某项目负责人账号

    image.png

    在用户管理列表中可进行用户配置比如设置用户密码等,也可以删除用户

     

    角色管理

    之所以提到角色管理,是由于跟用户权限控制有关,在jenkins中控制用户权限需要选择安全策略,比如有:安全矩阵策略、项目矩阵策略、基于角色的策略等,而企业最常用的就是基于角色的策略,本文也是以角色管理为主。

    角色分类

    在jenkins中角色管理分为两种:

    • 一种是全局角色,类似我们说的功能权限,此角色与具体的job无关,是一种全局权限的控制,比如控制用户能不能查看job,能不能配置job;
    • 还有一种是项目角色,类似我们所说的数据权限,此角色与具体job有关,可以精细化控制到用户具体能拥有哪些job的哪些权限。但是特殊说明的是:如果想要配置角色管理,必须安装插件才行。
    安装角色插件

    插件名:Role-based Authorization Strategy

    关于插件的介绍请先读文档:plugins.jenkins.io/role-strate…

    安全管理策略

    image.png

     

    进入全局权限控制后选择Role-Based Strategy选项,保存即可

    image.png

    权限配置需求

    账号名 岗位 查看job 点击构建job 取消构建job 配置job
    java01 研发
    web01 研发
    test01 测试
    ops01 运维
    leader01 负责人
    粗粒度

    以上是粗粒度权限控制要求:

    • Java视图里能够操作所有项目
    • Web视图里能够操作所有项目
    • 运维和测试视图里能够操作所有项目
    • 负责人视图里能看到所有项目
    细粒度

    下面是细力度权限控制要求(主要针对研发人员):

    • Java视图里只能操作Java相关的项目
    • Web视图里只能操作web相关的项目
    • 运维和测试视图里能够操作所有项目
    • 负责人视图里能看到所有项目

     

    全局角色(功能权限)

    配置演示

    1)新建演示用job

    均基于pipline进行创建,java的开发测试生产各一个,web的开发测试生产各一个

    在jenkins界面点击New Item创建任务

    java-dev-job、java-test-job、java-pro-job、web-dev-job、web-test-job、web-pro-job

    image.png

     

    2)选择管理角色:Manage Jenkins -> Security -> Manage and Assign Roles

    image.png

    3)点击全局角色并配置

    image.png

    说明:如上图新增两个角色,分别为builder、viewer

    角色说明:

    角色名 权限范围
    admin jenkins默认的角色,拥有所有权限
    builder 拥有查看job、构建job、配置job的权限
    viewer 拥有查看job的权限,不能构建

    全局角色会覆盖项目角色的配置。

     

    4)为用户指定全局角色

    image.png

    为测试方便:

    1,为:java01 指定builder角色,登录java01看是否能build

    2,为test01 指定 viewer角色,登录test01看是否只能查看不能build

    当然不嫌麻烦可以按讲义依次测试。

     

     

    5)登录各账号查看权限

    • 运维工程师ops01账号可以拥有所有权限

    image.png

    image.png

    • 项目负责人leader01账号只可以查看job

    image.png

    image.png

     

    测试工程师账号test01、开发工程师账号java01和web01可拥有查看、配置及构建job的权限

     

    项目角色(数据权限)

    1)项目角色配置

    这里提到的项目指的是jenkins里的job,之所以要进行项目角色配置,是因为企业开发一般有这么一种需求:开发人员不同、所以看到的项目也不同。比如Java工程师只能看到Java的项目、WEB工程师只能看到web的项目。接下来的配置就是为了实现此需求,单独为Java和web的账号分配不同的项目角色,其他账号权限不变。

    此处要设置项目角色之前,先创建个全局角色base,指定一个overall的read权限即可。

    image.png

    配置说明:

    名称 说明
    role 项目的角色名
    pattern 正则表达式,表示匹配什么样名字开头的job,我们这里java和前端的项目都分为三种环境。注意表示什么开头,在这里要写成"关键词.*"

    image.png

    角色说明:

    角色名 权限范围
    java java-.*表示角色java会匹配到java-开头的所有job
    web web-.*表示角色web会匹配到web-开头的所有job
    base 拥有查看job的权限

     

    2)调整角色及分配角色

    image.png

    上图注意为java01和web01账号分配项目角色的时候,一定要调整全局角色到base,然后分配项目角色

     

     

    3)登录开发账号查看权限

    • java01账号登陆后查看的页面

    image.png

    点击job名称进入发现也能看到配置按钮

     

    • web01账号登录后查看的页面

    image.png

    点击job名称进入发现也能看到配置按钮

     

    分组管理(选学)

    根据测试job列表,我们发现,如果是非开发的账号,比如测试、运维、负责人都可以查看到所有job,job如果太多则列表显示过长,所以可对job进行分组管理

    新建分组

    image.png

     

    新建Java分组

    image.png

     

     

    新建web分组

    image.png

     

    查看分组

    image.png

     

     

    说明:web组配置过程与上方过程一致,参考上方即可

     

    企业实战

    备份恢复(自学)

    存储结构

    1)概述

    在jenkins中,所有的数据默认都以文件形式存储在$JENKINS_HOME目录下。

    占用空间最大的目录就是jobs目录和workspace目录

    • jobs目录:项目在jenkins上的配置、构建日志、构建结果等所在目录
    • workspace目录:项目在jenkins上配置的源码仓库地址下载下的源码所在目录,比如Java中maven的构建操作在此目录下进行。

     

    2)说明

    目录 存放位置
    jobs目录 对应master的/home/jenkins/.jenkins/jobs目录
    workspace目录 对应master的/data/jenkins_data/workspace目录或者对应node节点的/home/jenkins/workspace目录

     

    3)结构

    image.png

     

    • jobs目录下的一级目录名,均为在jenkins上新建的job名称。
    • 二级目录下的build里出现的数字1、2、3...表示构建历史所在的目录,也就是一次构建就有一个构建版本号,从1开始随着构建次数的增加向上递增。
    • workspace下面都是空的,这是因为没有拉取过代码,我们下面到项目实施阶段再来看

     

    备份

    1)备份需求

    • 只备份重要的信息,保证恢复时除了构建历史,重要配置和job都在,排除掉build目录
    • 备份要周期性的执行,保证至少每天备份一次
    • 备份不仅仅要存放到Master,还要同步备份到备份服务器上

     

    2)备份实现

    • thin backup插件实现备份到Master机器
    • Rsync实现备份到备份服务器(拓展)

     

    3)备份配置

    • 创建备份目标目录

      [jenkins@linux30 .jenkins]$ mkdir -p /opt/jenkins/backup
      
    • 安装Thin Backup插件

    • 开始备份配置

      找到备份管理页面Manage Jenkins->ThinBackUp,进入后选择Settings进行配置

     

     

    配置好了每天14:42 执行一次,构建的最大备份文件个数为-1表示不限制,备份中排除了build的结果

    image.png

    image.png
    图中特殊配置了备份时需要将凭证目录secrets下的所有文件进行备份,通过正则表达式:^(secrets|.*)$

    image.png

    • 点击保存后,等待时间到14:42过后,我们查看master上的/opt/jenkins/backup目录

    image.png

    发现备份到点已经执行完毕,那么改目录下备份的内容是否是正确的内容,查看生成的备份目录
    
     
    
    由生成的备份目录发现,用户、插件、节点、JOB等核心的配置文件目录都已经备份完毕
    

    image.png

     

     

     

    课外拓展资料:rsync备份到其他机器

    1)说明

    rsync是一款文件同步工具,可以实现跨服务器同步某些文件目录,和jenkins无关。

    所以可以借助rsync命令实现在每天jenkins自己备份完毕后,将当天新增的文件,增量同步到备份服务器上

     

    2)操作

    在master上切换到jenkins用户,执行rsync备份命令

    特殊说明:执行sshpass命令前先在构建服务器上执行一次rsync命令(仅需一次即可),只有这次执行通过后,后续再执行sshpass带密码才可使用。后续再执行sshpass前都无需单独再执行rsync命令。

    [jenkins@linux31 jenkins]$ mkdir -p /opt/jenkins/backup
    
    
    [jenkins@linux30 jenkins]$ rsync -r backup/ jenkins@linux31:/opt/jenkins/backup
    
    
    [jenkins@linux30 jenkins]$ sshpass -p 12345678 rsync -avz /opt/jenkins/backup/ jenkins@linux31:/opt/jenkins/backup
    

    执行后,发现已经开始同步

    image.png

     

    登录到备份服务器,切换到jenkins用户,然后查看是否同步过来

    image.png

    在jenkins备份页面上,调整jenkins上的备份时间点,比如调整为58 14 * * *,14 点58 开始再执行一次,点击保存,过了14点58查看master上的目录:

    image.png

    登录到master,切换到jenkins用户再次执行同步命令:

    [jenkins@linux30 jenkins]$ sshpass -p 12345678 rsync -avz /opt/jenkins/backup/ jenkins@linux31:/opt/jenkins/backup/
    

    image.png

    发现已经开始同步,同步完成,再次登录到备份服务器,切换的jenkins用户查看

    手动同步比较麻烦,比较好的方式就是做成脚本自动化执行。

     

    3)脚本自动执行同步

    将rsync做成脚本自动执行,比如jenkins配置的是每天15:05执行同步,那么rsync可以在每天15:10再自动执行

    登录到master上,执行如下操作:

    1.编辑备份shell脚本

    [jenkins@linux30 jenkins]$ vi /opt/jenkins/backup.sh
    

    在脚本内填入如下内容

    sshpass -p 12345678 rsync -avz /opt/jenkins/backup/ jenkins@linux31:/opt/jenkins/backup/
    

    2.给脚本添加执行权限

    chmod +x  /opt/jenkins/backup.sh
    

    image.png
    3.添加到系统crontab文件中

    # 切换到root用户
    [jenkins@linux30 jenkins]$ su
    # 添加到系统crontab文件中
    [root@linux30 jenkins]# vi /etc/crontab
    

    在最后添加如下内容:

    10 15 * * * jenkins /bin/bash /opt/jenkins/backup.sh &>/dev/null
    

    image.png

    保存完后,重启contab

    [root@linux30 jenkins]# systemctl restart crond.service
    

    等待到15:10后,查看备份服务器的备份目录,就实现了自动的定时的备份

     

    以上jenkins设置的时间和crontab的时间均为演示需要,实际企业开发过程中根据需要自行调整

     

     

     

    恢复

    1)创建新环境

    为了演示恢复备份文件的效果,我们可以假设jenkins数据全丢了,现在什么配置都没有了。为了实现这个效果我们决定切换jenkins工作目录到一个空目录下,然后重启jenkins,这样jenkins等同于一个全新的jenkins,就相当于数据全丢了。

    • jenkins没有切换到空工作目录前:有上文所述的5个测试用户,角色配置,测试job,还有备份设置

    • 登录到master,新建一个空的工作目录并授权:

      [jenkins@linux30 jenkins]$ mkdir empty-home
      

      切换到jenkins用户,先设置JENKINS_HOME的值为/opt/jenkins/empty-home,再重新启动

      [jenkins@linux30 jenkins]$ export JENKINS_HOME=/opt/jenkins/empty-home
      
      
      [jenkins@linux30 jenkins]$ java -jar ./jenkins.war --httpPort=8888
      
    • 访问jenkins

      发现jenkins首页变成最初的初始化页面了

    image.png

     
    
    2)配置插件
    
    此时的jenkins已经是全新的无任何配置的jenkins了,我们需要更换镜像中心地址(),然后下载 thinbackup 插件
    

    image.png

     

    插件安装完毕后,重启jenkins ,然后登录找到ThinBackup的配置,点击Settings,配置备份目录,然后恢复的时候就能从备份目录中,找到之前备份的那些文件了

    image.png

     

    3)恢复环境

    选择要恢复的备份文件,选择最新的备份文件,点击开始恢复

    image.png

    恢复过程页面是不会有恢复完成提示的,等待几分钟后,执行jenkins的重启链接即可

    http://192.168.10.30:8888/restart

    再次登录发现所有的配置都恢复回来了

     

     

     

    pipeline(重要)

    前面的测试master - slave搭建的时候,我们已经用pipline测试过从机的连接情况,本节详细来看pipline的知识

     

    1)pipeline是什么

    流水线是用户定义的一个CD流水线模型 。流水线的代码定义了整个的构建过程, 他通常包括构建, 测试和交付应用程序的阶段 。对Jenkins 流水线的定义被写在一个文本文件中 (称为Jenkinsfile),该文件可以被提交到项目的源代码的控制仓库。 这是"流水线即代码"的基础, 将CD 流水线作为应用程序的一部分,像其他代码一样进行版本化和审查。 创建Jenkinsfile并提交它到源代码控制中提供了一些即时的好处:

    • 自动地为所有分支创建流水线构建过程并拉取请求。
    • 在流水线上代码复查/迭代 (以及剩余的源代码)。
    • 对流水线进行审计跟踪。
    • 该流水线的真正的源代码, 可以被项目的多个成员查看和编辑。

     

    注意一定要参看文档:

    www.jenkins.io/doc/book/pi…

    www.jenkins.io/zh/doc/book…

     

    2)语法支持

    Jenkinsfile能使用两种语法进行编写 - Declarative Pipeline声明式和Scripted Pipeline脚本化,两者都支持建立连续输送的Pipeline。这两种语法对比如下:

    共同点: 两者都是pipeline代码的持久实现,都能够使用pipeline内置的插件或者插件提供的steps,两者都可以利用共享库扩展。

    区别: 两者不同之处在于语法和灵活性。Declarative pipeline对用户来说,语法更严格,有固定的组织结构,更容易生成代码段,使其成为用户更理想的选择。

    但是Scripted pipeline更加灵活,因为Groovy本身只能对结构和语法进行限制,对于更复杂的pipeline来说,用户可以根据自己的业务进行灵活的实现和扩展。

     

    建议选择哪种语法?

    通常建议使用Declarative Pipeline的方式进行编写,从jenkins社区的动向来看,很明显这种语法结构也会是未来的趋势。声明式流水线比 Jenkins 脚本化流水线的特性:

    • 相比脚本化的流水线语法,它提供更丰富的语法特性
    • 是为了使编写和读取流水线代码更容易而设计的

    本课程有关pipeline的脚本也是基于Declarative Pipeline的方式进行编写

     

    3)基本概念

    • Stage: 阶段,一个Pipeline可以划分为若干个Stage,每个Stage代表一组操作。注意,Stage是一个逻辑分组的概念,可以跨多个Node。
    • Node: 构建服务器节点,一个Node就是一个Jenkins节点,或者是Master,或者是Agent,是执行Step的具体运行期环境。
    • Step: 步骤,Step是最基本的操作单元,小到创建一个目录,大到构建一个Docker镜像,由各类Jenkins Plugin提供

     

    创建Pipeline

    • 直接在jenkins web ui 网页界面输入脚本 (本课程大部分时候用这种方式)
    • 编写Jenkinsfile文件并将文件存放到项目根目录,项目需推送到源代码管理库 (本课程最后会有使用说明)

     

    Pipeline语法

    声明式pipeline 基本语法和表达式遵循 groovy语法,但是有以下例外:

    • 声明式pipeline 必须包含在固定格式的pipeline{} 块内,比如:

      pipeline {
          /* insert Declarative Pipeline here */
      }
      
    • 每个声明语句必须独立一行, 行尾无需使用分号

    • 块只能由阶段(stages{})、指令、步骤 (steps{})或赋值语句组成

    • 属性引用语句被视为无参数方法调用, 如input()

    块(Blocks)

    • 由大括号括起来的语句: 如 pipeline{}、parameters{}、script{}

    章节(Sections)

    • 通常包括一个或者多个指令或步骤 如 agent、post、stages、steps

    指令(Directives)

    • environment, options, parameters, triggers, stage, tools, when

    步骤(steps)

    • 执行脚本式pipeline, 如script{}

    详细语法参见官方文档:www.jenkins.io/zh/doc/book…

    www.jenkins.io/doc/book/pi…

     

    语法示例

    流水线语法示例:

    // Jenkinsfile (Declarative Pipeline)
    pipeline { 
        agent any 
        stages {
            stage('Build') { 
                steps { 
                    sh 'make' 
                    echo "hello world"
                    script {
                        def browsers = ['chrome', 'firefox']
                        for (int i = 0; i < browsers.size(); ++i) {
                            echo "Testing the ${browsers[i]} browser"
                        }
                    }
                }
            }
            stage('Test'){
                steps {
                    sh 'make check'
                    junit 'reports/**/*.xml' 
                }
            }
            stage('Deploy') {
                steps {
                    sh 'make publish'
                }
            }
        }
    }
    
    • pipeline是声明式流水线的一种特定语法,他定义了包含执行整个流水线的所有内容和指令的 "block" 。

    • agent 是声明式流水线的一种特定语法,指示 Jenkins 为整个流水线分配一个执行器(在 Jenkins 环境中的任何可用代理/节点上)和工作区。一般用作于指定在哪个节点上构建,如果不指定就写any表示任意节点。

    • 定义 "Build" 、 "Test" 、 "Deploy" 三个阶段,每个阶段内部执行不同的步骤。

    • stage 是一个描述 stage of this Pipeline的语法块。stage 块定义了在整个流水线的执行任务的概念性地不同的子集(比如 "Build", "Test" 和 "Deploy" 阶段), 它被许多插件用于可视化 或Jenkins流水线目前的 状态/进展,stage 块是可选的。

    • steps 是声明式流水线的一种特定语法,它描述了在这个 stage 中要运行的步骤。

    • sh 是一个执行给定的shell命令的流水线。

    • echo 写一个简单的字符串到控制台输出。

    • junit 是另一个聚合测试报告的流水线。

    • 注意stage括号的值表示阶段名称,值内容不是固定的,根据需要自定义即可。

       

     

     

    持续集成实战

    准备工作

    初始化项目
    码云创建项目

    在码云上面创建一个demo的仓库,我们做一个springboot的案例上传到码云

    image.png

     

    下载项目

    通过idea下载项目,并写入代码

    image.png

    运行测试

    运行项目,并访问http://localhost:8080

    image.png

    出现以上内容说明我们的项目启动成功

    提交代码

    提交并推送代码

     

    码云查看项目

    我们发现我们的demo已经提交到了码云了

    image.png

     

    集成流程

    image.png

    1)案例说明

    上图为真实企业级基于k8s容器化CI/CD的工作流程

    其中关于后面如何使用k8s 和 docker 仓库,k8s课程会有详细介绍,这里先简单使用本地镜像启动

    其他步骤与上图一致,重点来学习jenkins的使用。

    需要在机器上提前安装docker环境,安装地址:docs.docker.com/engine/inst…

    # 启动docker
    [root@linux31 jenkins]# systemctl start docker
    # docker安装成功后,自动创建了docker组,将jenkins用户加入到docker组中,不然jenkins用不了docker,报权限问题
    # 注意!授权完成后,重启jenkins!否则权限不生效!!!
    [root@linux31 jenkins]# usermod -G docker -a jenkins
    # 查看jenkins所在的组
    [root@linux31 jenkins]# groups jenkins
    jenkins : jenkins docker
    

     

     

    备注:权限报错

    image.png

    重启jenkins!

     

    2)完整流程说明

    根据以上流程图,梳理一下CI&CD的工作原理

  • 提交代码:开发人员提交项目代码推送到源码仓库中;
  • job构建:触发job执行构建,可能是人工点击也可能是系统定时自动触发,一般人工;
  • 开始构建:
  • 第一步:拉取代码,从微服务项目源码仓库中拉取最新代码到构建服务器的workspace目录中;
  • 第二步:单元测试,执行mvn test命令进行微服务项目的单元测试及覆盖率统计;
  • 第三步:项目打包,执行mvn命令进行微服务项目的打包;
  • 第四步:制作镜像,docker命令制作项目的docker镜像文件(根据微服务项目下的Dockerfile文件),并将镜像文件上传到指定的docker私有仓库中;
  • 第五步:远程ssh目标服务器的docker命令进行容器的停止、删除、从docker私有仓库下载镜像、新镜像启动。
  •  

    持续集成

    1)创建git用户

    添加git仓库的证书信息,找到Manage Jenkins->Manage Credentials->Credentials下的jenkins点击进去。

    进入后点击添加凭据,然后填写凭据的内容,也就是git仓库的账号和密码(这里选择:gitee的账号密码)

    image.png
     

    填写git信息:请根据实际情况填写你的账号

    账号:QQ952051088
    密码:******
    

     

    2)新建一个流水线job: test-boot (操作演练)

    image.png

     

    下一步后,进入配置页,直接拖到最低,找pipline,下拉选pipline script 模式,将以下脚本帖进去:

    pipeline { 
        //指定运行的节点,本案例从slave运行
        agent { 
            node { 
                label 'follower' 
            } 
        }
        //定义各个阶段
        stages {
            //获取git代码,注意,里面的credentialsId就是指定我们上面配置的git账号
            stage('pull') { 
                steps { 
                    git credentialsId: 'gitee-usr-psw', url: 'https://gitee.com/giteets/jenkinsdemo.git'
                }
            }
            //test阶段,调用maven执行测试代码
            stage('test'){
                steps {
                    // 可以从environment中获取 
                    sh '${MAVEN_HOME}/bin/mvn test'
                }
            }
            //编译打包阶段,打出可执行jar
            stage('build') {
                steps {
                    sh '${MAVEN_HOME}/bin/mvn clean package -DskipTests'
                }
            }
            //docker打镜像阶段,后面的version就是当前job的执行号,每次自增1
            stage('docker') {
                steps {
                    sh 'docker build -t tans666/jenkins-demo:${BUILD_NUMBER} .'
                }
            }
            
            stage('pushImage') {
                steps {
                    sh 'docker push tans666/jenkins-demo:${BUILD_NUMBER}'
                }
            }
            //部署阶段,停掉旧的docker进程,启动新镜像
            stage('deploy') {
                node { 
                    label 'master' 
                }
                steps {  
                    //如果test-boot没有在启动中,如果不跟随或语句,这里会执行失败,中断pipline!
                    sh 'docker rm -f jenkins-demo || sleep 0'
                    sh 'docker run --name jenkins-demo -d -p 8080:8080 tans666/jenkins-demo:${BUILD_NUMBER}'
                }
            }        
        }
    }
    

    注意:

    1,需要JAVA_HOME,可全局配置,也可针对node配置

     

    也可使用 Pipeline Syntax 生成脚本

    脚本辅助工具,点击下面红框部分,可以进入pipline语法提示工具(操作演练)

    image.png

     

    此页面的作用就是可以帮助我们生成部分的脚本,比如上方我们可以选择git,看拉取代码的语法怎么写,填写完git信息后,点击生成,就可以出现git拉取代码的脚本,那么此脚本就可以放到pipline的script内

    image.png

    4)配置完成后点构建,查看构建日志(操作演练)

    通过日志发现,执行构建的确是在slave上进行,并且最终输出了deploy ok,我们也可以查看可视化构建视图:

    image.png

    如果构建成功,那么就是绿色,如果有失败,那么就是红色

     

    3)验证

    http://192.168.10.31:8081/

    image.png
     

    更多用法

    0) agent 代理

    参看:agent

    pipeline { 
        agent { 
            //node any
            // node { 
            //     label 'follower' 
            // } 
        }
    }
    

     

    1) Environment 指令

    参看:environment

    pipeline { 
        // pipeline 全局变量
        environment { 
            CC = 'clang'
        }
        //定义各个阶段
        stages {
            
            //s1 echo 
            stage('echo1') {
                // pipeline stage 变量
                environment { 
                    FOLLOWER_CREDENTIAL = credentials('jenkins-follower-ssh-credential') 
                }
                
                steps { 
                    echo "${CC}"
                    echo "${FOLLOWER_CREDENTIAL_USR}:${FOLLOWER_CREDENTIAL_PSW}"
                }
            }
           // ........略      
        }
     }
    

     

    2)超时构建退出

    参看:options

    阻断执行,设定一个时间,如果构建时间在规定时间内没完成,那么就终止继续执行,我们可以在脚本内添加

    pipeline { 
        
        options {
            timeout(time: 30, unit: 'SECONDS') 
            retry(2)
        }
    }
    

    以上属于options指令的语法,timeout设置流水线运行的超时时间, 在此之后,Jenkins将中止流水线。

    unit根据需要可选值有:SECONDS、MINUTES、HOURS

     

    由于在test阶段超过10秒,所以导致abort退出不再继续执行,job最终状态就是aboarted

     

    3)参数化构建

    为提升脚本复用性,可以把部分参数提取出来,作为参数,在执行构建时加入。

    比如,上面的git默认从master获取代码,我们可以通过参数化构建实现切换任意分支部署

    配置参数:

    image.png

    更改脚本,将git的脚本内容修改为:

    git credentialsId: 'QQ952051088', url: 'https://gitee.com/QQ952051088/demo.git', branch: '${branch}'
    

     

    保存后执行构建,构建之前,我们提交不同代码到dev和master分支分别测试部署情况。

    再次构建时,会让你选择构建的参数,也就是获取代码的不同分支。比如选择dev分支:

    image.png

     

    访问浏览器

    image.png

     

    也可以在Jenkinsfile 中直接编写参数

    pipeline { 
    
    
        parameters {
            string(name: 'PERSON', defaultValue: 'ts', description: '谁在构建?')
        }
        //定义各个阶段
        stages {
            
            //s1 echo 
            stage('echo1') {
                // pipeline stage 变量
                environment { 
                    FOLLOWER_CREDENTIAL = credentials('jenkins-follower-ssh-credential') 
                }
                
                steps { 
                    echo "${CC}"
                    echo "${FOLLOWER_CREDENTIAL_USR}:${FOLLOWER_CREDENTIAL_PSW}"
                    echo "hello ${params.PERSON}"
                }
            }        
        }
    }
    

     

     

    4)触发器

    参看:triggers

     

    比如:可以设置一个cron表达式,让job按表达式的要求定时执行构建,如下配置了一个每天到点执行

    image.png

     

    到点后,发现job已经开始执行构建

    image.png

     

    5) input

    参看文档:input

    pipeline { 
    
    
        parameters {
            string(name: 'PERSON', defaultValue: 'ts', description: '谁在构建?')
        }
        //定义各个阶段
        stages {
            
            stage('echo1') {
                // pipeline stage 变量
                environment { 
                    FOLLOWER_CREDENTIAL = credentials('jenkins-follower-ssh-credential') 
                }
                input {
                    message "Should we continue?"
                    ok "Yes, we should."
                    submitter "alice,bob"
                    parameters {
                        string(name: 'NAME', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
                    }
                }
                steps { 
                    echo "${CC}"
                    echo "${FOLLOWER_CREDENTIAL_USR}:${FOLLOWER_CREDENTIAL_PSW}"
                    echo "hello ${params.PERSON}"
                    echo "hello ${NAME}"
                }
            }       
        }
    }
    

     

    6) when

    参看文档:when

    pipeline { 
        //指定运行的节点,本案例从slave运行
        agent { 
            //node any
            node { 
                label 'follower' 
            } 
        }
        
        options {
            timeout(time: 1, unit: 'HOURS') 
            retry(2)
        }
        
        // pipeline 全局变量
        environment { 
            CC = 'clang'
        }
        
        parameters {
            string(name: 'PERSON', defaultValue: 'ts', description: '谁在构建?')
        }
        //定义各个阶段
        stages {
            
            //s1 echo 
            stage('echo1') {
                // pipeline stage 变量
                environment { 
                    FOLLOWER_CREDENTIAL = credentials('jenkins-follower-ssh-credential') 
                }
                input {
                    message "Should we continue?"
                    ok "Yes, we should."
                    submitter "alice,bob"
                    parameters {
                        string(name: 'NAME', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
                    }
                }
                steps { 
                    echo "${CC}"
                    echo "${FOLLOWER_CREDENTIAL_USR}:${FOLLOWER_CREDENTIAL_PSW}"
                    echo "hello ${params.PERSON}"
                    echo "hello ${NAME}"
                }
            }
            
            
            //获取git代码,注意,里面的credentialsId就是指定我们上面配置的git账号
            stage('git') { 
                steps { 
                    git branch: "${branch}", credentialsId: 'gitee-username', url: 'https://gitee.com/giteets/jenkinsdemo.git'
                }
            }
            //test阶段,调用maven执行测试代码
            stage('test'){
                steps {
                    sh '${MAVEN_HOME}/bin/mvn test'
                }
            }
            //编译打包阶段,打出可执行jar
            stage('build') {
                steps {
                    sh '${MAVEN_HOME}/bin/mvn clean package -DskipTests'
                }
            }
            //docker打镜像阶段,后面的version就是当前job的执行号,每次自增1
            stage('docker') {
                steps {
                    sh 'docker build -t tans666/jenkins-demo:${BUILD_NUMBER} .'
                }
            }
            
            stage('push') {
                when {
                    environment name: 'CC', value: 'clang'
                }
                steps {
                    // 推送到镜像仓库
                    sh 'docker push tans666/jenkins-demo:${BUILD_NUMBER}'
                }
            }
            
            //部署阶段,停掉旧的docker进程,启动新镜像
            stage('deploy') {
                steps {  
                    //如果test-boot没有在启动中,如果不跟随或语句,这里会执行失败,中断pipline!
                    sh 'docker rm -f jenkins-demo || sleep 0'
                    sh 'docker run --name jenkins-demo -d -p 8080:8080 tans666/jenkins-demo:${BUILD_NUMBER}'
                }
            }        
        }
    }
    

    注意:要成功推送到hub.docker,需要先docker login

     

    9 ) 并行

    参看文档:并行

     

    7)保留构建个数

    为了节省空间,我们可以配置保留的构建个数,也就是build number的历史记录数量,一般保留10-20个足够。

    image.png

     

    image.png

     

    8)脚本优化,通用化

    以上脚本代码还可以继续优化,命令里涉及到的任意你想要的变量都能提取出来,比如微服务端口号

    充分发挥你的想象力……

    加一个参数

    image.png

    修改脚本,使用port作为端口:

    sh 'docker run --name test-boot -d -p ${port}:8080 test-boot:${BUILD_NUMBER}'
    

    再次构建,启动后用你输入的端口访问试试

    image.png

     

    9)Jenkinsfile提取到项目中

    根据jenkins官方推荐,建议我们将配置在JOB里的脚本内容写到一个名字为Jenkinsfile的文件中,并将此文件放在一个项目的根目录下,这里我们在项目的根目录新建一个Jenkinsfile文件,将上面小节的脚本全部复制到此文件中,然后提交文件到仓库。

    然后,从test-boot复制一个项目:test-boot-copy

    image.png

    image.png

    pipline我们不直接输入脚本,选择使用项目里的Jenkinsfile:

    image.png

    pipeline {
        //指定运行的节点,本案例从slave运行
        agent {
            //node any
            node {
                label 'follower'
            }
        }
    
    
        options {
            timeout(time: 1, unit: 'HOURS')
            retry(2)
        }
    
    
        // pipeline 全局变量
        environment {
            CC = 'clang'
        }
    
    
        parameters {
            string(name: 'PERSON', defaultValue: 'ts', description: '谁在构建?')
        }
        //定义各个阶段
        stages {
    
    
            //s1 echo
            stage('echo1') {
                // pipeline stage 变量
                environment {
                    FOLLOWER_CREDENTIAL = credentials('jenkins-follower-ssh-credential')
                }
                input {
                    message "Should we continue?"
                    ok "Yes, we should."
                    submitter "alice,bob"
                    parameters {
                        string(name: 'NAME', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
                    }
                }
                steps {
                    echo "${CC}"
                    echo "${FOLLOWER_CREDENTIAL_USR}:${FOLLOWER_CREDENTIAL_PSW}"
                    echo "hello ${params.PERSON}"
                    echo "hello ${NAME}"
                }
            }
    
    
    
    
            //获取git代码,注意,里面的credentialsId就是指定我们上面配置的git账号
            stage('git') {
                steps {
                    git branch: "${branch}", credentialsId: 'gitee-username', url: 'https://gitee.com/giteets/jenkinsdemo.git'
                }
            }
            //test阶段,调用maven执行测试代码
            stage('test'){
                steps {
                    sh '${MAVEN_HOME}/bin/mvn test'
                }
            }
            //编译打包阶段,打出可执行jar
            stage('build') {
                steps {
                    sh '${MAVEN_HOME}/bin/mvn clean package -DskipTests'
                }
            }
            //docker打镜像阶段,后面的version就是当前job的执行号,每次自增1
            stage('docker') {
                steps {
                    sh 'docker build -t tans666/jenkins-demo:${BUILD_NUMBER} .'
                }
            }
    
    
            stage('push') {
                when {
                    environment name: 'CC', value: 'push'
                }
                steps {
                    // 推送到镜像仓库
                    sh 'docker push tans666/jenkins-demo:${BUILD_NUMBER}'
                }
            }
    
    
            //部署阶段,停掉旧的docker进程,启动新镜像
            stage('deploy') {
                steps {
                    //如果test-boot没有在启动中,如果不跟随或语句,这里会执行失败,中断pipline!
                    sh 'docker rm -f jenkins-demo || sleep 0'
                    sh 'docker run --name jenkins-demo -d -p 8080:8080 tans666/jenkins-demo:${BUILD_NUMBER}'
                }
            }
        }
    }
    

    注意测试时:添加 branch 参数

    点击执行构建,发现最终也能执行完成!

    image.png

     

    总结

    • 本讲义内容基本包含了pipeline流水线工作绝大部分特性的应用,熟练掌握讲义内容有助于应对常规企业运维持续集成持续部署工作,讲义内容的重点在于对流水线的理解和声明式脚本语言的熟练掌握。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论