Jenkins on Jenkins 中文社区 https://jenkins-zh.github.io/tags/jenkins/ Recent content in Jenkins on Jenkins 中文社区 Hugo -- gohugo.io zh-CN Tue, 31 Dec 2019 00:00:00 +0000 使用 Jenkins 实现 CI/CD 多分支流水线 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-31-implement-cicd-for-multibranch-pipeline-in-jenkins/ Tue, 31 Dec 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-31-implement-cicd-for-multibranch-pipeline-in-jenkins/ 简介 Jenkins 是一个持续集成服务器,用于从版本控制系统(VCS)中获取最新代码,然后对其进行构建、测试并将结果通知给开发人员。除了作为一个持续集成(CI)服务器之外,Jenkins 还可以做很多其它的事情。最初它被称为 Hudson,是川口耕介(Kohsuke Kawaguchi)基于 Java 编写的一个开源项目,因此,在安装和运行 Jenkins 之前,首先需要安装 Java 8。 多分支流水线是 Jenkins 中的一种流水线类型,它允许您在 Jenkinsfile 的帮助下为源码管理(SCM)库中的每个分支自动地创建一支流水线。 什么是 Jenkinsfile Jenkinsfile 是一个文本文件,被用来定义一个 Jenkins 流水线。在 Jenkinsfile 中可以使用领域特定语言(DSL)编写运行 Jenkins 流水线所需要的步骤,从而将流水线实现为代码。 来自 Jenkins 的定义 使用多分支流水线,您可以为同一项目的不同分支实现不同的 Jenkinsfile,Jenkins 将会自动发现、管理和执行那些分支中包含 Jenkinsfile 的流水线。 创建一个简单多分支流水线任务的步骤 点击 Jenkins 工作台左上角的 New Item 选项: 在 Enter an item name 中填入任务名,向下滚动,然后选择 Multibranch Pipeline,最后点击 OK 按钮: 填写任务描述(可选)。 添加一个分支源(例如:GitHub)并且填写代码仓库的位置。 选择 Add 按钮添加凭证并点击 Jenkins。 键入 GitHub 用户名、密码、ID 和描述。 Webhook 通用触发插件 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-23-generic-webhook-trigger-plugin/ Mon, 23 Dec 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-23-generic-webhook-trigger-plugin/ 这篇文章将介绍我在 Jenkins 上遇到的一些常见问题,以及如何通过开发通用 Webhook 触发插件来解决这些问题。 问题 在使用 Jenkins 工作时,我经常遇到同样的问题: 代码重复和安全性-每个仓库中的 Jenkinsfiles。 分支不是功能-master 上的参数化任务通常会混合与不同功能相关的参数。 记录不良的触发器插件-记录正常服务但记录不佳的使用插件 代码重复和安全性 每个 Git 仓库中都有 Jenkinsfiles,使开发人员可以使这些文件分开。开发人员 push 他们的项目,并且很难维护共享代码的模式。 我几乎用共享库解决了代码重复问题,但是它不允许我设置必须遵循的严格模式。任何开发人员仍然可以决定不调用共享库提供的功能。 还允许开发人员运行 Jenkinsfiles 中的任何代码的安全性方面。例如,开发人员可能会打印从凭据收集的密码。让开发人员在 Jenkins 节点上执行任何代码对我来说似乎不合适。 分支不是功能 在 Bitbucket 中有项目,每个项目都有 git 仓库的集合。像这样: PROJ_1 REPO_1 REPO_2 PROJ_2 REPO_3 让我们考虑一下我们要为这些仓库提供的一些功能: pull request 验证 构建快照(如果需要的话,也可以预发布) 构建发布 如果开发人员习惯于在 Bitbucket 中像这样组织仓库,我们是否应该在 Jenkins 中以同样的方式组织它们?而且,如果他们浏览 Jenkins,是否不应该为每种功能(例如 pull-request,snapshot 和 release)找到一份构建任务?每个具有仅与该功能相关的参数的任务。我认同!像这样: / - Jenkins root /PROJ_1 - 一个文件夹,列出 git 仓库。 /PROJ_1/REPO_1 - 一个文件夹,列出与该仓库相关的任务。 /PROJ_1/REPO_1/release - 一份构建任务,执行发布。 /PROJ_1/REPO_1/snapshot - 一份构建任务,执行快照发布。 /PROJ_1/REPO_1/pull-request - 一份构建任务,验证 pull-request。 …​ 在此示例中,snapshot 和 release 任务都可以在同一 git 分支上工作。不同之处在于它们提供的功能。它们的参数可以很好地记录下来,因为您不必混合与发行版和快照相关的参数。使用多分支流水线插件无法做到这一点,在多分支流水线插件中,您将参数指定为每个分支的 properties。 使用 Docker 全自动构建 Java 应用 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-19-full-build-automation-for-java-application-using-docker/ Thu, 19 Dec 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-19-full-build-automation-for-java-application-using-docker/ 这次的流水线中,我们使用 Docker 容器来构建我们的 Java 应用。 我们会在 Docker 容器里运行 Jenkins,再使用 Jenkins 启动一个 Maven 容器,用来编译我们的代码,接着在另一个 Maven 容器中运行测试用例并生成制品(例如 jar 包),然后再在 Jenkins 容器中制作 Docker 镜像,最后将镜像推送到 Docker Hub。 我们会用到两个 Github 仓库。 Jenkins-complete:这是主仓库,包含了启动 Jenkins 容器所需的配置文件。 Simple-java-maven-app:使用 Maven 创建的 简单的 Java 应用。 在搭建之前,我们先来了解一下这两个仓库。 了解 Jenkins-complete 这是我们构建 Jenkins 镜像的核心仓库,它包含了所需的配置文件。我们通过 Jenkins 官方提供的 Docker 镜像启动 Jenkins 容器,然后完成一些动作,例如安装插件、创建用户等。 安装好之后,我们会创建用来获取 Java 应用的 Github 凭据,还有推送镜像到 Dockerhub 的 Docker 凭据。最后,开始创建我们应用的流水线 job。 这个过程很长,我们的目标是让所有这些事都自动化。主仓库包含的文件和详细配置会用来创建镜像。当创建好的镜像启动运行以后,我们就有了: 1. 新创建的 admin/admin 用户 2. 已经装好的一些插件 3. Docker 和 Github 凭据 4. Jenkins 健康检查顾问 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-11-jenkins-health-advisor-by-cloudbees-is-here/ Wed, 11 Dec 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/12/2019-12-11-jenkins-health-advisor-by-cloudbees-is-here/ 管理任何软件都面临着独特的挑战。Jenkins Masters 也不例外。例如, 您如何掌握 Jenkins 环境中发生的所有事情?您是否正在查看问题跟踪器中打开的每个新缺陷? 您如何确保您的 master 或 agents 不会默默失效?您是否正在监控其日志?监控其所有内部组件?如果出现问题,您该如何解决? 您如何避免出现 “Angry Jenkins” 图标? 这就是我们通过 CloudBees 创建 Jenkins Health Advisor 的原因。 在 CloudBees,我们拥有多年为使用 Jenkins 的客户提供支持的经验,其中包括基于 Jenkins 构建的专有产品,例如 CloudBees Core。因此,我们的支持团队由拥有 Jenkins 知识的自动化专家组成,您在其他任何地方都无法获得。 当我们的工程师创建一个平台时,便会开始自动运行状况检查,以便他们可以编写规则来检测客户提供的 support bundles 中的已知问题,并将其重定向到所需的知识源以诊断和解决问题。 经过多年的内部使用,我们决定与社区共享此服务,我们很高兴为 每个 Jenkins 用户推出一项新的免费服务:Jenkins Health Advisor by CloudBees。 Jenkins Health Advisor by CloudBees 自动分析您的 Jenkins 环境,主动识别潜在问题,并通过详细的电子邮件报告为您提供解决方案和建议。 Jenkins Health Advisor by CloudBees 可以检测到各种问题,从简单的配置问题到安全性和最佳实践问题-Jenkins 实现的所有关键要素。入门过程分为 3 个步骤,您将在 24 小时内收到第一份报告。 我们希望您会喜欢这项服务,它将帮助您保持 masters 的健康。 花几分钟时间阅读我们的文档,发现服务,并随时通过 Jenkins 社区渠道(Gitter、jenkinsci-users@googlegroups. 在大型企业里维护多分支流水线 https://jenkins-zh.github.io/wechat/articles/2019/08/2019-08-05-jenkins-multi-branch-pipeline/ Mon, 05 Aug 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/08/2019-08-05-jenkins-multi-branch-pipeline/ Jenkins 是 DevOps 领域里非常好的 CI/CD 工具,它凭借其独特的功能,几乎可以满足你一切的的业务要求。其中一个独特的功能是多分支流水线(Multi-branch 流水线),可以动态配置流水线。但是,随着公司的发展,单独的多分支流水线并不能完全满足你的所有需求,特别是在涉及大型企业时,你需要考虑流水线的集中管理,治理,稳定性,限制和安全性等其他事项。因此对于具有 Jenkins 流水线的大规模 CI/CD 环境,你需要添加之前没有想到的更多功能。 动态配置流水线 当一个开发人员创建一个新分支并将其推送到远程代码仓库时,Jenkins 会为这个新分支动态创建流水线。根据代码仓库,甚至也可以作为动态创建 Pull Request 流水线。这个动态功能在使用 Feature 分支或其他类似功能的团队中非常有用,由于本文的主题不是多分支流水线,你可以在端到端多分支流水线项目创建中找到详细信息和一些示例。 流水线即代码 在多分支流水线中,脚本存储在项目代码仓库中,这就是“流水线即代码”的概念。此外,当你拥有小型开发人员团队或项目没有大量分支时,它非常有用。这样,开发人员可以根据需要更改流水线,将更改推送到分支,并立即看到更改生效,但对于拥有数百或数千名拥有大量项目的开发人员的大型企业而言,这种方案就完成不可行了。 集中式库 当你的团队或项目增加时,是时候考虑一种方法,比如通过共享的的方式应该在所有项目中。从长远来看,这种“集中式库”变得非常关键,因为随着规模的扩大,流水线中出现了新的要求或变化,在这种情况下,手动更改每个流水线或脚本对管理员来说将是一场噩梦。因此,如果你在一个地方进行更改并且每个流水线都得到更新,那么拥有该集中式库将更加实用。这是 Jenkins 共享库概念的用武之地。有关详细信息,你可以访问该站点。 即使你只有一个流水线,仍然可以使用集中式库。 治理与稳定 如果你的团队有对 CI/CD 一定了解的开发人员,并且你确信他们不会做出重大更改或编写脚本错误导致影响环境的稳定性,那么将流水线脚本放在代码中是很好的。但是,你真的确定吗? 有人很可能会意外删除流水线文件或者可能出现小错误,这些小错误都会影响 CI/CD 的稳定性。如果你在早期发现这些错误时很容易解决这些错误,如果没有,这些微小的变化或错误将可能比你想象的更严重的影响 CI/CD,它将被传播到不同项目中的所有分支或 tag,这会变得很难解决。 你需要将正确的流水线脚本推送到所有分支和/或代码仓库,或是要求每个开发人员提取最新的脚本,这种类型的问题集中式库这种更高级的方式来解决,除此之外,你的环境会因为有人可能会删除 Jenkins 文件或输入一些拼写错误带来风险。 远程文件插件 为了消除不必要的更改的风险并降低使用的库的复杂性,我们需要以某种方式将流水线脚本与项目/代码代码仓库分开,同时仍继续使用多分支流水线功能。为此,我们有远程文件插件。 这个插件使多分支流水线能够从其他代码仓库运行/加载流水线脚本,而不是将它们放在项目/代码代码仓库中,通过这个功能,你可以拥有一个单独的代码仓库,你可以在其中放置所有流水线脚本,并且只能为你自己提供访问权限。这样,你将拥有与集中式库相同的集中式流水线脚本代码仓库。此外,你可以将流水线脚本存储在集中式库本身中。 这个功能的好处是除了有访问权限的人之外,没有人能够在流水线脚本中进行更改。你在集中流水线脚本中所做的任何更改都将影响使用该脚本文件的所有多分支流水线。这样,你无需等待所有开发人员获取更新版本或将脚本推送到所有代码仓库上的所有分支。 另一个好处是,如果你将集中式流水线脚本放入 BitBucket 或 GitHub 等代码仓库中,你还将拥有代码审查功能。这样,你可以与其他人共享代码仓库,同时仍可限制或查看其他人所做的更改。 结论 在大型企业中创建 CI/CD 流水线并不容易,你需要考虑治理,限制,稳定性和安全性等概念。在此上下文中,借助 Jenkins 的其他功能,Remote File Plugin 提供了一个独特的功能,用于集中,维护和共享流水线脚本。 有关插件的详细信息,你可以访问插件的 Wiki 页面。 Jenkins 流水线配置历史插件介绍 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-31-pipeline-config-history-plugin/ Wed, 31 Jul 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-31-pipeline-config-history-plugin/ 流水线是在 Jenkins 中创建任务的有效的和现代的方式。 为了快速、简单地识别流水线变更,我们开发了流水线配置历史插件。 这个插件检测流水线的变更,并为用户提供一个选项,以明显地、可追溯地查看流水线配置两次构建(差异)之间的变更。 一切是如何开始的 这一切开始于十年之前 —— 经典的任务类型 (例如:自由风格、Maven 等等)。 每隔一段时间,用户就会联系我们,因为他们的任务无法在一夜之间完成。 为什么这个任务失败了呢? 这次失败和任务配置变更有关系吗? 用户典型的回答是:”我们没有改任何东西”,但这是真的吗? 我们思考了这个问题,并决定开发一个插件来帮助我们解决这个问题。 这就是plugin:jobConfigHistory[任务配置历史]的想法和开始。 现在可以查看任务配置的变更(例如其他分支、JDK版本等),而且更常见的情况是,破坏构建的原因是任务配置的变更。 多年来,该插件得到了开发,目前仍在开发中。 添加了新的功能,不仅可以查看任务配置,还可以查看全局和代理配置的变更。 还可以恢复旧的配置版本。 如今,这个插件已经有超过30,000次安装量。 多年来,JobConfigHistory 减轻了我们的日常工作 —— 我们有超过3000个 Jenkins 任务! 然后出现了一种新的任务类型:流水线。 流水线 —— 需要一些新的东西 流水线任务和经典的任务类型有根本地区别。 经典的任务类型是通过 Jenkins GUI 配置的,而流水线任务是配置即代码。 实际上,每个流水线任务都是通过 Jenkins GUI 创建的,然而这并不一定是流水线配置的位置。 流水线可以被配置: 直接在 Jenkins 任务中作为脚本。 代码将直接插入任务配置页面。 作为源代码管理系统(SCM)中的 Jenkinsfile:流水线配置在 SCM 中的文本文件(Jenkinsfile)中定义。 在任务本身中,只配置了 Jenkinsfile 存储库的路径。 在构建过程中,Jenkinsfile 从 SCM 中被检出并被处理。 作为共享库:流水线配置的一部分被移动到单独文件中,它可以由多个任务使用。 这些文件也保存在 SCM 中。 即使这样仍然需要 Jenkinsfile(或者任务中的流水线脚本)。 对于任务配置的每次保存操作,如果发生了变更,JobConfigHistory 将创建实际任务配置的副本。 只有当流水线配置作为脚本插入到任务配置页面时,该方法才适用于流水线任务。 JobConfigHistory 未检测到 Jenkinsfile 或共享库中的变更。 您必须使用 SCM 系统查看 Jenkinsfile 或共享库的变更。 在构建时间和对 Jenkinsfile 或共享库的变更之间找到相关性是复杂且耗时的。 持续交付落地实践工作坊 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-14-jenkins-pipeline-workshop/ Sun, 14 Jul 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-14-jenkins-pipeline-workshop/ Jenkins 中文社区第二次线下持续交付落地实践工作坊在召唤每一位希望学习并掌握持续交付技术的同学,就在 2019年7月27日(周六)。 Kubernetes 已经成为容器技术中必不可少的平台,甚至会作为未来的“操作系统”。相信每一次 IT 从业人员都有理由把 Kubernetes 掌握,本次活动首先由 Linux 基金会与 CNCF 基金会官方认证 Kubernetes CKA 培训讲师(LFAI)的孟凡浩为我们分享 Kubernetes 的入门介绍。 之后,分享如何基于 Kubernetes 强大的平台下实践持续交付。 在上次的工作坊实践中,我们首先完整地介绍了 Jenkins 的流水线功能,然后大家一起通过四个练习项目加强并巩固了 Jenkins 流水线 Jenkinsfile 文件的编写。 上次练习的项目包括: 构建 Maven 项目 制品归档 构建 Docker 镜像 参数化构建,指定 Docker 镜像 Tag 过程中录制的视频,可以从我们的优酷地址上找到 https://i.youku.com/jenkinszh 而对于参加本次工作坊实践活动的同学,可以根据自身的情况选择练习上面的题目或者下面进阶的题目: 构建 Maven 项目并发布到 Nexus 使用私有 Nexus 中的依赖进行构建 构建 Docker 镜像并推送到 Harbor 构建 Heml Charts 并推送到 Chartmuseum 我们期望每一位参加的同学都可以从中学习并掌握基于 Jenkins 的持续交付技术,助力你所在团队的 DevOps 实践。更多的实训项目请参考 https://jenkins-zh.cn/about/course/#17 最后,让我们一起感谢京东云为我们本次活动提供的 Kubernetes 云计算资源。因此,每一位参加练习的同学,只需要带上自己的笔记本,以及 SSH 客户端即可。 Jenkins 每周版更新 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-18-jenkins-weekly-release/ Tue, 09 Jul 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-18-jenkins-weekly-release/ 2.184 (2019-07-07) 注销时,移除过期的会话 cookies ,阻止头信息中的相关错误太大。 (issue 25046) 当运行在 Java 11 上时,增加缺失类相关的 telemetry 实验。 (issue 57223) 修复使用“记住我”时的性能问题(于 2.160 中退化) (issue 56243) 开发者:清理 AbstractCloudSlave 的构造器 (pull 4086) 2.183 (2019-06-30) 在 Jenkins 的 URL 配置增加对 IPv6 地址的支持。 (issue 58041) 更新 args4j 2.0.31 到 2.33。 (issue 57959) 开发者:允许插件为 CodeMirror 文本域控制提供 onBlur() 的支持。 (issue 58240) 开发者:使得 WindowsUtil 可以让插件使用。 (pull 4038) 内部:更新 maven-war-plugin 3.0.0 到 3.2.3 (issue 47127) 2.182 (2019-06-23) 当删除目录时,移除 Windows 下的只读标记。 (issue 57855) 更新 Remoting 3. Jenkins 长期支持版更新 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-09-jenkins-release/ Tue, 09 Jul 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/07/2019-07-09-jenkins-release/ 2.176.1 (2019-06-10) 自 2.176 以来的变更: 恢复安装向导中用到的中文本地化资源。 (issue 57412) Robustness: 当 ComputerListener#onOnline() 发生运行时异常后不把节点设置为离线状态。 (issue 57111) CLI 中通过参数 (-remoting option) 对远程模式的支持已经被移除。 (pull 3838, 博客发布) 移除符号 nonStoredPasswordParam 对密码参数定义的误导,因为,它会存储加密后的数据。 (issue 56776) 移除对 CCtray (cc.xml) 文件的默认支持。 要使用该功能,需要按照插件 CCtray XML Plugin。 (issue 40750) 增加 CLI 命令 stop-job 终止构建。 (issue 11888) 在日志配置中支持关闭一项日志记录器。 (issue 56200) 为 REST API 的响应增加运行参数过滤器。 (issue 56554) 构建结束后更新状态图标。 (issue 16750) 在 Jenkins 节点的界面上移除对 Java Web Start and JNLP 的误导性引用。 (pull 3998) 使用Active-Choices-Plugin插件将十个Job合成一个 https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-26-using-active-choices-plugin-merge-jobs/ Wed, 26 Jun 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-26-using-active-choices-plugin-merge-jobs/ 现在Spring Cloud越来越火爆,许多公司也都在如火如荼投入使用中,而微服务最大的一个特点,就是多,同一大项目之下,可能会被拆分成十几二十几个子服务,对于运维而言,可能也需要一个对应一个地在Jenkins中创建十几二十几个Job。 刚刚还在一个博主的自我介绍里看到这样一句话:喜欢一切优雅的运维方式··· 于是,我一直在想着,通过一些合理的参数变幻,从而将刚刚提到的十几二十几个服务,汇集到一个Job当中就能完成。 1,环境说明 主机:CentOS-7.5 Jdk:jdk1.8.0_192 Tomcat:8 Jenkins:2.177 如上环境的准备工作本文就不赘述了。 2,安装插件。 官方地址:https://wiki.jenkins.io/display/JENKINS/Active+Choices+Plugin 安装方式:在Jenkins插件当中直接搜索即可安装。 功能说明:根据所选参数,自动调出对应参数所依赖的后续参数。 3,使用前介绍。 插件安装之后,可以在项目配置中的参数化配置中看到一些新增了的选项。 1,Active Choices Parameter(主动选择参数) Active Choices参数使用Groovy脚本或Scriptler目录中的脚本动态生成构建参数的值选项列表。 2,Active Choices Reactive Parameter(主动选择反应参数) 根据主动选择参数的选项而提供不同的对应值或者列表选项。 3,Active Choices Reactive Reference Parameter(主动选择反应参考参数) 根据主动选择参数的选项而展示对应参数的一些说明,与第二项的区别在于本参数只作为说明信息,而不能够作为变量往下传递。 可能刚刚这些说明都比较抽象,接下来容我通过项目实战,来对其进行一一解析。 4,配置前分析。 优秀的插件,它的优秀之处,往往是需要我们结合生产实际,开动聪明的大脑,打破常规使用套路来成就的。 因此,如何才能更好地应用插件的优秀功能,需要我们先对项目进行分析,从全局的眼光,判断项目前后该配置什么样的参数来进行联动。 这里我说明一下我准备的实验项目情况,为了简便测试,我这里仅使用两个项目来进行举例,聪明的你也一定能够通过案例进行举一反三,将二合一推广为十合一的。 两个项目的情况如下: 1,eureka Gitlab地址:git@192.168.10.0:ishangjie/ishangjie-eureka-server.git port:8761 包名:ishangjie-eureka-server-1.0.0.jar 2,user Gitlab地址:git@192.168.10.0:ishangjie/ishangjie-user-service.git port:6666 包名:ishangjie-user-service-1.0.0.jar 从刚刚这些配置里边可以看出,有不少共同点,也有不少不同点,我们只需把眼光放在不同点上,通过一些统一的变量控制,就能达到二合一的目的。 另外说明一点,这个项目已经部署在k8s环境当中,因此我的脚本内容也就展示成了k8s项目部署的流程了。 5,创建项目。 首先创建一个自由风格的Jenkins项目,然后配置一下项目构建保存历史。 6,字符参数。 添加一个名为branch的字符参数以用于控制代码分支的变量。 7,选项参数。 添加一个名为mode的选项参数以用于控制部署或者回滚的变量。 8,选择参数。 1,主动选择参数 首先添加一个主动选择参数,用于控制项目名称这个变量。 Name:project Groovy Script: return[ "eureka", "user" ] Description:选择对应的应用名称部署对应的应用。 Choice Type:Radio Buttons 2,主动选择反应参数 接着添加一个主动选择反应参数,用于控制项目类型这个变量。 30分钟搞定 Jenkins CI https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-14-setup-jenkins-ci-in-30-minutes/ Fri, 14 Jun 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-14-setup-jenkins-ci-in-30-minutes/ 你想在本地设置中使用 Jenkins CI 进行实验吗?在本文中,我们将设置一个本地 Jenkins CI 服务,为一个简单的 Spring Boot Maven 项目创建一个构建工作,并将创建的 Docker 镜像推送到 DockerHub。这将是一个本地实验的设置,但如果你想尝试一个 Jenkins 插件,它会非常方便。 1.先决条件 开始之前,我们需要以下先决条件: 我们使用了 Ubuntu 18.04; 必须安装 Docker,有关安装说明,请参见此处; 我们需要在 Docker registry 来推送我们的 Docker 镜像。最简单的方法是在DockerHub上创建一个帐户。你可以免费创建帐户。也不会收到垃圾广告邮件; 构建工作的 Spring Boot 应用程序。我们将使用前一篇文章中的 Spring Boot MVC 应用程序。源代码可以在GitHub上找到,相应的Docker图像可以在DockerHub上找到。该应用程序包含 http://localhost:8080/hello 上的一个 HTTP 端点,并只返回一条 Hello Kubernetes 欢迎消息。 2.运行 Jenkins CI 我们将使用 Jenkins CI Docker 官方镜像运行 Jenkins 服务。完整的文档可以在这里找到。用以下命令启动容器: $ docker run -p 8080:8080 --name myjenkins -v jenkins_home:/var/jenkins_home -v jenkins_downloads:/var/jenkins_home/downloads jenkins/jenkins:lts 让我们来仔细看看我们正在做什么: 还在苦恼不会写 Jenkins 流水线?来场工作坊! https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-10-jenkins-pipeline-workshop/ Mon, 10 Jun 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-10-jenkins-pipeline-workshop/ 前段时间,Jenkins 中文社区建了一个“Jenkins 中文社区技术交流”的微信群。 群里不温不火,不时有人抛出几个关于 Jenkins 流水线的问题。比如以下聊天记录: 而这些问题都共同说明另一个问题:Jenkins 的流水线的普及度还很低。大家都苦恼着不知道如何写 Jenkins 流水线呢。 所以,Jenkins 中文社区决定6月22日组织一场工作坊,手把手教大家如何写 Jenkins pipeline。工作坊内容包括: * 流水线基础讲解及其练习。 * 流水线高级部分讲解及其练习。 * 案例实战(注意啦,可是有案例的。不是虚的。) 问题来了?谁是这次工作坊的教练呢? 赵晓杰:jenkinsci Contributor,Jenkins 中文社区发起人。 想参加的同学,请点击阅读原文报名参加。 如果无法现场参加的同学可以发邮件至 events@mail.jenkins-zh.cn 申请 ZOOM 网络会议接入。另,我们鼓励由一人申请,并组织好其他人一起参与。这样多人一起进行工作坊,效果更佳。申请邮件中写明:申请人所在公司、地点、参与人数。 对了想入伙加群?很简单,Jenkins 公众号后台回复“微信群”,扫码入群。趁现在群没满,你懂的!~ Jenkins 2.176~2.178版本更新 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-29-jenkins-release/ Wed, 29 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-29-jenkins-release/ 2.178 (2019-05-20) 将 jmDNS 从3.4.0-jenkins-3更新到3.5.5,以防止不必要的 DNS 组播错误消息。 (issue 25369) 将 WinP 从1.27更新到1.28,以修复 Windows 优雅进程关闭逻辑中缺少 DLL 和控制台窗口闪烁的问题。 (issue 57477, 完整的变更日志) 确保独立的插件(插件曾经是 Jenkins 本身的一部分功能)在 Jenkins 启动时(需要时)作为已经存在的其他插件的隐含依赖项安装。 这简化了不使用更新中心的特殊安装场景的兼容性,例如当 Jenkins 从预先打包了一些插件的 Docker 镜像运行时。 (issue 57528) 将脚本安全插件的捆绑版本与最新的安全警告一起更新,在不太可能的情况下,它确实是从 WAR 而不是更新中心安装的。 (pull 4000) 2.177 (2019-05-12) 支持在流水线或其它任务类型的 fingerprint() 构建步骤中设置排除和区分大小写。 (文档, pull 3915) 允许通过不同的阴影构建球区分新任务、禁用的任务和中止构建的任务。 (pull 3997) 将 Windows 代理安装程序从1.10.0更新到1.11,当在 .NET 4.6 或更新版本运行时,在代理下载时启用 TLS 1.2。 (issue 51577, 完整的变更日志) 将 Winstone-Jetty 从5.2更新到5.3以更新 Jetty 到 9.4.18。 (pull 4016, 完整的变更日志, Jetty 9. 如何对 Jenkins 共享库进行单元测试 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-28-jenkins-pipeline-shared-lib-unit-test/ Tue, 28 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-28-jenkins-pipeline-shared-lib-unit-test/ Jenkins 共享库是除了 Jenkins 插件外,另一种扩展 Jenkins 流水线的技术。通过它,可以轻松地自定义步骤,还可以对现有的流水线逻辑进行一定程度的抽象与封装。至于如何写及如何使用它,读者朋友可以移步附录中的官方文档。 对共享库进行单元测试的原因 但是如何对它进行单元测试呢?共享库越来越大时,你不得不考虑这个问题。因为如果你不在早期就开始单元测试,共享库后期可能就会发展成如下图所示的“艺术品”——能工作,但是脆弱到没有人敢动。 [图片来自网络,侵权必删] 这就是代码越写越慢的原因之一。后人要不断地填前人有意无意挖的坑。 共享库单元测试搭建 共享库官方文档介绍的代码仓库结构 (root) +- src # Groovy source files | +- org | +- foo | +- Bar.groovy # for org.foo.Bar class +- vars | +- foo.groovy # for global 'foo' variable | +- foo.txt # help for 'foo' variable +- resources # resource files (external libraries only) | +- org | +- foo | +- bar.json # static helper data for org. 基于 Jenkins + JaCoCo 实现功能测试代码覆盖率统计 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-22-jacoco-coverage-for-functional-test/ Wed, 22 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-22-jacoco-coverage-for-functional-test/ 使用 JaCoCo 统计功能测试代码覆盖率? 对于 JaCoCo,有所了解但又不是很熟悉。 “有所了解”指的是在 CI 实践中已经使用 JaCoCo 对单元测试代码覆盖率统计: 当代码 push 到代码仓库后,用 JaCoCo 进行单元测试代码覆盖率统计,并将相应数据推送到 SonarQube。 “不是很熟”指的是应用场景也仅限于此,并未进行过多研究与实践。 前不久,有测试同事提出,想要在实际测试时,用 JaCoCo 统计功能测试代码覆盖率。 其主要目的是在经过功能测试后,通过查看代码覆盖率统计的相关指标,增强对软件质量的信心。 经查阅资料,证明这是可行的。 由于对 JaCoCo 不甚了解,于是查阅官网资料对 JaCoCo 进一步了解。 进一步了解 JaCoCo JaCoCo,即 Java Code Coverage,是一款开源的 Java 代码覆盖率统计工具。 它由 EclEmma 团队根据多年来使用和集成现有库的经验教训而创建。 JaCoCo 愿景 JaCoCo 应该为基于 Java VM 的环境中的代码覆盖率分析提供标准技术。 重点是提供一个轻量级的、灵活的、文档良好的库,以便与各种构建和开发工具集成。 JaCoCo 产品功能 指令(C0)、分支(C1)、行、方法、类型和圈复杂度的覆盖率分析。 基于 Java 字节码,因此也可以在没有源文件的情况下工作。 通过基于 Java agent 的实时检测进行简单集成。其他集成场景(如自定义类加载器)也可以通过 API 实现。 框架无关性:平稳地与基于 Java VM 的应用程序集成,比如普通 Java 程序、OSGi 框架、web 容器或 EJB 服务器。 兼容所有已发布的 Java 类文件版本。 支持不同的 JVM 语言。 支持几种报告格式( HTML、XML、CSV )。 远程协议和 JMX 控件,以便在任何时间点从覆盖率 agent 请求执行数据 dump 。 Ant 任务,用于收集和管理执行数据并创建结构化覆盖报告。 Maven 插件,用于收集覆盖信息并在Maven构建中创建报告。 非功能特性 使用简单和与现有构建脚本和工具集成。 良好的性能和最小的运行时开销,特别是对大型项目。 轻量级实现,对外部库和系统资源的依赖性最小。 全面的文档。 完整文档化的 API ( JavaDoc ) 和用于与其他工具集成的示例。 回归测试基于 JUnit 测试用例,具有完整的功能测试覆盖率。 对 JaCoCo 可以与现有构建脚本和工具进行集成这里做进一步说明: 官方提供了 Java API、Java Agent 、CLI、Ant 、Maven、Eclipse 这几种集成方式; 第三方提供了诸如与 Gradle、IDEA、Jenkins 等其它工具的集成方式。 使用 Jenkins + Ansible 实现 Spring Boot 自动化部署101 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-20-jenkins-ansible-springboot/ Mon, 20 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-20-jenkins-ansible-springboot/ 本文要点: 1. 设计一条 Spring Boot 最基本的流水线:包括构建、制品上传、部署。 1. 使用 Docker 容器运行构建逻辑。 1. 自动化整个实验环境:包括 Jenkins 的配置,Jenkins agent 的配置等。 1. 代码仓库安排 本次实验涉及以下多个代码仓库: % tree -L 1 ├── 1-cd-platform # 实验环境相关代码 ├── 1-env-conf # 环境配置代码-实现配置独立 └── 1-springboot # Spring Boot 应用的代码及其部署代码 1-springboot 的目录结构如下: % cd 1-springboot % tree -L 1 ├── Jenkinsfile # 流水线代码 ├── README.md ├── deploy # 部署代码 ├── pom.xml └── src # 业务代码 所有代码,均放在 GitHub:https://github.com/cd-in-practice 2. 实验环境准备 笔者使用 Docker Compose + Vagrant 进行实验。环境包括以下几个系统: * Jenkins * 1 Jenkins master,全自动安装插件、默认用户名密码:admin/admin。 * Jenkins agent * 2 Jenkins agent 运行在 Docker 容器中,共启动两个。 * Artifactory * 1 一个商业版的制品库。笔者申请了一个 30 天的商业版。 从 Jenkins 到 Jenkins X https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-17-from-jenkins-to-jenkins-x/ Fri, 17 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-17-from-jenkins-to-jenkins-x/ 这是一个关于 dailymotion 从 Jenkins 到 Jenkins X 的旅程,我们遇到的问题,以及我们是如何解决它们的故事。 我们的上下文 在 dailymotion ,我们坚信 devops 最佳实践,并且在 Kubernetes 投入了大量投资。 我们的部分产品已经部署在 Kubernetes 上,但并不是全部。 因此,当迁移我们的广告技术平台的时候,我们想要完全采用“ Kubernetes 式”——或者云原生,以追随技术趋势! 这意味着要重新定义整个 CI/CD 流水线,从静态/永久环境迁移,转向动态按需分配环境。 我们的目标是授权给我们的开发人员,缩短我们的上线时间以及降低我们的运营成本。 对于新的 CI/CD 平台我们的初始需求是: - 尽可能避免从零开始:我们的开发人员已经习惯使用 Jenkins 和声明式流水线,并且它们可以很好地满足我们当前的需求。 - 以公有云基础设施为目标——Google 云平台和 Kubernetes 集群 - 与 gitops 方法论兼容——因为我们喜欢版本控制、同行评审和自动化 在 CI/CD 生态系统中有相当多的参与者,但是只有一个符合我们的需求,Jenkins X ,它基于 Jenkins 和 Kubernetes ,原生支持预览环境和 gitops Kubernetes 之上的 Jenkins Jenkins X 的设置相当简单,并且在他们的官方网站上已经有很好的文档(译注:译者曾对 Jenkins X 文档中文本地化做了一些贡献,同时也期待更多的人参与以完善中文文档)。 由于我们已经使用了 Google Kubernetes Engine (GKE),所以 jx 命令行工具自己创建了所有东西,包括 Kubernetes 集群。 这里有一个小小的*哇哦效果*,在几分钟内获得一个完整的工作系统是非常令人印象深刻的。 19年 GSoC 中 Jenkins 的七个项目 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-15-gsoc-annoncement/ Wed, 15 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-15-gsoc-annoncement/ Google Summer of Code (GSoC) 项目是一个年度性的全球化活动,该项目旨在鼓励高校学生在暑假期间参与到开源项目中来。 通过审核的学生会收到由 Google 提供的带薪工作,参与到设计好的项目中以改进或提升 Jenkins 项目。作为回报,数名 Jenkins 社区成员会志愿作为学生“导师”来帮助他们融入开源社区并成功完成他们的夏令营项目。 Jenkins 社区从2009年开始以开源社区的身份参与到 GSoC 中,并分别在16年有5个项目、18年有3个项目被选中。 而今年的项目、导师的数量是最多的一年,相信在这个夏天里,Jenkins 社区可以给我们的用户带来很多不错的 成果,其中也许正有你或者你们团队所希望有的功能或者改进。 2019年被选中的七个项目包括: 支持制品升级的流水线插件 基于云的外部工作空间管理器插件 多分支流水线对 Gitlab 的支持 插件安装管理器的 CLI 工具以及库 基于 Apache Kafka 以及 Kubernetes 的远程协议 基于角色策略的插件的改进 时间窗口插件——UI 改进 上面的每个项目都有一位学生主导进行,至少两位具有相关经验的导师加以指导,每周会有两次的同步会议来 保证方向与进度。当然,在开源社区里任何人都可以通过 PR 的形式对代码或者文档进行 Review。 今年负责 GSoC 的管理员为: Martin d’Anjou Jeff Pearce Lloyd Chang Oleg Nenashev 我本人是“多分支流水线对 Gitlab 的支持”项目的领队导师,请大家与我一起期待这七位高校学生的精彩表现,后续社区也会及时发布上面项目的介绍以及进展。 基于 Jenkins 的 DevOps 平台应该如何设计凭证管理 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-14-devops-jenkins-credential-manage/ Tue, 14 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-14-devops-jenkins-credential-manage/ 背景 了解到行业内有些团队是基于 Jenkins 开发 DevOps 平台。而基于 Jenkins 实现的 DevOps 平台,就不得不考虑凭证的管理问题。 本文就此问题进行讨论,尝试找出相对合理的管理凭证的方案。 一开始我们想到的方案可能是这样的:用户在 DevOps 平台增加凭证后,DevOps 再将凭证同步到 Jenkins 上。Jenkins 任务在使用凭证时,使用的是存储在 Jenkins 上的凭证,而不是 DevOps 平台上的。 但是,仔细想想,这样做会存在以下问题: * Jenkins 与 DevOps 平台之间的凭证数据会存在不一致问题。 * 存在一定的安全隐患。通过 Jenkins 脚本命令行很容易就把所有密码的明文拿到。哪天 Jenkins 被注入了,所有的凭证一下子就被扒走。 * 无法实现 Jenkins 高可用,因为凭证存在 Jenkins master 机器上。 那么,有没有更好的办法呢? 期望实现的目标 先定我们觉得更合理的目标,然后讨论如何实现。以下是笔者觉得合理的目标: > 用户还是在 DevOps 管理自己的凭证。但是 DevOps 不需要将自己凭证同步到 Jenkins 上。Jenkins 任务在使用凭证时,从 DevOps 上取。 实现方式 Jenkins 有一个 Credentials Binding Plugin 插件,在 Jenkins pipeline 中的用法如下: withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) { sh ''' curl -u "$USERPASS" https://private. Jenkins 公众号送书福利 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-13-jenkins-book-gift/ Mon, 13 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-13-jenkins-book-gift/ Jenkins 中文社区是一个开放、包容、活跃的社区,包含大量的 Jenkins 干货。 当然,它也会为公众号的粉丝们发放福利。 本次福利是《Jenkins 2.x实践指南》x 5,以下是介绍: 本次活动书籍均由博文视点(Broadview)提供,特此感谢。 参与方式: 关注本公众号,并在后台回复【抽奖】,根据二维码进入小程序抽奖。 开奖时间为:5月19日晚上7点自动开奖(记得填自己的手机号,地址以便中奖后邮寄发出)。 中奖的同学,不要忘记发朋友圈分享支持噢~ 等不急的同学,还可以扫二维码直接购买: Jenkins 版本发布 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-09-jenkins-release/ Thu, 09 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-09-jenkins-release/ 2.175 (2019-04-28) 当构建完成后,更新状态图标 (issue 16750) 插件管理页面提供了更方便的插件更新选项,包括:“全选”、“兼容的“或”全不选“。 “兼容”的选择(之前为“全选”)已经不再包括含有任何兼容性警告的插件。 (issue 56477) 从连接 Jenkins 节点的界面上移除会误导到 Java Web Start 和 JNLP 的链接等引用。 (pull 3998) 再次启用 Stapler 请求分发 telemetry。 (pull 3999) 确保远程对象仅通过远程通道被序列化。 确定永远不会设计以 XML 形式持久化到磁盘中的类包括: FilePath, [Stream]TaskListener, and ProcessTree. (issue 47896) 修复在 Linux 代理安装器中看到的一些错误。 (issue 57071) 使得 Debian/Ubuntu 启动器脚本对 Java 11 兼容。 (issue 57096) 开发者:使得 mvn -f war hudson-dev:run支持${port}。 (pull 3984) 2.174 (2019-04-21) 重命名一个代理节点,保持旧的配置,导致重启后旧的代理节点再次出现。 (issue 56403) 嵌套的视图现在也可以根据名称搜索了。 (issue 43322) Jenkins 插件开发之旅:两天内从 idea 到发布(下篇) https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-08-jenkins-plugin-develop-within-two-days-part02/ Wed, 08 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-08-jenkins-plugin-develop-within-two-days-part02/ 本文分上下两篇,上篇介绍了从产生 idea 到插件开发完成的过程; 下篇将介绍将插件托管到 Jenkins 插件更新中心的一系列过程。 托管插件 托管插件包括一系列流程步骤。 笔者完成了它所有步骤(包括非必须的步骤),其中主要有两个具有标志性的任务: - 插件代码被托管在 jenkinsci GitHub 组织的一个仓库,然后作者拥有它的管理权限。 笔者插件的代码仓库为:jenkinsci/maven-snapshot-check-plugin 。 - 你可以将插件发布到 Jenkins 项目的 Maven 仓库,它是 Jenkins 项目所使用的更新站点的数据来源。 准备工作 在请求插件托管之前,需要完成以下几个步骤。 查找类似的插件 Jenkins 社区欢迎任何人的贡献,但为了让 Jenkins 用户受益, 它要求查找解决相同或类似问题的插件,看看是否可以与现有的维护人员联手。 可以在 https://plugins.jenkins.io 查看所有的插件, 以确认是否已有类似的插件实现了你计划实现的功能。 笔者在之前已进行过查找,并没有找到可以实现笔者计划实现的功能的类似插件。 命名规约 Jenkins 制定了一些与插件相关的命名规约。 插件开发者要确保遵循这些命名规约。 artifactId 插件的 artifactId 被用于文件基本名称,是 Jenkins 插件和更新站点的唯一标识。 它需要遵循一些发布规约: - 使用小写 ID ,并根据需要使用连字符分隔术语。 - 除非名称有任何意义,否则不要在 ID 中包含 jenkins 或 plugin 。 插件名称 插件的名称在 Jenkins UI 和其它地方(如:插件站点)展示给用户。 如果可以,建议使用简短的描述性名称,如 Subversion 。 笔者所写的插件的名称为:Maven SNAPSHOT Check 。 Jenkins 自动化安装插件 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-07-jenkins-install-plugins-shell/ Tue, 07 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-07-jenkins-install-plugins-shell/ 手工安装 Jenkins 插件的方法 通常,我们有两种方法安装 Jenkins 插件。第一种方法是到 Jenkins 插件管理页面搜索插件,然后安装。第二种方法是上传 Jenkins 插件的 hpi 文件安装。这两种方法能满足大多数人的需求。 第一种方法,如下图所示: 第二种方法,如下图所示: 但是对于需要保证 Jenkins 稳定或在 Jenkins 上进行二次开发的同学来说,以上方法是无法满足需求的。 第一种方法是无法指定插件的版本。第二种方式必须自己找到该插件的依赖树,然后根据依赖关系一个个地安装。是的,手工上传插件的这种方法,Jenkins 是不会自动下载依赖的。 还有,就是这两种方式都无法实现批量安装。 自动安装插件的方法 那么,有什么方法能指定插件的版本,又能自动下载它的依赖,还能批量下载呢? 幸运的是,Jenkins 的 Docker 镜像的代码仓库里的 install-plugins.sh 脚本已经实现。只不过需要我们拿过来小小修改才能使用。笔者修改后创建了相应的代码仓库:jenkins-install-plugins-shell 。链接在文章末尾。 以下是 jenkins-install-plugins-shell 的使用方法: 1. 将代码 clone 到 JENKINS_HOME 目录中。 cd $JENKINS_HOME git clone https://github.com/zacker330/jenkins-install-plugins-shell.git cd jenkins-install-plugins-shell 在 plugins.txt 中加入希望安装的插件 在 jenkins-install-plugins-shell 目录中,有一个 plugins.txt 文件,在文件中写入希望安装的插件及版本号。例如: ansible:1.0 powershell:1.3 执行安装 # Jenkins War 的路径,用于分析 export JENKINS_WAR_PATH=<Jenkins war文件的路径> chmod +x install-plugins. Jenkins 插件开发之旅:两天内从 idea 到发布(上篇) https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-06-jenkins-plugin-develop-within-two-days-part01/ Mon, 06 May 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/05/2019-05-06-jenkins-plugin-develop-within-two-days-part01/ 本文介绍了笔者首个 Jenkins 插件开发的旅程, 包括从产生 idea 开始,然后经过插件定制开发, 接着申请将代码托管到 jenkinsci GitHub 组织, 最后将插件发布到 Jenkins 插件更新中心的过程。 鉴于文章篇幅过长,将分为上下两篇进行介绍。 从一个 idea 说起 前几天和朋友聊天时,聊到了 Maven 版本管理领域的 SNAPSHOT 版本依赖问题, 这给他带来了一些困扰,消灭掉历史遗留应用的 SNAPSHOT 版本依赖并非易事。 类似问题也曾经给笔者带来过困扰,在最初没能去规避问题, 等到再想去解决问题时却发现困难重重,牵一发而动全身, 导致这个问题一直被搁置,而这也给笔者留下深刻的印象。 等到再次制定 Maven 规范时,从一开始就考虑 强制禁止 SNAPSHOT 版本依赖发到生产环境。 这里是通过在 Jenkins 构建时做校验实现的。 因为没有找到提供类似功能的 Jenkins 插件, 目前这个校验通过 shell 脚本来实现的, 具体的做法是在 Jenkins 任务中 Maven 构建之前增加一个 Execute shell 的步骤, 来判断 pom.xml 中是否包含 SNAPSHOT 关键字,如果包含,该次构建状态将被标记为失败。 脚本内容如下: #!/bin/bash if [[ ` grep -R --include="pom.xml" SNAPSHOT .` =~ "SNAPSHOT" ]]; then echo "SNAPSHOT check failed" && grep -R --include="pom. 使用 Jenkins X 渐进式交付:自动化金丝雀部署 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-29-progressive-delivery-with-jenkins-x-automatic-cana/ Mon, 29 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-29-progressive-delivery-with-jenkins-x-automatic-cana/ 这是渐进式交付系列的第三篇文章,前两篇请参见: - Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署 - 使用 Jenkins X 渐进式交付 渐进式交付被 Netflix, Facebook 以及其它公司使用用来减轻部署的风险。 但是现在你可以在使用Jenkins X时采用它。 渐进式交付是持续交付的下一步,它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估,如果不匹配某些关键指标,则进行回滚。 尤其是,我们聚焦金丝雀发布,并让它在你的 Jenkins X 应用中变得易于采用。 金丝雀发布包括向应用程序的新版本发送一小部分流量,并在向其他用户发布之前验证这里没有错误。 Facebook 就是这样做的,首先向内部员工提供新版本,然后是一小部分用户,然后是其他所有用户,但是你要采用它并不需要成为 Facebook ! 你可以在 Martin Fowler 的网站阅读更多与金丝雀发布相关信息。 Jenkins X 如果在 Jenkins X 中你已经有一个应用,那么你知道的你可以 通过 jx promote myapp --version 1.0 --env production 命令 promote 它到”生产”环境。 但是,在检查新版本是否失败的同时,它也可以自动并逐步地向一定比例的用户推出。 如果发生失败,应用程序将自动回滚。 整个过程中完全没有人为干预。 注意:这个新功能是非常新的,在将来这些步骤将不再需要,因为它们也将由 Jenkins X 自动化了。 作为第一步,三个 Jenkins X 插件需要被安装: - Istio : 一种服务网格容许我们管理我们服务的流量。 - Prometheus :Kubernetes 中最流行的监控系统。 - Flagger :一个使用 Istio 的项目,该项目使用 Prometheus 的指标自动化进行金丝雀发布和回滚。 使用 Jenkins X 渐进式交付 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-26-progressive-delivery-with-jenkins-x/ Fri, 26 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-26-progressive-delivery-with-jenkins-x/ 这是渐进式交付系列的第二篇文章,第一篇请看:Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署。 我使用的我的 Croc Hunter 示例项目评估了 Jenkins X 中金丝雀部署和蓝绿色部署的三种渐进式交付方案。 - Shipper 为 Jenkins X 构建的 Helm 图表启用了蓝绿部署和多集群部署,但是对图表的内容有限制。 你可以在 staging 和生产环境之间做蓝绿部署。 - Istio 允许通过创建一个虚拟服务将一定比例的流量发送到 staging 或预览环境。 - Flagger 构建在 Istio 之上,并添加了金丝雀部署,可以根据指标自动进行滚动部署和回滚。 Jenkins X 可以通过创建一个 Canary 对象自动启用金丝雀功能,从而实现优雅的滚动部署,以升级到生产环境。 这里可以查看 Shipper、Isito 和 Flager 的示例代码。 Shipper 由于 Shipper 对创建的 Helm 图表有多个限制,因此我必须对应用做一些更改。 而且 Jenkins X 只从 master 分支构建 Helm 包,所以我们不能做 PRs 的滚动部署,只能对 master 分支做滚动部署。 应用标签不能包含发布名称,例如: app: {{ template “fullname” . }} 不起作用, 需要一些类似这样的标签: app: {{ . 使用 Jenkins + Ansible 实现自动化部署 Nginx https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-25-jenkins-ansible-nginx/ Thu, 25 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-25-jenkins-ansible-nginx/ 本文介绍如何使用 Jenkins + Ansible 实现对 Nginx 的自动化部署。最终达到的效果有如下几点: 1. 只要你将 Nginx 的配置推送到 GitHub 中,Jenkins 就会自动执行部署,然后目标服务器的 Nginx 配置自动生效。这个过程是幂等(idempotent)的,只要代码不变,执行多少遍,最终效果不变。 2. 如果目标机器没有安装 Nginx,则会自动安装 Nginx。 3. 自动设置服务器防火墙规则。 1. 实验环境介绍 本次实验使用 Docker Compose 搭建 Jenkins 及 Jenkins agent。使用 Vagrant 启动一台虚拟机,用于部署 Nginx。使用 Vagrant 是可选的,读者可以使用 VirtualBox 启动一个虚拟机。使用 Vagrant 完全是为了自动化搭建实验环境。 以下是整个实验环境的架构图: 注意,图中的 5123 <-> 80 代表将宿主机的 5123 端口请求转发到虚拟机中的 80 端口。 Vagrant:虚拟机管理工具,通过它,我们可以使用文本来定义、管理虚拟机。 Ansible:自动化运维工具 Docker Compose:它是一个用于定义和运行多容器 Docker 应用程序的工具。可以使用 YAML 文件来配置应用程序的服务。 2. 启动实验环境 克隆代码并进入文件夹 bash git clone https://github.com/zacker330/jenkins-ansible-nginx.git cd jenkins-ansible-nginx 构建 Jenkins agent 的镜像 需要自定义 Jenkins agent 镜像有两个原因: 本次实验,使用 Swarm 插件实现 Jenkins master 与 agent 之间的通信,所以 Jenkins agent 需要启动 swarm 客户端。 Jenkins agent 必须支持 Ansible。 bash docker build -f JenkinsSlaveAnsibleDockerfile -t jenkins-swarm-ansible . 关于 Jenkins master 共享 JENKINS_HOME 目录的实验 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-23-jenkins-master-shared-home/ Tue, 23 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-23-jenkins-master-shared-home/ 审校:王冬辉,linuxsuren Jenkins master 的高可用是个老大难的问题。和很多人一样,笔者也想过两个 Jenkins master 共享同一个 JENKINS_HOME 的方案。了解 Jenkins 原理的人,都会觉得这个方案不可行。但是真的不可行吗? 由于工作原因,笔者需要亲自验证以上猜想。 JENKINS_HOME 介绍 Jenkins 所有状态数据都存放文件系统的目录中,这个目录被称为 JENKINS_HOME 目录。 实验环境介绍 笔者通过 Docker compose 启动两个独立的 Jenkins master,分别为 jenkins-a 和 jenkins-b。它们共用同一个 JENKINS_HOME 目录。相应的代码仓库的链接放在文章底部。 将代码克隆到本地后,进入仓库,执行 docker-compose up -d 即可启动实验环境。启动完成,在浏览器中输入 http://localhost:7088 可访问 jenkins-a,jenkins-b 的地址是 http://localhost:7089 。但是你会发现它们启动后的界面显示是不一样的。 jenkins-b 的界面如下图所示: 而 jenkins-a 的界面如下图所示: 这时,将 jenkins-a 日志中的解锁密码(Unlock password)输入到 jenkins-b 的页面中,会得到报错信息: ERROR: The password entered is incorrect, please check the file for the correct password 这时,再次 jenkins-b 日志中的解锁密码(Unlock password)输入到表单中即可进入下一步。接下来就是按照提示一步步完成了。在 jenkins-b 安装步骤的最后一步,我们设置了管理员的用户名密码:admin/admin。然后就算完成任务了。 持续交付的商业价值 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-19-the-business-value-of-cd/ Fri, 19 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-19-the-business-value-of-cd/ 持续交付使你能够以更低地风险、更快低交付新软件或是更新已有软件。 降低风险很重要,但是,支持持续交付的流程将转化为对业务更重要的价值: - 加速价值时间。 一个小企业不需要一个 MBA 就可以认识到持续交付可以帮助他们完成工作。 一家大型企业已经规划了其价值流, 并且在整个大型组织中拥有复杂的投资和合约, 将发现持续交付有助于加速实现价值的时间。 - 数据驱动决策。 部署、度量和调整。 你仍然可以推动更大规模的发布,但你的流程将更适合于持续的数据收集。 这将缩短与客户的反馈循环。 它提高了你的反应能力,计划你的下一步行动,并保持领先的竞争力。 - 质量。 你持续发布的行为使你必须提高你的质量标准以及完全的自动化测试实践。 更好的质量意味着更快乐的客户、更低的成本、更少的消防演习和更少的计划外工作。 - 试验 = 创新。 开发人员和业务线可以自由地以较低的成本尝试新的想法, 从而释放出长期高投资发布周期背后的创新想法。 - 降低成本。 大的发布会有巨大的成本,如果出现错误会有严重的后果。 保持可交付成果处于可发布状态会降低交付成本。 对企业来说,这些价值一起使持续交付成为真正的游戏变革者。 尽管可以在团队或项目级别开始采用和验证,但持续交付的本质是它以需要真正投资和自上而下承诺的方式跨越了组织边界。 选择与现有投资互补并共存的持续交付工具链是走向成功的关键一步, 特别是因为 CD 可以引导你的组织采用 DevOps 文化。 持续交付为创建更好的软件开辟了全新的道路。 CD 是商业层面的热门话题,这有很多的原因: - 早期的采用者已经证明了它的价值。 主流采用者都观察到了它的优势,并感觉到竞争的刺痛,因为他们更灵活的竞争对手超过了他们。 - DevOps 作为一种运动获得了关注。 业务人员理解,在开发和运营之间有一个共同的理解,打破孤立的行为,并在整个组织内发展一种责任文化,是提高效率和上市时间的关键步骤。 在许多方面,持续交付等同于 DevOps 。 - 随着软件“吞噬世界”,商业领袖们越来越清楚 IT 必须被用作战略资产。 在正确处理安全性、可用性和合规性的同时,能够缩短交付时间、提高质量并快速适应变化是一项挑战。 持续交付,强调自动化和尽早的、直接的反馈,是实现这些目标的方法。 - 当你通过持续交付实现廉价的、低风险的试验时,你可以用更多的信息指导业务投资,并发现你可能完全错过的机会。 持续交付正在改变企业使用其 IT 资产与客户和合作伙伴联系的方式。 CD 建立在多年来之不易的敏捷过程和持续集成经验的基础上, 将这些好处提升到业务级别,而不是简单地成为开发团队使用的技术, 并最终导致 DevOps 。 随着开发和运营人员学习如何协作和分担责任时,许多成功的关键都植根于组织和文化的变革。 无论是在组织范围内还是在本地,实现这种变革的技术工具链可能包括 Jenkins 。 CloudBees Jenkins 企业版,通过扩展开源 Jenkins 的使用范围, 提供了一个支持 Jenkins 混合模型(本地部署、云上部署或混合部署)的平台, 是组织在今天转向持续交付和在不久的将来实施 DevOps 的必要工具。 使用 Zabbix 监控 Jenkins https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-15-zabbix-monitor-jenkins/ Mon, 15 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-15-zabbix-monitor-jenkins/ 本文假设读者已经了解 Jenkins 基本概念及插件安装,Zabbix 基础概念。基于 Zabbix 3.4,Jenkins 2.8 做实验 笔者最近的工作涉及到使用 Zabbix 监控 Jenkins。在谷歌上搜索到的文章非常少,能操作的就更少了。所以决定写一篇文章介绍如何使用 Zabbix 监控 Jenkins。 下图为整体架构图: 整体并不复杂,大体步骤如下: 在 Jenkins 上安装 Metrics 插件,使 Jenkins 暴露 metrics api。 配置 Zabbix server 及 agent 以实现监控及告警 为方便读者实验,笔者将自己做实验的代码上传到了 GitHub,链接在文章末尾。使用的是 Docker Compose 技术(方便一次性启动所有的系统)。 接下来,我们详细介绍 Metrics插件及如何实现 Zabbix 监控 Jenkins。 1. 使 Jenkins 暴露 metrics api 安装 Metrics 插件,在系统配置中,会多出“Metrics”的配置,如下图: 配置项不复杂。我们需要点击“Generate…”生成一个 Access Key(生成后,记得要保存)。这个 Key 用于身份校验,后面我们会用到。 保存后,我们在浏览器中输入URL:http://localhost:8080/metrics/<刚生成的 Access Key> 验证 Jenkins 是否已经暴露 metrics。如果看到如下图,就说明可以进行下一步了。 1.1 Metrics 插件介绍 Metrics 插件是基于 dropwizard/metrics 实现。它通过4个接口暴露指标数据:/metrics,/ping,/threads,/healthcheck。 简析 Jenkins 专有用户数据库加密算法 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-12-brief-analysis-the-encryption-algorithm-of-the-built-in-jenkins-user-database/ Fri, 12 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-12-brief-analysis-the-encryption-algorithm-of-the-built-in-jenkins-user-database/ 认识Jenkins专有用户数据库 Jenkins 访问控制分为:安全域(即认证)与授权策略。 其中,安全域可以采用三种形式,分别为:Jenkins 专有用户数据库、LDAP、Servlet 容器代理。 在哪里看到加密后的用户密码信息? Jenkins 专有用户的数据信息存放位置:$JENKINS_HOME/users/ 每个用户的相关信息存放在各自的 config.xml 文件中: $JENKINS_HOME/users/$user/config.xml 在 config.xml 文件中的 passwordHash 节点可以看到用户密码加密后的密文哈希值: 用户密码是用什么算法加密的呢? 那么问题来了,用户密码是用何种加密方式加密的呢?可否通过解密密文得到明文呢? 在 GitHub 上查看其源码,通过关键字 #jbcrypt 搜索定位到 HudsonPrivateSecurityRealm.java 这个文件。 HudsonPrivateSecurityRealm.java 具体路径是:jenkins/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java 源码片段如下: /** * {@link PasswordEncoder} that uses jBCrypt. */ private static final PasswordEncoder JBCRYPT_ENCODER = new PasswordEncoder() { public String encodePassword(String rawPass, Object _) throws DataAccessException { return BCrypt.hashpw(rawPass,BCrypt.gensalt()); } public boolean isPasswordValid(String encPass, String rawPass, Object _) throws DataAccessException { return BCrypt. Java 应用使用 Docker 的入门指南:建立一个 CI/CD 流水线 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-10-getting-started-with-docker-for-java-applications/ Wed, 10 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-10-getting-started-with-docker-for-java-applications/ Docker 已经非常出名并且更多的组织正在转向基于 Docker 的应用开发和部署。这里有一个关于如何容器化现有 Java Web 应用以及使用 Jenkins 为它建立一个端到端部署流水线的快速指南。 为此我使用了非常著名的基于 Spring 的宠物商店应用,它代表了一个很好的示例,因为大多数应用都遵循类似的体系结构。 步骤 构建宠物商店应用。 运行一次 Sonar 质量检查。 使用该 Web 应用准备 Docker 镜像。 运行容器以及执行集成测试。 如果所有测试成功,推送该镜像到一个 dockerhub 账户。 所有的代码都在这里。 这里是可用于以上步骤的 Jenkins 流水线代码: node { stage 'checkout' git 'https://gitlab.com/RavisankarCts/hello-world.git' stage 'build' sh 'mvn clean install' stage('Results - 1') { junit '**/target/surefire-reports/TEST-*.xml' archive 'target/*.jar' } stage 'bake image' docker.withRegistry('https://registry.hub.docker.com','docker-hub-credentials') { def image = docker.build("ravisankar/ravisankardevops:${env.BUILD_TAG}",'.') stage 'test image' image.withRun('-p 8888:8888') {springboot -> sh 'while ! 介绍:成为一名 Jenkins 贡献者的旅程 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-08-becoming-contributor-intro/ Mon, 08 Apr 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/04/2019-04-08-becoming-contributor-intro/ 作为一名软件工程师,这些年来在我工作过的不同公司里用到过许多开源软件(包括框架、库、工具等)。 然而,在此之前我从没有以一名贡献者的身份参与过开源项目。 自从我向 Jenkins 提交第一个简单又滑稽的 commit 已经过去六个月(2018 年 9 月)了, 我也尝试过作出更多贡献。然而总的来说,向开源项目贡献代码是具有挑战的, 特别是像 Jenkins 这样有着很长生命周期的项目,项目中不乏遗留代码和系统知识。 它通常难以入手,也很难想到一个计划来持续贡献使你的付出从长远看来是有意义的。 对于 Jenkins 社区来说,我在尝试加入社区时所遇到的困难是其它人也有可能会面临的, 因此我决定分享我成为 Jenkins 活跃贡献者的心路历程。 我计划大概每月发布一篇博文来描述我的这段旅程,我将从简单容易入手的项目开始, 随着时间推移再介绍更加复杂的项目。 从哪开始 jenkins.io 要成为 Jenkins 的贡献者,首先会看到的就是 jenkins.io, 在顶部导航中”社区”下拉列表里第一个”参与”的链接就能将我们带到”参与和贡献”这个页面。 在这个页面中列举了我们能够参与 Jenkins 项目和社区的许多方式。尽管它展示了所有可能的选项供读者选择,但一下子看上去令人有些无所适从。 这个页面被分成了左右两个部分,左边提供了参与社区的方法,右边是向社区贡献的方法。 参与社区的建议 在“参与和贡献”页面的左侧是有关参与社区的建议,其中包括结交他人、审阅修改或者提供反馈信息。 这里面最让我困惑的是沟通渠道,里面列出的沟通渠道有 几个邮件列表 还有 IRC 和 Gitter 频道。 当我第一次尝试参与时,我订阅了许多邮件列表和几个 IRC 和 Gitter 频道,但我很快发现里面有重要的讨论正在进行, 并且活跃的讨论中多数是关于特定的用户或开发者的问题。因此,我不建议你一开始在这上面花太多时间, 除非你是要为其他用户提供帮助(当你是经验丰富的 Jenkins 用户时可能会有这种情况)或者你已经有一个明确的问题需要提问。 看一看社区成员如何互相帮助是好事,但是对新人来说它的信息量过于庞大。如果你的兴趣在于向 Jenkins 项目作贡献(不管是翻译、文档还是代码), 这些对话不会对你有太大的帮助。 向社区贡献的建议 在“参与和贡献”页面的右侧有一些关于如何贡献的建议,主要分为:编写代码,翻译,文档和测试。 在之后的博客中,我将介绍所有的这些贡献类型,以及如何参与的建议包括如何审阅 Pull Requests(PRs)或提供反馈 (反馈问题或者复现其它用户反映过的问题,提供额外信息来帮助维护者复现和修复它们。) 开源之旅的第一次贡献 当看到「参与和贡献」页面时,我发现我可以帮助改进这个页面的一些内容。本来我打算选择其中一个作为这篇文章的第一个例子,但当我阅读贡献指南时, 我发现了一个更简单的贡献。我认为它可以更好的说明开始贡献社区是多么的简单,于是我决定就用它来当例子。 网站代码仓库 在「文档」菜单中有一个链接 jenkins.io 的贡献指南, 这个 CONTRIBUTING 文件是大多数开源项目代码仓库的根目录中都会有的常见文件。 Electron 应用的流水线设计 https://jenkins-zh.github.io/wechat/articles/2019/03/2019-03-13-electron-pipeline-demo/ Wed, 13 Mar 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/03/2019-03-13-electron-pipeline-demo/ 审校:LinuxSuRen(https://github.com/LinuxSuRen) 面向读者:需要了解 Jenkins 流水线的基本语法。 Electron 是由 Github 开发,用 HTML,CSS 和 JavaScript 来构建跨平台桌面应用程序的一个开源库。 本文将介绍 Electron 桌面应用的流水线的设计。 但是如何介绍呢?倒是个大问题。笔者尝试直接贴代码,在代码注释中讲解。这是一次尝试,希望得到你的反馈。 完整代码 pipeline { // 我们决定每一个阶段指定 agent,所以, // 流水线的 agent 设置为 none,这样不会占用 agent agent none // 指定整条流水线的环境变量 environment { APP_VERSION = "" APP_NAME = "electron-webpack-quick-start" } stages { stage("生成版本号"){ agent {label "linux" } steps{ script{ APP_VERSION = generateVersion("1.0.0") echo "version is ${APP_VERSION}" }} } stage('并行构建') { // 快速失败,只要其中一个平台构建失败, // 整次构建算失败 failFast true // parallel 闭包内的阶段将并行执行 parallel { stage('Windows平台下构建') { agent {label "windows && nodejs" } steps { echo "${APP_VERSION}" } } stage('Linux平台下构建') { agent {label "linux && nodejs" } // 不同平台可能存在不同的环境变量 // environment 支持阶段级的环境变量 environment{ SUFFIX = "tar. 为 Continuous Delivery Foundation 的成立感到兴奋 https://jenkins-zh.github.io/wechat/articles/2019/03/2019-03-13-ready-for-cdf/ Wed, 13 Mar 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/03/2019-03-13-ready-for-cdf/ 大概十一年前,我就开始为现在被称为 Jenkins 的项目做贡献,自己当时其实也并不知道在做什么。但是接下来发生的事情令人感觉难以置信,数以百计的贡献者加入,成千上万的新用户开始使用 Jenkins,每天都会运行数以百万条的流水线。这样的增长是充满挑战性的,用户的增长意味着问题的增长,问题的增长就意味着需要新的解决方式。 在大约两年半之前,我在2017年的 Jenkins World Contributor Summit 大会上面对一大群 Jenkins 的贡献者们,为我的所谓的 ‘Jenkins软件基金会’ 做了宣传,那就是,不要羞于从 Python 社区汲取思想,在我的朋友 Chris Aniszczyk 和 Linux 基金会的帮助下,这个基金会变成了一个更加全面的 *持续交付基金会*(CDF),我的同事 Tracy Miranda 一直在领导这项工作,帮助推动 CDF 的成立。 Kohsuke 为 jenkinsci-dev@ mailing list 撰写了一篇很好的概述文章,其中列举了如果 Jenkins 项目一旦建立后就应该加入 Continuous Delivery Foundation 的原因。如果你对 Jenkins 项目感兴趣,但是还没有阅读过这边文章的话,那我认为你应该花些时间来阅读 Kohsuke 的这份邮件。但是在 这篇文章 中,我 想分享我愿意帮助建立持续交付基金会(CDF)的原因。 持续交付(CD)已经成为我职业生涯中不可或缺的一部分,甚至在 Jez Humble 将此概念清晰地表述之前,我就开始学习 CD 并且对它一直充满热情。我认为它对软件的开发实践至关重要,当有人说他们没有练习使用 CI 或 CD 时,我感觉这就像回到了原始社会。想象一下,如果有人说 “呃,我们在这里有一个采用 Source Control 的项目,但领导们觉得这个东西不太靠谱”,我想你肯定会惊掉下巴。”在这个时代竟然还有开发团队都不使用源代码管理?”。总体来说,我认为CD已经是现代软件开发的基础了。 持续交付也 不是 说只依赖于 Jenkins 这样的单一工具,它也是依赖于其他的用于协同工作的许多工具。虽然我可能觉得 Jenkins 是所有工具中占最中心位置的工具,但也不是说 Jenkins 是这些工具中唯一优秀的一款工具。但是不幸的是,像 Jenkins 这样的许多开源社区往往对他们的世界有着一定的狭隘观点。他们只专注于他们的事情,虽然这是有道理的,但这及可能导致错失交叉合作产生新价值的机会。 MPL - 模块化的流水线库 https://jenkins-zh.github.io/wechat/articles/2019/03/2019-01-08-mpl-modular-pipeline-library/ Wed, 06 Mar 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/03/2019-01-08-mpl-modular-pipeline-library/ MPL - 模块化的流水线库 尽管通过自动化部署加快了开发速度,但由于在 DevOps 方面缺少协作,我们一个客户正因此而放慢产品的上市时间。虽然他们也投入了资源来做 DevOps ,但每条生产流水线都是独立设置的,迫使团队为每个项目重新造轮子。更糟糕的是,由于没有跨团队协作,平台中的任何错误又会出现在每条新的流水线中。许多客户都有类似的问题存在,因此我们决定开发一个既能帮助现有客户,又能适应未来使用需求的通用工具。使用通用框架且标准化的 CI/CD 平台是最显而易见的选择,但这将导致缺少灵活性的单体结构(monolithic structure),最终会变得举步维艰。每个团队都需要在自己的流水线上工作,基于此,我们开发了一个方便 DevOps 流水线的每个可重用部分可供以后使用的解决方案 — Jenkins 驱动的模块化流水线库。 解决方案:模块化流水线库 模块化流水线库(译注:modular pipeline library,简称 MPL)是一个高度灵活的 Jenkins 流水线共享库,它可以轻松将最佳实践共享到整个公司。它具有清晰的模块化结构,先进的测试框架,多级嵌套的能力,流水线配置系统,被改进了的错误处理机制以及许多其他有用的组件。 我们将通过以下几部分内容深入了解并解释 MPL 是如何工作的: 探索用于构建 MPL 的技术和工具 回顾MPL,并说明它为何有效 一步一步在流水线样例中使用 MPL 深入研究 MPL 的一些重要的组件,例如测试框架和嵌套库 首先,让我们介绍构建 MPL 时使用到的关键技术。 使用共享库和 Jenkins 流水线构建 MPL 我们的 Jenkins 自动化平台最近收到了一些 Jenkins 流水线的更新。这些更新允许我们创建一个 Jenkinsfile 文件来描述整条流水线,并用于执行一系列不言自明的脚本。这提高了最终用户对 CI/CD 自动化流程的可视化程度,并提高了 DevOps 团队对流水线的可支持性。 然而,流水线存在一个很大的问题:很难用唯一的流水线支持多个 Jenkinsfile 文件(因此存在多少个项目就存在多少个 Jenkinsfile 文件)。我们需要一个地方存放公共逻辑,这正是 Jenkins 共享库能够实现的。共享库用于存放流水线公共的部分,它定义在 Jenkinsfile 文件中,并允许在其中使用接口简化自动化脚本。 虽然共享库允许你存储公共逻辑并操作 Jenkins,但它们并没有提供一种好的方式去使用这些公共逻辑。所以,MPL 通过允许用户创建易于理解的流程描述来优化流水线和共享库,然后方便其他团队使用。 MPL 致力于创建跨团队协作 DevOps 流程 通过 MPL,我们现在能够跨团队协作和共享 DevOps 实践,轻松地为特定的项目指定特定的流水线,并能在将它们集成到 MPL 库中之前进行调试和测试。每个团队都可以创建一个嵌套库,在其中增加流水线和模块,并在流水线中使用,这样还可以提高流水线的可视化程度。MPL 能够适用于任何包含 Jenkinsfile 文件的项目,还可以根据项目团队的需要灵活地管理它。 批量修改 Jenkins 任务的技巧 https://jenkins-zh.github.io/wechat/articles/2019/02/2019-02-27-jenkins-script-console-in-practice/ Wed, 27 Feb 2019 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/02/2019-02-27-jenkins-script-console-in-practice/ 通过脚本命令行批量修改 Jenkins 任务 最近,笔者所在团队的 Jenkins 所在的服务器经常报硬盘空间不足。经查发现很多任务没有设置“丢弃旧的构建”。通知所有的团队检查自己的 Jenkins 任务有没有设置丢弃旧的构建,有些不现实。 一开始想到的是使用 Jenkins 的 API 来实现批量修改所有的 Jenkins 任务。笔者对这个解决方案不满意,经 Google 发现有同学和我遇到了同样的问题。他使用的更“技巧”的方式:在 Jenkins 脚本命令行中,通过执行 Groovy 代码操作 Jenkins 任务。 总的来说,就两步: 进入菜单:系统管理 –> 脚本命令行 在输入框中,粘贴如下代码: import jenkins.model.Jenkins import hudson.model.Job import jenkins.model.BuildDiscarderProperty import hudson.tasks.LogRotator // 遍历所有的任务 Jenkins.instance.allItems(Job).each { job -> if ( job.isBuildable() && job.supportsLogRotator() && job.getProperty(BuildDiscarderProperty) == null) { println " \"${job.fullDisplayName}\" 处理中" job.addProperty(new BuildDiscarderProperty(new LogRotator (2, 10, 2, 10))) println "$job.name 已更新" } } return; /** LogRotator构造参数分别为: daysToKeep: If not -1, history is only kept up to this days. 在安全防火墙内通过 WebHook 触发构建 https://jenkins-zh.github.io/wechat/articles/2019/01/2019-01-16-webhook-firewalls/ Mon, 01 Jan 0001 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/01/2019-01-16-webhook-firewalls/ 在这篇文章中,我将向大家展示,如何让运行在防火墙内的 Jenkins 依然可以实时地收到 GitHub 的 WebHook。当然,你也可以把这个方法应用到如 BitBucket、 DockerHub 或任何可以推送 WebHook 的其他服务中。但是,下面的步骤仅适用于托管在 GitHub 上的项目。 什么是 WebHook 简单地描述下什么是 WebHook:事件消息(通常是 JSON,也可以是其他的)由服务端以 HTTP(S) 协议发送到监听的客户端。 事件流自左到右,Jenkins 会监听类似 /github-webhook/ 或 /dockerhub-webhook/ 等路径上的 HTTP 请求,唤醒并执行一些任务。 GitHub 或 BitBucket 可能会报告一个新的提交或 PR,DockerHub 报告一个上游的镜像发生了变更。这些事情的共同之处在于,它们会推送给 Jenkins,并期待可以推送成功(例如:可以访问到 Jenkins)。在网络是开放的情况下时,例如 GitHub 企业版 或 Jenkins 在监听公网时,这是可以正常工作的。 内网环境 当有东西挡在中间时,也就是防火墙: (_按照行业标准,所有防火墙都必须能起到屏障的作用。因此,无论如何,请不要在你的组织内搞破坏_) 当你在笔记本电脑上运行 Jenkins 并希望从 GitHub 接收 WebHook 时,这也是一样的。可能是为了测试你的设置,也可能是为了在 Mac 上运行 iOS 版本构建,又或者是部分网络没有暴露在互联网中,这都是合理的。 除非你的笔记本电脑可以让整个互联网访问到(这当然不太可能),或者你的网络配置得恰到好处,否则网络连接将无法流动,此时 WebHook是不可用的。 没关系,我们可以退而求其次,使用轮询变更的方式。只是这样很糟糕。你会用尽 API 配额,还无法实时地获取变更,这真的不是一个好方法。 问题可能也是机会 我们可以解决这个问题,但也可以把这个视为一个机会。有的东西在互联网中不可访问,或者以某些默认的方法锁定是一个特色,不是一个 Bug。你可以很大程度上减少你的攻击面,同时可以进行深度防护: 一个 WebHook 转发服务 输入 link:https://smee.io/[Smee] 这个很容易记住的名字。这是一个由 GitHub 提供的 link:https://github. 成为一名 Jenkins 贡献者:对新手友好的工单 https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-24-becoming-contributor-newbie-tickets/ Mon, 01 Jan 0001 00:00:00 +0000 https://jenkins-zh.github.io/wechat/articles/2019/06/2019-06-24-becoming-contributor-newbie-tickets/ 两个月前,我发表了一篇介绍性文章, 成为一名 Jenkins 贡献者的旅程。在那篇第一次发表的文章 review 过后,学习到了我们可以参与和贡献的多种途径。 因此,在这个站点仓库中有对首次、基础的贡献的描述。 现在,我们将会在这篇文章中探索更多高级的贡献,向 Jenkins 核心中提交代码。 从工单和过程开始 新手贡献指导以及 Jenkins Jira 查看位于 jenins.io 上的开发者章节可能是最好的起点, 参考链接也很方便。同时,向 Jenkins 贡献的新手指导也很有用,因为它指出了不同的仓库、工具(例如问题跟踪系统)以及治理文档。 此外,它还描述了提交消息、代码风格约定、PR 指导等的最佳实践。 一旦我们对之前描述的有了一般性的了解,并想要真正地开始编码,我们可能会对该做些什么感到困惑。 似乎浏览Jenkins 问题跟踪系统是顺其自然 的下一步,因为那里充满了已经由社区报告了的潜在的缺陷和待改进的部分。然而,你很容易被无数的可能性列表所淹没。 请记住一点,对于一个像这样有十年历史之久的项目,很多是为新手准备的。因此,通过newbie-friendly tickets来过滤可能是最好的主意。 选择一个工单 在我案例中,我花了一些时间来浏览带 newbie-friendly 标签的工单,直到发现了一个我似乎感兴趣并看起来有能力修复的: 过程 在这个阶段,当我们准备接手这个工单时,最好让社区中的其他人知道我们正在开始解决它。我们可以很容易做到这一点, 只要把工单分配给我们自己即可(查看工单概览下的 “_Assign_” 按钮)。 在 Jenkins 的 Jira 中把工单分配给我们自己的话,可以让其他的贡献者知道我们正在处理;另外,为了保证其他人有兴趣对此一起做贡献时,可以知道 该去联系谁或者如何询问状态。也就是说,把工单分配给你自己,并不意味着其他贡献者就无法继续推进。Jenkins 是一个开源项目,欢迎任何人创建他们自己 的 PR,因此,任何人都可以在工单中提出自己的方案。但是,你也能想到,如果工单分配给某个人的话,大多数人在开始工作前也可能会去联系承接人。 与之相关的是,请牢记当我们把工单分配给自己时,不应该在这个工作上拖延太久。其他的贡献者,可能会由于工单已被分配而忽略。 当我们马上就要开始工作时,推荐的做法是先点击”Start Progress“按钮。这个动作,会把状态修改为“_In progress_”,对社区而言, 意味着我们正在处理这个工单。 在我们的电脑设置必要的工具 配置,安装和测试 正如在该旅程的第一篇文章中描述的,开始为某个仓库做贡献的第一步 是首先派生到我们自己的 GitHub 账号下,然后,克隆到你的电脑上。 正如,在 Jenkins Core 仓库中的CONTRIBUTING 文件里 所描述的,让仓库在本地运行的必要步骤。它包括,安装必要的开发工具:Java Development Kit (https://adoptopenjdk.net/[OpenJDK] 为推荐的选择),Maven 以及任意支持 Maven 项目的 IDE。注意,安装 JDK 和 Maven 的步骤在贡献指南中有链接。