1. 前言
随着互联网软件行业快速发展, 为了抢占市场先机, 企业不得不持续提高软件的交付效率. 特别是现在国内越来越多企业已经在逐步引入 DevOps 研发模式的变迁, 在这些背景催促之下, 对于企业研发团队所需要具备的持续集成和持续交付 (简称 CI/CD) 能力变得越来越不可或缺.
相信现在不管是开发人员, 测试人员或者是运维人员, 在求职招聘时, 基本上如果是面试的是中高级以上的职位, 大多都要求要具备相关 CI/CD 的项目建设或参与搭建经验.
为了帮助到更多技术读者, 从本周起, 将以《持续集成实践系列》为主题, 分享几篇搭建 CI 持续集成实践的技术干货.
关于持续集成和持续交付 (CI/CD) 概念的介绍, 之前的文章:《DevOps 研发模式下 CI/CD 实践详解指南》 https://mp.weixin.qq.com/s/4tgWfcbi433jMSzx1Z7mqg 中有过较详细的介绍, 如果还不清楚什么是 CI/CD 的读者, 可以在阅读本文前先, 参考一下这篇文章.
2. CI 系列大纲
市面上关于 CI/CD 的建设如果仅从工具, 框架层面来讲, 方案有挺多, 如 TeamCity,GitLab CI,Bamboo,Circle CI,Travis CI,Jenkins, 公司自研(在研发建设 CI/CD 能力时, 除了 CI/CD 工具, 框架链的建设外, 还包括研发协同文化的建设等, 文化层面的这个不在本系列的讨论范围内).
而在众多的持续集成 CI 建设工具体系中, Jenkins 基本上可以说是独占鳌头, 也是大多数公司最常用, 最首选的工具之一, 占据了将近 70% 以上的市场.
而随着 Jenkins 本身的不断发展, 当前 Jenkins 已演变发展到了 2.x 系列, 在 Jenkins 2.x 系列中, 其中最核心的特性是引入了流水线机制, 并提出了流水线即代码 (pipeline as code) 的理念.
因此本系列也将以 Jenkins 2.x 作为《持续集成实践系列》的载体, 为大家介绍在结合 Jenkins 2.x 搭建持续集成 CI 能力过程中常见的一些知识要点和实现过程.
系列大纲分为(初步拟订):
Jenkins 2.x 搭建 CI 需要掌握的硬核要点(一)
Jenkins 2.x 搭建 CI 流水线执行流程(二)
Jenkins 2.x 搭建 CI 流水线实现案例(三)
Jenkins 2.x 搭建 CI 流水线通知机制(四)
Jenkins 2.x 搭建 CI 扩展流水线: 自定义共享库(五)
PS: 当然 Jenkins 2.x & CI 流水线的知识要点远不止如此.
3. 先介绍一下 Jenkins 2.x
Jenkins 2 本身的概念比较宽泛. 在特定的上下文环境中, 它用来泛指支持流水线即代码及其它类似 Jenkinsfile 等新特性的新版 Jenkins.
Jenkins 1.X 版本主要通过插件的方式来实现, 确切地讲, Jenkins 2 也是通过对已有插件的重点升级和新插件的引入来获取新功能.
相比之前, 用户只能通过 web 界面进行配置的方式来定义 Jenkins 任务, Jenkins 2 则通过使用 Jenkins DSL 和 Groovy 语言编写程序, 用户可以定义流水线并执行各种任务.
这里提到的 DSL 代表领域特定语言(Domain-Specific Language), 可以理解为一种适用于 Jenkins 的编程语言. DSL 基于 Grovvy 实现, 并通过概念和结构封装了 Jenkins 的特定功能.
Jenkins 2 推荐使用名为 Jenkinsfile 的文件保存任务配置和流水线信息, 不同的项目和分支都会有自己的 Jenkinsfile, 其内容各不相同. 你可以将全部代码写在一个 Jenkinsfile 中, 也可以通过共享库的方式调用外部代码.
4. Jenkins 2.x 实现流水线的两种语法
当我们通过 Jenkins 2.x 实现流水线时, 有两种不同的语法样式: 脚本式语法 (script syntax) 和声明式语法(declarative syntax).
脚本式语法 (script syntax) 是 Jenkins 最开始实现流水线即代码的方式, 这是一种命令式风格, 在以前版本的 Jenkins 中, 流水线即代码大体就是 Groovy 脚本, 其中插件部分针对 Jenkins 的 DSL 步骤. 这种方式几乎没有结构上的约束, 程序流程也基于 Groovy 语法结构实现.
这种模式现在被称为脚本式流水线. 在脚本式流水线中, DSL 支持为数众多的任务步骤, 但是仍然缺失了部分面向 Jenkins 任务的核心特性, 比如, 构建后处理, 流水线结构错误检查以及基于不同执行状态发送通知的功能. 当然大多数功能都可以通过 Groovy 编程机制来模拟实现, 比如 try-catch-finally 语法. 但是这在面向 Jenkins 编程的基础上对 Groovy 语言技能提出了更高的要求.
而声明式语法, 是 Jenkins 提供的一种新的选择, 声明式风格的流水线代码被编排在清晰的段落中, 相对于只关注实现逻辑.
5. 如何选择脚本式语法或声明式语法
那么有哪些因素会影响选择脚本式语法或声明式语法呢? 和大多数事情一样, 这也不是一个严谨的科学问题. 在特定的情况下, 对比需求, 实现的结构和流程以及构建流水线的人员技能和背景, 二者可能各有千秋.
比如, 脚本式流水线具有以下优点:
更少的代码段落和弱规范要求.
更强大的程序代码能力.
更像编写代码程序.
传统的流水线即代码模型, 用户熟悉并向后兼容性.
更灵活的自定义代码操作.
能够构建更复杂的工作流和流水线.
但同时, 脚本式流水线也具有以下缺点:
普遍要求更高的编程水平.
语法检查受限于 Groovy 语言及环境.
和传统的 Jenkins 模型有很大差异.
与声明式流水线的实现相比, 同一工作流会更复杂.
看一则简单的, 脚本式流水线示例:
- node("worker_node1"){
- stage("Source"){
- // 从 Git 仓库中获取代码
- Git 'git@github.com:zhoujinjian/intelligent-test-platform.git'
- }
- stage("Compile"){
- // 运行 Gradle 进行编译和单元测试
- sh "gradle clean comileJava test"
- }
- }
而声明式流水线优点有:
更结构化, 贴近传统的 Jenkins Web 表单形式.
更强大的声明内容能力, 高可读性.
可以能过 Blue Ocean 图形化界面自动生成.
段落可映射到常见的 Jenkins 概念, 比如通过.
更友好的语法检查和错误识别.
提升流水线间的一致性.
但如此同时, 声明式流水线的缺点也很明显:
对迭代逻辑支持较弱(相比程序而已)
对于传统的 Jenkins 中部分功能缺乏支持.
更严格的结构.
目前对于复杂的流水线和工作流难以胜任.
声明式流水线示例:
- pipeline{
- agent{
- lable "worker_node1"
- }
- stages{
- stage("Source"){
- steps{
- // 从 Git 仓库中获取代码
- Git 'git@github.com:zhoujinjian/intelligent-test-platform.git'
- }
- }
- stage("Compile"){
- steps{
- // 运行 Gradle 进行编译和单元测试
- sh "gradle clean comileJava test"
- }
- }
- }
- }
简而言之, 对于新用户和那些希望流水线具备传统 Jenkins 一样可读性的用户来说, 声明式流水线更容易学习和维护. 脚本式流水线更加灵活, 允许用户不受结构结束实现更多功能.
不过, 总的来说, 任何一种流水线类型对大多数场景而言同样适用. 好了本文作为 CI 持续集成系列的开篇, 先介绍到这里吧.
详细可查看: 原文阅读 https://mp.weixin.qq.com/s/TuAIL7yICF0bstDmM7L_yw
来源: https://www.cnblogs.com/jinjiangongzuoshi/p/12970627.html