[ { "uri": "https://jenkins-zh.cn/about/sponsors-list/", "title": "社区捐助", "type": "about", "date": "2019-09-07 00:00:00 +0000 UTC", "tags": [], "description": "社区捐助", "content": " 社区得以持续、健康地发展,需要很多方面的支持,尤其对于社区的基础运营、活动组织上,资金和物资的捐助是非常重要的。\n用途 对于所收到的资金、物资捐助,我们都会用于社区基础设施(域名、服务器等)、线下活动、社区成员奖励。\n列表 为了对给予社区捐助的朋友们表示感谢,我们在此列出来:\n 捐助者 金额(单位:元) 日期 备注 UCloud 2170 2020-04-04 2核2G 2M 80G系统盘 1年,地区北京,台数1台 霍格沃兹测试学院 10,000 2019-11-05 社区捐赠 geshujiang 100 2019-05-11 活动链接 资金去向 用途 金额 日期 申请人 阿里云服务器升级 786.57 2020.6.9 linuxsuren 购买梯子帐号(一年) 276 2020.02.23 linuxsuren , yJunS , donhui , linan607 购买阿里云服务器 5,640 2019.11.8 linuxsuren 阿里云服务器带宽充值 100 2019.10.24 linuxsuren ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/code-of-conduct/", "title": "行为规范", "type": "about", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "行为规范", "content": " 留言 留言之前需要使用 GitHub 账号登陆。大家要注意文明用语,严禁攻击、诋毁、灌水、广告等无关的话。对于违反人,一经发现将会被拉入黑名单。\n提问 欢迎每一位朋友在这里提出与 Jenkins 或相关领域的技术问题,但是,在提问之前建议先在搜索引擎和本站中进行搜索。\n问题至少要包含如下部分:\n 场景以及问题是如何发生的,方便阅读的人复现 软件、环境相关版本信息 日志、截图等(建议使用附件的方式) 出于对回答问题者的尊重,请得到解决方案后及时表示感谢,或者从其他地方得到答案后添加相关链接以及说明。\nGitHub 请您使用同一个 GitHub 账号来与大家交流,不欢迎使用所谓的“小号”。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/07/2020-07-06-machine-learning-plugin-project-community-bonding-blog-post/", "title": "社区推送博客-机器学习插件项目", "type": "wechat", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": ["machinelearning", "datascience", "plugins", "communitybonding", "gsoc", "gsoc2020"], "description": "我认为机器插件学习一直都是一件很有意义的事,带你们一起回顾我的学习历程", "content": " 大家好!\n这是 GSoC 2020 中的 Jenkins 项目之一。我们正在为此 GSoC 2020 使用此新的机器学习插件。这是我在社区关于 GSoC 2020 的故事。我很高兴与您分享我的旅程。\n自我介绍和神奇的 4 位导师 我是 Moratuwa 大学的 Loghi Perinpanayagam。我被选为 Jenkins 的 GSoC 2020 机器学习插件的负责人。我很高兴向我的导师介绍这个项目。我分配了四位导师,他们非常热心地帮助我在今年夏天开发代码。\n学生\n Loghi Perinpanayagam 导师\n Bruno P. Kinoshita Ioannis Moutsatsos Marky Jackson Shivay Lamba 去年我的准备情况如何? 我在第二年就了解了 GSoC 开源项目。但是我至少在去年尝试了另一个组织的项目,该项目与《数据科学的数据可视化建议》有关。但是问题是我的贡献不如今年那么大,在申请过程中为时已晚。像往常一样,与其他项目相比,与机器学习相关的项目有很多竞争。我准备学习机器学习中的数据可视化以及推荐系统的现有模型。最后,我当时用 SeqToSeq 模型编写了一个提案,当时对神经网络知识不多。而且我没有通过专用的闲暇渠道进行太多交流。这可能是失败的原因之一。但是主要原因是我对 GSoC 2019 的了解不多。\n我如何跨过 GSoC 2020? 自从我意识到开源的必要性和对社区的帮助以来,我一直热衷于为开源项目做出贡献。实际上,我于 2019 年在印度班加罗尔完成了实习,我立即专注于参与 GSoC。这是我作为计算机科学理学学士学位课程的学生的最后一年(2020年),我希望今年能被选为学生。\n我们部门举办了一次指导研讨会,我知道 Jenkins 已经打开了他们的项目构想。这是我的 GSoC 2020 旅程的一个非常令人印象深刻的开始。我在 jenkins.io 页面上浏览了所有草案并接受了项目。因为我已经对机器学习感兴趣,并且对 Java 很熟悉,所以我选择了最令人印象深刻的想法,因为它没有初始回购协议。这意味着我想利用我的知识对该项目进行很多思考和研究。但是我必须做出贡献,并且想了解 Jenkins 代码库的基础结构。因为这样可以使选择面板易于接洽该项目的学生。然后,我反复搜索为 Jenkins 做贡献。我发现从 git 插件和 git 客户端插件可以轻松解决的问题。我开始在 git 插件和 git 客户端插件上贡献一些测试问题。在清楚了解插件在 Jenkins 中的工作原理后,我开始使用项目构想页面中提供的提示来进行 POC 的工作。实际上,编写代码很有趣。\n导师在申请过程中帮助了许多学生。我能够进行工作的 POC,但其执行项目任务的能力最低。最后,导师开始提交提案。我急忙准备提案草案。在得到导师的评价后,我开始改进提案。在提案提交结束时,我能够为该项目提交一个好的提案。当我对这个插件感到好奇时,我深入研究了如何将 Jupyter Notebook 与该插件集成。我在接受等待期间的研究结果发表了一篇中等文章。\n结果发布 结果将于 5 月 4 日宣布,我相信我的项目建议和 POC,因此入选了 GSoC 2020。那是我一生中最激动人心的。这种感觉就像我实现的目标。由于我的辛勤工作,我应得的。例如,我花了 7 天的时间使 POC 正常工作,而 Maven 工件之间没有任何冲突。\n社区联结 结果发布后,我正在为社区联结做准备。我和导师之间的互动比以前更多了。我不得不在 jenkins.io 中更新项目页面和个人资料。5 月 10 日,我们第一次会面充满了热情和友爱。我和导师介绍了自己,尽管我们彼此认识。我们讨论了 GSoC 的高级观点,并提出了一些我观点中存在的问题。由于我的插件是一个新的存储库,因此大部分讨论都与该存储库及其名称有关。我必须为新插件找到一个名称。最后,我们定期讨论了博客文章和演示文稿。\n在第二次会议上,我们讨论了在 Jenkins 中托管新插件,跟踪 JIRA 问题,博客文章和项目高级路线图的过程。我建议了一些有趣的插件名称,但它们与项目目标不符,导师告诉我尝试使用其他名称来完美描述项目。建议我阅读所有研究指南和插件命名约定。我们讨论了如何通过 git 完成代码审查和源代码管理。这次会议之后,我们的会议已转移到 Jenkins Zoom 的正式帐户。\n我们的第三次会议对我们的项目计划非常认真。在开会之前,我一直在导师的帮助下为项目准备设计文件。因此,对于第 1 阶段的未来工作,我得到了很多评论和有用的示例。在这一点上,我们决定使用插件名称 Machine Learning Plugin,该插件被所有导师接受,我创建了回购协议,并要求提供 Jira 单据进行插件托管请求。我们计划在未来 3 天内提醒您 Jira 单据。导师希望我确保在社区活动结束之前更新了 Jenkins GSoC 页面。关于会议上周我一直在准备的设计文件的讨论很多。会议记录中的一些要点如下:\n 在设计文档中定义特征 操作图 插件如何在分布式环境中工作 代码编辑器库 第一个插件版本的要求 博客文章草稿文件 下周我即将开展的工作计划 因此,在这次会议之后,我不得不努力工作,这使我更加深入参与了该项目。我必须付出巨大的努力才能使这个机会变成黄金。我们的团队愿意完成此项目,并且一定会通过此插件为 Data Science 社区提供帮助。到目前为止,我的团队所做的出色工作,对此我表示敬意!!!\n到目前为止,这是我的整个旅程。希望您喜欢它,希望您了解我去年犯的错误,并在今年夏天纠正了错误。感谢您的阅读和关注,我将为感兴趣的人上传博客文章。\n资源和链接 项目页面 设计文档 ", "auhtor": "Loghi Perinpanayagam", "translator": "wenjunzhangp", "original": "https://www.jenkins.io/blog/2020/06/03/machine-learning-plugin-community-bonding/", "poster": "jenkins-gsoc-logo_small.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/07/2020-07-02-jcli-v0.0.29/", "title": "Jenkins CLI 命令行 v0.0.29", "type": "wechat", "date": "2020-07-02 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.29 发布", "content": " 截止到编辑本文时,GitHub 上统计到的下载量为:6,648次。GitHub 上的 Star 数为180,码云上的 Star 数为151。\nJenkins CLI 加入了码云最有价值开源项目计划(GVP),并且迎来了两位社区贡献者的首次贡献。非常感谢码云对该项目的认可,以及开源贡献者的努力。到目前为止,在 GitHub 上记录的有11位社区开发者参与过项目贡献,我们非常地欢迎更多的人加入!\n🚀 功能 支持把 HTTP 请求以 curl 命令的形式输出 (#409) @LinuxSuRen 支持关闭 Jenkins (#346) @LinuxSuRen 支持保存 token 到 keyring (#399) @LinuxSuRen 触发 Jenkins 参数化任务时,支持传递文件 @WangXiangUSTC 添加函数 default 到子命令 cwp 到配置文件解析 (#415) @LinuxSuRen 支持直接运行 jenkinsfile (#379) @sladyn98 🐛 缺陷修复 修复读取 keyring 中的 token 时可能发生的错误 (#419) @LinuxSuRen 📝 文档完善 添加相似的项目 jenni (#401) @LinuxSuRen 👻 维护 多个依赖的版本更新 @dependabot-preview 增加徽章 hits 用于显示项目页面访问次数 (#418) @LinuxSuRen 改进 docker 构建 (#396) @LinuxSuRen ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "jenkins-cli.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/07/2020-07-01-monitoring-linux-logs-with-kibana-and-rsyslog/", "title": "使用 Kibana 和 Rsyslog 监控 Linux 日志", "type": "wechat", "date": "2020-07-01 00:00:00 +0000 UTC", "tags": ["Programming", "Software Development", "Software Engineering", "Monitoring", "Linux"], "description": "通过具体配置 Rsyslog 与 ELK 堆栈(ElasticSearch,Logstash,Kibana)介绍了如何使用这些工具监控 Linux 系统的系统日志", "content": " 如果你是一名系统管理员,或者是一名好奇的软件开发工程师,那么你很有可能在平常挖掘日志信息的时候找到一些很有价值的信息。\n有时你或许想监控虚拟机的 SSH 指令。\n有时你或许想查看下你的应用程序服务器在某一天某一个特定的时间出现了什么样的错误信息。\n或者你为了想一探究竟到底是谁停了你的一个虚拟机的 systemd 服务。\n如果你想从这几个地方了解的话,或许你来对地方了。\n在这篇文章当中,我们将会构建一个完整的日志监控流水线,使用 ELK 堆栈(ElasticSearch、Logstash、和 Kibana)和 Rsyslog 作为一个强力的系统日志服务器。\n在开始动手之前,让我们先快速的考虑下技术因素,让我们讨论下为什么我们使用 Kibana 监控 Linux 日志。\nⅠ-为什么你需要监控 Linux 日志? 监控 Linux 日志是非常关键的,而且每一名 DevOps 工程师都需要知道怎样做。理由如下:\n 你可以通过日志得到实时可视化的反馈: 这或许是众多日志监控理由中最关键的一个,你可以构建一些有意义的可视化视图(例如表格,饼状图,图表或者柱状图)来为你的日志赋予一些意义。\n 你可以汇总这些信息来构建高级以及复杂的仪表盘: 有时一个原始数据是不够的,你或许想加上一些其他的日志或者将它们与其他日志比较从而了解一个整体的变化趋势。一个具有表达式处理功能的可视化平台可以让你这样操作这些信息。\n 你可以快速过滤一个特定的术语或者是一个给定的时间段: 如果你只对 SSH 日志感兴趣,你可以为其构建一个指定的仪表盘。\n 以一种快捷和优雅的方式,日志是可导航的: 我知道从日志文件中无止尽的日志信息中抓取信息的痛苦。我宁愿有一个平台来专门做这件事。\n Ⅱ- 你将会学习到什么 这篇入门文章你将会学习到下面的一些知识:\n 日志在 Linux 系统是如何处理的(Ubuntu 或 Debian)以及什么是 rsyslog。\n 怎样安装 ELK 堆栈(*ElasticSearch 7.2,LogStash 和 Kibana*)以及这些工具是用来做什么的。\n 怎样配置 rsyslog 从而将日志转发到 Logstash。\n 怎样配置 Logstash 从而获取日志以及 ElasticSearch 存储。\n 怎样使用 Kibana 来构建我们最终的可视化仪表盘。\n 这篇入门文章的准备工作如下:\n 有一个安装了 rsyslog 的 Linux 系统。可以有一个带有 rsyslog 的独立计算机或者是一个集中式日志处理系统。\n 有管理员权限或者是有足够的权限在你的 Linux 系统上安装新的安装包。\n 没有其他可以说明的了,让我们开搞!\nⅢ-一个日志监控系统的架构看起来长什么样子? a-Linux 日志的关键概念 在描述我们的日志监控系统架构的样貌细节之前,让我们再稍微回顾一下。\n回溯历史,Linux 日志始于 syslog。\nSyslog 是 1980 年开发的一个协议主要目的是标准化日志信息的格式,不仅适用于 Linux,对于任何日志交换系统同样适用。\n从这之后,syslog 服务器开发了出来,并带有 syslog 消息的处理功能。\n它们快速衍生出一些功能比如过滤,有内容路由能力,以及或许是这些服务器最关键的特性: 存储日志并对其进行轮换。\nRsyslog 的开发保持了这些关键的功能: 拥有一个模块以及一个可定制化的方式来处理这些日志。\n模块化的方式可以以模块的形式处理日志信息以及定制化日志模板。\n在某种程度上,rsyslog 可以从许多不同的源接收日志,并且将它们转发到更多种类的目标位置。这也就是我们为什么在这篇文章中使用它的原因。\nb-构建一个日志监控架构 我们这篇文章最终使用的架构如下:\n rsyslog: 作为高级的 syslog 服务器,rsyslog 将日志使用我们先前提到的 RFC 5424 的格式转发到 Logstash 上。\n Logstash: 作为 ELK 堆栈的一部分,Logstash 会将日志由 syslog 格式转换为 JSON。提醒一下,ElasticSearch 使用 JSON 作为输入。\n ElasticSearch: 著名的搜索引擎会将日志存储在一个专用的日志索引(logstash-*)中。ElasticSearch 索引这些日志然后令其可用于分析当中。\n Kibana: 作为一个可探测的以及可视化的平台,Kibana 将会存放我们最终显示的仪表盘。\n 现在我们知道了我们需要努力的方向了,让我们安装这些需要用到的工具吧。\nⅣ-安装各种工具 a-在 Ubuntu 上安装 Java 在安装 ELK 堆栈之前,你需要在你的机器上安装 Java。\n运行下面的命令以进行安装:\n$ sudo apt-get install default-jre\n这篇文章中,该实例运行的是 OpenJDK version 11。\nubuntu:~$ java -version openjdk version \u0026quot;11.0.3\u0026quot; 2019-04-16 OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.04.1) OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.04.1, mixed mode, sharing) b-添加 Elastic 安装包到你的实例 这篇文章,我将会使用 Ubuntu,但也会为 Debian 提供详细信息。\n首先,添加 GPG key 到你的 APT 仓库。\n$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -\n然后,你可以添加 Elastic 源到你的 APT source list 文件中。\n$ echo \u0026quot;deb https://artifacts.elastic.co/packages/7.x/apt stable main\u0026quot; | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list $ cat /etc/apt/sources.list.d/elastic-7.x.list deb https://artifacts.elastic.co/packages/7.x/apt stable main $ sudo apt-get update 到这里,你已经可以准备安装 ELK 堆栈下的所有工具了。\n让我们从 ElasticSearch 开始吧。\nc-安装 ElasticSearch ElasticSearch 是一款基于 Elastic 开发的搜索引擎,该搜索引擎会以索引的方式存储数据以便快速检索。\n通过下面的命令安装它:\n$ sudo apt-get install elasticsearch\n该命令会自动执行如下操作:\n 下载 ElasticSearch deb 安装包;\n 创建一个 elasticsearch 用户;\n 创建一个 elasticsearch 用户组;\n 自动创建一个配置好的 systemd 服务(默认为 inactive)\n 一开始,服务是 inactive 的,运行它并且确保所有运行正常。\n$ sudo systemctl start elasticsearch ● elasticsearch.service - Elasticsearch Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; disabled; vendor preset: enabled) Active: active (running) since Mon 2019-07-08 18:19:45 UTC; 2 days ago Docs: http://www.elastic.co 为了验证 ElasticSearch 是实际运行的,你可以运行下面两个命令中的任何一个进行验证:\n$ sudo lsof -i -P -n | grep LISTEN | grep 9200 java 10667 elasticsearch 212u IPv6 1159208890 0t0 TCP [::1]:9200 (LISTEN) java 10667 elasticsearch 213u IPv6 1159208891 0t0 TCP 127.0.0.1:9200 (LISTEN) 执行一个简单的 ElasticSearch 查询 $ curl -XGET 'http://localhost:9200/_all/_search?q=*\u0026amp;pretty'\n你的 ElasticSearch 实例就都设置好啦!\n然后,让我们安装 Logstash 作为日志采集和过滤工具吧。\nd-安装 Logstash 如果你之前添加了 Elastic 安装源了,安装 Logstash 就只需要执行下面的命令就可以了:\n$ sudo apt-get install logstash\n同样,Logstash 服务将会被创建出来,你需要启动它。\n$ sudo systemctl status logstash $ sudo systemctl start logstash 默认情况下,Logstash 在 9600 端口上监听所有的指标项。如我们之前所做的那样,列出你的机器上所有开放的端口然后查看其中的指定端口。\n$ sudo lsof -i -P -n | grep LISTEN | grep 9600 java 28872 logstash 79u IPv6 1160098941 0t0 TCP 127.0.0.1:9600 (LISTEN) 棒极了!\n我们只需要安装 Kibana 就可以完成整个的安装工作了。\ne-安装 Kibana 提醒下,Kibana 是为 ElasticSearch 量身定制的可视化工具被用来监控我们最终的日志信息。\n没有惊喜,下面是安装 Kibana 的命令:\n$ sudo apt-get install kibana\n依旧需要启动服务验证是否正确运行。\n$ sudo systemctl start kibana $ sudo lsof -i -P -n | grep LISTEN | grep 5601 node 7253 kibana 18u IPv4 1159451844 0t0 TCP *:5601 (LISTEN) Kibana Web UI 在 5601 端口可访问。\n在你的浏览器中访问 http://localhost:5601 你应该会看到下面屏幕所示的界面。\n现在我们已经准备好从 rsyslog 接收日志然后将它们在 Kibana 上展示出来了。\nⅤ-转发 Linux 日志至 ElasticSearch 提醒下,我们将日志从 rsyslog 转发至 Logstash,然后这些日志将会被自动的发送到 ElasticSearch。\na-从 Logstash 转发到 ElasticSearch 在日志从 rsyslog 转发到 Logstash 之前,设置 Logstash 与 ElasticSearch 之间的日志转发是非常重要的。\n为此,我们将会创建一个 Logstash 的配置文件告诉它做哪些事情。\n转到 /etc/logstash/conf.d 目录创建一个 logstash.conf 的文件。\n文件内容是这样的:\ninput { udp { host =\u0026gt; \u0026quot;127.0.0.1\u0026quot; port =\u0026gt; 10514 codec =\u0026gt; \u0026quot;json\u0026quot; type =\u0026gt; \u0026quot;rsyslog\u0026quot; } } # The Filter pipeline stays empty here, no formatting is done. filter { } # Every single log will be forwarded to ElasticSearch. If you are using another port, you should specify it here. output { if [type] == \u0026quot;rsyslog\u0026quot; { elasticsearch { hosts =\u0026gt; [ \u0026quot;127.0.0.1:9200\u0026quot; ] } } } 注: 这篇文章中,我们为 Logstash 使用 UDP 输入,但是如果你想寻找一个更可靠的传输日志的方式,你或许会使用 TCP 输入。格式基本上是一样的,只是将 UDP 那一行改为 TCP。\n重启 Logstash 服务。\n$ sudo systemctl restart logstash\n运行下面的命令以验证所有运行正常:\n$ netstat -na | grep 10514 udp 0 0 127.0.0.1:10514 0.0.0.0:* 太棒啦!\nLogstash 现在在 10504 端口上监听了。\nb-从 rsyslog 转发至 Logstash 同之前内容描述的那样,rsyslog 有许多不同的模块允许将接收到的日志传到各种各样的目标位置。\nRsyslog 有使用模板转换日志的能力。这就是我们寻找的东西,因为 ElasticSearch 希望以 JSON 作为输入而不是 syslog RFC 5424 字符串。\n为了让 rsyslog 转发日志,找到 /etc/rsyslog.d 目录创建一个名为 70-output.conf 的新文件。\n文件中写如下内容:\n# This line sends all lines to defined IP address at port 10514 # using the json-template format. *.* @127.0.0.1:10514;json-template 现在你有了日志转发功能了,在同级目录下创建一个 01-json-template.conf 的文件,然后粘贴下面的内容到文件中:\ntemplate(name=\u0026quot;json-template\u0026quot; type=\u0026quot;list\u0026quot;) { constant(value=\u0026quot;{\u0026quot;) constant(value=\u0026quot;\\\u0026quot;@timestamp\\\u0026quot;:\\\u0026quot;\u0026quot;) property(name=\u0026quot;timereported\u0026quot; dateFormat=\u0026quot;rfc3339\u0026quot;) constant(value=\u0026quot;\\\u0026quot;,\\\u0026quot;@version\\\u0026quot;:\\\u0026quot;1\u0026quot;) constant(value=\u0026quot;\\\u0026quot;,\\\u0026quot;message\\\u0026quot;:\\\u0026quot;\u0026quot;) property(name=\u0026quot;msg\u0026quot; format=\u0026quot;json\u0026quot;) constant(value=\u0026quot;\\\u0026quot;,\\\u0026quot;sysloghost\\\u0026quot;:\\\u0026quot;\u0026quot;) property(name=\u0026quot;hostname\u0026quot;) constant(value=\u0026quot;\\\u0026quot;,\\\u0026quot;severity\\\u0026quot;:\\\u0026quot;\u0026quot;) property(name=\u0026quot;syslogseverity-text\u0026quot;) constant(value=\u0026quot;\\\u0026quot;,\\\u0026quot;facility\\\u0026quot;:\\\u0026quot;\u0026quot;) property(name=\u0026quot;syslogfacility-text\u0026quot;) constant(value=\u0026quot;\\\u0026quot;,\\\u0026quot;programname\\\u0026quot;:\\\u0026quot;\u0026quot;) property(name=\u0026quot;programname\u0026quot;) constant(value=\u0026quot;\\\u0026quot;,\\\u0026quot;procid\\\u0026quot;:\\\u0026quot;\u0026quot;) property(name=\u0026quot;procid\u0026quot;) constant(value=\u0026quot;\\\u0026quot;}\\n\u0026quot;) } 你或许猜到了,对于每一个输入的信息,rsyslog 会将日志参数插入到 JSON 格式的消息中,然后转发到在 10514 端口上监听的 Logstash。\n重启 rsyslog 服务,然后验证日志可以正确的转发到 ElasticSearch。\n注: 日志将会被转发到一个名为 logstash-* 的索引中。\n$ sudo systemctl restart rsyslog $ curl -XGET 'http://localhost:9200/logstash-*/_search?q=*\u0026amp;pretty' { \u0026quot;took\u0026quot;: 2, \u0026quot;timed_out\u0026quot;: false, \u0026quot;_shards\u0026quot;: { \u0026quot;total\u0026quot;: 1, \u0026quot;successful\u0026quot;: 1, \u0026quot;skipped\u0026quot;: 0, \u0026quot;failed\u0026quot;: 0 }, \u0026quot;hits\u0026quot;: { \u0026quot;total\u0026quot;: { \u0026quot;value\u0026quot;: 10000, \u0026quot;relation\u0026quot;: \u0026quot;gte\u0026quot; }, \u0026quot;max_score\u0026quot;: 1, \u0026quot;hits\u0026quot;: [ { \u0026quot;_index\u0026quot;: \u0026quot;logstash-2019.07.08-000001\u0026quot;, \u0026quot;_type\u0026quot;: \u0026quot;_doc\u0026quot;, \u0026quot;_id\u0026quot;: \u0026quot;GEBK1WsBQwXNQFYwP8D_\u0026quot;, \u0026quot;_score\u0026quot;: 1, \u0026quot;_source\u0026quot;: { \u0026quot;host\u0026quot;: \u0026quot;127.0.0.1\u0026quot;, \u0026quot;severity\u0026quot;: \u0026quot;info\u0026quot;, \u0026quot;programname\u0026quot;: \u0026quot;memory_usage\u0026quot;, \u0026quot;facility\u0026quot;: \u0026quot;user\u0026quot;, \u0026quot;@timestamp\u0026quot;: \u0026quot;2019-07-09T05:52:21.402Z\u0026quot;, \u0026quot;sysloghost\u0026quot;: \u0026quot;schkn-ubuntu\u0026quot;, \u0026quot;message\u0026quot;: \u0026quot; Dload Upload Total Spent Left Speed\u0026quot;, \u0026quot;@version\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;procid\u0026quot;: \u0026quot;16780\u0026quot;, \u0026quot;type\u0026quot;: \u0026quot;rsyslog\u0026quot; } } ] } } 太棒了!现在我们将 rsyslog 的日志存储到了 ElasticSearch 中了。\n 是时候在 Kibana 上构建我们最终的仪表盘了。\nⅥ-在 Kibana 构建一个日志仪表盘 这是所有乐趣开始的地方。\n 我们将会构建第一部分展示的仪表盘然后让收集的数据变得有意义。\n类似于我们的这篇文章 Linux 进程监控,这部分根据最终仪表盘中面板的不同分成了不同的部分,所以对哪部分感兴趣就浏览哪一部分吧。\na-简单说下 Kibana 访问 Kibana(http://localhost:5601),你会看到下面的界面。\n如果这是你第一次使用 Kibana,这里有一点让我花了一段时间明白的小陷阱想要跟你说一下。\n为了创建一个仪表盘,你需要创建可视化面板。Kibana 有两个面板,一个叫 “Visualize” 另一个叫 “Dashboard”。\n为了创建仪表盘,你首先将会使用 Visualize 面板创建每一个独立的可视化面板并且保存它们。\n创建完成后,你需要一个一个地导入到你最终的仪表盘中。\n转到 “Visualize” 面板,让我们开始做第一个面板。\nb-为进程绘制汇总的条形图 为了创建第一个仪表盘,点击 Kibana 右上角的 “Create new visualization”。选择一个垂直方向的柱状图面板。\n构建的面板最终的效果是这样的:\n你可以看到,柱状图以一种汇总的方式提供了进程的日志总数。\n如果你在多台主机上工作,该柱状图同样可以显示不同主机的日志数。\n没有其他说明的了,这是这个面板的配置过程清单。\nc-按程序名称显示的饼形图 跟之前做的事情很相似,目标是构建一个饼形图按照程序名显示日志的比重。\n这是这个面板的配置过程清单!\nd-按严重程度显示的饼状图 这个面板看起来很像之前创建的,除了它是按日志严重等级显示的。\n当你的系统发生了一个特别严重的故障时这个面板会非常有用,并且你希望看到故障发生时面板显示错误数量也会快速增加。\n它同样提供了一个简单的方法能让你看到一段时间内日志严重程度的概要,例如你想看看夜间或者特定日期记录的严重等级。\n同样你可能在等这个,这是这个面板的配置过程清单!\ne-监控 SSH 条目 这部分有一点特殊,你需要到 “Discover” 标签栏去构建这个面板。\n当进入到这个探索标签栏时,“logstash-*” 默认被自动选中的。\n在过滤栏位,输入如下的过滤条件 “programname: ssh*”。\n正如你所看到的那样,你有了直接访问在你机器上与 SSHd 服务有关的每一个日志的权限。你可以追踪例如非法访问或者错误登录的记录。\n为了能够访问到该仪表盘的面板,点击 “Save” 选项,然后为你的面板起一个名字。\n在仪表盘面板处,你可以点击 “Add”,然后选择刚才创建的面板。\n 干得漂亮!现在你的面板已经从 discover 面板添加到仪表盘中了。\n Ⅵ-总结 这篇文章中,你已经很好的理解了怎样轻松的使用 Rsyslog 和 ELK 堆栈监控整个的日志基础设施了。\n如该文中所展示的架构那样,你可以通过转发日志到你的中心服务器这种方式为你的日志监控架构扩大为一个完整的集群。\n为了能够在日志数量增长较多的情况下扩容主节点(例如使用 Kubernetes)一种建议是为你的 rsyslog 与 ELK 堆栈使用 Docker 镜像。\n同样重要的一点是如果你想未来修改监控日志的方式,这个架构是一个理想的选择。\n你可以继续依赖 rsyslog 集中日志,但是你也可以换成网关(这个例子中的 Logstash),或者是可视化工具。\n重要的一点是使用例如 Grafana 这样的工具监控 ElasticSearch 日志也是很容易的。\n 通过这篇文章,你会着手使用这个架构应用到你的基础设施中吗?\n你会觉得其他的面板跟你在系统中调试故障时息息相关吗?\n 如果你有其他的想法,请在下方留言,这样可以帮助到其他的工程师。\n在那之前,开心如常。\n", "auhtor": "Antoine Solnichkin", "translator": "0N0thing", "original": "https://medium.com/schkn/monitoring-linux-logs-with-kibana-and-rsyslog-4dfbbd287807", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/06/2020-06-30-kubesphere-devops-using-jenkins/", "title": "KubeSphere DevOps 初体验,内置 Jenkins 引擎", "type": "wechat", "date": "2020-06-30 00:00:00 +0000 UTC", "tags": ["jenkins", "kubesphere", "devops", "open source"], "description": "基于 Kubernetes 安装 KubeSphere 并开启 DevOps 系统", "content": " 初识 KubeSphere KubeSphere 是在 Kubernetes 之上构建的以应用为中心的多租户容器平台,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。KubeSphere 提供了运维友好的向导式操作界面,帮助企业快速构建一个强大和功能丰富的容器云平台。KubeSphere 支持部署在任何基础设施环境,提供在线与离线安装,支持一键升级与扩容集群,并且各功能组件支持模块化和可插拔的安装。\n解读 KubeSphere DevOps KubeSphere DevOps 作为 KubeSphere 容器平台的一个可插拔功能组件,内置了 Jenkins 作为在 Kubernetes 之上的 CI/CD 引擎。借助 Jenkins 丰富的插件体系和易于进行扩展开发的特性,帮助 DevOps 团队在一个统一的平台中,打通开发、测试、构建、部署、监控、日志与通知等流程。KubeSphere 为 DevOps 团队打造了以容器为载体的端到端的应用交付平台,实现从应用开发、持续集成、单元测试、制品构建到应用的生产交付,所有的流程都是一个完整的闭环。\nKubeSphere DevOps 充分利用和释放 Kubernetes 动态扩展的能力。例如,KubeSphere 在内置的 DevOps 系统使用了 Jenkins Kubernetes 的动态 Agent,这样的方案相较于传统虚拟机上的 Jenkins 要更加灵活敏捷。同时,在 KubeSphere DevOps 中内置了常用的 Agent 类型,例如 Maven、Node.js、Go 等,并且还支持自定义与扩展的 Agent 类型。\n除了基于 Jenkins 引擎打造的 CI/CD 流水线,KubeSphere 还为业务开发者提供了自动化打包部署的工具集。业务开发者即使还没有深入了解 Docker 与 Kubernetes 的机制,也可以借助 KubeSphere 内置的自动化 CD 工具,如 Binary to Image 和 Source to Image。用户只需要提交一个仓库地址,或上传 JAR/WAR/Binary 等二进制文件,即可快速将制品打包成 Docker 镜像并发布到镜像仓库,最终将服务自动发布至 Kubernetes 中,无需编写一行 Dockerfile。\n关于 KubeSphere DevOps 更多的介绍,可以参考 KubeSphere 官网(https://kubesphere.io/devops/)获得更进一步的了解。\n在 Kubernetes 安装 KubeSphere 开启 DevOps 组件 以下步骤将基于 Kubernetes 集群演示如何安装 KubeSphere v2.1.1,并开启 KubeSphere DevOps 组件。\n前提条件 已有 Kubernetes 集群,并且 Kubernetes 版本: 1.15.x ≤ K8s version ≤ 1.17.x。若没有 K8s 环境可参考文档(https://kubesphere.com.cn/docs/zh-CN/installation/all-in-one/)在 Linux 环境安装; 集群能够访问外网,若无外网请参考 在 Kubernetes 离线安装 KubeSphere,地址 https://kubesphere.com.cn/docs/installation/install-on-k8s-airgapped/ 安装 Helm 和 Tiller 提示:若集群已有 Helm 和 Tiller,可跳过本节操作。\n 从 Helm 的 GitHub https://github.com/helm/helm/releases/tag/v2.16.3 下载 helm-v2.16.3-linux-amd64.tar.gz。\n 上传到服务器,解压移动 Helm、Tiller 到 /usr/local/bin/:\n [root@k8s-node1 linux-amd64]# cp helm /usr/local/bin/ [root@k8s-node1 linux-amd64]# cp tiller /usr/local/bin/ 验证 Helm 的安装: helm help 创建权限: 创建一个新的文件 helm_rbac.yaml,内容如下:\napiVersion: v1 kind: ServiceAccount metadata: name: tiller namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tiller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: tiller namespace: kube-system 然后使用 kubectl 使其创建生效。 [root@k8s-node1 k8s]# kubectl apply -f helm_rbac.yaml serviceaccount/tiller created clusterrolebinding.rbac.authorization.k8s.io/tiller created 初始化 Helm,这里用的国内的镜像源。 helm init --service-account=tiller --tiller-image=registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.16.3 --history-max 300 验证 Helm Tiller。如果状态是 ImagePullBackOff,表示镜像未拉取成功,需要手动拉取。 kubectl -n kube-system get pods|grep tiller 检查 Tiller 是否部署到 Kubernetes: [root@k8s-node1 local]# kubectl get pod -n kube-system -l app=helm NAME READY STATUS RESTARTS AGE tiller-deploy-7b76b656b5-m4k2x 1/1 Running 0 94s 安装持久化存储与 StorageClass 提示: - 若您的集群已有持久化存储与 StorageClass,可跳过本小节 - OpenEBS 将使用 LocalPV 作为存储卷,仅建议用作开发测试环境,生产环境建议使用如 Ceph、GlusterFS 等独立的分布式存储服务 - 安装之前,请确保 master 节点没有 Taints (待安装完 KubeSphere 之后再添加 Taints)\n 确认 master 节点是否有 Taint,如下看到 master 节点有 Taint。 $ kubectl describe node master | grep Taint Taints: node-role.kubernetes.io/master:NoSchedule 去掉 master 节点的 Taint: $ kubectl taint nodes master node-role.kubernetes.io/master:NoSchedule- 创建 OpenEBS 的 namespace,OpenEBS 相关资源将创建在这个 namespace 下: $ kubectl create ns openebs 安装 OpenEBS helm init helm install --namespace openebs --name openebs stable/openebs --version 1.5.0 安装 OpenEBS 后将自动创建 4 个 StorageClass,查看创建的 StorageClass: $ kubectl get sc NAME PROVISIONER AGE openebs-device openebs.io/local 10h openebs-hostpath openebs.io/local 10h openebs-jiva-default openebs.io/provisioner-iscsi 10h openebs-snapshot-promoter volumesnapshot.external-storage.k8s.io/snapshot-promoter 10h 如下将 openebs-hostpath 设置为 默认的 StorageClass: $ kubectl patch storageclass openebs-hostpath -p '{\u0026quot;metadata\u0026quot;: {\u0026quot;annotations\u0026quot;:{\u0026quot;storageclass.kubernetes.io/is-default-class\u0026quot;:\u0026quot;true\u0026quot;}}}' storageclass.storage.k8s.io/openebs-hostpath patched 至此,OpenEBS 的 LocalPV 已作为默认的存储类型创建成功。可以通过命令 kubectl get pod -n openebs 来查看 OpenEBS 相关 Pod 的状态,若 Pod 的状态都是 running,则说明存储安装成功。 kubectl 安装 KubeSphere 当 Kubernetes 集群满足前提条件,实际上安装 KubeSphere 的步骤非常简单,仅一条命令。根据集群资源情况,使用 kubectl 安装 KubeSphere。\n最小化安装 KubeSphere 若集群可用 CPU \u0026gt; 1 Core 且可用内存 \u0026gt; 2 G,可以使用以下命令最小化安装 KubeSphere:\nkubectl apply -f https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-minimal.yaml 提示:若您的服务器提示无法访问 GitHub,可将 kubesphere-minimal.yaml 从 GitHub 地址 https://github.com/kubesphere/ks-installer/ 拷贝文件保存到本地作为本地的静态文件,再参考上述命令进行安装。\n 验证与访问 查看滚动刷新的安装日志,请耐心等待安装成功。 $ kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f 说明:安装过程中若遇到问题,也可以通过以上日志命令来排查问题。\n 通过 kubectl get pod --all-namespaces 查看 KubeSphere 相关 namespace 下所有 Pod 状态是否为 Running。确认 Pod 都正常运行后,可使用 IP:30880 访问 KubeSphere UI 界面,默认的集群管理员账号为 admin/P@88w0rd。 登录控制台首页,查看集群状态。 开启 KubeSphere DevOps 的安装 通过修改 ks-installer 的 ConfigMap 可以选装可插拔的功能组件,执行以下命令开启 KubeSphere DevOps 系统: $ kubectl edit cm -n kubesphere-system ks-installer 参考如下修改 ConfigMap\ndevops: enabled: True jenkinsMemoryLim: 2Gi jenkinsMemoryReq: 1500Mi jenkinsVolumeSize: 8Gi jenkinsJavaOpts_Xms: 512m jenkinsJavaOpts_Xmx: 512m jenkinsJavaOpts_MaxRAM: 2g sonarqube: enabled: True 保存退出,安装任务将自动在后台执行。等待几分钟,若看到 ks-installer 日志返回安装成功的日志,即可通过以下命令来验证 KubeSphere DevOps 系统下相关 Pod 与 Job 的状态: kubectl get pod -n kubesphere-devops-system 若 Pod 状态都是 Running,并且在 KubeSphere 控制台的服务组件看到 DevOps 相关服务都是 健康 状态,说明 KubeSphere DevOps 系统已成功开启安装。 可参考如下文档进一步上手 KubeSphere DevOps 系统的功能:\n Binary-to-Image: 将 WAR、JAR、Binary 这一类的制品快速打包成 Docker 镜像,并发布到镜像仓库中,最终将服务自动发布至 Kubernetes,参考文档 https://kubesphere.com.cn/docs/zh-CN/quick-start/b2i-war; Source-to-Image: 无需写 Dockerfile,仅输入源代码地址即可自动打包成可运行程序到 Docker 镜像的工具,方便构建镜像发布至镜像仓库和 Kubernetes,参考文档 https://kubesphere.com.cn/docs/zh-CN/quick-start/source-to-image 图形化构建流水线: 通过图形化编辑的界面构建流水线,无需写 Jenkinsfile,交互友好,参考文档 https://kubesphere.com.cn/docs/zh-CN/quick-start/jenkinsfile-out-of-scm 基于 Jenkinsfile 构建流水线: 基于项目仓库中已有的 Jenkinsfile 快速构建流水线,参考文档 https://kubesphere.com.cn/docs/zh-CN/quick-start/devops-online 活动预告 KubeSphere 将在七月份重磅发布 v3.0!欢迎大家关注和报名参加 6 月 30 日 (本周二下午 14:00) 的 KubeSphere 线上发布会的直播,提前知晓 v3.0 的重大更新。\n", "auhtor": "FeynmanZhou", "translator": "", "original": "", "poster": "https://pek3b.qingstor.com/kubesphere-docs/png/20200628225840.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/06/2020-06-29-generate-jenkins-plugins-word-cloud/", "title": "使用 Python 制作酷炫多彩的 Jenkins 插件词云图", "type": "wechat", "date": "2020-06-29 00:00:00 +0000 UTC", "tags": ["jenkins", "wordcloud"], "description": "Jenkins 插件名称高频关键词有哪些?一切尽在酷炫多彩的词云图", "content": " 作为最流行的 CI/CD 工具,Jenkins 的优势之一是其生态强大,而这与其插件体系分不开的。 目前 Jenkins 插件 1500+ (截止2020年06月17日,插件数量为1749)。\n近日发现词云比较好玩,于是想着以 Jenkins 插件名称为数据源,形成的词云会是什么样的呢,什么关键字会比较突出呢? 想到就去做,带着问题,带着好奇心,开始了实践之旅~\n插件基本字段说明 以 Jenkins 中文本地化插件为例,在 Jenkins 官网插件详情页面可以看出: 其 ID 为 localization-zh-cn,Name 为 Localization: Chinese (Simplified)。\n获取所有 Jenkins 插件的名称 如何获取所有 Jenkins 插件的名称呢?这里我想到3种方式,或许还有更多方式:\n 插件官网爬虫抓取\n 插件权限文件获取\n 插件更新中心配置文件获取\n 对比上面的三种方式,插件权限文件中并没有 Name 字段,插件更新中心配置文件相对从插件官网抓取比较简单。 所以计划从 update-center.json 进行解析,其中插件名称在 json 中对应字段为 title。\n生成 Jenkins 插件名称文件 读取 update-center.json 中 plugin 的 title 字段,按行写入到 jenkins-plugins.txt 文件,代码如下:\n# -*- coding: UTF-8 -*- import json if __name__ == \u0026quot;__main__\u0026quot;: json_obj = json.load(open(\u0026quot;update-center.json\u0026quot;, \u0026quot;r\u0026quot;)) plugins_obj = json_obj[\u0026quot;plugins\u0026quot;] with open(\u0026quot;jenkins-plugins.txt\u0026quot;, \u0026quot;w\u0026quot;) as fw: for plugin_name in plugins_obj: plugin_obj = plugins_obj[plugin_name] print plugin_obj[\u0026quot;title\u0026quot;] fw.write(plugin_obj[\u0026quot;title\u0026quot;].encode('utf-8') + \u0026quot;\\n\u0026quot;) jenkins-plugins.txt 文件共有 1749 行(与 Jenkins 1749个插件对应),其内容截图如下:\n生成词云图 这里使用 Python 代码生成词云图,词的来源为 jenkins-plugins.txt,代码如下:\n# -*- coding: UTF-8 -*- from wordcloud import WordCloud import matplotlib.pyplot as plt import numpy as np from PIL import Image def generate_word_cloud_image(background_image): # mask mask = np.array(Image.open(background_image)) # generate word cloud wc = WordCloud(mask=mask, scale=1.5, mode='RGBA', background_color=\u0026quot;white\u0026quot;, max_words=2000).generate(text=text) # show word cloud plt.imshow(wc, interpolation='bilinear') plt.axis('off') plt.show() # save to file background_image = str(background_image).split(\u0026quot;/\u0026quot;)[-1].replace(\u0026quot;.png\u0026quot;, \u0026quot;\u0026quot;) wc.to_file(\u0026quot;word-cloud-img/\u0026quot; + background_image + '-word-cloud.png') if __name__ == \u0026quot;__main__\u0026quot;: with open('jenkins-plugins.txt') as f: text = f.read() for image_name in [\u0026quot;background-img/kongfu.png\u0026quot;, \u0026quot;background-img/jenkins-logo.png\u0026quot;]: generate_word_cloud_image(background_image=image_name) 生成的词云图各个关键字以不同大小和比例,绘制出一幅多彩的画卷,感觉很美观、很酷炫!\n以 Jenkins logo 为背景图片,生成的词云图如下:\n以 Jenkins 中文社区的 kongfu 为背景图片,生成的词云图如下:\n从词云图中可以看出,Pipeline 词频最高,Build、API、Job 次之,紧接着还有 Publisher、Notifier、Trigger、Step、GitHub 等等。\n资源说明 所有代码及文件可以在 GitHub 仓库找到,如果你也觉得好玩有趣,顺便点个 star 吧,谢谢~\n https://github.com/donhui/jenkins-plugins-word-cloud ", "auhtor": "donhui", "translator": "", "original": "", "poster": "jenkins-logo-word-cloud.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/06/2020-06-24-jenkins-user-experience-hackfest-documentation-results/", "title": "Jenkins Hackfest 用户体验文档报告", "type": "wechat", "date": "2020-06-24 00:00:00 +0000 UTC", "tags": ["ux", "documentation", "community"], "description": "通过 Hackfest,我们得到了很多的进步,我们会进一步丰富技术文档,来提高 Jenkins 用户体验", "content": " Jenkins 技术文档是我们项目的重要组成部分,因为它是正确使用 Jenkins 的关键。好的文档可以指导用户,并鼓励选择好的实现方式。这是用户体验的关键部分。\n在最近的 Jenkins UI/UX hackfest 中,文档是改善 Jenkins 用户体验的特定途径。我们从经验丰富的 Jenkins 贡献者和新人那里获得了许多进步。来自世界各地的贡献者提交了有关安装,管理和操作 Jenkins 文档的 PR。\n从 Wiki 迁移文档 Jenkins Wiki 页面为 Jenkins 用户收集了 15 年的经验和智慧。但是,这种经验和智慧与不准确,不完整和过时的信息混杂在一起。\nJenkins Wiki 迁移项目确定了 Jenkins Wiki 上访问量最大的 50 个页面,并创建了 GitHub 问题来跟踪这些页面到 www.jenkins.io 的迁移。这是我们第一次使用 GitHub 问题作为文档的大规模实验。结果是压倒性的正面。Hackfest 贡献者在许多文档章节中添加了新的章节,包括:\n Jenkins 使用 流水线 Jenkins 管理 系统管理 Hackfest 解决了 Wiki 迁移问题中的 19 个问题。有关其他 25 个 Wiki 迁移问题的工作正在进行中。我们已经取得了长足的进步,并期待将来取得更好的成绩。新的贡献者非常有效地使用了“good first issues”标签。我们以未分配的 25 个“good first issues”中的大多数未分配开始了 Hackfest,并以 14 个已关闭的项目和另外 10 个正在进行的项目完成了 Hackfest。 当我们使用 Jenkins Wiki 迁移来欢迎新的文档撰稿人时,我们将提供更多的“good first issues”。\n迁移插件文档 插件文档也在过渡中。自 2019 年 11 月以来,插件一直将其文档移至托管插件源代码的 GitHub 存储库中。这种“文档即代码”的方法使插件维护人员可以在实现新功能的相同 PR 中包括文档改进。它确保文档更改由审查和批准新功能的相同维护者审查。\nHackfest 参与者提交了 PR,以将插件文档迁移到 GitHub。Hackfest 正在进行 10 个插件 PR。来自 Hackfest 的 5 个插件 PR 已被合并,正在等待插件的发布。\nChuck Norris 文档即代码 出于娱乐和冒险的精神,Oleg Nenashev 在 2020 年 5 月 26 日的 Hackfest 现场演示中将 “Chuck Norris 插件” 迁移为 GitHub 文档中的代码。可以从以下链接获取录音,插件迁移指南和导出工具的链接:将插件迁移为代码文档”。\n文档更新 Jenkins 与其他技术合作,解决了许多不同环境中的自动化挑战。我们在“解决方案页面”中描述了这些环境。作为 Hackfest 的一部分,我们已经对解决方案页面进行了一系列改进。\nDocker 解决方案页面现在包括更新的视频和更好的页面布局,以便于阅读和导航。其他解决方案页面将来也会得到类似的改进。\n系统属性 可以在启动时通过定义 Java 属性来修改 Jenkins 的全局配置。当新的默认配置可能与现有安装不兼容时,系统属性可以更改系统默认值,并可以提供兼容性“转义阴影线”。\nDaniel Beck 作为 Hackfest 的一部分,改进了系统属性页面的导航和用户体验。现在,通过将鼠标悬停在每个属性的右侧以及对每个属性进行分类和分类的标签,可以使用可嵌入的链接来轻松阅读和引用。\n插件站点改进 在 Hackfest 期间,Gavin Mogan 继续致力于改善 Jenkins 插件站点,以便用户可以轻松访问插件更改日志和报告的问题。合并此 PR 后,它将极大地改善那些想要更新插件并查找有关其变化和可能遇到的问题的文档的 Jenkins 用户的体验。\nJira 插件的传入 UI 示例:\n下一步是什么? Jenkins 文档中仍有很多工作要做,我们需要您的帮助。参与 Jenkins 项目的方式有很多,包括文档。请参阅贡献指南以获取详细说明。加入文档聊天室,获得个性化的帮助和鼓励。\nJenkins 项目也已于今年加入 Google Docs。这项开源指导计划使开源社区和技术作家社区聚集在一起,从而使双方受益。我们正在寻找有兴趣为 2020 年 9 月至 12 月对该项目做出贡献的技术撰稿人。这是学习作为文档编码的工具并了解有关为开源项目做出贡献的更多信息的绝佳机会。您可以在此处找到 Jenkins 项目构想和更多信息。\n", "auhtor": "Mark Waite, Tracy Miranda", "translator": "wenjunzhangp", "original": "https://www.jenkins.io/blog/2020/06/08/hackfest-docs-results/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/06/2020-06-17-github-app-authentication-support-released/", "title": "GitHub App 身份验证支持已发布", "type": "wechat", "date": "2020-06-17 00:00:00 +0000 UTC", "tags": ["github", "authentication"], "description": "GitHub App 身份验证支持已发布,本文教你简单使用以及一些注意事项", "content": " 我很高兴的宣布在 Jenkins 中作为 GitHub 应用进行身份验证现已支持。这是许多用户期待已久的功能。它已在 GitHub Branch Source 2.7.1 中发布,现在可以在 Jenkins 更新中心使用。\n身份验证为 GitHub 应用带来了很多好处:\n 更高的请求频率限制 - GitHub 应用程序的速率限制随您的组织规模而定,而基于用户的令牌的限制为 5000,无论您拥有多少存储库。 与用户无关的身份验证 - 每个 GitHub 应用都有自己的用户独立身份验证。不再需要“机器人”用户或确定谁应该是 2FA 或 OAuth 令牌的所有者。 改进的安全性和更严格的权限 - 与服务用户及其个人访问令牌相比,GitHub Apps 提供了更精细的权限。这使 Jenkins GitHub 应用程序需要更少的权限集即可正常运行。 访问 GitHub Checks API - GitHub Apps 可以访问 GitHub Checks API 以从 Jenkins 作业创建检查运行和检查套件,并提供有关提交和代码注释的详细反馈。 开始使用 安装 GitHub Branch Source 插件,确保版本为 2.7.1 或更高。\n配置 GitHub Organization 文件夹 遵循 GitHub App Authentication setup guide。这些说明也可在 GitHub 上的插件 README 文件中看到。\n设置完成后,Jenkins 将验证您的凭据,并且您应该会看到新的速率限制。这是一个大型组织的示例:\n如何在流水线中获取 API 令牌? 除了将 GitHub App 身份验证用于多分支流水线之外,您还可以直接在流水线中使用 app 身份验证。您只需照常加载“用户名/密码”凭据即可访问 GitHub API 的 Bearer 令牌,该插件将在后台处理 GitHub 的身份验证。\n这可以用于从流水线中调用其他 GitHub API 端点,可能是 deployments api,或者您可能希望实现自己的 checks api 集成,直到 Jenkins 开箱即用为止。\n注意:您获得的 API 令牌仅有效一小时,请勿在流水线开始时获得它,并假设它一直有效\n示例:让我们通过流水线向 Jenkins 提交检查运行:\npipeline { agent any stages{ stage('Check run') { steps { withCredentials([usernamePassword(credentialsId: 'githubapp-jenkins', usernameVariable: 'GITHUB_APP', passwordVariable: 'GITHUB_JWT_TOKEN')]) { sh ''' curl -H \u0026quot;Content-Type: application/json\u0026quot; \\ -H \u0026quot;Accept: application/vnd.github.antiope-preview+json\u0026quot; \\ -H \u0026quot;authorization: Bearer ${GITHUB_JWT_TOKEN}\u0026quot; \\ -d '{ \u0026quot;name\u0026quot;: \u0026quot;check_run\u0026quot;, \\ \u0026quot;head_sha\u0026quot;: \u0026quot;'${GIT_COMMIT}'\u0026quot;, \\ \u0026quot;status\u0026quot;: \u0026quot;in_progress\u0026quot;, \\ \u0026quot;external_id\u0026quot;: \u0026quot;42\u0026quot;, \\ \u0026quot;started_at\u0026quot;: \u0026quot;2020-03-05T11:14:52Z\u0026quot;, \\ \u0026quot;output\u0026quot;: { \u0026quot;title\u0026quot;: \u0026quot;Check run from Jenkins!\u0026quot;, \\ \u0026quot;summary\u0026quot;: \u0026quot;This is a check run which has been generated from Jenkins as GitHub App\u0026quot;, \\ \u0026quot;text\u0026quot;: \u0026quot;...and that is awesome\u0026quot;}}' https://api.github.com/repos/\u0026lt;org\u0026gt;/\u0026lt;repo\u0026gt;/check-runs ''' } } } } } 下一步打算 Jenkins 中的 GitHub Apps 身份验证是一个巨大的进步。许多团队已经开始使用它,并通过提供预发布反馈来帮助改进它。途中还有更多改进。\n有一个拟议的 Google Summer of Code 项目:GitHub Checks for Jenkins Plugins。它将着眼于与 Checks API 集成,重点是将使用 warnings-ng 插件直接发现的问题报告到 GitHub pull request 中,以及 GitHub 上的测试结果摘要。希望它将为 Jenkins 用户简化下面的 Pipeline 示例:)如果您想参与其中,请加入 GSoC Gitter 渠道并询问如何提供帮助。\n", "auhtor": "Tim Jacomb", "translator": "wenjunzhangp", "original": "https://www.jenkins.io/blog/2020/04/16/github-app-authentication/#github-app-authentication-support-released", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/meeting/2020-06-10/", "title": "", "type": "meeting", "date": "2020-06-10 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " UCloud 服务器管理 Nexus 上线了 https 有问题 企业合作 中信 技术活动没有确定 句子互动 作为赞助商 提供了一年的套餐 https://github.com/jenkins-zh/jenkins-zh/pull/271 kubesphere https://github.com/kubesphere/kubesphere/issues/2182 著作权 * 翻译文章不能算是原创(个例,来自 jenkins.io 可以在公众号里申明为原创) * 在社区提供的翻译稿,在我们的公众号上首次发布 * 应该说明作者、翻译者等的具体版权说明 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/06/2020-06-03-monitoring-linux-processes-using-prometheus-and-grafana/", "title": "使用 Prometheus 和 Grafana 监控 Linux 进程", "type": "wechat", "date": "2020-06-03 00:00:00 +0000 UTC", "tags": ["DevOps", "Monitoring", "Grafana", "Software Development", "Software Engineering"], "description": "从安装到配置使用讲解了如何使用 Prometheus 与 Grafana 监控 Linux 进程", "content": " 无论你是否是一名 Linux 系统管理员或是一名 DevOps 工程师,你都会在监控服务器性能指标的时候花费很长时间。\n有时候实例运行非常慢但是哪里出的问题却没有任何线索。\n有一些不响应的实例会阻止你在这些实例上执行类似 top 或者 htop 的远程命令。\n服务器有一个瓶颈存在,但是你并不能简单快速的找到问题所在。\n 如果我们有一个完整的仪表盘可以帮助我们跟踪整体性能以及独立的进程该怎么操作?\n可以在该链接中实时查看: http://grafana.devconnected.com/d/nZMDMoiZk/grafana-top?orgId=1\u0026amp;refresh=5s\n 这篇入门文章旨在如何为 Linux 系统管理员创建一个完整的监控仪表盘\n该仪表盘会展示完全可定制并且可扩展到分布式架构的多个实例的不同面板。\n你将会学到什么 在即将踏入技术旅途之前,让我们快速看下通过阅读这篇文章你将学到哪些东西:\n 了解在 Unix 系统性能监控方面的最新技术;\n 怎样安装最新版本的 Prometheus v2.9.2、Pushgateway v0.8.0 以及 Grafana v6.2;\n 构建一个简单的 bash 脚本用来导出指标项到 Pushgateway;\n 构建一个完整的 Grafana 仪表盘包括最新的面板例如 ‘Gauge’ 和 ‘Bar Gauge’。\n 额外内容: 集成 ad-hoc 过滤器跟踪单个进程或实例。\n 现在我们大体浏览了一下我们将要学习哪些东西,并且没有进一步的要求,让我们介绍一些当前 Unix 系统中目前已有的内容。\nUnix 进程监控基础 当提到 Unix 系统进程监控的时候,在你脑海中出现的有好几个选项。\n最流行的或许就是 ‘top’ 了。\n这个命令在系统管理员中间被广泛使用当系统出现性能瓶颈或许是第一条执行的命令(如果你可以访问它当然就是第一条!)\ntop 命令可读性已经是非常好了,但是仍有一条命令比 top 命令可读性更好:htop。\nHtop 提供了与 top 相同的一些功能(CPU、内存、正常运行时间\u0026hellip;)但是是以一种彩色并且很友好的方式展示出来的。\nHtop 还提供当前系统使用情况的仪表盘\n 既然已经有这两个命令了,那为什么我们想要构建另一种监控进程的方法呢?\n 主要原因是系统可用性: 一旦系统过载,你或许没有办法从物理层面或者远程访问实例。\n通过外部监控进程,你可以在不需要访问服务器的前提下分析哪个地方出现的问题。\n另一个原因就是进程总是通过内核本身被创建以及被杀死。\n因此,运行 top 命令你得不到任何信息,当你想要分析什么导致系统出现性能问题时已经为时已晚。\n你或许需要挖掘内核日志去查看哪个进程被杀死了。\n使用监控仪表盘的话,你可以非常简单的回到过去查看哪个进程导致了这个问题。\n现在已知道了为什么我们想构建这样一个仪表盘了,让我们看下为了构建它的架构是什么样的吧。\n监控架构的细节 在我们查看我们将要使用的架构之前,我们想要使用一个这样的解决方案:\n 节省资源: 比如不会消耗我们主机上太多的资源;\n 易于安装: 不需要太多的时间进行实例化;\n 可扩展: 如果我们想要监控另一个主机,我们可以快速且高效的实现。\n 这些特点需要我们在这篇文章中始终需要牢记的。\n我们今天将要实践的具体细节是这样的:\n我们的架构使用了四种不同的组件:\n 一个用来周期性提供指标到 Pushgateway 的 bash 脚本;\n Pushgateway: 单个脚本用作目标的指标项缓存;\n Prometheus: 实例化用于存储指标项的时间序列数据库。Prometheus 会将 Pushgateway 作为目标,以便检索并存储指标项;\n Grafana: 一个仪表盘监控工具通过 PromQL 从 Prometheus 检索数据然后绘制它们。\n 对于已经非常熟悉 Prometheus 的朋友,你已经知道 Prometheus 从暴露 HTTP 的实例获取指标然后存储它们。\n在这篇文章中,bash 脚本的生命周期非常短并且不会给 Prometheus 暴露任何的 HTTP 实例。\n这也就是为什么我们需要使用 Pushgateway;为短命任务而设计,Pushgateway 会缓存从脚本中接收的指标并将它们暴露给 Prometheus。\n安装不同的工具 现在你已经知道我们应用程序是怎样运行的了,让我们安装这些需要的工具吧。\na \u0026ndash; 安装 Pushgateway 为了安装 ** Pushgateway**,运行一个简单的 wget 命令来获取二进制文件。\nwget https://github.com/prometheus/pushgateway/releases/download/v0.8.0/pushgateway-0.8.0.linux-amd64.tar.gz 现在你获取到了这个压缩文件,解压,在 pushgateway 目录下运行这个可执行文件。\n\u0026gt; tar xvzf pushgateway-0.8.0.linux-amd64.tar.gz \u0026gt; cd pushgateway-0.8.0.linux-amd64/ \u0026gt; ./pushgateway \u0026amp; 结果是,你的 Pushgateway 会以后台进程的形式启动。\nme@schkn-ubuntu:~/softs/pushgateway/pushgateway-0.8.0.linux-amd64$ ./pushgateway \u0026amp; [1] 22806 me@schkn-ubuntu:~/softs/pushgateway/pushgateway-0.8.0.linux-amd64$ INFO[0000] Starting pushgateway (version=0.8.0, branch=HEAD, revision=d90bf3239c5ca08d72ccc9e2e2ff3a62b99a122e) source=\u0026quot;main.go:65\u0026quot;INFO[0000] Build context (go=go1.11.8, user=root@00855c3ed64f, date=20190413-11:29:19) source=\u0026quot;main.go:66\u0026quot;INFO[0000] Listening on :9091. source=\u0026quot;main.go:108\u0026quot; 干得漂亮!\n从那里,Pushgateway 会在 9091 端口上监听接收的指标。\nb \u0026ndash; 安装 Prometheus 如在 Prometheus 官网上 ‘Getting Started’ 章节讲的那样,请访问 https://prometheus.io/download/ 运行一个简单的 wget 命令从你的系统中获取 Prometheus 压缩包。\nwget https://github.com/prometheus/prometheus/releases/download/v2.9.2/prometheus-2.9.2.linux -amd64.tar.gz 现在获取到压缩包之后,解压,切换到主目录:\n\u0026gt; tar xvzf prometheus-2.9.2.linux-amd64.tar.gz \u0026gt; cd prometheus-2.9.2.linux-amd64/ 如之前所述,Prometheus 周期性地获取‘目标’然后收集指标。目标(在这里是 Pushgateway)需要被配置到 Prometheus 配置文件中。\n\u0026gt; vi prometheus.yml 在 ‘global’ 部分,编辑 ‘_scrape_interval’ 值减少为 1 秒。\nglobal: scrape_interval: 1s # Set the scrape interval to every 1 second. 在 ‘_scrape_configs_’ 部分,在 scrape_configs 部分的 targets 下新增一个值。\nstatic_configs: - targets: ['localhost:9090', 'localhost:9091'] 退出 vi,最后运行目录下的 prometheus 可执行文件。\n当执行最后的 prometheus 命令 Prometheus 启动。为了确保所有配置都是正确的,你可以访问 http://localhost:9090/graph 查看。\n如果你能访问 Prometheus web 控制台,也就证明所有的配置都是正确的。\n你也可以在 Web UI 的 ‘Status’ \u0026gt; ‘Targets’ 验证 Pushgateway 是否正确配置为目标。\nc \u0026ndash; 安装 Grafana 最后,我们将要安装 Grafana v6.2。访问 https://grafana.com/grafana/download/beta 。\n同之前做的那些一样,运行一个简单的 wget 命令获取它。\n\u0026gt; wget https://dl.grafana.com/oss/release/grafana_6.2.0-beta1_amd64.deb\u0026gt; sudo dpkg -i grafana_6.2.0-beta1_amd64.deb 现在你获取到了一个可执行的 deb 文件,grafana 会以服务的方式运行在你的实例上。\n你可以通过运行下面的命令验证:\n\u0026gt; sudo systemctl status grafana-server ● grafana-server.service - Grafana instance Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2019-05-09 10:44:49 UTC; 5 days ago Docs: http://docs.grafana.org 你可以查看 http://localhost:3000/ 这个是 Grafana Web UI 的默认地址。\n现在你已经将 Grafana 安装到你的实例上了,我们需要配置 Prometheus 作为数据源。\n你可以这样配置数据源:\n就是它!\n点击 ‘Save and Test’ 确保你的数据源运行正常。\n构建脚本以检索指标 下一个任务是构建一个简单的脚本用来检索指标比如单个进程的 CPU 使用率以及内存使用率。\n你的脚本可以定义为一个 cron 任务这样将会每秒运行一次。\n为了执行这个任务,你有多个候选。\n你可以每秒运行 top 命令,使用 sed 解析它然后发送指标给 Pushgateway。\n麻烦的部分是 top 运行多次,提供一个这段时间的平均指标值。这不是我们真正想要的。\n取而代之的,我们将会使用 ps 命令为了更精确的话使用 ps aux 命令。\n该命令暴露了单独的 CPU 以及内存使用率以及运行后台实际运行的命令。\n这就是我们想要的。\n但是在继续后面的工作之前,让我们看看 Pushgateway 期望输入的内容。\nPushgateway,非常像 Prometheus,使用键值对运行: 键描述了监控的指标然后值就不言自明了。\n这里有一些例子:\n你可以说,第一个表格简单描述为 CPU 使用率,但是第二个描述了 java 进程的 CPU 使用率。\n添加标签是指定你的指标描述更准确的一种方法。\n现在我们有这个信息了,我们需要构建最终的脚本。\n提醒一下,我们的脚本将会使用 ps aux 命令运行,解析结果,转换并通过我们之前描述的语法发送给 Pushgateway 。\n创建一个脚本文件,赋给一些权限然后切换至该位置。\n\u0026gt; touch better-top \u0026gt; chmod u+x better-top \u0026gt; vi better-top 脚本如下:\n如果你想用作收集内存使用率,将 ‘cpu_usage’ 标签修改为 ‘memory_usage’ 然后 $3z 改为 $4z\n#!/bin/bash z=$(ps aux) while read -r z do var=$var$(awk '{print \u0026quot;cpu_usage{process=\\\u0026quot;\u0026quot;$11\u0026quot;\\\u0026quot;, pid=\\\u0026quot;\u0026quot;$2\u0026quot;\\\u0026quot;}\u0026quot;, $3z}'); done \u0026lt;\u0026lt;\u0026lt; \u0026quot;$z\u0026quot; curl -X POST -H \u0026quot;Content-Type: text/plain\u0026quot; --data \u0026quot;$var \u0026quot; http://localhost:9091/metrics/job/top/instance/machine 所以这个脚本干了些啥呢?\n首先,它执行了我们之前说的 ps aux 命令。\n如同你所说的那样,这个脚本收集进程所有的指标但是它只执行一次。\n现在我们使用 sleep 只是简单的每秒运行一次。\n然后,你可以自由创建一个服务使用计时器每秒执行一次(至少使用 systemd)。\n 对 systemd 好奇?我创建了一个关于使用 Chronograf 监控它们的完整教程\n \u0026gt; while sleep 1; do ./better-top; done; 现在我们的指标发送到 Pushgateway 了,让我们看看是否我们可以在 Prometheus Web 控制台看到它们。\n访问 http://localhost:9090/ 。在 ‘Expression’ 位置,简单输入 ‘cpu_usage’。你可以在浏览器上看到所有的指标。\n恭喜你!你的 CPU 指标被存储到 Prometheus TSDB 中了。\n使用 Grafana 构建一个酷炫的仪表盘 现在我们的指标存储到 Prometheus 了,我们需要简单的构建一个 Grafana 仪表盘目的是为了可视化它们。\n为了看起来舒服一些,我从 1 到 4 标注了最终的仪表盘。\n这些与这个章节的各个子章节匹配。如果你只对其中的一些面板感兴趣,就直接跳转到匹配的子章节即可。\n1\u0026ndash; 构建圆形仪表盘 这个是我们面板中圆形仪表盘的特写。\n目前,我们主要专注于进程的 CPU 使用率,也可以简单的映射到内存使用率。\n通过这些面板,我们将要跟踪两个指标: 所有进程当前的 CPU 使用率以及平均 CPU 使用率。\n为了检索这些指标,我们将在我们的 Prometheus 实例上执行 PromQL 队列。\n所以.. 什么是 PromQL 呢?\nPromQL 是为 Prometheus 而设计的队列语言。\n类似于使用 InfluxQL(或者是 IFQL)的 InfluxDB 实例,PromQL 队列查询可以使用求和、取平均值以及标准差之类的函数来汇总数据。\n语法使用起来非常简单我们将会在面板中使用它。\na \u0026ndash; 检索当前总体的 CPU 使用率 为了检索当前的总体 CPU 使用率,我们将会使用 PromQL sum 函数。\n在给定的时间内,我们总体的 CPU 使用率就是简单的各个使用率的总和。\n以下是配置清单:\nb \u0026ndash; 检索平均 CPU 使用率 平均 CPU 使用率不需要太多的工作,你只需要简单的使用 PromQL 的 avg 函数。你可以通过下面的配置清单查看到。\n2 \u0026ndash; 构建水平仪表盘 水平仪表盘是最新版 Grafana v6.2 版本的一部分。\n我们的目标是显示 10 个消耗最系统的进程。\n为了实现这个,我们将会使用 topk 函数检索一个指标项的前 k 个元素。\n类似于之前所做的工作,我们将会定义几个阈当消耗太多资源的时候得到通知。\n3 \u0026ndash; 构建垂直仪表盘 垂直仪表盘与水平仪表盘类似,我们只需要在 Grafana 的可视化面板调整方向参数即可。\n同样,我们将会使用这个面板监控内存使用率因此队列会有轻微的不同。\n棒极了!我们目前的进度好极了,还剩一个面板啦。\n4 \u0026ndash; 构建线性图 线性图在 Grafana 已经有很长时间了我们将会使用它来展示这段时间内进程演变的历史。\n这个图表在以下情况下特别方便:\n 过去曾经发生过故障想要调查一下哪些进程在这个过程中是运行的。\n 一些进程没有运行但是你想查看它们之前的一些行为。\n 当提到错误排查的时候,真的需要这一整篇文章(特别似乎最近 Grafana Loki 新增的内容)。\n好的,这是最后一个配置清单!\n到这里,我们已经设置了最后的仪表盘上所有需要的面板了。\n你可以以自己喜欢的方式安排它们或者从我们构建的方法中汲取灵感。\n额外内容: 使用 ad hoc filters 探索数据 实时数据看起来很有意思 \u0026ndash; 但是当你探索你的这些数据时才是真正的价值所在。\n在这部分额外内容里面,我们不会使用 ‘Explore’ 函数(或许在另一篇文章会说一下呢?),我们将要使用 ad hoc filters。\n使用 Grafana,你可以定义一个图表相关的变量。对变量来说有许多不同的选项: 比如你可以为你的数据源定义一个变量可以允许动态切换一个队列中的数据源。\n我们的话,将会使用简单的 ad hoc filters 来探索数据。\n从这个地方,点击左边菜单的 ‘Variables’ ,然后点击 ‘New’。\n如上图所示,ad hoc filters 自动应用到仪表盘中并指向 Prometheus 的数据源。回到我们的仪表盘上。\n看一下仪表盘左上角的地方。\n现在假如你想在系统中查看某个进程的情况: 以 Prometheus 为例。\n简单的切换到过滤器然后可以看到仪表盘根据过滤器进行了更新。\n现在你可以直观的看到 Prometheus 在你的实例上是怎样的了。\n甚至可以看过去这个进程做了什么,与它的 pid 无关!\n快速总结一下 这篇文章中,你应该能更好的理解 Prometheus 和 Grafana 提供哪些功能了。\n你也知道了给一个实例配置一个完整的监控仪表盘,但是这只是扩展规模以及监控 Unix 实例整个集群的一小步。\nDevOps 监控是一个非常有趣的话题 \u0026ndash; 但是如果你做错了一些东西会成为你的梦魇。\n这也就是我们写这篇文章构建这些仪表盘的原因所在: 帮助你尽可能全面的使用这些工具所能提供功能。\n我们相信出色的技术通过有用的展示可以得到提升。\n我写了相同的文章,如果你喜欢这篇文章,可以再读一下其他的文章:\n在那之前,开心如常。\n", "auhtor": "Antoine Solnichkin", "translator": "0N0thing", "original": "https://medium.com/schkn/monitoring-linux-processes-using-prometheus-and-grafana-113b3e271971", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/06/2020-06-01-Your-DevOps-Brain-Ways-of-Thinking-Ways-of-Working/", "title": "你的 DevOps 大脑:思考方式和工作方式", "type": "wechat", "date": "2020-06-01 00:00:00 +0000 UTC", "tags": ["Neuroscience", "DevOps", "Software Engineering", "Automation", "Work"], "description": "DevOps 原理和实践的最大挑战是文化,而改变文化的本质是改变人的行为。改变行为的关键在于了解驱动行为的大脑。", "content": " 我经常不得不说的 DevOps 神话之一就是 DevOps 完全是关于自动化和工具的。尽管二者是达到 DevOps 目标的基本要素( DevOps 的目标是为了更快更安全地交付更有价值成果而优化从创意到价值实现的过程),但在 DevOps 的发展初期,Damon Edwards 和 John Willis 提出了 CALMS 这一缩写词来帮助解释有关 DevOps 的问题,其中字母 C 表示的文化也是一个重要元素。该想法得到了 Gartner 一篇文章的支持。该文章提到研究表明有 50%的受访者表示人的问题(与流程、技术和信息的问题相对)是目前采用 DevOps 原理和实践的最大障碍。我对自己客户的观察也支持这一想法,我的客户说文化是他们当下面临的最困难的挑战。\n客户从一开始就这么说。大约七年前,当我们启动 Ranger4 的 DevOps 业务时,我们以为正在构建的是一个围绕软件和工具的业务。我们之前做么做过,并且这样做也是作为技术人员的合理选择。我们惊讶于客户一遍又一遍地问我们该如何改变文化。我们习惯于谈论技术;情感和感觉这些“软性”的东西是在饮水机旁闲谈的内容,或者用英式术语,说是酒吧里的话题。但是,当我们立即开始帮助客户后就迅速弄清了,文化可以被量化并文化生成的东西可以被确定。显而易见,文化本质上是行为,这很关键,因为我们意识到,可以使用一种在想到改变文化时常常令人感到莫名其妙的方式来影响行为,而文化这种模糊、多面的东西是很难理解的。\n帮助组织采用 DevOps 原则意味着我们必须支持组织变革的推动者和领导者,帮助训练大量人力的大脑来理解和实践新的工作方式,从以项目为中心过渡到以产品、自治、价值流或链式思考以及跨职能、渐进式方法的重要转变。\n工作做的越多,就越能意识到改变行为是核心,而其关键在于了解驱动行为的因素:我们的大脑。在过去的几年中,我发现神经科学在帮助组织变革上提供了大量指导。由于这是一门科学,是由数据驱动的,所以我们可以信任它。\n关于我们都拥有的大脑的一些事实包括:\n 重 3 磅(体重的 2%) 使用人体内 20%的血液和氧气 干重的 60%是脂肪(那是相当多的) 100,000 英里的血管 2%的脱水时会影响认知能力 每分钟有一公升的血液流过大脑 人类的大脑与体重的比例是最大的 包含 860 亿个神经元 重要提示:如果您想了解更多有关大脑不同部位的信息,可以使用 Wellcome Trust 的交互式 3D 模型 AMAZE 。\n关于神经元的一些事实:\n 它们使用电信号和化学信号相互沟通 神经元通过轴突链接产生神经回路 不同的回路执行不同的任务 一个神经元每秒可以传输 1,000 次神经冲动 大脑中有 10,000 种特定类型的神经元 脑信息以每小时 268 英里的速度传播 学习和不学习( unlearning ) 无一例外,我们客户都将努力从瀑布式过渡到敏捷作为业务和技术挑战核心。他们认识到自己正受到数字化的干扰。如果想要生存,能够蓬勃发展那更好,那么他们就需要在吞吐量和稳定性方面都能做得更好。但是,如果组织中的所有人(无论是 200 人还是 20,000 人)都接受过以项目为导向的工作方式的培训,资金也是以项目为导向,系统随着自身的发展而变成紧密耦合的整体,组织结构被孤立,组织中有负责变革咨询和发布管理团队,组织的工作被外包,技术发展滞后,那么组织中的人将很难改变自己的行为。实际上他们必须忘记( unlearn )多年甚至几十年已经学习到并坚信的东西。\nBarry O’Reill 在他最近的著作《Unlearn》中将 unlearn 定义为:\n“一个放开、远离和重新定义那些曾经有效但是现在限制我们成功的那些有用的心态和后天行为的过程。这不是在忘记或丢弃已有的知识或经验;这是一种有意识的行为,放弃过时的信息,积极收集和吸收新信息以为有效的决策和行动提供信息。”\n但是之前我们还从 Carol Dweck 那里学习了有关思维方式的内容:简单来说,人要么是学习型(成长型思维方式),要么不是(固定型思维方式)。但是神经可塑性告诉我们这不一定是正确的。因此,即使有些人可能觉得大脑限制了他们的潜力并阻止他们学习,但科学告诉我们,学习可以在功能、连通性和结构方面改变我们的大脑。研究表明,仅了解大脑可塑性的存在就可以提高人们的学习能力。考虑以下例子:\n伦敦的出租车司机比公交车司机拥有更大的海马体(其还包含有内嗅皮层,是用于感知空间的神经回路,你也可以称之为我们身体内置的 GPS ),这是因为大脑这一区域专门用于获取和使用复杂的空间信息以有效地进行导航。出租车司机必须在伦敦的各处行驶,而公交车司机则按照有限的路线行驶。\n有趣的事实:海马体源自希语的“海马”一词,请查看上方的3D 大脑,就会明白为什么。\n通过改变大脑的功能来学习第二语言是可能的:双语者大脑左顶壁小叶比单语者大脑大。\n在运动区域、前顶顶区域和颞下区域这几个涉及演奏音乐的大脑区域中,专业音乐家的灰质(皮层)的体积最大,业余音乐家的中等,非音乐家中的最低。运动区域,前顶顶区域和颞下区域。\n有趣的事实:在秋天,松鼠的大脑会长大,因为在冬天它们需要在大脑中绘制大量关于所有隐藏坚果位置的地图。\n这使我想知道,开发人员是否具有与建筑师或财务专业人员不同的大脑。\n现在我们知道了大脑是为学习而生的,让我们进一步探讨它是如何工作的。在额叶皮层中,额叶是工作记忆所在。想想以下一串字符:\nMCB IRB RDN AFO UFV NAA\n现在想想这些:\nBBC RAF MRI UFO DNA VAN\n相同的字母,只是处在不同的集合中,但是第二个集合更容易记住。这是因为工作记忆实际上一次只能存储大约三块信息。但是如果你(尤其是你是英国人的话)已经知道 BBC 是英国广播公司,RAF 是皇家航空,那么本质上这每一条就是一条信息。\n但是,实践中,活动从工作记忆转移到更多涉及自动无意识处理的区域(远离大脑的前端)。实践有助于巩固新学的心理过程,直到我们几乎可以不加思考地完成这个过程,从而减轻了工作记忆的负担。这就是为什么 DevOps 中学习到的一部分就是改进方法。认知负荷理论假设知识以模式的形式存储在长期记忆中:模式根据信息的使用方式来组织信息元素。通过结合复杂的模式来开发熟练的性能,有效地使大脑自动化(曾经开车回家,却不记得开车回家的动作)。尽管这种自动化令人难以置信,但也解释了忘记( unlearn )这些深深植根于大脑中的模式是个挑战。\n在不断变化的思维和工作方式中,为什么不学习( unlearn )很重要?首先,人们一次只能处理一些新概念。某些事情会干扰工作记忆,从而影响学习过程。\n其中关键之一就是恐惧。杏仁核位于我们的大脑深处,通常被称为“蜥蜴脑”,因为它是早最进化的那一部,会引发战斗或逃跑反应,并支配身体产生肾上腺素和皮质醇(压力激素)。但是我们在工作中没有受到威胁。但这确实是应对社会威胁的同一系统,如果工作环境指责他人随处可见,犯错误和失败会受到惩罚,那大多数人往往会感到恐惧。\n面对变化会感到害怕。许多与我们合作的组织宣布并启动了大规模的“转型”计划,这些计将彻底改变其运营方式。但是正如 Britt Andreatta在她的《天生抵抗》( Wired to Resist )一书中所说:\n“我们大脑中的几个结构实际上旨在保护我们免受变化的潜在有害影响。人类天生抵抗变化,而我们正在处处反抗我们的生物本性。据记载,每年 50%到 70%的变革计划都会失败。”\n恐惧会引起杏仁核的皮层下活动,进而激活额叶(有意识的注意力发生的地方)中的工作记忆网络,这使学习变得更加困难,因为焦虑会分散注意力。恐惧会产生回避反应:一种阻止不愉快经历发生的反应,会避免事情发生。恐惧使学习变得更加困难,难以改变。我们必须要做的工作就是创建一个安全的环境:这个环境里,失败是个进行学习的好机会,我们可以拥有安全感以及系统的机制保护自己免受最严重、最灾难性的失败的影响。这种机制包括持续的整合/交付、自动部署、主动监控、可控影响范围和抗脆弱性能力。\n从好的方面来说,大脑也有可能表现出一种接近反应:使人更接近奖励的行为。这也是被杏仁核驱动的,并且还涉及一种激素,“快乐激素多巴胺”。期待会从大脑深处吸收神经调节剂,从而影响额叶皮层的运作方式,使大脑可以更加专注于兴奋的来源并改善对体验的记忆。使人好奇的话题可以刺激大脑奖励区域的活动,而满足好奇心本身就是个奖励:这让人感觉很好(多巴胺的作用)。共同的关注可以产生这种效果,社会学习是一个待研究的领域。\n那么我们知道奖励是好的,那么如何找到合适的奖励来激励与我们共事的人呢?神经学领导者 David Rock 的研究表明,边缘大脑(蜥蜴脑)不仅在身体受到威胁和奖励方面起作用,在社会威胁和奖励方面也同样起作用,并且在工作环境中会表现出相同的恐惧和应对方式。他假设我们每个人在不同情况下都有不同的反应,并使用 SCARF 模型来帮助了解自己和周围的人。前提是我们主要受到以下激励的其中一个驱动:\n 地位:对他人的相对重要 确定性:预测未来的能力 自治:对事件的控制感 关联性:与他人的安全感 公平:对公平交流的看法 因此,我们需要考虑与我们共事的人的需求、他们的驱动力以及如何帮助他们采用新的工作和思维方式。在进行这项工作时,可能还需要考虑镜像神经元。当我们看到某个人正在做某件事时,比如在微笑或将要与人交谈,镜像神经元就会激活,它还与移情、社交和模仿行为有关。镜像神经元是学习的基本工具,是影响人们的一种重要方式。\n将所有这些信息汇总起来,可以用于帮助组织进行变革。如果你正在组织中推动 DevOps 之类的新工作方式,我们建议你:\n 意识到(注意)这些概念 通过了解同事的兴趣、他们现有的对事情理解并观察他们对不同方法的反应,发现什么可以使他们参与进来 透过行为的研究大脑 建立心理安全感以改善学习 成为行为模范:你是一面镜子 ", "auhtor": "Helen Beal", "translator": "reneeteng", "original": "https://medium.com/itrevolution/your-devops-brain-ways-of-thinking-ways-of-working-a2b046708d3a", "poster": "Your_DevOps_Brain.jpeg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-28-docker-windows-agents/", "title": "Windows Docker Agent 镜像可以常规使用了", "type": "wechat", "date": "2020-05-28 00:00:00 +0000 UTC", "tags": ["公告", "docker", "platform-sig", "windows"], "description": "介绍了几个官方的 Windows Docker Agent 镜像", "content": " 我们想宣布可以使用官方 Windows agent Docker 镜像,这些镜像允许在 Docker 和 Kubernetes 上使用 Windows 操作系统配置 Jenkins agent。\n新镜像 现在,所有 agent 的正式 Docker 镜像都提供 nanoserver-1809 和 windowsservercore-1809 标签,其中包括 Windows 镜像以及当前的 Java 8(类似于 latest 标签)。 我们还提供了明确的 Java 选择,例如 jdk8-windowsservercore-1809 或 jdk11-nanoserver-1809。 版本标记也可用,例如 jenkins/agent:4.3-4-jdk8-nanoserver-1809。\n jenkins/agent 是一个基础的 agent,它捆绑 agent.jar 来进行 agent\u0026lt;= =\u0026gt; master之间的通讯,最有用的是可以作为其他镜像的基础镜像。Windows 镜像从版本 4.3-4 开始可用。\n jenkins/inbound-agent 是一个基于上面 jenkins/agent 镜像的 agent,它提供了用 PowerShell 编写的包装类脚本,以帮助指定 agent.jar 的参数。Windows 镜像从版本 4.3-4 开始可用。\n jenkins/ssh-agent 是一个安装了 OpenSSH 的镜像, 应该与 SSH Build Agents Plugin 一起使用。Windows 镜像从版本 2.1.0 开始可用。\n 使用 Windows Docker 镜像 要使用新镜像,您将需要支持运行 Windows 容器的合适 Docker 或 Kubernetes 环境。对于 Windows 桌面用户,最简单的方法是使用Docker for Windows。此处记录了 Kubernetes 对于 Windows 的支持。\njenkins/agent jenkins/agent 镜像是 JDK 和 agent.jar(Jenkins Remoting 库)的简单 agent。\n该镜像有两个主要用途:\n 作为其他 Docker 镜像的基础镜像(例如 Dockerfile 中的 FROM jenkins/agent:jdk8-nanoserver-1809),jenkins/inbound-agent 就是基于这个镜像。 该镜像还可用于通过 Launch agent via execution of command on the master 的 Launch method 启动agent,这允许主服务器自动在 docker 容器内启动 agent。 要针对第二个用途运行 agent,请在设置 Remote root directory 为 C:\\Users\\jenkins\\agent 后,在 Jenkins 主服务器上指定以下命令:\n docker run -i --rm --name agent --init jenkins/agent:jdk8-windowsservercore-1809 java -jar C:/ProgramData/Jenkins/agent.jar jenkins/inbound-agent inbound-agent Docker 镜像尝试提供与 agent.jar 可执行文件的更高级别的交互。它提供了一个围绕 agent.jar 的 PowerShell 包装类脚本,并且被指定为入口点,因此您只需要传递一些命令行参数即可运行 agent。已打开一个 pull request,其中记录了这些命令行参数和环境变量。\n示例:\n docker run jenkins/inbound-agent:windowsservercore-1809 ` -Url http://jenkins-server:port ` -WorkDir=C:/Users/jenkins/Agent ` -Secret \u0026lt;SECRET\u0026gt; ` -Name \u0026lt;AGENTNAME\u0026gt; 使用环境变量的示例:\n docker run -e \u0026quot;JENKINS_URL=http://jenkins-server:port\u0026quot; -e \u0026quot;JENKINS_AGENT_NAME=AGENTNAME\u0026quot; ` jenkins/inbound-agent:windowsservercore-1809 ` -WorkDir=C:/Users/jenkins/Agent ` -Secret \u0026lt;SECRET\u0026gt; ` -Name \u0026lt;AGENTNAME\u0026gt; 注意:-Url、-Name 和 -Secret 是必选参数,但可以将其指定为命令行参数或环境变量。 jenkins/ssh-agent 如上所述,jenkins/ssh-agent docker 镜像基于与主机的 SSH 通信,而不是基于远程 TCP 或 WebSocket 协议。 该镜像设置了一个 jenkins 用户和 OpenSSH 服务器,以便主服务器可以通过 SSH 连接到 agent。该镜像需要 SSH 公钥作为参数,并将该密钥放入 jenkins 用户的 authorized_keys 文件中,应在主服务器上的 agent 配置中指定私钥,以允许主服务器连接。\n示例:\n docker run jenkins/ssh-agent:jdk8-windowsservercore-1809 \u0026quot;\u0026lt;public key\u0026gt;\u0026quot; 使用 docker run 时,还可以将公钥作为环境变量传递。\n示例:\n docker run -e \u0026quot;JENKINS_AGENT_SSH_PUBKEY=\u0026lt;public key\u0026gt;\u0026quot; jenkins/ssh-agent:jdk8-windowsservercore-1809 然后,将能够作为 “jenkins” 使用 SSH Build Agents Plugin与匹配的私钥连接该 agent。\n下一步计划? 我们正在考虑提供基于 Windows Server 2019 build 1909 的版本,以便 Jenkins 用户可以在 GKE 群集上运行这些镜像(请参阅此问题)。\n我们还正在研究提供多体系结构清单,以使 Windows 镜像成为 latest 标签的一部分。\n还有一个开放的 pull-request,用于为 Jenkins 主服务器创建基于 Windows 的 Docker 镜像。对此没有很多要求,但是为了使 Windows 用户的产品完善,创建了这个 pull request。\n对于与 Windows 不相关的计划,请参阅 agent 的 Docker镜像:新名称和下一步博客文章。\n", "auhtor": "slide_o_mix", "translator": "zhaoying818", "original": "https://www.jenkins.io/blog/2020/05/11/docker-windows-agents/", "poster": "dockerJenkins_social.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-25-weekly-release/", "title": "Jenkins 每周版更新", "type": "wechat", "date": "2020-05-25 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "本次更新的版本包括:2.231~2.237", "content": " 2.237 (2020-05-18) 防止以 Java 11 运行时缺少 javax.annotation 类的导致的遥测告警(由 2.231 引入的缺陷回归)。 (issue 61920) 在类字段解组问题的情况下,防止 Old Data Monitor 插件加载失败。 (issue 62231) 确保在 UserLanguages 遥测初始化程序总是在扩展后运行。 (issue 60118) 确保 job/folder 创建事务正确检查请求的名称中是否包含无效字符。 (issue 61956) 开发者: 将 Apache Ant 从 1.10.7 更新到 1.10.8。 (pull 4725) 开发者: 将 JSTL API 库从 1.2.1 更新到 1.2.7。 (pull 4656, 变更日志更新到 1.2.5, 1.2.3 到 1.2.7 的差异, 1.2.1 到 1.2.3 的差异) 开发者: 在 Java API 中弃用 jenkins.model.Configuration。 (pull 4715) 2.236 (2020-05-11) 使插件管理可以再次支持 Internet Explorer 11 (由 2.231 引入的缺陷回归)。 (issue 62163) 安全增强: 即使没有加密的 Secret 字段支持,也始终以加密形式来回传递密码表单控制值。 如果出现问题,可以通过在启动时将系统属性 hudson.util.Secret.AUTO_ENCRYPT_PASSWORD_CONTROL 设置为 false 来禁用此功能。 (issue 61808) 安全增强: 当用户缺少“项目/配置”权限时,即使没有加密的 Secret 字段支持,也始终在项目相关的配置表单中使用占位符值作为密码表单控制值。 如果出现问题,可以通过将系统属性 hudson.util.Secret.BLANK_NONSECRET_PASSWORD_FIELDS_WITHOUT_ITEM_CONFIGURE 设置为 false 来禁用此功能 (issue 61808) 开发者: 使 SystemProperties API 可用于插件,以便它们的属性可以由标准引擎管理。 (pull 4707, Javadoc 系统属性, 受系统属性控制的 Jenkins 功能) 2.235 (2020-05-04) 当根目录 URL 配置指向先前配置的根目录 URL 时,防止表单验证出现 “404 Not Found” 错误(由 2.205 引入的缺陷回归)。 (issue 62133) 在通知告警可再次单击之前一直显示面包屑导航页面。 (issue 62065) 允许系统读取以查看更多管理员监视器。 (issue 61208) 限制某些操作(例如递归目录删除)引发的异常数。 在这之前,在极少数情况下,无法删除大目录时引发的异常会占用大量内存。 (issue 61841) 指示哪个组件提供的 URL 在全局安全配置中无需身份验证即始终可用。 (pull 4668) 解决执行 ProcessTree.get() 时的类加载问题。 (issue 62006) 开发者: 一次可以从多个特定扩展点查找扩展实现。 (issue 62056) 开发者: Add nogrid 在 layout.jelly 标签中添加 nogrid 选项,以禁止隐藏 bootstrap 3 网格。 详细信息,请参见 bootstrap4-api-plugin 。 (issue 61326) 开发者: 升级 javax.mail 为 jakarta.mail 1.6.5。 (pull 4660) 内部: 从 ReverseProxySetupMonitor 视图中删除内联资源。 当 Jenkins 根 URL 不包含 contextPath 时,添加特定的告警。 (issue 60866) 内部: 从 LogRecorder 视图中删除内联资源。 将 bigtables 的列标题向左对齐。 (issue 60866) 2.234 (2020-04-27) 修复插件管理 \u0026ldquo;Available\u0026rdquo; 页签中的排序顺序(由 2.233 引入的缺陷回归)。 (pull 4675) 重新设置帮助图标的样式。 (issue 62001) 允许具有系统读取权限的用户查看系统日志。 (issue 61207) 改写插件设置向导的“以管理员身份继续”按钮。 (issue 46669) 现在,以程序化方式(或代码化方式)创建的代理的默认执行者数量为 1 而不是 2。 (pull 4677) 会话劫持保护功能得到加强。 (issue 61738) 在具有“全局/系统读取”或“项目/扩展读取”权限的用户的只读配置表单上,区分已定义(*****)和未定义(N/A)密码。 (issue 61812) 开发者: 删除了未使用的不推荐使用的 HudsonExceptionNote。 (pull 4667) 2.233 (2020-04-20) 允许使用预填充的过滤器字段链接到插件管理 URL。 将插件管理中的标签链接到预先过滤的列表。 (pull 4591) 添加系统读取支持到管理监视器。 (issue 61208) 允许具有系统读取权限的用户查看全局工具配置。 (pull 4519) 如果更新站点提供了流行程度数据,将在 \u0026ldquo;Available\u0026rdquo; 插件管理选项卡上按流行程度对插件进行排序。 (pull 4588) 重新设置了按钮样式。 增加了对于大按钮、超链接样式按钮和图标样式按钮的支持。 (issue 61840) 跳转 Groovy 视图显示错误界面到登录表单。 当缺少必要的权限时,某些视图显示错误界面,而不是转发到登录表单。 (issue 61905) 2.232 (2020-04-16) 修复 git 插件之类的工具(这些工具会在 PATH 中搜索其可执行文件)的输入字段提示 (由 2.205 和 2.222.1 引入的缺陷回归)。 (issue 61711) 内部: 从任务视图中删除内联资源。 (issue 60866) 内部: 引入新的 Jenkins 核心维护者指南。 (pull 4472) 2.231 (2020-04-12) 将章节标题添加到 管理 Jenkins 的上下文菜单。 (pull 4586) 改善没有任务时的视图显示。 (pull 4633) Configuration as code plugin 支持配置用户时区。 (pull 4557) 默认情况下,禁止显示有关缺少可选扩展名的日志消息。 (pull 4617) 默认不是显示所有可用的插件;使用搜索字段查找插件。 (pull 4580) 允许在插件管理中使用以多个空格分隔的过滤条件。 (pull 4580) 允许具有系统读取权限的用户查看插件管理 配置。 (issue 61203) 增加对从资源根 URL 提供文件参数值的支持(如果已设置)。 (pull 4614) 在 cookie 上设置 httpOnly 标头以存储 iconSize。 (pull 4609) 修复安装向导中错误消息之间的间隔(由 2.217 引入的缺陷回归)。 (issue 61660) 在代理上创建日志条目时,请确保日志消息不缺少数字参数。 修复由 Support Core 插件收集的日志。 (pull 4621) 确保从系统日志消息中删除了编码的控制台注解。 (pull 4632) 将 crypto-util 从 1.1 更新到 1.5,以修复 Jenkins Web UI 中的许可证链接。 (pull 4631) 开发者: 将 bug 检测注解从 JSR-305 切换到 SpotBugs / net.jcp 等效项。 (pull 4604) 开发者: commons-codec 升级到 1.14。 (pull 4636) ", "auhtor": "jenkinsci", "translator": "zhaoying818", "original": "", "poster": "./2020-05-25-jenkins-release/great-wall.jpeg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-20-devops-with-docker-kubernetes-and-azure-devops/", "title": "使用 Docker、Kubernetes 和 Azure DevOps 实现 DevOps", "type": "wechat", "date": "2020-05-20 00:00:00 +0000 UTC", "tags": ["DevOps", "Docker", "Kubernetes", "Azure DevOps"], "description": "介绍了整个软件开发的发展历程,并介绍了 DevOps 的方法论", "content": " 这篇文章,我们将会分解关于你想了解的 DevOps 的所有知识,因而你可以着手构建自己的 CI/CD 流水线。\n这篇文章,我们将注意力集中于 DevOps 上。\n什么是 DevOps?它跟 Agile 有什么不同?有哪些受欢迎的 DevOps 工具?在 DevOps 中,Docker、Kubernetes 和 Azure DevOps 又是充当了什么样的角色。让我们从一个简单的使用场景开始这次的内容。\n你将会学习 什么是 DevOps?\n 为什么我们需要 DevOps?\n DevOps 和 Agile 有什么区别?\n 有哪些重要的 DevOps 工具?\n Docker 怎样能够帮助到 DevOps?\n Kubernetes 怎样能够帮助到 DevOps?\n Azure DevOps 怎样能够帮助到 DevOps?\n 什么是持续集成,持续交付?\n 什么是基础设施即代码?\n Terraform 和 Ansible 怎样能够帮助 DevOps?\n 免费课程 - 10 步速成 10 步学习 Docker\n 10 步学习 Kubernetes\n 10 步学习 AWS\n 什么是 DevOps? 与围绕软件开发的大多数流行语一样,关于 DevOps 没有公认的定义。\n简单来说可以用下面这两段文字描述,往复杂了说足以在书里面写一整页。\nDevOps 是文化理念、实践、工具的组合,能够让一个组织提升高效交付应用程序和服务的能力。- Amazon Web Services(AWS)\nDevOps 是一个组织内部的跨学科协作的概念,通过实现自动化交付新的软件版本,从而能够确保它们的正确性和可靠性。- L Leite\n与其尝试对它做定义,不如让我们来了解下软件开发是怎样一步步发展到 DevOps 的。\n瀑布模型 软件开发的头几十年都是围绕瀑布模型开展的。\n瀑布软件开发模型与实际开发房地产项目有异曲同工之处 \u0026ndash; 比如,建造一座令人惊叹的桥梁。\n你需要分多个阶段构建软件,这些阶段可以持续几个星期到几个月不等。\n大多数的瀑布项目中,企业需要数月才能等到一个能运行的应用程序版本。\n构建出色软件产品的关键因素 使用瀑布模型几十年后,我们意识到开发出色软件的一些关键因素:\n 沟通\n 反馈\n 自动化\n 沟通的重要性 软件开发是一项包含了多重技巧的跨学科的工作。\n人与人之间的沟通对软件项目的成功起到了至关重要的作用。\n在瀑布模型当中,我们尝试通过准备多达 1000 页的关于需求、设计、架构以及部署的文档来增强沟通。\n但是,使用一段时间后,我们体会到\n 团队内部增强沟通的最好方法,是团队的凝聚力。以及在同一团队获取一系列技能的能力。\n 跨部门的团队(有更多技能的)工作更出色。\n 尽快反馈的重要性 尽快得到反馈是重要的。构建出色的软件就是需要尽快得到反馈。\n我们开发的软件能够符合市场的期望吗?\n你不能等好几个月了才得到反馈。你想要尽可能快的知道。\n你的应用如果部署到生产环境会有问题吗?\n你不想等过了好几月才知道这个结果。你肯定想知道的越快越好。\n尽早发现问题,修复起来就越简单。\n我们发现出色的软件研发团队可以很快的得到反馈。我所开发的功能,我需要尽可能早的知道我是否正朝着正确的方向做这些事情。\n自动化的重要性 自动化是非常重要的。软件开发包括了很多方面的活动。手动做这些事情效率低并且容易出错。我们了解到寻求引入自动化的机会至关重要。\n在了解了怎样开发出色的软件的关键因素之后,让我们看看我们是怎样发展到 Agile 以及 DevOps 的。\n发展至 Agile Agile 是我们提升团队间的沟通,获取反馈以及引入自动化实施到我们学习内容的第一步。\nAgile 将业务与研发团队整合到一个团队当中,在称为 Sprint 的小型迭代过程中开发出色的软件。\n不同于在每次开发阶段耗费数周乃至数月,Agile 着眼于几天甚至一天内的整个开发周期中处理称为用户故事的小需求。\nAgile 是怎样促进团队间沟通的呢? Agile 将业务与研发团队整合到一起。\n 业务团队负责定义开发什么样的产品。有什么样的需求?\n 开发团队负责开发符合这些需求的产品。开发团队成员包括设计、编码、测试以及打包应用程序的人员。\n 在 Agile 中,业务代表即产品经理,总是会出现在团队中,让团队明确具体的业务目标。\n当开发团队没有很好的理解需求或者是在一条错误的方向上时,产品经理会帮助他们进行修正以帮助他们重新回到正确的轨道上。\n结果: 团队最终开发出来的产品也就是市场最终需要的产品。\n另一项重要的因素就是 Agile 团队有跨功能的技能: 编码技能(前端,API 还有数据库)、测试技能、以及业务技能。这些促进了需要一同工作并且开发出色软件的人们之间的沟通。\nAgile 和 Automation Agile 团队专注于 Automation 领域的哪方面呢?\n软件产品有多种缺陷:\n 功能缺陷意思就是产品不能如预期那样正常运行。\n 技术缺陷会造成软件维护困难。举个例子,代码质量问题。\n 总的来说,Agile 团队着眼于使用自动化来尽早的发现技术上以及功能上的缺陷。\nAgile 团队着眼于自动化测试。编写出色的单元测试来测试你的方法和类。编写出色的集成测试来测试你的模块和应用。Agile 团队同样非常关注代码质量。使用诸如 SONAR 这样的工具可以用来评估应用程序的代码质量。\n如果你有出色的自动化测试和出色的代码质量检查是否就够了呢?你可能想经常的运行它们。Agile 团队着眼于持续集成。你提交了一次变更到版本控制系统。运行单元测试、自动化测试和代码检查。这些都在持续集成流水线自动运行。在 Agile 早期阶段,比较流行的 CI/CD 工具是 Jenkins。\nAgile 是如何提升快速反馈的呢? 一个重要的因素是市场不需要等待好几个月看到最终产品。每次迭代的尾声,会给利益相关者包括架构和业务团队演示产品。得到的所有反馈会作为下一次迭代优先处理的用户故事。结果: 最终团队开发的软件就是市场需要的。\n另外一项可以迅速反馈的关键因素是持续集成。比如我提交一些代码到版本控制系统。不出 30 分钟,如果代码导致了单元测试和集成测试失败我就可以得到反馈。对不符合代码质量标准或者没有足够单元测试代码覆盖率的代码同样我也会得到反馈。\nAgile 是成功的吗?当然。通过专注于提升市场和开发团队之间的沟通以及尽早发现问题,Agile 将软件开发提升到下一个等级。\n就我个人而言,在 Agile 模型中与一些让人激动的团队一起工作是一个非常美妙的体验。软件工程,对我来说意味着从需求到最终应用程序使用中间付出的所有努力的结果,第一次,觉得编程是一种享受。\n但是,发展的脚步停止了吗?并没有。\n新的挑战出现了。\n微服务架构的转变 当我们尝试转向微服务架构,我们开始开发一些小型 API 而不是大型的应用程序。\n带来的新的挑战是什么呢?\n运维变得更重要了。不同于一个月发布一个版本,每周都要发布上百个小型的微服务。调试微服务的问题以及搞清楚微服务之间如何工作的变得非常重要。\n那时软件开发诞生了一个新的流行语。DevOps。\nDevOps 的出现 DevOps 主要聚焦哪些方面呢?\nDevOps 主要聚焦提升开发团队与运维团队之间的沟通。\n 我们怎样能让开发更容易一些?\n 怎样让运维团队的工作在开发团队那里看起来更透明?\n DevOps 是如何提升团队之间沟通的? DevOps 拉近了运维团队与开发团队之间的距离。\n 在更成熟的公司内,运维与开发团队如同一个团队。他们开始分享共同的目标,彼此也能了解对方面临的挑战。\n 一些刚开始转向 DevOps 的企业,运维团队的代表会参与到 Sprint 中 \u0026ndash; 站会以及回顾都会参与。\n DevOps 会专注于自动化的哪些方面呢? 除了 Agile 专注的领域之外(持续集成和自动化测试),DevOps 团队会专注于帮助实现一些运维团队活动的自动化,比如配置服务器、服务器上配置软件、部署应用以及监控生产环境。有一些关键术语它们是持续部署、持续交付以及基础设施即代码。\n持续部署是指的在测试环境上部署新的版本。甚至在诸如 Google、Facebook 这样成熟的公司,持续交付每天都或许可以部署上百个版本到生产环境当中。\n基础设施即代码则是将你的基础设施同你的应用程序代码等同对待。你利用配置以自动化的方式创建了这些基础架构(服务器、负载均衡器、还有数据库)。你需要对你的基础架构做到版本控制,这样你可以以后追踪基础架构的变更。\nDevOps 是怎样提升立即反馈的呢? DevOps 将运维团队和开发团队整合到一起。因为运维和开发团队是一个团队的组成部分,整个团队都能够知晓跟运维和开发团队相关的挑战。\n 任何操作的问题都能得到开发人员的注意。\n 上线软件的任何挑战都会尽早得到运维团队的注意。\n DevOps 鼓励持续集成、持续交付以及基础设施即代码。\n 因为使用持续交付,如果我产生了一次代码变更或者是一次配置变更或许会阻断测试或者是一个暂存环境,我会在几个小时内知道。\n 因为使用基础设施即代码,开发人员可以自行配置环境、部署代码、在不需要运维团队帮助的前提下自行发现问题。\n 虽然我们谈论 Agile 和 DevOps 是让事情变得简单的两种不同的事物,但事实上,对于 DevOps 是什么意思仍没有一个公认的定义。\n我把 Agile 和 DevOps 看做帮助我们提高如何开发出色软件的两种阶段。它们不是竞争关系,但是一起使用能够帮助我们构建令人惊叹的软件产品。\n就我而言,Agile 和 DevOps 一起使用的目的具体来说是\n 提升市场、研发和运维团队的沟通\n 减缓自动化的痛点。在这个课程的奇妙旅程中我们将会讨论单元测试、集成测试、代码质量检查、持续集成、持续交付、基础设施即代码以及通过容器标准化。\n 一个 DevOps 故事 话说有这样一个令人惊叹的故事:\n你是团队中的开发之星,然后你需要快速修复一个 bug。你要到 GitHub 上去看看!\n快速的检出了项目代码。\n快速的创建了本地环境。\n创建了一个变更。也测试完了。然后更新了单元测试和自动化测试。\n提交了。\n你查收到一封邮件说是它已经部署到了 QA。\n一些集成测试在自动运行。\n你的 QA 团队收到一封请求测试的邮件。他们开始手工测试然后通过。\n你的代码在几分钟内上线到生产环境。\n你或许为想这事一个理想的场景。但是,你需要知道的是这就是在诸如 Netflix、Amazon 以及 Google 这些创新公司的日常!\n这就是 DevOps 的故事。\nDevOps = Development + Operations DevOps 是软件开发的一个自然的进化。DevOps *不仅仅*是一个工具,一个框架或者仅仅就是自动化而已。它是这些东西的组合。\nDevOps 专注于人、流程和产品。DevOps 中的人指的是文化以及创造一个出色的心态 \u0026ndash; 一种促进开放交流以及快速反馈的文化,一种创造高质量软件的文化。\nAgile 则帮助在市场和开发团队之间架设桥梁。开发团队了解市场的优先级同市场一道传递最有价值的故事。然而,Dev 和 Ops 并没有保持一致。\n他们有不同的目标。\nDev 团队的目标是将尽可能多的功能添加到产品中。\nOps 团队的目标是保持生产环境越稳定越好。\n如你所见,如果产品进入市场这么难的话,开发和运维团队就没法达成一致。\nDevOps 目标是让 Dev 和 Ops 团队通过一些相同的目标凝聚到一起。\nDev 团队与 Ops 团队一同工作能够了解和解决运维中遇到的挑战。Ops 团队是 Scrum 团队的一部分能够了解到开发功能的一些事情。\n我们怎样能让其实现呢?\n打破 Dev 和 Ops 之间的隔阂!\nDev Ops 在一起 - 情景 1 在有成熟的 DevOps 企业里,Dev 和 Ops 作为 scrum 团队的组成部分彼此分担责任。\nDev Ops 在一起 - 情景 2 然而,如果你处于转至 DevOps 的初始阶段,怎样让 Dev 和 Ops 团队有共同的目标并且一起工作呢?\n这里有一些你需要去做的事情:\n 第一件事你可以开始着手做的就是让运维团队分享一些工作任务给开发团队。例如,开发团队可以负责产品上线的一周后新版本的发布工作。这能帮助开发团队了解到运维团队在上线新版本面对的挑战并且可以协助他们探索更好的解决方案。\n 另一件你需要做的就是将一名运维团队的成员参与到 Scrum 日常活动中。让他们参加团队的站会以及总结会。\n 下一件你可以做的事情就是让运维团队面临的问题能更清晰的呈现给 Development 团队。当你在运维方面遇到问题的时候,可以让开发团队中的一部分成员成为解决方案团队的一部分。\n 不管你要做哪一件事情,找到一条打破开发和运维团队共同工作的隔阂的方法。\n因为自动化另一个有趣的情景出现了。通过使用基础设施即代码以及 开发自行配置,你可以创造一个不论开发还是运维都能理解的语言 - 代码。细节会在下面的几个步骤中再做说明。\n一个 DevOps 使用场景 思考下面的图片:\n这张图片展示了两个简单的工作流\n No 1: 使用 Terraform 和 Azure DevOps 为 Kubernetes 配置基础设施即代码。\n No 2: 微服务持续部署: 使用 Azure DevOps 构建部署微服务的 Docker 镜像到 Kubernetes Cluster\n 听起来很复杂是吗?\n让我们试着分解然后再去理解一下。\n让我们先从 No 2 \u0026ndash; 持续部署开始。\n使用 Azure DevOps 和 Jenkins 实现 DevOps 持续部署 如果有出色的测试和代码质量检查但不经常运行它们的话那它们还有什么用呢?\n如果你有自动部署但是不常部署软件的话那它还有什么用呢?\n只要开发人员提交代码到版本控制系统,下面的步骤就会被执行:\n 单元测试。\n 代码质量检查。\n 集成测试。\n 应用程序打包 \u0026ndash; 推出新的应用程序或者上线新版本的应用程序。\n 给测试团队发送测试应用程序的邮件\n 一旦得到了测试团队的允许,应用就立即部署到下一个环境。\n这被称作持续部署。如果你持续部署到生产环境,则称作持续交付。\n最受欢迎的 CI/CD 工具是 Azure DevOps 和 Jenkins。\nNo 1 : 使用 Terraform 实现 DevOps 基础设施即代码 过去,我们手动创建环境还有部署应用程序。\n每次创建一个服务器,这些就需要手工做完。\n 如果 Java 版本需要更新怎么办?\n 需要应用一个安全补丁吗?\n 你需要手动做。\n结果是什么呢?\n 非常有可能会出错。\n 复制环境非常困难。\n 基础设施即代码 基础设施即代码 \u0026ndash; 将基础设施等同于应用代码。\n这里有几个理解基础设施即代码比较重要的知识点\n 基础设施团队专注于能够增值的工作(而不是日常工作)。\n 更少的错误可以更快的从失败中恢复。\n 服务器是一致的(避免了 Configuration Drift)。\n 最受欢迎的 IaC 工具是 Ansible 和 Terraform。\n一般来说在 IaC 中有这样几步\n 从一个模板中配置服务器(通过 Cloud 启用)\n 安装软件\n 配置软件\n 服务器配置 一般来说,配置工具用在配置服务器上起到让服务器具备网络功能的作用。最受欢迎的配置工具是 CloudFormation 和 Terraform。\n使用 Terraform,你可以配置服务器以及其他的基础设施,比如负载均衡器、数据库、网络配置等。你可以使用类似 Packer 和 AMI(Amazon Machine Image)工具预创建的镜像创建服务器。\n配置管理 配置管理用来\n 安装软件\n 配置软件\n 受欢迎的配置管理工具有 Chef、Puppet、Ansible 和 SaltStack。这些被设计用作在已有服务器上安装管理软件。\nDocker 和 Kubernetes 在 DevOps 中的角色 Docker 和 Kubernetes 在DevOps 起到的角色是什么样的?\n在微服务世界,一些微服务使用 Java 构建的,一部分是用的 Python,一部分是用 JavaScript。\n不同的微服务在构建应用程序以及部署到服务器上也是各不相同。\n这就让运维团队的工作变得很困难。\n我们怎样能找到一个类似的方法可以部署多种类型的应用程序呢?来说说容器和 Docker 吧。\n使用 Docker,你可以构建微服务镜像 \u0026ndash; 不论语言是什么。你可以运行在任意基础设施上使用相同的方法运行这些镜像。\n这样简化了操作。\nKubernetes 在这个基础上添加了编排不同种类的容器和部署它们到集群的功能。\nKubernetes 同样提供了:\n 服务发现。\n 负载均衡。\n 集中配置。\n Docker 和 Kubernetes 让 DevOps 更简单。\n重要的 DevOps 指标 以下是几个你可以在一段时间内跟踪和提升的比较重要的 DevOps 指标项。\n 部署频率 - 隔多长时间就会部署一次应用程序到生产环境中?\n 投入市场的时间 - 将一个特性从编码到最终的产品需要耗费多长时间?\n 新发布版本的失败率 - 多少个发布版本是失败的?\n 修复时间 - 从需要修复产品问题到发布到生产环境需要多长时间?\n 平均恢复时间 - 生产环境从一个关键问题中恢复需要多长时间?\n DevOps 最佳实践 以下为一些 DevOps 的最佳实践\n 标准化\n 有跨部门技能的团队\n 聚焦文化\n 自动化,自动化,还是自动化\n 不变的基础设施\n 开发生产等同\n 版本控制所有事物\n 自行配置\n DevOps 成熟的标志 应该怎样度量 DevOps 集成的成熟度呢?这里有一些关键的问题需要解答。\n开发 每次提交都会自动触发自动化测试和代码质量检查吗?\n 你的代码都持续分发到生产环境了吗?\n 你使用结对编程吗?\n 你使用 TDD 和 BDD 吗?\n 你是否有许多复用的模块?\n 开发团队可以自己配置环境吗?\n 快速修复生产环境的问题需要耗费多长时间?\n 测试 你是否使用高质量的类似生产环境的数据执行完整的自动化测试?\n 当你的自动化测试失败的时候你的构建是失败的吗?\n 你的测试周期短吗?\n 你有自动 NFR 测试吗?\n 部署 你有开发生产等同吗?\n 你有使用 A/B 测试吗?\n 你有使用金丝雀部署吗?\n 你能按下按钮就可以开始部署吗?\n 你能按下按钮就可以执行回滚吗?\n 你能按下按钮就可以配置和发布基础架构吗?\n 你可以为你的基础架构使用 IAC 和版本控制吗?\n 监控 团队使用的是一个集中监控工具吗?\n 开发团队可以按下按钮就可以获得日志吗?\n 生产环境出现问题时团队能自动收到报警吗?\n 团队和流程 团队看起来是持续改进的吗?\n 团队是否拥有业务、开发、和运维的全部技能?\n 团队是否跟踪 DevOps 的关键指标然后去改进它们吗?\n 你是否使用本地发现并用它们进一步实现全球改进的文化?\n DevOps 转换最佳实践 领导力积累至关重要\n 包括前期成本\n 设置 COE 以帮助团队\n 选择正确的应用程序和团队\n 从小开始\n 分享学习心得 (时事、沟通、COE)\n 以探索和自动化的思维方式激励人们\n 认可 DevOps 团队\n 在你离开本文之前 \u0026ndash; 我们令人惊叹的 DevOps 课程 如果你喜欢这篇文章,你应该也会喜欢我们关于 DevOps 的课程\n 200+ 视频。\n 20+ 小时。\n 6 DevOps 工具 - Docker、Kubernetes、Azure DevOps、Jenkins、Terraform、and Ansible。\n 3 不同的云平台 - AWS、Azure and Google Cloud。\n ", "auhtor": "Ranga Karanam", "translator": "0N0thing", "original": "https://dzone.com/articles/devops-tutorial-devops-with-docker-kubernetes-and", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-19-jenkins-kubesphere-partner/", "title": "Jenkins 中文社区携手 KubeSphere,共建 DevOps 技术生态", "type": "wechat", "date": "2020-05-19 00:00:00 +0000 UTC", "tags": ["jenkins", "kubesphere", "devops", "open source"], "description": "KubeSphere 与 Jenkins 中文社区强强合作,加速企业 DevOps 落地", "content": " 今天,Jenkins 中文社区 与 KubeSphere 开源社区 联合官宣,两大开源社区从今天开始正式合作,携手共建 DevOps 技术生态!\n4 月 14 日,Jenkins 中文社区负责人 Rick 与 KubeSphere 社区多名成员,在技术层面、内容层面、开源社区建设等三个方向进行深入地探讨,最终对两个社区的合作不约而同地达成了一致。\n在此次交流会上,KubeSphere 社区 Maintainer @runze xia 先向 Jenkins 中文社区介绍了 KubeSphere DevOps 的技术实现方案,以及为什么采用 Jenkins 作为 KubeSphere DevOps 的引擎。同时,Rick 也向 KubeSphere 社区介绍了 Jenkins-formulas 项目,该项目将来可用来替换 KubeSphere 当前的 Nginx 作为下载插件的 Update Center 方案。\n并且,两个社区还将在开源协作与技术内容输出方向共同努力,为社区的开发者和用户带来 DevOps 相关的优质技术文章与实践案例。当然,有一些开发者和社区用户表示,两个社区都开始紧密合作了,两个社区的小伙伴们是不是要约时间面基了?这些要求我们都可以统统安排上!两大社区后续计划联合举办线上的技术直播分享活动、在线研讨会,以及线下 Meetup,欢迎社区小伙伴持续关注我们的动态。\n交流会后,Rick 表示自己非常希望加入 KubeSphere 社区,参与 KubeSphere 社区贡献。KubeSphere 社区非常欢迎 Jenkins 中文社区的所有对 KubeSphere 与云原生技术兴趣的同学参与社区开发和文档贡献,KubeSphere 所有的代码、文档、沟通均在 GitHub、Slack 和论坛可见,对于 Jenkins 爱好者我们还在社区设立了 SIG-DevOps 供开发者交流,欢迎大家加入 Slack Channel。\n关于 Jenkins 中文社区 Jenkins 中文社区是由 Jenkins 国内的爱好者、贡献者 组成,共同推广以及完善 CI/CD 技术的学习试用和落地。Jenkins 中文社区秉承开源的精神,在社区治理上高度开放,代码、文档以及设计等开源免费,致力于为 Jenkins 用户带来更好的体验。\n为了能让 Jenkins 的技术爱好者、用户有个方便讨论、学习的场所,我们提供了社区论坛、微信群。另外,在我们定期的网络研讨会上,会邀请业界的讲师来分享关于 DevOps 的技术话题。回放的视频可以在哔哩哔哩上找到。除了线上、线下的交流活动的内容外,社区还有很多志愿者提供的原创、翻译博文会在社区官网、Jenkins 官方微信公众号上发布,并在开源中国、知乎等平台进行转载。\n另外,本着以开源技术服务开源用户的精神,社区还维护着多个开源项目,包括:Jenkins 国内定制发行版、Jenkins CLI、简体中文插件。\n欢迎大家访问 Jenkins 中文社区官网 了解如何参与 Jenkins 中文社区的交流与贡献!\n关于 KubeSphere 开源社区 最近几年时间,CNCF 基金会主导的云原生社区不断孵化和涌现了大量的开源项目,以 Kubernetes、Prometheus 为代表的诸多开源项目已被全球企业广泛采用,云原生软件的发展颠覆了传统的基础设施架构。但是,当用户在实际测试生产环境中管理与运维大量的云原生工具,并且在不同的 GUI 和 CLI 来回切换时,会有非常大的复杂性和较高的学习成本,并且这些组件的存储、网络、安全和易用性等问题也成为了企业在云原生实践落地的痛点。\n为了解决这些问题,KubeSphere 应运而生。作为云原生家族的的后起之秀,KubeSphere 坚持完全开源和开放的迭代思路,联合多个企业与开源社区,共同打造了以 KubeSphere 容器平台为核心的开源项目,还开源了 Porter、OpenPitrix、Fluent-bit Operator、CSI 插件等一系列开源项目,同时运营 KubeSphere 开发者论坛 与微信群。KubeSphere 开源社区尚处建设初期,我们希望不断完善与壮大开源社区,培养以开发者为核心的国际化的社区生态。\n至今,KubeSphere 容器平台已被 Aqara 智能家居、本来生活、微众银行、新浪、云智汇、VPG Corporation 等海内外的数千家企业采用。\n欢迎大家访问 KubeSphere 官网,安装使用 KubeSphere 以及参与社区交流与贡献。\n", "auhtor": "FeynmanZhou", "translator": "", "original": "", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-18-docker-agent-image-renaming/", "title": "Jenkins agent Docker 镜像重新命名了,你知道吗?", "type": "wechat", "date": "2020-05-18 00:00:00 +0000 UTC", "tags": ["announcement", "docker", "jenkins", "platform-sig"], "description": "本文介绍了 Jenkins agent Docker 镜像新名称、重新命名的缘由、升级说明以及下一步计划", "content": " 我们正式宣布对 Jenkins agent 官方 Docker 镜像重新命名。 它不会对 Jenkins 用户产生任何直接影响,但是希望他们逐渐升级其实例。 本文提供了新的镜像名称、升级过程以及旧镜像支持策略等相关信息。 我们还将讨论在 Jenkins 中 Docker 包的下一步计划。\n新镜像名称 jenkins/agent 是旧的 jenkins/slave 镜像从 4.3-2 开始的新名称 jenkins/inbound-agent 是旧的 jenkins/jnlp-slave 镜像从 4.3-2 开始的新名称 jenkins/ssh-agent 是旧的 jenkins/ssh-slave 镜像从 2.0.0 开始的新名称 请参阅下面的升级指南。\n为什么要重新命名? \u0026ldquo;slave\u0026rdquo; 一词在开源社区中被广泛认为是不合适的。它已于2016年在 Jenkins 2.0中正式弃用,但在某些 Jenkins 组件中仍有遗留用法。 这个 Epic —— JENKINS-42816:Slave 到 Agent 的重命名遗留问题 用于跟踪此类问题的清理。 官方 Docker agent 镜像是一个显而易见的案例,要修改在 DockerHub 上的旧版本镜像并非易事。很高兴这次更新终于解决了镜像命名问题。\n另一个值得注意的变化是使用 inbound agent 代替 JNLP agent 术语。 历史上,\u0026rdquo;JNLP\u0026rdquo; 已被用作远程协议的名称。 JNLP 代表 Java Network Launch Protocol,它是 Java Web Start 的一部分。 在 Java 1.8 上运行 agent 时,Jenkins 支持 agent 的 Java Web Start 模式,但是我们的网络协议基于 TCP 的,与 Java Network Launch Protocol 无关。 此名称从一开始就非常混乱,随着 Jenkins 2.217(JEP-222)中引入 WebSocket 支持而变得更糟。 Docker agent 镜像支持 WebSockets,因此我们决定将镜像名称更改为 jenkins/inbound-agent,这样可以防止进一步的混乱。 Inbound agent 术语是指 agent 协议,其中 agent 通过不同的协议启动与 Jenkins master 的连接。\n非常感谢 Alex Earl 和 krufab 进行的存储库重组工作,这使重命名成为可能!还要感谢 Tim Jacomb、Marky Jackson、Mark Waite、Ivan Fernandez Calvo 和其他贡献者的评审和测试。\n升级和兼容性说明 好消息是此命名不会引起重大变化。所有镜像已被修改为在内部使用新术语。 如果使用以前镜像的最新版本,那么可以使用新名称替换就名称。 这些名称可以在 Dockerfile、脚本和 Jenkins 配置中引用。\n我们将继续在 DockerHub 上更新旧镜像至少3个月(直到2020年8月5日)。 不会在旧镜像中添加任何新配置和平台,但是所有现有配置和平台都将保持可用( Java 1.8的 Debian 和 Java 1.8的 Alpine,等等)。 2020年8月5日之后,旧镜像将不再接收更新,但以前的版本将仍然对 DockerHub 的用户可用。\n下一步计划是什么? 我们将继续在 Jenkins 组件中重命名引用旧镜像名称的 Docker 镜像。 还有一组便利的 Docker 镜像,其中包括 Maven 或 Gradle 之类的构建工具,这些工具将在以后重命名。 该 jenkins/ssh-agent 镜像将来也可能会重命名;请参阅此开发人员邮件列表线程中正在进行的讨论。\n如果您对 Jenkins Docker 包中的新功能非常感兴趣,请继续关注未来的公告! 您可以在 Jenkins 公开路线图中 找到多个正在进行的计划 (在草案阶段,请参阅 JEP-14)\n一些故事:\n Windows 镜像的一般可用性。 支持更多平台(AArch64、IBM s390x、PowerPC)。 切换到 AdoptOpenJDK。 引入多平台 Docker 镜像。 如果您对这些项目中的任何一个感兴趣并想做出贡献,请联系 Platform Special Interest Group,该小组负责协调与 Docker 中的 Jenkins 相关的计划。\n关于 Docker 镜像之外的 agent 术语清除,我们将继续在 Advocacy&Outreach SIG 中进行此项目。 如果您在 Jenkins 组织中的任何地方(Web UI、文档等)看到过时的 \u0026ldquo;slave\u0026rdquo; 术语的使用,请随时提交 pull request 或在这个 Epic —— JENKINS-42816:Slave 到 Agent 的重命名遗留问题中报告问题。 在 jenkinsci GitHub 组织中恰好有 3000个问题,但我们会完成这个目标。 对于任何贡献将不胜感激!\n", "auhtor": "Oleg Nenashev", "translator": "donhui", "original": "https://www.jenkins.io/blog/2020/05/06/docker-agent-image-renaming/", "poster": "dockerJenkins.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-16-a-thank-you-letter-for-jenkins-fans/", "title": "致广大Jenkins 中文社区关注者的感谢信", "type": "wechat", "date": "2020-05-16 00:00:00 +0000 UTC", "tags": [], "description": "致广大Jenkins 中文社区关注者的感谢信", "content": " 故事要从 2020/5/12 社区公众号发布的文章 手把手教会你 Jenkins 备份与恢复 说起。\n1-先从故事本身说起 5月12日,公众号发布了一篇有关 Jenkins 备份与恢复的文章,其中分享了以下一段备份 Shell 脚本:\n#!/bin/bash # Jenkins Configuraitons Directory cd $JENKINS_HOME # Add general configurations, job configurations, and user content git add -- *.xml jobs/*/*.xml userContent/* ansible/* # only add user configurations if they exist if [ -d users ]; then user_configs=`ls users/*/config.xml` if [ -n \u0026quot;$user_configs\u0026quot; ]; then git add $user_configs fi fi # mark as deleted anything that's been, well, deleted to_remove=`git status | grep \u0026quot;deleted\u0026quot; | awk '{print $3}'` if [ -n \u0026quot;$toremove\u0026quot; ]; then git rm --ignore-unmatch $toremove fi git commit -m \u0026quot;Automated Jenkins commit\u0026quot; git push -q -u origin master 文章格式核对完成后,便在公众号上发布了。\n2-火眼金睛出现了 5月13日,微信公众号有一昵称为\u0026rdquo;奋斗”的小伙伴给我们留言,指出了文中的一处错误:\n我们仔细核对后,发现脚本确实存在错误,并立马修改为正确的版本,目前修改后的文章已发布。 对“奋斗”小伙伴的反馈再次表示感谢!\n3-故事引发的几点感想 1.由于我们在发布文章时检查不够细致导致发布文章有误,给各位带来的困惑,在此对各位社区关注者表示歉意。\n2.我们相信,还有很多小伙伴一直密切关注着 Jenkins 中文社区的发展及动态,欢迎每一位关注社区的人来监督并提出宝贵意见。\n关于我们 我们是由Jenkins国内爱好者、贡献者自发组建的一个技术社区,致力于共同推广以及完善 CI/CD 技术的学习使用和落地。\n我们尊重每一位技术人的梦想,真诚的欢迎每一位对Jenkins、CI/CD 或开源社区感兴趣的小伙伴加入我们,共同推广以及完善 CI/CD 技术的学习试用和落地。\n", "auhtor": "zhouyou", "translator": "", "original": "", "poster": "cover.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-15-call-for-user-stories-jenkins-is-the-way/", "title": "征集用户故事- Jenkins is the Way", "type": "wechat", "date": "2020-05-15 00:00:00 +0000 UTC", "tags": ["announcement", "outreach-programs", "advocacy-and-outreach"], "description": "Jenkins 社区通过 Jenkins Is the Way 的活动征集用户使用 Jenkins 的故事。", "content": " Jenkins Is The Way 参加开发者大会最让我们喜欢的一件事就是与 Jenkins 用户(无论是新手还是老用户)见面。用户们高兴地谈论自己的项目,分享如何使用 Jenkins 推进项目的技巧。自从冠状病毒大流行以来,我们正更多地依靠新的方式聚集起来,比如通过 Jenkins 在线聚会,GitHub 合作以及 Twitter threads。\n这是一个重大的改变。但不变的是,分享用户构建的故事、解决方案,以及在实施 Jenkins 中获得的出色成果的这一需求。我们好奇,为什么没有人收集这些用户故事并与 Jenkins 社区分享。\n引入 Jenkins Is The Way 因此,我们迈出了第一步,把社区中每个人用 Jenkins 创造的所有很棒的东西进行记录和存档。这样,Jenkins 的新老用户都可以使用这个存档搜索 Jenkins 解决方案以获取灵感。我们预见将会建成一个庞大的来自世界各地的解决方案的库,解决可以想象到的各个行业中的各种困难与挑战。我们决定将该档案称为“Jenkins Is The Way”,并将托管在 https://JenkinsIsTheWay.io 上。\n为了汇总这些故事,我们创建了一个简单的在线问卷,以便 Jenkins 用户可以使用这个领先的开源自动化服务器提交自己的经验故事。拥有如此多的插件来支持构建、部署和自动化大家的项目,我们期待收集大量的故事。\n我们已经收到了一些,包括一些说明了为什么 Jenkins Is The Way 的故事:\n 可以编写自己的发布流水线\n 可以创造持续交付\n 可以理解并简化软件生命周期\n 可以简化云端自动化\n 可以促进日常工作\n 添加您的故事,展示使用 Jenkins 的骄傲成果,获得 T 恤衫 通过分享您的 Jenkins 故事,成为可以激发 Jenkins 社区的灵感。只需访问此链接并填写表格即可。我们将会询问您的项目目标,使用 Jenkins 克服的技术挑战以及所创建的解决方案。只需20-30分钟就可以完成填表。\n我们将故事整理并将其发布在 https://JenkinsIsTheWay.io 上。\n被存档后,我们将向您发送2020年 Jenkins Is the Way T 恤。\n越多越快乐。所以,请与同行和同事分享此博客文章。我们想听听每个人是如何巧妙使用 Jenkins 来实现自动化的故事。\n感谢与致谢 特别感谢 abConsulting 创建和管理 https://JenkinsIsTheWay.io 网站,以及审阅、编辑和发布提交的故事。\n感谢 Jenkins 倡导和外联 SIG 的评论和反馈。\n感谢 CloudBees 赞助了 Jenkins is the Way 项目。\n", "auhtor": "Alyssa Tong, Mark Waite", "translator": "reneeteng", "original": "https://www.jenkins.io/blog/2020/04/30/jenkins-is-the-way/", "poster": "jenkins-is-the-way.png" }, { "uri": "https://jenkins-zh.cn/meeting/2020-05-13/", "title": "", "type": "meeting", "date": "2020-05-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " UCloud 服务器管理 Nexus 上线了 http://repo.jenkins-zh.cn/ https 有问题 企业合作 KubeSphere 5月19日 官宣 https://github.com/jenkins-zh/jenkins-zh/pull/252 中信 招聘信息的发布(论坛) 技术活动没有确定 句子互动 作为赞助商 提供了一年的套餐 https://github.com/jenkins-zh/jenkins-zh/pull/271 禅道 技术分享 5月20日 有礼品赞助 文章的贡献(原创、翻译) 杰蛙 5月23日下午(周六),沙龙 F5 Nginx 中文社区成立的官宣 著作权 * 翻译文章不能算是原创(个例,来自 jenkins.io 可以在公众号里申明为原创) * 在社区提供的翻译稿,在我们的公众号上首次发布 * 应该说明作者、翻译者等的具体版权说明 社区激励 推文 https://github.com/jenkins-zh/jenkins-zh/issues/237 社区媒体账号运营情况 简书 @yJunS 开源中国 微博 公众号 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-13-using-nexus-oss-as-a-proxy-cache-for-docker-images/", "title": "使用 Nexus OSS 为 Docker 镜像提供代理/缓存功能", "type": "wechat", "date": "2020-05-13 00:00:00 +0000 UTC", "tags": ["Nexus OSS", "Docker"], "description": "通过具体操作步骤讲解了如何使用 Nexus OSS 作为中间仓库获取互联网上的 Docker 镜像", "content": " 在企业环境中工作,无论是商业组织还是非商业组织,你会发现在互联网上获取信息存在着种种限制。\n通常,服务器会运行在一个控制非常严格的环境中并且不能从互联网中获取资源以确保获取的所有资源都是安全的。\n当你要使用一些公开的可获取的 Docker 容器时这会变得更麻烦,你会用到“古法”偷偷摸摸的把 Docker 镜像放到你的主机上。\n对我而言,事情甚至更加困难。我需要一个通过第三方访问的(受限的)私有仓库。所以现在我该怎么办呢?\n幸运的是,目前市面上有好几个可以作为代理或者‘拉入式缓存’的 Docker Registries,这正是我们所需要的。用来作为代理或者缓存的主机需要互联网的权限,而且只有这一台机器需要。其他所有需要获取 Docker 镜像的主机通过这台机器访问互联网,该机器同样很方便的缓存了数据这样只需要检索一次就可以更快的分发到内部局域网的主机上。\n诸如 Sonatype Nexus、JFrog Artifactory、甚至 Docker Registry 都提供这些确切的功能,以及一些功能。这里我将会使用 Sonatype Nexus 完成所有的设置,主要的功能在 OSS 版本中可以使用(Artifactory 功能则是 Pro 版本的一部分功能)。\n这篇文章将会向你展示怎样配置 Nexus OSS 来实现类似 Docker Hub ,私有仓库或者两者的结合那样的拉入式缓存功能。同样会向你展示怎样配置 Docker 客户端从而在检索镜像的时候能够使用到你的缓存。\n需要的软件 Sonatype Nexus OSS 3.15.0(或更高版本)\n Docker 17.09(或更高版本)\n 我设置了两个基于 Ubuntu LTS 版本的虚拟机,一个运行了 Sonatype Nexus 3.14.0 的 Docker 容器(这个机器称作 docker-host),另一个只运行 Docker(称作 docker-client)。\n请注意一些网络配置或许跟你的配置不一样(例如 IP)但是方法是相同的。同样,请注意那台运行 Nexus OSS 的机器(docker-host)需要有访问互联网的权限。\n[更新,2018年10月] 请使用 Nexus 3.15 或者更高版本因为从 3.14 到 3.15 中间修复了多个 CVE 的漏洞问题。\n配置 Nexus OSS 我们在 Nexus 中至少配置 3 样东西,给仓库命名,以及一些安全配置。请记住在公司中不要按照这些方法来做,因为可能会考虑到一些性能问题,比如修改 Blobstore 配置。\n为 Docker Hub 添加 Docker Proxy Repository 使用有管理员权限的账号登录到你的 Nexus 实例,转到 Admin 页面。点击 Repository -\u0026gt; Repositories,然后点击 ‘Create repository’。\n选择‘docker(proxy)’然后开始配置。\n你需要为这个 Proxy 添加一个唯一的名字,确保它是 ‘Oneline’ 状态。\n为了避免我们在危险的边缘试探,我们不会为这个 Repository 提供 V1 API(勾掉 ‘Enable Docker V1 API’ 选项),但我们是允许匿名访问的权限的。\n这非常重要,所以再次强调下:\n勾掉 ‘Force Basic Authentication’。\n这会允许我们的 Docker Clients 在不需要提供凭据的前提下访问我们的 Repository。这是最简单的方法了!\n在 ‘Proxy’ 下面输入如下信息:\nRemote storage: https://registry-1.docker.io/\nDocker Index: Use Docker Hub\n所有的配置信息如下所示。\n为 Private Repository 添加 Docker Proxy Repository(可选) 该部分是可选环节,这要取决于在 Docker Cloud 中怎样访问你的私有仓库。\n仍旧是创建一个唯一的名字,设置为 ‘oneline’,禁止 V1 API,允许匿名访问,在 ‘Proxy’ 下面输入如下信息:\nRemote storage: https://registry-1.docker.io\nDocker Index: Use proxy registry\n不同的地方是在页面底部的 Authentication-部分,你需要在该位置输入可以访问 Docker Cloud 私有仓库的用户名跟密码。\n所有配置如下所示。\n为 Docker Repository 添加 Group 组可以为多个仓库提供一个单独的权限。这是 Docker 所不具备的功能,当 Docker Client 尝试访问 Docker Hub 时,这是唯一访问的入口。\n当我们不想让它只包括 Docker Hub 还想包括其他我们想要的仓库(例如 私有的 Docker Cloud 仓库、我们内部局域网托管的 Docker 仓库,等等)时,所有检索到的 Docker 镜像都可以通过 Nexus 传输,不需要 Client 知道去哪里查看哪个镜像。\nRepository Group 仅仅是一个 Repositories 的集合,但是我们需要 Docker Client 能够与它通信。\n添加一个唯一的名字,设置为 ‘oneline’,禁用 V1 API,允许匿名访问权限。\n我们需要配置一个 Repository Connector,它为 Repository Group 存储的内容提供了可访问的端口。我选择使用 8181(Nexus 默认端口为8081)并且只配置 HTTP 因为我真的太懒了不想配置 HTTPS 的了。:)\n你需要选择 Docker Repository(一个托管的仓库或者一个代理亦或为另一个组)作为这个 Group 需要的 Members,然后保存配置。\n所有的配置如下所示。\n配置安全设置 为了确保匿名权限可以正常访问我们的仓库,我们需要在 Nexus 中添加‘Docker Bearer Token Realm’ 到 Active Realms 中。\n切换到 Administrator -\u0026gt; Scurity -\u0026gt; Realms 然后选择 ‘Available’ Realms 列表中的 Realm。点击右侧的箭头按钮然后保存。\n齐活儿!\n配置 Docker Client 现在我们的 Nexus 实例已经成功配置了,需要确保我们的 Docker Client 可以从这个地方获取所有的 Docker 镜像,而非互联网。\n这需要我们配置 Docker Client Daemon,能让它们将 Nexus 作为镜像源。还有,因为它使用的是 HTTP 而非 HTTPS 我们需要 Docker 能够理解该协议是可以的并且可以通过 Nexus 查看镜像。\n使用 root 用户,创建或者是编辑下面的文件: /etc/docker/daemon.json\n{ \u0026quot;insecure-registries\u0026quot;: [\u0026quot;10.0.2.2:8181\u0026quot;], \u0026quot;registry-mirrors\u0026quot;: [\u0026quot;http://10.0.2.2:8181\u0026quot;] } 需要注意的是,这会跟你配置的有较大差别,因为我运行的虚拟机。这个 IP 是我主机上 VM1 出来映射用来解决 VM2 上的问题的 IP。\n如果需要的话,你可以安全的将你的 主机名或者 IP 替换为 10.0.2.2。请做全量替换。\n文件保存后,Docker 需要重启。如果成功: docker info 命令信息会如下图所示:\nInsecure Registries: 10.0.2.2:8181 127.0.0.0/8 Registry Mirrors: http://10.0.2.2:8181/ 大功告成! 现在你可以在 Docker Client 不需要访问互联网的前提下从 Nexus 获取 Docker 镜像了。\ndocker pull mysql 它会在 Nexus 的 Docker Group Repository 中显示出来,你会看到缓存的 blobs,标签和清单。\n", "auhtor": "Maarten Tijhof", "translator": "0N0thing", "original": "https://mtijhof.wordpress.com/2018/07/23/using-nexus-oss-as-a-proxy-cache-for-docker-images/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-12-how-to-backup-and-restore-jenkins/", "title": "手把手教会你 Jenkins 备份与恢复", "type": "wechat", "date": "2020-05-12 00:00:00 +0000 UTC", "tags": ["Jenkins", "CI/CD"], "description": "手把手教你如何完成 Jenkins 备份和恢复", "content": " 前言 Jenkins 是一个 Java 语言编写的开源工具,结合持续集成与持续交付相关技术的运用可提升软件开发过程的自动化水平。\nJenkins 从最开始安装到权限设置,插件安装,任务维护等是一个费力的工程,因此定期备份数据的重要性不言而喻。\n在本文中,我们将手把手演示如何备份并恢复 Jenkins。\n备份操作指引 Step1:创建一个新的任务 这里推荐自由风格任务类型,即 Freestyle project\nStep2:源码管理选择 None Step3:设置任务执行时间 选择 “Build Periodically”,然后可以根据需要设置备份时间和频率\n例如,25 12 * * * 会在每天白天 12:25 运行任务\nStep4:Build 模块添加 “Execute Shell” 在 Build 模块选择 Execute Shell,添加以下脚本内容\n为方便读者直接使用,脚本内容如下:\n #!/bin/bash # Jenkins Configuraitons Directory cd $JENKINS_HOME # Add general configurations, job configurations, and user content git add -- *.xml jobs/*/*.xml userContent/* ansible/* # only add user configurations if they exist if [ -d users ]; then user_configs=`ls users/*/config.xml` if [ -n \u0026quot;$user_configs\u0026quot; ]; then git add $user_configs fi fi # mark as deleted anything that's been, well, deleted to_remove=`git status | grep \u0026quot;deleted\u0026quot; | awk '{print $3}'` if [ -n \u0026quot;$to_remove\u0026quot; ]; then git rm --ignore-unmatch $to_remove fi git commit -m \u0026quot;Automated Jenkins commit\u0026quot; git push -q -u origin master Step5:保存以上设置 Step6:初始化本地 git 仓库 我们现在已经添加了一个备份所有 Jenkins 数据的任务,所有的备份数据将会存储到服务端的 /var/lib/jenkins 目录。\n假如目前有一个用户名为 jenkins,进入此目录,执行以下命令\ncd /var/lib/jenkins \u0026amp;\u0026amp; git init\nStep7:本地仓库关联 GitHub git remote add origin git@github.com:username/new_repo\nStep8:测试备份任务是否生效 Jenkins 任务主页,点击 Build now 按键。如果看到以下输出,说明备份任务已成功创建并生效。\n数据恢复操作指引 Step1:清空 Jenkins 主目录 cd /var/lib/jenkins \u0026amp;\u0026amp; rm -rf *\nStep2:Jenkins 主目录初始化成 git 仓库 cd /var/lib/jenkins \u0026amp;\u0026amp; git init\nStep3:递归清除未纳入版本控制的文件 git clean -df\nStep4:添加新的远程仓库地址 git remote add origin git@github.com:username/new_repo\nStep5:从 GitHub pull 备份数据 git pull origin master\nStep6. 以 root 账户重启 Jenkins service jenkins restart\n至此,数据已完全恢复。\n", "auhtor": "oleksii_y", "translator": "walker0921", "original": "https://medium.com/@_oleksii_/how-to-backup-and-restore-jenkins-complete-guide-62fc2f99b457", "poster": "jenkins.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-08-how-to-use-the-jenkins-declarative-pipeline/", "title": "如何使用 Jenkins 声明式流水线", "type": "wechat", "date": "2020-05-08 00:00:00 +0000 UTC", "tags": ["Jenkins", "Pipeline", "Declarative Pipeline"], "description": "在本教程中了解如何使用 Jenkins 的声明性流水线,其中涵盖了开发流水线脚本的所有可用指令", "content": " Jenkins 为您提供了两种开发流水线代码的方式:脚本式和声明式。\n脚本式流水线(也称为“传统”流水线)基于 Groovy 作为其特定于域的语言。 而声明式流水线提供了简化且更友好的语法,并带有用于定义它们的特定语句,而无需学习 Groovy。\nJenkins 的流水线插件版本2.5引入了对声明式流水线的支持。\n在本文中,我们将介绍开发声明式流水线脚本的所有可用指令,这将清楚地说明其功能。\n声明式流水线语法 必须使用 pipeline 语句定义有效的声明式流水线,并包括以下必需的部分:\n agent stages stage steps 另外,还有这些可用的指令:\n environment (在流水线或阶段级别定义) input (阶段级别定义) options (在流水线或阶段级别定义) parallel parameters post script tools triggers when 现在,我们将从所需的指令/部分开始,对列出的每个指令/部分进行描述。\nagent Jenkins 通过将分布式构建委托给“代理/agent”节点来提供执行分布式构建的能力。 这样做可以使您仅使用 Jenkins 服务器的一个实例来执行多个项目,而工作负载却被分配给了它的代理。 有关如何配置主/代理模式的详细信息超出了本博客的范围。请参阅 Jenkins 分布式构建以获取更多信息。\n代理应标记上标签,以便彼此轻松识别。 例如,节点可以通过其平台(Linux,Windows 等),其版本或位置等来标记。 “agent”部分配置流水线可以在哪些节点上运行。 指定 agent any 意味着 Jenkins 将在任何可用节点上运行任务。\n其用法的一个示例可以是:\npipeline { agent any ... } stages 本部分允许在流水线上生成不同的阶段,这些阶段将在运行任务时显示为不同的段。\n一个包含阶段语句的示例流水线:\npipeline { agent any stages { ... } } stage 必须在“stages”部分上定义至少一个“stage”部分。 它将包含流水线将执行的工作。 阶段必须命名,因为 Jenkins 将在界面上显示每个阶段,如下所示:\nJenkins 根据定义的阶段以图形方式拆分流水线执行,并显示它们的持续时间以及是否成功。\n上一个图像的流水线脚本如下所示:\npipeline { agent any stages { stage ('build') { ... } stage ('test: integration-\u0026amp;-quality') { ... } stage ('test: functional') { ... } stage ('test: load-\u0026amp;-security') { ... } stage ('approval') { ... } stage ('deploy:prod') { ... } } } steps 最后一个必需的部分是“steps”,它被定义为在“stage”内。 在“steps”部分中必须至少定义一个步骤。\n对于 Linux 和 MacOS,支持使用 shell。 这是一个例子:\nsteps { sh 'echo \u0026quot;A one line step\u0026quot;' sh ''' echo \u0026quot;A multiline step\u0026quot;' cd /tests/results ls -lrt ''' } 对于 Windows,可以使用 bat 或 PowerShell,如下所示:\nsteps { bat \u0026quot;mvn clean test -Dsuite=SMOKE_TEST -Denvironment=QA\u0026quot; powershell \u0026quot;.\\funcional_tests.ps1\u0026quot; } 其他非必需的指令将在以下段落中说明。\nenvironment 可以在阶段或流水线级别定义此指令,这将决定其定义的范围。在“pipeline”级别使用“environment”时,其定义将对所有流水线步骤均有效。 相反,如果它是在“stage”中定义的,则它仅对特定阶段有效。\n该指令的示例用法:\n在“pipeline”级别:\npipeline { agent any environment { OUTPUT_PATH = './outputs/' } stages { stage ('build') { ... } ... } } 在\u0026rdquo;stage\u0026rdquo;级别:\npipeline { agent any stages { stage ('build') { environment { OUTPUT_PATH = './outputs/' } ... } ... } } input “input”指令在阶段级别定义,提供提示输入的功能。该阶段将被暂停,直到用户手动确认为止。\n以下配置选项可用于此指令:\n message:这是必需的选项,其中指定了要显示给用户的消息。 id:可选标识符。 默认情况下,使用“阶段”名称。 ok:“确定”按钮的可选文本。 submitter:允许提交输入的用户或外部组名的可选列表。 默认情况下,允许任何用户。 submitterParameter:要使用提交者名称设置的环境变量的可选名称(如果存在)。 parameters:提交者将提供的可选参数列表。 这是包含此指令的示例流水线:\npipeline { agent any stages { stage ('build') { input{ message \u0026quot;Press Ok to continue\u0026quot; submitter \u0026quot;user1,user2\u0026quot; parameters { string(name:'username', defaultValue: 'user', description: 'Username of the user pressing Ok') } } steps { echo \u0026quot;User: ${username} said Ok.\u0026quot; } } } } options 在流水线级别定义,此指令将对整个流水线的特定选项进行分组。可用的选项有:\n buildDiscarder disableConcurrentBuilds overrideIndexTriggers skipDefaultCheckout skipStagesAfterUnstable checkoutToSubdirectory newContainerPerStage timeout retry timestamps 请参阅 Jenkins 声明式流水线选项,以获取有关此内容的完整参考。\n例如,您可以通过以下操作将流水线配置为在失败前重试3次:\npipeline { agent any options { retry(3) } stages { echo 'do something' } } parallel Jenkins 流水线阶段可以在内部嵌套其他阶段,这些阶段将并行执行。\n这是通过在脚本中添加“parallel”指令来完成的。 使用示例:\nstage('run-parallel-branches') { steps { parallel( a: { echo \u0026quot;Tests on Linux\u0026quot; }, b: { echo \u0026quot;Tests on Windows\u0026quot; } ) } } 从声明式流水线1.2版开始,引入了一种新语法,使并行语法的使用更像声明式的。\n使用此新语法重写的先前脚本如下所示:\npipeline { agent none stages { stage('Run Tests') { parallel { stage('Test On Windows') { agent { label \u0026quot;windows\u0026quot; } steps { bat \u0026quot;run-tests.bat\u0026quot; } } stage('Test On Linux') { agent { label \u0026quot;linux\u0026quot; } steps { sh \u0026quot;run-tests.sh\u0026quot; } } } } } } 上述的任何一个流水线都将如下所示:\n由于两个脚本都运行特定的平台测试,因此它们将在不同的节点上运行测试。 如果您的 Jenkins 服务器具有足够的 CPU,则还可以通过使用多线程将并行用于在同一节点上同时运行阶段。\n使用并行阶段时有一些限制:\n stage 指令可以具有 parallel 指令或 steps 指令,但不能同时具有两者。 parallel 指令中的一个 stage 指令不能嵌套另一个 parallel 指令,仅允许 steps。 在内部具有 parallel 指令的 stage 指令不能定义“agent”或“tools”指令。 parameters 该指令允许您定义脚本中要使用的参数列表。一旦触发流水线,应提供参数。应该在“pipeline”级别定义它,并且整个流水线只允许一个指令。\n字符串和布尔值是可以使用的有效参数类型。\npipeline { agent any parameters { string(name: 'user', defaultValue: 'John', description: 'A user that triggers the pipeline') } stages { stage('Trigger pipeline') { steps { echo \u0026quot;Pipeline triggered by ${params.USER}\u0026quot; } } } } post 可以在流水线级别或每个阶段上添加 post,一旦阶段或流水线完成,便会执行其中包含的语句。可以使用几个 post 条件来控制是否执行该 post:\n always:无论完成状态如何,都会执行步骤。 changed:仅当完成结果与上次运行的状态不同时才执行。 fixed:仅在完成结果是成功且上次运行失败时执行 regression:仅在当前执行失败,中止或不稳定并且上一次运行成功时执行。 aborted:仅在流水线或阶段中止时才执行步骤。 failure:仅在流水线或阶段失败时才执行步骤。 success:仅在流水线或阶段成功时才执行步骤。 unstable:仅当流水线或阶段不稳定时才执行步骤。 由于流水线 post 包含的句子将在脚本的末尾运行,因此可以在此处执行清除任务或通知等。\npipeline { agent any stages { stage('Some steps') { steps { echo 'do something' } } } post { always { echo \u0026quot;Pipeline finished\u0026quot; bat './performCleanUp.bat' } } } script 此步骤用于将脚本化流水线语句添加到声明式流水线中,从而提供更多功能。此步骤必须包括在“stage”级别。\n脚本块可以多次用于不同的项目。这些块使您可以扩展 Jenkins 功能,并可以实现为共享库。可以在 Jenkins 共享库中找到有关此内容的更多信息。 同样,可以将共享库导入并使用到“script”中,从而扩展了流水线功能。\n接下来,我们将提供示例流水线。第一个只有一个包含一段脚本化流水线代码的块,而第二个将展示如何导入和使用共享库:\npipeline { agent any stages { stage('Sample') { steps { echo \u0026quot;Scripted block\u0026quot; script { } } } } } 有关此主题的更多信息,请参阅如何使用 Jenkins 脚本式流水线的文章。\ntools 可以在流水线级别或阶段级别添加“tools”指令。 它允许您指定要在脚本上使用的 Maven,JDK 或 Gradle 版本。 必须在“全局工具配置” Jenkins 菜单上配置这些工具中的任何一个,在撰写本文时,这三个工具都受支持。\n另外,Jenkins 将尝试安装列出的工具(如果尚未安装)。通过使用此指令,可以确保安装了项目所需的特定版本。\npipeline { agent any tools { maven 'apache-maven-3.0.1' } stages { echo 'do something' } } triggers 触发器允许 Jenkins 通过使用以下任何一个可用的方式自动触发流水线:\n cron:通过使用 cron 语法,它可以定义何时重新触发流水线。 pollSCM:通过使用 cron 语法,它允许您定义 Jenkins 何时检查新的源存储库更新。如果检测到更改,则将重新触发流水线。(从 Jenkins 2.22 开始可用)。 upstream:将 Jenkins 任务和阈值条件作为输入。 当列表中的任何任务符合阈值条件时,将触发流水线。 带有可用触发器的示例流水线如下所示:\npipeline { agent any triggers { //Execute weekdays every four hours starting at minute 0 cron('0 */4 * * 1-5') } stages { ... } } pipeline { agent any triggers { //Query repository weekdays every four hours starting at minute 0 pollSCM('0 */4 * * 1-5') } stages { ... } } pipeline { agent any triggers { //Execute when either job1 or job2 are successful upstream(upstreamProjects: 'job1, job2', threshold: hudson.model.Result.SUCCESS) } stages { ... } } when 可以根据“when”指令中定义的条件执行流水线步骤。如果条件匹配,将运行相应阶段中定义的步骤。它应该在阶段级别定义。\n有关条件及其说明的完整列表,请参阅 Jenkins 声明式流水线“when”指令。\n例如,流水线使您可以在具有多个分支的项目上执行任务。这被称为多分支流水线,其中可以根据分支名称(例如“master”,“ feature*”,“development”等)采取特定的操作。 这是一个示例流水线,它将运行 master 分支的步骤:\npipeline { agent any stages { stage('Deploy stage') { when { branch 'master' } steps { echo 'Deploy master to stage' } } } } 最后2个 Jenkins 声明式流水线提示 声明式流水线语法错误在脚本开始时报告。 这是一个很好的功能,因为您不会浪费时间,直到某个步骤未能意识到拼写错误或拼写错误。\n如前所述,流水线可以以声明式或脚本式编写。而且,声明式方法建立在脚本式方法的基础之上,通过添加\u0026rdquo;script\u0026rdquo;步骤,可以很容易地进行扩展。\nJenkins 流水线已在 CI/CD 环境中广泛使用。不管是使用声明式或脚本式流水线都具有多个优点。在本文中,我们介绍了编写示例脚本展示声明式流水线的所有语法元素。 就像我们已经说过的那样,声明式提供了更加友好的语法,而无需 Groovy 知识。\n", "auhtor": "Alejandro Berardinelli", "translator": "hummerstudio", "original": "https://dzone.com/articles/how-to-use-the-jenkins-declarative-pipeline", "poster": "Jenkins-Declarative-Pipeline.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-07-jcli-v0.0.28/", "title": "Jenkins CLI 命令行 v0.0.28", "type": "wechat", "date": "2020-05-07 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.28 发布", "content": " 截止到编辑本文时,GitHub 上统计到的下载量为:5,498次。GitHub 上的 Star 数为157,码云上的 Star 数为89。\nJenkins CLI 增加对了对插件机制的支持,用户可以通过编写插件的方式增强 jcli 的功能。第一个插件可以以 git 仓库的形式,在团队内部分享你的配置文件。\n为了保证交付质量,我们增加了 e2e 测试。后续,也会逐渐增加 e2e 的测试用例。\n🚀 功能 支持清理无效的配置项 (#383) @LinuxSuRen 在版本打印的命令中增加了日期 (#388) @LinuxSuRen 增加插件机制 (#385) @LinuxSuRen 支持打开外部链接 (#384) @LinuxSuRen 给命令 jcli center start 增加命令行补全 (#380) @LinuxSuRen 增加 man 文档的支持 (#382) @LinuxSuRen 给命令 jcli plugin upload 增加命令行补全 (#378) @LinuxSuRen 支持用指定的浏览器打开 (#377) @LinuxSuRen 🐛 缺陷修复 修复命令 job log 的错误帮助信息 (#375) @LinuxSuRen 命令 jcli doc 不需要读取配置文件 (#376) @yJunS 📝 文档完善 命令文档的完善 (#392) @LinuxSuRen 👻 维护 修复 readme 文件中失效的链接 (#393) @LinuxSuRen 升级 github.com/AlecAivazis/survey/v2 从 2.0.6 到 2.0.7 (#343) @dependabot-preview 🚦 测试 增加 e2e 测试 (#301) @LinuxSuRen ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "jenkins-cli.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/05/2020-05-06-using-a-k3s-kubernetes-cluster-for-your-gitlab-project/", "title": "为你的 GitLab 项目使用 k3s Kubernetes 集群", "type": "wechat", "date": "2020-05-06 00:00:00 +0000 UTC", "tags": ["Kubernetes", "Programming", "DevOps", "Data Science", "Software Development"], "description": "通过介绍以及实际操作展示了使用轻量的经过 Kubernetes 认证的 k3s 是如何集成到 GitLab 项目上的", "content": " TL;DR k3s 是一个轻量级的 Kubernetes 发行版(小于 40 MB),它非常容易安装,仅需要 512 MB 的 RAM。对 IoT 设备、边缘计算以及运行 CI 任务来说均是一个完美的选择。这篇文章中,我将创建一个 k3s 集群然后向你们展示怎样将它集成到一个 GitLab 项目中。\n关于 k3s k3s 是一款由 Rancher Labs 开发的轻量级的 Kubernetes 发行版。\n它作为 Kubernetes 认证的发行版使用最低的系统要求:\n Linux 3.10+ 每个服务器 521 MB ram 每个节点 75 MB ram 200 MB 磁盘空间 x86_64,ARMv7,ARM64 这使得 k3s 非常适合 IoT 相关的事物。\n在 GitLab 创建一个项目 在安装 k3s 之前,我们先在 GitLab 上创建一个名为 api 的新项目。\n创建完成后,我们进入到 Operation \u0026gt; Kubernetes 菜单。\n这里我们有两种选择:\n 我们可以在 GKE(Google Kubernetes Engine)上创建一个 Kubernetes 集群。 我们可以导入一个已存在的 Kubernetes 集群的配置(不管在哪里创建的)。 注意: 最新版本的 GitLab,新集群只能在 GKE 中创建。GitLab,有没有允许在其他 Kubernetes 提供商(AKS、EKS、DOKS\u0026hellip;)创建集群的计划呢?:)\n我们选择*添加现有集群*标签栏。\n从这里我们能看到,我们需要填写几个栏位的配置信息提供给需要集成的集群。让我们保持这个页面为打开状态然后先创建一个 Kubernetes 集群。\n创建 k3s 集群 我们将要基于 k3s 初始化一个 Kubernetes。为什么是 k3s 呢?因为我想展示一下设置它有多简单。:)简单起见,我们只设置一个单节点集群。\n我已经配置了一个名为 node1 的 Ubuntu 18.04 的服务器。当我们在主机上启动一个 shell 程序后,我们仅需要运行如下命令安装 k3s,一个 Kubernetes 认证的集群。真的!\nroot@node1:~ $ curl -sfL [https://get.k3s.io](https://get.k3s.io/) | sh - 上面的命令跟快速安装 Docker 有些相似: curl [https://get.docker.com](https://get.docker.com/) | sh\n安装完成后(真的非常快),用来连接集群的配置文件会在 /etc/rancher/k3s/k3s.yaml 中获取到。\n**root@node1:~ $ cat /etc/rancher/k3s/k3s.yaml **apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tL...tCg== server: https://localhost:6443 name: default contexts: - context: cluster: default user: default name: default current-context: default kind: Config preferences: {} users: - name: default user: password: 48f4b...4b4e7 username: admin 本地的 kubectl 自动配置为试用该配置。\n$ kubectl get nodes NAME STATUS ROLES AGE VERSION node1 Ready master 3m v1.14.5-k3s.1 注意: 当我们参照文章最后的快速入门添加额外的节点将会非常容易。它仅仅是从主节点 /var/lib/rancher/k3s/server/node-token 获取一个令牌然后使用下面的命令加入到其他的节点:\n$ curl -sfL [https://get.k3s.io](https://get.k3s.io/) | K3S_URL=https://myserver:6443 K3S_TOKEN=XXX sh - 集成到 GitLab 现在我们要收集将 k3s 集群集成到我们的 GitLab 项目中的所有信息。\n 集群名称 我们给它命名为 *k3s*。\n API Server 的 URL 在配置文件中,API Server 指定 https://localhost:6443。为了从外部获取,我们需要提供 node1 的外部 IP 地址。\n 集群的 CA 认证 为了提供集群到 GitLab 的 CA 认证,我们需要对配置中指定的证书进行解码(它以 base 64编码的)。\n$ kubectl config view --raw \\ -o=jsonpath='{.clusters[0].cluster.certificate-authority-data}' \\ | base64 --decode Service 令牌 获取标识令牌的过程包含了几步。首先需要创建一个 ServiceAccount 并为其提供 cluster-admin 角色。可以通过下面的命令实现这个操作:\n$ cat \u0026lt;\u0026lt;EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-admin namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: gitlab-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: gitlab-admin namespace: kube-system EOF 服务账号创建好之后,我们将检索 secret 类型关联的资源:\n$ SECRET=$(kubectl -n kube-system get secret | grep gitlab-admin | awk '{print $1}') 下一步就是提取与密码相关联的的 JWT 令牌:\n$ TOKEN=$(kubectl -n kube-system get secret $SECRET -o jsonpath='{.data.token}' | base64 --decode) $ echo $TOKEN 全部配置好之后,我们将收集起来的所有信息填入到 GitLab 添加已有集群 表格中:\n集群集成进来之后,我们可以直接从 web 页面安装 helm(Kubernetes 包管理工具)。\n现在我们可以通过命令行检查一下 tiller 守护进程(helm 的服务器端组件)是否运行。\n$ kubectl get deploy --all-namespaces | grep tiller NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE gitlab-managed-apps tiller-deploy 1/1 1 1 67s 集群准备就绪,最重要的是,GitLab 的 web 页面允许一键安装其他组件:\n Ingress Controller 用来公开集群中运行的服务\n Cert-Manager 用来同 Let\u0026rsquo;s Encrypt 配合管理 TLS 证书\n Prometheus 用来监控集群中运行的应用程序\n Knative 用来部署 Serveless 工作负载\n 等等。\n 总结 这篇文章中,我们看到了怎样创建 k3s 集群以及将它集成到 GitLab 项目。当然,该步骤同样适用于其他任何 Kubernetes 集群。\n我们可以添加资源到项目中:\n 源码\n Dockerfile 指定了怎样通过代码创建一个 Docker 镜像\n Kubernetes 资源例如 Deployment,Service,\u0026hellip;\n 一个 gitlab-ci.yaml 文件定义了 CI 流水线以及应用程序是怎样被部署和测试相关的 Kubernetes 集群\n 你或许会发现上一篇文章很有用。它提供了另外的内容就是关于怎样创建 CI/CD 流水线。\n你会为你的 GitLab 项目集成 Kubernetes 吗?\n", "auhtor": "Luc Juggery", "translator": "0N0thing", "original": "https://medium.com/better-programming/using-a-k3s-kubernetes-cluster-for-your-gitlab-project-b0b035c291a9", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-29-starting-local-kubernetes-using-kind-and-docker/", "title": "使用 kind 和 Docker 启动本地的 Kubernetes", "type": "wechat", "date": "2020-04-29 00:00:00 +0000 UTC", "tags": ["Kubernetes", "Kind", "Docker", "WordPress", "MySQL"], "description": "介绍了 kind 这款工具,并且通过例子讲解了怎样通过 kind 在你本地的机器上部署应用到 Kubernetes 集群", "content": " 介绍 你曾经花过一整天时间尝试入门 Kubernetes 吗?多亏最近新出现的一些工具,你可以不用再为此大费周章了。\n这篇文章中,我将向你展示使用 kind 在单个 Docker 容器中启动一个集群的步骤。\n什么是 kind? kind 是一款使用 Docker 容器 “nodes” 运行 Kubernetes 集群的工具。 https://kind.sigs.k8s.io/\n 介绍看起来没有描述信息,但是很明显能知道是源于 “Kubernetes IN Docker”。该工具具备了跨平台友好的优势即便你使用的是 Windows 版本的 Docker。当然了,缺点就是它的可追溯性比较差。\n安装 kind 因为 kind 是 go 语言实现的,请确保安装了最新版本的 golang。根据开发者文档,推荐使用 go1.11.5 及以上版本。为了安装 kind,请运行这些命令(可能需要运行一段时间)\ngo get -u sigs.k8s.io/kind kind create cluster 然后确认 “kind” 集群是可用的。\nkind get clusters 设置 kubectl 同样的,使用 Homebrew 或者 Chocolatey 安装最新版本的 kubernetes-cli。最新版本的 Docker 包含了 Kubernetes 的功能,但使用的是老版本的 kubectl。\n运行该命令检查它的版本号。\nkubectl version 请确保显示 GitVersion: \u0026quot;v1.14.1\u0026quot; 或更高版本。\n如果你发现通过 Docker 运行的 kubectl,试着使用 brew link 或对环境变量重新排序。\n一旦 kubectl 和 kind 安装就绪,打开 bash 控制台运行这些命令。\nexport KUBECONFIG=”$(kind get kubeconfig-path)” kubectl cluster-info 如果 kind 正确的配置了,会显示一些信息出来。现在你就可以继续开始下面的工作了。耶!\n部署第一个应用程序 我们需要部署什么到集群上呢?一个很好的选择就是 Wordpress 因为它包括 MySQL 和 PHP 应用程序。\n幸运的是,有一个官方的入门介绍并且描述的非常棒。我们可以尝试使用刚才创建的 kind 集群来操作里面的大多数步骤。\nhttps://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/\n首先,从这个页面上下载 mysql-deployment.yaml 和 wordpress-deployment.yaml。\n运行两个 cat 命令创建 kustomization.yaml。一旦这些 yaml 文件准备好之后,将文件按照下面显示的那样放到相应的目录里面。\nk8s-wp/ kustomization.yaml mysql-deployment.yaml wordpress-deployment.yaml 然后应用到你的集群当中。\ncd k8s-wp kubectl apply -k ./ 如果命令成功执行你会看到如下的输出。\nsecret/mysql-pass-7tt4f27774 created service/wordpress-mysql created service/wordpress created deployment.apps/wordpress-mysql created deployment.apps/wordpress created persistentvolumeclaim/mysql-pv-claim created persistentvolumeclaim/wp-pv-claim created 让我们输入这些命令检查下集群的状态:\nkubectl get secrets kubectl get pvc kubectl get pods kubectl get services wordpress 等待所有的 pod 变成 Running 状态。\n然后,运行这个命令来获取服务。\nkubectl port-forward svc/wordpress 8080:80 然后打开http://localhost:8080/\n瞧!\n如果你想查看数据库,检查你的pod,像这样运行一个命令,然后打开你的客户端应用。\nkubectl port-forward wordpress-mysql-bc9864c58-ffh4c 3306:3306 结论 kind 对 minikube 来说是一个好的选择因为它只使用单个 Docker 容器。\n通过跟集成到 Kubernetes 1.14 的 Kustomze 结合使用,在你本地的机器上尝试使用 Kubernetes 会更加简单。\n", "auhtor": "Youichi Fujimoto", "translator": "0N0thing", "original": "https://itnext.io/starting-local-kubernetes-using-kind-and-docker-c6089acfc1c0", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-24-jenkins-release/", "title": "Jenkins 长期支持版更新", "type": "wechat", "date": "2020-04-22 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "本次更新的版本包括:2.176.3~2.176.4、2.190.1~2.190.3、2.204.1~2.204.6、2.222.1", "content": " 2.222.1 (2020-03-25) Jenkins 启动时将不从磁盘加载全局构建丢弃程序的配置(JENKINS-61688)。 配置已保存,但在重新启动时将不加载。 Jenkins 2.222.1 将始终以 Job Build Discarder 的默认配置启动。 重新启动时将忽略自定义全局构建丢弃配置。 每次 Jenkins 重新启动时,都会配置默认的全局构建丢弃。\n 自 2.222 以来的变更: 重要安全修复。 (安全公告) 修复了任务配置表单中之前保存步骤中存在的拖放操作问题 (由 2.217 引入的缺陷回归)。 (issue 61429) Winstone 5.9: 修复最大表单内容大小和表单内容密钥的传递(由 Jetty 9.4.20 和 Jenkins 2.205 引入的缺陷回归)。 (pull 4542, issue 60409, Winstone 5.9 变更日志, Jetty 9.4.27 变更日志) Winstone 5.9: 修复由于 X-Forwarded-Host 和 X-Forwarded-Port 订阅问题而导致的将不正确的反向代理重定向到 Host 的问题(由 Jetty 9.4.20 和 Jenkins 2.205 引入的缺陷回归)。 (pull 4542, issue 60199, Winstone 5.9 变更日志, Jetty 9.4.27 变更日志) 与请求路由和 CSRF 保护有关的安全增强。 (相关升级指导) 开发者: 在调试模式下,默认监听回送接口。 (pull 4515) 自 2.204.6 以来的重大变更: 修改标题栏和 breadcrumbs 导航的布局和图标。 依赖于 Jenkins 布局细节的插件的实例(例如 Simple Theme Plugin)可能会遇到 UI/布局问题。 通过将 jenkins.ui.refresh 系统属性设置为 true,可以启用新的实验性标题颜色方案。 (issue 60920) 添加全局配置的构建丢弃程序,删除未标记为“永久保留”的旧构建,即使没有配置、积极性较低、配置的按项目构建丢弃程序或者在构建完成后定期执行。 (pull 4368) 将云配置从\u0026rdquo;配置系统\u0026rdquo;移动到\u0026rdquo;管理节点\u0026rdquo;页面上其自身的配置表单中。 (pull 4339) 删除全局安全配置中的启用安全复选框。 (issue 40228) 删除禁用 CSRF 保护的功能。 从较旧版本的 Jenkins 升级的实例将启用 CSRF 保护和设置默认的发行者,如果之前被禁用。 (pull 4509) 重新设计密码字段,以防止自动填写密码(登录表单除外)。 减少提供更新存储密码的浏览器。 通过将系统属性 hudson.Functions.hidingPasswordFields 设置为 false 来还原。 (pull 3991) 弃用 macOS 本地安装程序包。 (Jenkins macOS 本地安装程序弃用) 删除古老的、不推荐使用的、不支持的代理协议 Inbound TCP Agent Protocol/1, Inbound TCP Agent Protocol/2 和 Inbound TCP Agent Protocol/3。 将 Remoting 从 3.36 更新到 4.2,以删除不受支持的协议和增加对于 WebSocket 的支持。 (issue 60381, Remoting 3.40 发布说明, Remoting 4.0 发布说明, Remoting 4.0.1 发布说明, Remoting 4.2 发布说明) 增加实验性的 WebSocket 支持。 (JEP-222, 博客文章) 扩展当前里程碑,以便插件可以在 Jenkins 初始化期间更新任务和配置。 增加初始化里程碑: SYSTEM_CONFIG_LOADED、SYSTEM_CONFIG_ADAPTED 和 JOB_CONFIG_ADAPTED。 (issue 51856) 引入一个新的实验性 UI,可以通过将 jenkins.ui.refresh 系统属性设置为 true 来启用。 作为 UI/UX 改进的一部分,当前,它包括一个新的标题颜色方案,后续将添加更多更改。 (pull 4463, issue 60920, JEP-223, Jenkins UX SIG) 添加新的实验性 全局/管理 权限,该权限允许用户在不具有 全局/Administer 权限的情况下配置部分全局 Jenkins 配置。 这是一项实验性功能,默认情况下处于禁用状态,可以通过将 jenkins.security.ManagePermission 系统属性设置为 true 来启用。 (pull 4501, issue 60266, JEP-223) 添加一个新的实验性全局/系统读取权限,该权限(几乎)为 Jenkins 实例提供完全读取权限。 默认情况下,该权限是禁用的,请安装 Extended Read Permission 插件以将其激活。 (pull 4506, issue 12548, JEP-224, Extended Read Permission 插件) 现在可以从(非流水线)构建中使用环境变量 WORKSPACE_TMP 来访问与构建工作空间关联的临时目录。 (issue 60634) 弃用全局/运行脚本、全局/上传插件和全局/配置更新中心权限。 在 2017 年,主要授权插件中的权限被宣布为危险且默认情况下被禁用。 自定义授权策略实现将授予全局/Administer 权限,而不暗示这三个权限中的一个或多个将不再按预期工作。 在没有全局/Administer 权限的情况下向用户授予这些权限中任何一个的配置将不能按预期工作。 (pull 4365, issue 60266, JEP-223, 2017-04-10 Matrix Authorization 插件的安全公告, 2017-04-10 Role-Based Authorization 插件的安全公告) 修复在获取具有状态阈值的运行列表时的空指针异常(由 2.202 引入的缺陷回归)。 (issue 60884) 验证另一个用户时,当前用户不再注销。 (issue 59107) Winstone 5.9: 修复对自定义系统日志的支持(由 2.204.5 引入的缺陷回归)。 (pull 4452, issue 57888, Winstone 5.9 变更日志, Jetty 9.4.27 变更日志) 2.204.6 (2020-03-25) 重要安全修复。 (安全公告) 与请求路由和 CSRF 保护有关的安全增强。 (相关升级指导) 2.204.5 (2020-03-07) 此版本重新引入了 Jenkins 2.177 到 2.203.3 的系统日志记录自定义缺陷(JENKINS-57888 - 系统日志记录自定义),因为它不如其它被修复的缺陷那么严重。 计划在 2.22.1 版本中修复。\n 修复最大表单内容大小和表单内容密钥的传递(由 Jenkins 2.204.3 和 Jetty 9.4.20 引入的缺陷回归)。 (issue 60409) 修复由于 X-Forwarded-Host 和 X-Forwarded-Port 订阅问题而导致的将不正确的反向代理重定向到 127.0.0.1 的问题(由 Jenkins 2.204.3 和 Jetty 9.4.20 引入的缺陷回归)。 (issue 60199) 将 Winstone 从 5.8 还原到 5.3,以解决 Winstone 更高版本中嵌入的 Jetty Web 容器引入的问题。 默认最大表单大小限制和反向代理重定向被还原(由 2.204.3 引入的缺陷回归)。 (issue 60409, issue 60199, Winstone 变更日志) 2.204.4 (2020-03-03) 传递某些类型(例如域通配符)的证书时,修复 Jetty 不支持包含多个证书的密钥库的错误(由 2.204.3 引入的缺陷回归)。 (pull 4539, issue 60857, Winstone 5.8 发布说明) 2.204.3 (2020-02-28) 内部: Winstone 5.7: 将 Jetty 线程池名称更改为 “Jetty(winstone)”。 (pull 4452, issue 60821, Winstone 5.7 发布说明) 如果在运行安装向导之前已经通过脚本配置了 Jenkins 根 URL,即使跳过了创建 admin 用户的选项,也要跳过配置面板。 (issue 60750) 在安装 Monitoring 插件时,防止有关 Java 11 缺少的、由 JavaMelody 触发的类的错误告警。 (issue 60725) 当构建连续失败时,在系统日志中包括详细信息。 (issue 60716) 修复 AdoptOpenJDK 11 的 Java 版本检查。 (issue 60678) 防止更新中心在进行数据解析时 Jenkins 页面卡住。 (issue 60625) Winstone 5.7: 修复对系统日志记录定制的支持 (由 2.177 引入的缺陷回归)。 (pull 4452, issue 57888, Winstone 5.7 release notes) 修复代理脱机时代理 API 中的空指针异常(例如查询代理版本或操作系统说明)。 (issue 42658) 2.204.2 (2020-01-29) 重要的安全修复。 (安全公告) 验证另一个用户时,当前用户不再注销。 (issue 59107) 与 Stapler 路由相关的安全增强。 安全增强:在 REST API 响应中将 X-Content-Type-Options 设置为 nosniff。 如果 hudson.Util.maxFileDeletionRetries 为零,禁用多次删除尝试。 (issue 60351) 通过在 Computer.removeExecutor 中删除一次性执行器来防止 master 上的“僵尸”执行器。 (issue 57304) 修复在 CephFS 上创建空文件时的 AtomicFileWriter 性能问题。 (issue 60167) 开发者: ViewGroupMixIn#getPrimaryView() 可能返回 null,需要基于这个周版本及以后的版本在插件中进行检查。 这是一个过渡状态,直到实现默认视图为止。 (issue 60092) 2.204.1 (2019-12-18) 升级为 Jenkins 2.204.1 的 Configuration as code plugin 用户需要查看 LTS升级指南全局配置保存主题和 LTS 升级指南下载设置主题\n 自 2.204 以来的变更: 将鼠标悬停在侧栏链接上时,显示带有完整链接名称的工具提示。 (issue 59508) 防止错误的子任务提供者使构建永久运行。 (issue 59793) 修复\u0026rdquo;插件管理-已安装\u0026rdquo;列表中卸载列的排序。 (issue 59665)\n自 2.190.3 以来的重大变更: 在完成加载内存模型之前,请避免调用 Jenkins#save 持久数据。 这样可以防止 Jenkins 主配置损坏。 (issue 58993)\n 删除使用用户浏览器下载更新中心元数据的功能(自 2015 年起不推荐使用)。 如果没有连接更新站点,Jenkins 将不再通知可用更新。 在这种情况下,建议使用更新站点的本地镜像,或使用 Juseppe 之类的自托管更新中心。 (pull 3970)\n 允许按用户设置时区。 (issue 19887)\n 为资源根 URL 添加一个选项,Jenkins 可以通过该选项为用户生成的静态资源(例如工作空间文件或已归档的制品)提供服务,而无需 Content-Security-Policy 标头。 (issue 41891)\n 停止绑定 Maven 插件、 Subversion 插件和 Jenkins war 文件中的一些其他插件。 在极少数情况下,尝试安装与 1.310 版本之前的 Jenkins 兼容的插件时,可能会导致问题。 Jenkins 项目目前未发布任何此类插件。 (pull 4040)\n 弃用 macOS 本地安装程序以使用 Homebrew。 (macOS 本地安装程序弃用博客文章)\n 还原在 Firefox 的 Jenkins 经典 UI 中对表单提交的更改(此更改导致了带有\u0026rdquo;文件\u0026rdquo;输入的表单的缺陷回归)。 这样做是为了预料 Firefox 中的错误修正,此错误已被撤消。 (由 2.173 引入的缺陷回归) (issue 58296, issue 53462, Firefox issue 1370630)\n 删除构建历史记录小部件中关于构建说明的 100 个字符长度限制。 (issue 19760, issue 31209)\n 将 Remoting 从 3.33 更新到 3.36。 为入站 TCP 代理添加新的连接模式。 将最低必需的 Remoting 版本更新为 3.14。 添加命令行选项 \u0026ldquo;-help\u0026rdquo; 和 \u0026ldquo;-version\u0026rdquo;。 (Remoting 3.36 发布说明, pull 4193, Remoting 3.35 发布说明, pull 4208, pull 4186, issue 53461, pull 4165, Remoting 3.34 发布说明, 减少远程连接步骤)\n 2.190.3 (2019-11-20) 稳定性: 不允许用户使用 POST 在需要提交表单的 URL 上重新提交请求,因为那样无论如何都会失败。 (issue 59514) lastCompletedBuild 永久链接未缓存在 …/builds/permalinks 文件中。 (issue 56809) 将标签固定到 Atom 供稿链接。 (issue 48375) 在 Firefox 的 Jenkins 经典 UI 中还原表单提交的更改。 更改导致了带有\u0026rdquo;文件\u0026rdquo;格式的内容提交的表单的缺陷回归。 这样做是为了预料 Firefox 中的错误修正,此错误已被撤消。 (由 2.164.3 引入的缺陷回归) (issue 58296, issue 53462, Firefox issue 1370630) 2.190.2 (2019-10-28) 无法访问名称中带有表情符号的某些项目 URL 。 (issue 59406) 在基于 HTTP 的 CLI 上增加客户端保持活动 ping 的频率,以防止超时。 (issue 59267) 内部: 发生错误时,hudson.util.ProcessTree.OSProcess#getEnvironmentVariables 返回 null ,即使它不应该发生也是如此。 (issue 59580) 2.190.1 (2019-09-25) 自 2.190 以来的变更: 重要的安全修复。 (2019-09-25 安全公告, 2019-08-28 安全公告) 修复 RSS / Atom 提要中缺少的绝对 URL 。 (由 2.190 引入的缺陷回归) (issue 59167) 当提示慢触发的管理警告时, Jenkins UI 中断。 (由 2.189 引入的缺陷回归) (issue 58938)\n自 2.176.4 以来的重大变更: Jenkins 不再在项目或构建目录中创建符号链接。 如果需要,可以安装 Build Symlink 插件来恢复此功能。 诸如 /job/…/lastStableBuild/ 之类的URL不受影响,仅影响直接访问 $JENKINS_HOME 文件系统的工具。 (issue 37862)\n 从 Jenkins 核心中删除 Trilead SSH 库,并使其在新的独立插件中可用。 (issue 43610)\n 在任务名称中添加对表情符号和其他非 UTF-8 字符的支持。 🎉 (issue 23349)\n 更新 Windows Agent Installer 从 1.10.0 到 1.11 ,以 .NET 4.6 或更高版本运行时,在代理下载上启用 TLS 1.2 。 (issue 51577, 完整变更日志)\n 更新 Winstone-Jetty 从 5.2 到 5.3 ,以更新 Jetty 到 9.4.18 。 (pull 4016, 完整变更日志, Jetty 9.4.18 变更日志, Jetty 9.4.17 变更日志, Jetty 9.4.16 变更日志)\n 更新 JNA 从 4.5.2 到 5.3.1 ,以解决使用 OpenJDK 时在 AIX 上加载共享库的问题。 (issue 57515)\n 更新 Remoting 到 3.33 。 (issue 57959, issue 50095, issue 57713, 完整变更日志)\n 支持在流水线和其他任务类型的 fingerprint() 构建步骤中设置排除和大小写敏感。 (文档, pull 3915)\n 提升 ListView 中 Configuration-as-Code 的兼容性。 (issue 57121)\n 停止在 install-plugin CLI 命令中使用 name 参数。 (pull 4123)\n 注销时删除超时的会话 cookie ,以防止与 header 太大等相关的错误。 (issue 25046)\n 在 Jenkins URL 配置中添加对 IPv6 地址的支持。 (issue 58041)\n 通过不同阴影的构建球,可以区分新项目、禁用项目和已中止构建的项目。 (pull 3997)\n 当 cron 触发器的执行时间较长时,添加告警。 (issue 54854)\n 在安装向导中分批安装插件以提高性能。 (pull 4124)\n 现在可以通过设置系统属性 hudson.node_monitors.AbstractNodeMonitorDescriptor.periodMinutes 来更改节点监视器的默认大小(例如可用磁盘空间)。 (pull 4105, 受系统属性控制的 Jenkins 功能)\n 2.176.4 (2019-09-25) 2.176.4 和 2.190.1 包含相同的安全修复程序。 我们将提供 2.176.x LTS 系列的附加版本,以允许管理员应用安全更新,而无需进行重大升级。\n 安全更新。 (安全公告) 2.176.3 (2019-08-28) 重要的安全修复。 (安全公告) 当其他插件对其仅具有可选依赖时,插件管理器 UI 不再阻止禁用插件。 (issue 33843) 解决使用 \u0026ldquo;记住我\u0026rdquo; 时的性能问题。 (由 2.160 引入的缺陷回归) (issue 56243) 测试代理配置时不要抛出异常。 (由 2.168 引入的缺陷回归) (issue 57383) 防止 Jenkins 重启和用户会话无效时的偶发 IllegalStateException 异常。 (issue 55945) ", "auhtor": "jenkinsci", "translator": "zhaoying818", "original": "", "poster": "“./2020-04-22-jenkins-release/great-wall.jpeg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-22-scale-your-jenkins-agents-using-kubernetes/", "title": "Kubernetes 构造可自由扩展的 Jenkins", "type": "wechat", "date": "2020-04-22 00:00:00 +0000 UTC", "tags": ["Jenkins", "Kubernetes", "CI/CD"], "description": "主要介绍 Jenkins 在 kubernetes 集群上的运行模式及配置", "content": " 如果你是一名在职软件工程师,那你大概率已经使用过 Jenkins,至少听说过。\nJenkins 是目前最受欢迎的开源持续集成与持续交付(CI/CD)工具。为何它会受到如此多用户的追捧?诸如 CloudBees 这样的组织及相关优秀社区提供了坚实的帮助与支持,此外,一大批开发人员贡献了数以千计的插件,加上 Jenkins 良好的易用性,都让 Jenkins 从开源工具中脱颖而出。\n基于以上特点,Jenkins 可以轻松实现以下事情:\n 结合主流版本管理工具,如 Git,Subversion 和 Mercurial; 集成代码质量管理工具,如 Sonarqube,Fortify; 使用 Maven 或 Gradle 构建 ; 使用 Junit 进行单元测试; 虽然 Jenkins 如此强大,但其入门使用却非常简单,你只需要准备一个 Web 应用服务器如 Tomcat 和一份可执行的安装文件 jenkins.war 即可。Jenkins 的运行方式有很多种,这里将介绍几种非常典型的方式。\n独立的 Jenkins 服务器 在这种模式下,只有一个 Jenkins 服务器负责所有的构建任务并使用 TCP 连接部署到远程服务器上。这也是最简单的一种方式,你完全不需要担心其他可变因素。\n主从策略 采用单机模式运行 Jenkins 有一些弊端。\n尽管单机模式你无需考虑多服务器和节点,但当大量的构建任务在同一时间运行时,服务器可能会负荷过重。你可能会考虑增加节点可并发执行的构建任务数量,但是很快就会遇到性能瓶颈。\n为了解决这个问题,你可以将部分任务分发到其他的机器上去,即 Jenkins 从节点。Jenkins 从节点会运行一段程序与主节点进行通信,判断是够有可执行的构建任务。一旦 Jenkins 主节点调度安排好构建任务,就将其分发至相应的从节点。那我们的问题解决了吗?接着往下看。\n可扩展的 Jenkins 我们进一步来探索 Jenkins 的运行方式。当你的团队中还未建立 CI 时,你可能无需多台静态服务器来执行 Jenkins 任务。\n当你无需 7*24 运行时,你的服务器可能会空闲,这时就产生资源浪费了。\n但如果你正在使用容器技术如 Kubernetes,你可以让 Jenkins 的运行架构变得更高级。简单的说,就是让主节点处理调度构建任务,把任务分发任务到从节点进行执行,但是你并不需要事先就生成相应的从节点——当从节点需要使用时,会立刻应运而生。\n这种运行架构可以解决下面的问题\nJenkins 服务器性能不再是问题 当你将 Jenkins 运行在 Kubernetes 集群中时,Jenkins 可以根据集群资源使用情况调节并启动。因为很多应用都共享一个集群,这样就能有效的节约资源——这种情况下 Jenkins 并不会运行在一个资源使用顶峰时候。\n如果你将集群部署在云端,如 Google Cloud Platform,Jenkins 的运行将会变得更加轻松灵活。GKE 不仅仅可以根据容器的情况自我调节,还可以根据集群的负载情况添加或移除节点,如此一来就有了无限扩展的能力。\n并行运行构建任务 你无需再仔细考虑同一时间并发执行的任务数目,Jenkins 会准备好一个从节点以便于运行相关的任务。\n负载均衡 Kubernetes 也可以很好的实现负载均衡,它会让 Jenkins 从节点运行在最适合的服务器上,正因如此,构建任务的运行会更快且更有效率。\n自我修复 如果你的构建任务或者从节点突然遇到问题了,这个时候你完全不用担心,Jenkins 会自动移除有问题的从节点并启动一个新的从节点。\n这样会节省大量的故障排查时间,因为每个从节点不是必须存在的,如果某个从节点遇到障碍,Jenkins 会请求 Kubernetes 移除它并启动一个全新的从节点。就是这么简单。\n我们选择哪种运行架构 一开始,我们可能采用单机模式使用 Jenkins,半年内可能不会有什么问题,当使用的人越来越多,负载也越来越高,最终我们都不得不面临负载超出范围的问题。\n当我们还没有使用 Kubernetes,解决办法可能是搭建主从架构或给单机服务器增加 CPU 和内存。我们可能会选择后面这种办法,因为这是最有效和最直接的方式。然而这种方法并不能彻底解决我们的问题。\n如何解决这个问题 多次尝试后,我们公司 CTO 提出云部署的方式,我们决定将 Jenkins 部署到云端并和已有的 Kubernetes 集群结合在一起,除此之外,我们还将其他的工具也一并迁移到了云端。是不是很简单?让我们来验证一下。\n我们有两个方案。一是将主节点运行在容器中的单机模式,另外一个方案就是利用将 Jenkins 运行在 Kubernetes 集群 。后者我们提出以下2层拓扑结构:\n Jenkins 主节点作为控制器,管理用户登陆及调度构建任务; 使用 Kubernetes 启动额外的 Jenkins 从节点容器,用户将在这些从节点容器中触发任务并运行,当任务成功执行完成后,容器会被移除; 接下来我们看看如何进行配置。\n创建 Jenkins 主节点实例镜像 创建主节点实例镜像的 Dockerfile 如下:\n version: \u0026quot;3\u0026quot; FROM jenkins/jenkins:centos # # Distributed Builds plugins RUN /usr/local/bin/install-plugins.sh ssh-slaves # # install Notifications and Publishing plugins RUN /usr/local/bin/install-plugins.sh email-ext RUN /usr/local/bin/install-plugins.sh mailer RUN /usr/local/bin/install-plugins.sh slack # # Artifacts RUN /usr/local/bin/install-plugins.sh htmlpublisher # # UI RUN /usr/local/bin/install-plugins.sh greenballs RUN /usr/local/bin/install-plugins.sh simple-theme-plugin # # Scaling RUN /usr/local/bin/install-plugins.sh kubernetes # # install Maven USER root RUN yum update -y \u0026amp;\u0026amp; yum install -y maven USER jenkins 构建镜像\ndocker build -t \u0026lt;your-docker-registry\u0026gt;/jenkins-master:0.0.1 .\n将镜像推送至中央仓库\ndocker push \u0026lt;your-docker-registry\u0026gt;/jenkins-master:0.0.1\n这个 Dockerfile 很简单,不需要安装任何软件,因为主节点不用运行任何构建任务,而仅仅是管理各节点。你可以根据自己的需求修改。\n自启动 Jenkins 主节点运行实例 接下来使用 Kubernetes mainfest 文件启动Jenkins 主节点的运行实例,文件内容如下:\n apiVersion: v1 kind: ServiceAccount metadata: labels: k8s-app: jenkins name: jenkins namespace: default apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: jenkins-crb roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: jenkins namespace: default apiVersion: v1 kind: PersistentVolumeClaim metadata: name: jenkins-pv-claim labels: app: jenkins spec: accessModes: - ReadWriteOnce resources: requests: storage: 30Gi apiVersion: apps/v1 kind: Deployment metadata: name: jenkins-deployment labels: app: jenkins spec: replicas: 1 selector: matchLabels: app: jenkins template: metadata: labels: app: jenkins spec: serviceAccountName: jenkins volumes: - name: jenkins-pv-storage persistentVolumeClaim: claimName: jenkins-pv-claim containers: - name: jenkins image: \u0026lt;your-docker-registry\u0026gt;/jenkins-master:0.0.1 env: - name: JAVA_OPTS value: -Djenkins.install.runSetupWizard=false imagePullPolicy: Always ports: - containerPort: 8080 - containerPort: 50000 volumeMounts: - mountPath: \u0026quot;/var/jenkins_home\u0026quot; name: jenkins-pv-storage securityContext: privileged: true imagePullSecrets: - name: regcred initContainers: - name: volume-mount-data-log image: busybox imagePullPolicy: Always command: [\u0026quot;sh\u0026quot;, \u0026quot;-c\u0026quot;, \u0026quot;chown -R 1000:1000 /var/jenkins_home\u0026quot;] volumeMounts: - mountPath: \u0026quot;/var/jenkins_home\u0026quot; name: jenkins-pv-storage apiVersion: v1 kind: Service metadata: name: jenkins-service labels: app: jenkins-svc spec: ports: - port: 8080 targetPort: 8080 protocol: TCP name: app - port: 50000 targetPort: 50000 protocol: TCP name: jnlp selector: app: jenkins apiVersion: extensions/v1beta1 kind: Ingress metadata: name: jenkins-ingress annotations: nginx.ingress.kubernetes.io/add-base-url: \u0026quot;true\u0026quot; nginx.ingress.kubernetes.io/proxy-body-size: \u0026quot;0\u0026quot; spec: rules: - host: jenkins.example.com http: paths: - path: / backend: serviceName: jenkins-service servicePort: 8080 - host: jenkinsmaster.example.com http: paths: - path: / backend: serviceName: jenkins-service servicePort: 50000 manifest file 主要定义了以下内容:\n 默认命名空间中增加一个名为 Jenkins 的服务; jenkins-crb,将 jenkins 服务与集群管理员 cluster-admin 绑定,这就允许 Jenkins 主节点和 Kubernetes 集群进行通信并执行一些集群管理的任务如启动或停止 pods; jenkins-pv-claim,作为一个持久化的数据卷,可以保存 30GB 的Jenkins 数据; Jenkins 主节点运行实例启动后,Jenkins 服务和 jenkins-pv-claim 数据卷对外暴露的端口分别是8080和50000 说明 Jenkins 主节点在集群中的 IP; 设置 Jenkins 对外提供的 URL; 上述配置生效后,你可以自行选择负载均衡方式或者从节点运行方式,也可以根据需要改变,然后使用 kubectl apply-f\u0026lt;manifest_file\u0026gt; 使文件生效。接下来你就可以在浏览器中通过Jenkins.example.com 上(或自行定义的url)来访问 Jenkins。\n构建从节点运行实例镜像 相比主节点,从节点镜像有所不同,它们并不会管理你的构建任务而仅仅是执行而已。因此,我们需确保从节点符合运行的所有要求。\n既然我们目前所构建的应用都是运行在容器上的微服务,我们需在 Jenkins 的从节点服务器上安装 docker,只有这样我们才能在从节点上运行 docker。\n所用的Dockerfile 如下:\n FROM jenkins/jnlp-slave # # install Maven USER root RUN apt update -y RUN apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common RUN curl -fsSL https://apt.dockerproject.org/gpg | apt-key add - RUN apt-add-repository \u0026quot;deb https://apt.dockerproject.org/repo debian-$(lsb_release -cs) main\u0026quot; RUN apt-get update RUN apt-cache policy docker-engine RUN apt-get install -y docker-engine=1.13.1-0~debian-stretch VOLUME /root/.docker RUN cd /usr/bin \u0026amp;\u0026amp; curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl RUN chmod +x /usr/bin/kubectl COPY config /root/.kube/ RUN wget -O /root/helm.tar.gz https://get.helm.sh/helm-v2.15.2-linux-amd64.tar.gz RUN cd /root \u0026amp;\u0026amp; tar -zxvf helm.tar.gz RUN cd /root \u0026amp;\u0026amp; mv /root/linux-amd64/helm /usr/bin/helm RUN chmod +x /usr/bin/helm RUN cp -a /usr/bin/helm /usr/local/bin/helm RUN helm init --upgrade USER root 构建镜像\ndocker build -t \u0026lt;your-docker-registry\u0026gt;/jenkins-slave .\n将镜像推送至中央仓库\ndocker push \u0026lt;your-docker-registry\u0026gt;/jenkins-slave\n在Jenkins 上配置 Kubernetes 集群 从节点的运行镜像已经推送至中央仓库后,下一步就是在 Jenkins 上设置一旦有构建任务触发时如何用 Kunernetes 启动一个运行容器。主要步骤分为以下两个步骤:\n通过 kubectl cluster-info | grep master 获取 URL 或 Kunernetes API\n在 Jenkins 的 cloud configure 界面 [your_jenkins_url]/configureClouds/)配置如下:\n最后记得保存以上设置\n禁用主节点执行器 为了确保主节点仅仅作为控制器而不执行具体的构建任务,我们需要将主节点的 executors 设置为0.\n访问[your_jenkins_url]/computer/(master)/configure ,根据下图指示executors 设置为0并保存\n测试配置是否生效 创建一个自由风格任务,并命名为 job-1,并根据以下步骤进行配置\n创建一个和 job-1 完全一样的任务,命名为 job-2\n同时启动两个任务,此时你会注意到这两个构建任务都分别在 kubernetes 生成了一个新的 pod ,并且同时执行着。\n在控制台查看两个任务的输出:\n", "auhtor": "Gaurav Agarwal", "translator": "walker0921", "original": "https://medium.com/better-programming/how-we-scaled-jenkins-in-less-than-a-day-ccbcada8e4a4", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-20-weekly-release/", "title": "Jenkins 每周版更新", "type": "wechat", "date": "2020-04-20 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "本次更新的版本包括:2.185~2.230", "content": " 2.230 (2020-04-06) 改进告警横幅的样式,使其更具视觉吸引力并更好地匹配现有的用户界面组件。 现在,警报在显示时完全覆盖了导航栏,而不是仅覆盖导航栏的一部分。 (issue 61478) 检查任何一个权限时,权限错误中将不再显示已禁用的权限。 (issue 61467) 显示与标签相关而非单个节点的阻塞原因时,允许使用超链接。 (pull 4616) 添加选项以支持配置归档制品时的符号链接。 (issue 5597) 除了通常的全局/Administer权限之外,具有全局/管理权限的用户现在也可以访问准备关机管理链接。 (issue 61453) 更新页脚样式。 (issue 61496) 允许 configuration-as-code plugin 禁用管理员监控。 (issue 56937) 更新 Groovy Init hooks,使其在任务配置修改后运行。 (issue 61694) 修复指纹清除线程中的类强制转换异常。 (issue 61479) 2.229 (2020-03-29) 重新启动时使用保存的全局构建丢弃配置。 Jenkins 2.221 到 2.228 在重新启动时会忽略保存的全局构建丢弃配置。 (issue 61688) 修复设置密码后代理表单验证的问题(由 2.205 引入的缺陷回归)。 (issue 61692) 更新 .NET 版本检查,使其更适合自带的 .NET 版本。 (pull 4554) 具有全局/管理或全局/系统读取(以及通常的全局/Administer)权限的用户可以访问关于 Jenkins 的管理链接。 (issue 61455) 稳定性: 将 null 转换为 Secret 时不再抛出 NullPointerException。 (pull 4608) 升级到 Remoting 4.3,以解决 WebSockets 上的大量有效负载的问题。 需要具有 Remoting 4.3 或更高版本的配套 agent.jar。 (pull 4601, pull 4596, issue 61409, Remoting 4.3 变更日志, WebSockets 博客文章, JEP-222) 开发者: 在失败时自动创建符号链接,并记录告警。 (issue 56643) 开发者: 无需 JenkinsRule 即可在单元测试中使用 Secret 和 ConfidentialKey。 (pull 4603) 2.228 (2020-03-25) 重要安全修复。 (安全公告) 与请求路由和 CSRF 保护有关的安全增强。 (相关升级指导) 2.227 (2020-03-22) 具有全局/管理权限的用户可以访问系统信息管理链接,其中仅显示插件和内存使用信息。 (issue 61456) 在超大屏幕上限制管理 Jenkins 条目的最大宽度。 (pull 4582) 具有全局/管理权限(以及通常的全局/Administer)的用户可以配置系统配置中的使用统计。 (issue 61457) 使基于 HTTP DELETE 的项目删除行为更像 API,建议通过 POST /doDelete 进行删除。 (issue 61308) 提高上下文菜单的滚动速度。 (pull 4592) 在插件管理的已安装选项卡上列出未能加载的插件。 (pull 4589) 当插件正在寻找新的维护者时,在插件管理器中突出显示(“领养此插件”)。 (pull 4584) 开发者: 添加用于管理链接类别定义的 Javadoc。 (pull 4578) 内部: 允许使用高于 8 的 JDK 版本进行 core 构建。 (issue 61105) 2.226 (2020-03-15) 修复了任务配置表单中之前保存步骤中存在的拖放操作问题 (由 2.217 引入的缺陷回归)。 (issue 61429) 删除铃铛旁边不必要的“监视器”文本,以使 UI 更加整洁。 更改铃铛旁边的通知颜色,以使其更引人注意。 (issue 61224) 允许使用 configuration-as-code 插件配置使用情况统计信息。 (issue 54662) 允许使用 configuration-as-code 插件配置 ssh 鉴权密钥。 (pull 4563, ssh-cli-auth 1.8 变更日志) 尽可能使用浏览器提供的当前系统字体。 更改正文和标题的字体大小,以提高一致性和可读性。 (issue 60921) 将捆绑的 Script Security 插件从 1.70 更新到 1.71。 (pull 4561, Script security plugin 1.70 变更日志, SECURITY-1754 sandbox bypass 漏洞) 当前已安装的插件中存在安全问题时,在插件管理列表中显示。 (pull 4553) 为\u0026rsquo;新建视图\u0026rsquo;添加法语翻译。 (issue 61424) 修复了 Jelly enum 格式控件中对 default 属性的支持。 (issue 61385) 添加 ManagementLink#getCategory() 以便于将“管理 Jenkins” 上的条目分类。 有关支持的返回值,请参见 ManagementLink.Category 枚举。 (pull 4546) 开发者: 使 h.checkAnyPermission 和 可以在非 AccessControlled 的对象上工作。 (issue 61465) 标记 newInstanceFromRadioList() 方法和调用者可以为 null。 (pull 4543) 内部: 重新启动视图中删除内联资源。 (issue 60866) 2.225 (2020-03-09) 保存任务时不丢失 SCM 配置(由 2.224 引入的缺陷回归)。 (issue 61398) 2.224 (2020-03-08) WARNING: 此版本在保存任务时引入了严重的问题。 请参阅 JENKINS-61398。 请避免更新到此版本。 Winstone 5.9: 修复最大表单内容大小和表单内容密钥的传递(由 Jetty 9.4.20 和 Jenkins 2.205 引入的缺陷回归)。 (pull 4542, issue 60409, Winstone 5.9 变更日志) Winstone 5.9: 修复由于 X-Forwarded-Host 和 X-Forwarded-Port 订阅问题而导致的将不正确的反向代理重定向到 Host 的问题(由 Jetty 9.4.20 和 Jenkins 2.205 引入的缺陷回归)。 (pull 4542, issue 60199, Winstone 5.9 变更日志, Jetty 9.4.27 变更日志) 不会对某些具有任务/配置权限的用户禁用任务配置表单上的所有控件(由 2.223 引入的缺陷回归)。 (issue 61321) 在插件管理器中显示插件发布日期。 (pull 4535) 禁止将非管理员用户的错误堆栈跟踪作为核心功能。 (issue 60410) 指示何时通过插件管理器中的更新解决安全问题。 (issue 61166) 在插件管理器中将插件类别显示为标签,而不是将它们分组到不同的表格中。 (pull 4534) 防止在 DescriptorList#newInstanceFromRadioList() 和 ExtensionDescriptorList#newInstanceFromRadioList() 中处理未处理的 JSONException。 (issue 61345) 调整屏幕大小时,调整搜索框到合适的大小。 (issue 61300) 删除只读用户在 textarea 表单元素下方的灰色条。 (issue 61284) 防止在没有工具安装程序元数据的情况下单击自定义更新中心的“立即检查”时的 NullPointerException。 (issue 60788) 如果未安装 cloud plugin,修复 clouds 配置页面上的空白页面。 (issue 61285) 更新 descriptorRadioList 表单元素,以遵循 DescriptorVisibilityFilter 扩展点。 (issue 51495) 将版本号库从 1.6 更新到 1.7,以解除对 FindBugs 注解的暂时依赖性。 (issue 61279) 2.223 (2020-03-01) 删除“自动刷新”功能,包括现在已过时的自动刷新遥测功能。 (pull 4503) 允许具有系统读取权限的用户查看全局安全配置页面。 (issue 61205) 允许具有系统读取权限的用户查看关于 Jenkins 页面。 (issue 61201) 具有扩展读取权限的用户现在将获得外观更具只读性的 UI。 (issue 61202) 防止出现 “Jenkins.instance 丢失”的情况。 (pull 4525, issue 55070, issue 59992, issue 60454, issue 61192) 默认情况下重新引入构建历史描述截断。 允许通过 historyWidget.descriptionLimit 系统属性管理/禁用限制。 负值将消除限制,0 则强制为空。 (pull 4529, issue 61004, issue 60299) 避免在将自定义根目录设置为文件系统根目录(例如 C:\\)的情况下启动非流水线构建时的 NullPointerException。 (issue 61197) 允许 FingerprintFacet 阻止删除指纹。 (issue 28379) 内部: 删除未使用的类 StringConverter2。 (pull 4468) 内部: 删除未使用的内部类 Memoizer(此类使用了 ConcurrentHashMap)。 (pull 4470) 开发者: 在调试模式下,默认监听回送接口。 (pull 4515) 2.222 (2020-02-23) 修改标题栏和 breadcrumbs 导航的布局和图标。 依赖于 Jenkins 布局细节的插件的实例(例如简易主题插件)可能会遇到 UI/布局问题。 通过将 jenkins.ui.refresh 系统属性设置为 true,可以启用新的实验性标题颜色方案。 (issue 60920) 引入一个新的实验性 UI,可以通过将 jenkins.ui.refresh 系统属性设置为 true 来启用。 作为 UI/UX 改进的一部分,当前,它包括一个新的标题颜色方案,后续将添加更多更改。 (pull 4463, issue 60920, JEP-223, Jenkins UX SIG) 添加新的实验性 全局/管理 权限,该权限允许用户在不具有 全局/Administer 权限的情况下配置部分全局 Jenkins 配置。 这是一项实验性功能,默认情况下处于禁用状态,可以通过将 jenkins.security.ManagePermission 系统属性设置为 true 来启用。 (pull 4501, issue 60266, JEP-223) 添加一个新的实验性全局/系统读取权限,该权限(几乎)为 Jenkins 实例提供完全读取权限。 默认情况下,该权限是禁用的,请安装 Extended Read Permission 插件以将其激活。 (pull 4506, issue 12548, JEP-224, Extended Read Permission 插件) 弃用全局/运行脚本、全局/上传插件和全局/配置更新中心权限。 在 2017 年,主要授权插件中的权限被宣布为危险且默认情况下被禁用。 自定义授权策略实现将授予全局/Administer 权限,而不暗示这三个权限中的一个或多个将不再按预期工作。 在没有全局/Administer 权限的情况下向用户授予这些权限中任何一个的配置将不能按预期工作。 (pull 4365, issue 60266, JEP-223, 2017-04-10 Matrix Authorization 插件的安全公告, 2017-04-10 Role-Based Authorization 插件的安全公告) 删除禁用 CSRF 保护的功能。 从较旧版本的 Jenkins 升级的实例将启用 CSRF 保护和设置默认的发行者,如果之前被禁用。 (pull 4509) 在全局配置页面中订购管理员监视器。 (issue 60966) 将内存使用情况监视器添加到系统信息页面。 (pull 4499) 提高加载捆绑任务时的性能。 (pull 4497) 解决使用资源域时打开文件过多错误的问题。 (issue 61121) 添加法语翻译以获取并发构建帮助。 (pull 4505) 开发者: 添加新的 checkAnyPermission 和 hasAnyPermission 方法,如果用户具有上述权限之一,则允许访问。 (pull 4506, issue 12548, JEP-224) 开发者: 添加一个新的 f:possibleReadOnlyField jelly 标签,将字段包装为 if 只读检查,如果经过身份验证的用户仅具有读取访问权限,则将结果以文本输出。 如果该字段为空,则添加 N/A。 (pull 4506, issue 12548, JEP-224) 开发者: 添加一个新的 l:hasAdministerOrManage jelly 标签,如果用户没有 Jenkins.ADMINISTER 或Jenkins.MANAGE,则隐藏标签的正文。 (pull 4506, issue 12548, JEP-224) 开发者: 允许插件基于 UpdateSite 强制更新。 (issue 61046) 2.221 (2020-02-19) 此版本首次提供了全局配置的构建废弃器。 Jenkins 现在将定期执行已配置的每个项目的构建废弃器,即使当前尚无构建完成。 如果自上次运行构建以来,已经为项目配置了更激进的构建丢弃程序配置,则全局配置的构建丢弃程序可能会删除旧的构建。\n 添加全局配置的构建丢弃程序,删除未标记为“永久保留”的旧构建,即使没有配置、积极性较低、配置的按项目构建丢弃程序或者在构建完成后定期执行。 (pull 4368) 默认情况下,即使当前没有构建完成,Jenkins 也会定期执行配置的每个项目的构建废弃器。 这可能会删除自上次运行以来具有更积极的构建丢弃程序配置的项目的旧构建。 (pull 4368) 动态加载某些插件可能会导致权限错误。 (issue 61071) 将捆绑的脚本安全性插件从 1.68 更新到 1.70。 (pull 4490) 权限错误中不再显示禁用的权限。 (pull 4482) 开发者: 在 Javadoc 说明中使用正确的告警框名称。 (pull 4493) 开发者: 向 getAllItems()、allItems() 和 getItems() 引入过滤重载。 (pull 4469) 开发者: 添加新的扩展点 BackgroundBuildDiscarderStrategy,以便为全局构建丢弃程序配置提供更灵活的构建丢弃策略。 (pull 4368) 开发者: 将 findsecbugs 插件添加到 spotbugs 构建插件。 (pull 4381) 内部: 从 HudsonPrivateSecurityRealm 视图中删除内联资源。 (issue 60866) 内部: 当 AtomicFileWriter 无法写入文件时显示已更改异常。 (pull 3989) 2.220 (2020-02-09) 将代理安装作为 Windows 上的服务的问题修复(由 2.217 引入的缺陷回归)。 (Remoting 4.2 变更日志, Agent Installer Module 1.7 变更日志) 修复在获取具有状态阈值的运行列表时的空指针异常(由 2.202 引入的缺陷回归)。 (issue 60884) 移除网络发现服务(UDP 和 DNS)。 (issue 60913) 扩展当前里程碑,以便插件可以在 Jenkins 初始化期间更新任务和配置。 增加初始化里程碑:SYSTEM_CONFIG_LOADED、SYSTEM_CONFIG_ADAPTED 和 JOB_CONFIG_ADAPTED。 (issue 51856) 在更新站点 REST API 中导出插件兼容性标志。 (pull 4385) 在安装向导中建议安装 Jenkins Configuration as Code 插件。 (pull 4410) 在某些情况下,不会记录创建代理的用户。 (issue 21837) 避免记录由节点删除引起的节点监视异常。 (issue 54496) 改进 RSS 订阅的标题。 (issue 60848) 在任务的构建历史记录中显示构建持续时长作为一个工具提示到构建日期/时间。 (pull 4453) 提高表视图在显示项目时的性能。 (pull 4462) 提高在使用 jenkins.model.StandardArtifactManager.disableTrafficCompression=true 时制品归档的性能。 (issue 60907) 防止在 Jenkins 启动时创建重复的设置向导单例实例。 (issue 60867) 修复 ChoiceParameterDefinition.getDefaultParameterValue 中的 IndexOutOfBounds 异常。 (issue 60721) 更新插件管理器页面,以便在 Jenkins 正在重新启动时显示图标。 (issue 59486) 2.219 (2020-01-29) 重要的安全修复。 (安全公告) 与 Stapler 路由相关的安全增强。 安全增强: 在 REST API 响应中将 X-Content-Type-Options 设置为 nosniff。 2.218 (2020-01-27) Winstone 5.8: 修复传递某些种类的证书(例如域通配符)时,Jetty 的 KeyStores with multiple certificates are not supported 错误 (由 2.217 引入的缺陷回归) (issue 60857, Winstone 5.8 发布说明 - 由 Winstone 5.6 引入的缺陷回归) Winstone 5.7: 修复对系统日志记录定制的支持 (由 2.177 引入的缺陷回归) (issue 57888, Winstone 5.7 发布说明) 将布尔禁用标志添加到适用于任务的 REST API 输出中,以用于 Freestyle、Maven 和 Multi-configuration(Matrix)等经典项目类型。 (pull 4436) 内部: Winstone 5.7: 将 Jetty 线程池名称更改为“Jetty(winstone)” (Winstone 5.7 发布说明) 2.217 (2020-01-23) 将本地化版本修复为不再报告 can\u0026rsquo;t parse argument number: changelog.url (由 2.214 引入的缺陷回归)。 (issue 60822) Jenkins 2.212+ 无法加载某些注入的字段,例如 Bitbucket Server Integration 插件使用的字段。 (issue 60816) 添加实验性的 WebSocket 支持。 (JEP-222, blog post) 将 Jetty 从 9.4.22.v20191022 升级到 9.4.25.v20191220。 (Jetty 9.4.23 发布说明, Jetty 9.4.24 发布说明, Jetty 9.4.25 发布说明) 将 Remoting 升级到 4.0。 (Remoting 4.0 发布说明) 在安装 Monitoring 插件时,防止有关 Java 11 缺少的、由 JavaMelody 触发的类的错误告警。 (issue 60725) 修复 AdoptOpenJDK 11 的 Java 版本检查。 (issue 60678) 内部: 前端工具链已升级为使用 webpack。 使 babel 能够转义某些 JS 模块。 (issue 60734) 开发者: 更新访问修饰符以允许插件使用屏蔽。 (pull 4441) 2.216 (2020-01-22) NOTE: 版本构建失败,不发布。 * 构建失败,版本不发布。\n 2.215 (2020-01-19) 如果在运行安装向导之前已经通过脚本配置了 Jenkins 根 URL,即使选择跳过创建 admin 用户的选项,跳过位置配置面板。 (issue 60750) 防止计算节点页面中的 RSS 订阅返回错误 404。 (issue 60577) 当构建连续失败时,在系统日志中包括详细信息。 (issue 60716) 2.214 (2020-01-11) 删除古老的、不推荐使用的、不支持的代理协议 Inbound TCP Agent Protocol/1, Inbound TCP Agent Protocol/2 和 Inbound TCP Agent Protocol/3。 将 Remoting 从 3.36 更新到 3.40,以删除不受支持的协议和较小的维护改进。 (issue 60381, Remoting 3.40 发布说明) 删除全局安全配置中的启用安全复选框。 (issue 40228) 阐明构建历史不包括流水线阶段。 (issue 59412) 现在可以从(非流水线)构建中使用环境变量 WORKSPACE_TMP 来访问与构建工作空间关联的临时目录。 (issue 60634) 内部: 在 EnvVars 中添加一个方法,该方法通过滤除 null 值来扩展 TreeMap.putAll() 功能。 (issue 59220) 内部: 允许使用 DescriptorVisibilityFilter 来过滤 UI 上的 View 属性。 (issue 60579) 修复代理脱机时代理 API 中的空指针异常(例如查询代理版本或操作系统说明)。 (issue 42658) 当无法检索可选的依赖元数据时,修复插件管理器中的 JavaScript 错误。 改进插件管理器 UI 中的措辞。 (issue 56152) 解决一些较小的本地化问题(例如转义、条目不完整等)。 (pull 4420) 修复 Javadoc 和 WebUI 中的错别字和拼写。 (pull 4418) 2.213 (2020-01-06) 修复了包含库 JAR 的插件的插件类资源加载失败的问题。 至少已知脚本安全性和活动目录插件会受到影响。 (由 2.112 引入的缺陷回归) (issue 60641, issue 60644) 2.212 (2020-01-05) WARNING: 此版本存在严重的问题,请参阅 JENKINS-60644。 请避免更新到此版本。\n 防止更新中心在进行数据解析时 Jenkins 页面卡住。 (issue 60625) 当无效字符串作为运行状态 CLI 参数传递时,将返回错误。 (pull 4212) 修复了加载可选依赖项的极端情况,这些依赖项会导致 Jenkins 在启动时崩溃。 (pull 4393, pull 4417, issue 60449) 开发者: 引入新的 AntClassLoader.getUrl() 方法以防止代码重复。 (pull 4254) 2.211 (2020-01-02) 使 queue/cancelItem REST API 返回有意义的结果代码,而不是错误 404。 (issue 60326) 从 Jenkins CLI 中移除未使用的 commons-codec 依赖。 (issue 60326) 2.210 (2019-12-22) 解决启动日志中的 AtomicInteger 和类过滤器告警。 (issue 60513) 验证另一个用户时,当前用户不再注销。 (issue 59107) 呈现某些用户控制的字符串时,显示 null 文本而不是空白文本。 (issue 60554) 从安装向导中删除易受攻击的 Team Concert 插件。 (CSRF 漏洞, 凭据枚举漏洞) 如果 hudson.Util.maxFileDeletionRetries 为零,禁用多次删除尝试。 (issue 60351) 2.209 (2019-12-15) 改进了传统 GUI 的执行程序小部件中的停止按钮行为,以避免意外中断错误的任务。 (issue 59656) 使用 SCMDescriptor#generation 中的 AtomicInteger 修复 Spotbugs 报告的并发问题。 (pull 4337) 2.208 (2019-12-09) 修复文件访问规则的在线示例、文档。 (pull 4383) 基于“代理节点到 master 的访问控制”使用白名单命令,当输入为空时,防止出现异常。 (issue 60278) 通过在 Computer.removeExecutor 中删除一次性执行器来防止 master 上的“僵尸”执行器。 (issue 57304) 2.207 (2019-12-01) 将捆绑的脚本安全性插件更新为 1.68。 (pull 4367) 当 Jenkins 使用反向代理并重新启动时,请不要过早重新加载。 (issue 6798) 2.206 (2019-11-24) 弃用 macOS 本机安装程序打包。 (Jenkins macOS 本机安装程序描述) 在插件管理器通过独立的页签打开插件和许可证链接。 (issue 60189) 为页面自动刷新标记设置 HttpOnly 标志。 (pull 4363) 避免在使用任务 DSL 定义视图时出现异常。 (issue 60092) 修复在 CephFS 上创建空文件时的 AtomicFileWriter 性能问题。 (issue 60167) 开发者: ViewGroupMixIn#getPrimaryView() 可能返回 null,需要基于这个周版本及以后的版本在插件中进行检查。 这是一个过渡状态,直到实现默认视图为止。 (issue 60092) 开发者: 使用 junit5 进行 CLI 测试。 (pull 4220) 2.205 (2019-11-17) 将云配置从\u0026rdquo;配置系统\u0026rdquo;移动到\u0026rdquo;管理节点\u0026rdquo;页面上其自身的配置表单中。 (pull 4339) 重新设计密码字段,以防止自动填写密码(登录表单除外)。 减少提供更新存储密码的浏览器。 通过将系统属性 hudson.Functions.hidingPasswordFields 设置为 false 来还原。 (pull 3991) 将鼠标悬停在文本上时,工作台上显示代理错误状态。 (issue 6722) 将鼠标悬停在侧栏链接上时,显示带有完整链接名称的工具提示。 (issue 59508) 运行完成和更新中心轮询事件的级别从 INFO 降低为 FINEST。 (pull 4345) 尝试始终在主服务器上执行轻量级任务,例如流水线或矩阵任务的主要构建。 (pull 3983) 将 Winstone 从 5.3 更新到 5.4,将 Jetty 从 9.4.18 更新到 9.4.22。 (Winstone 5.4 完整变更日志, Jetty 9.4.22 变更日志, Jetty 9.4.21 变更日志, Jetty 9.4.20 变更日志, Jetty 9.4.19 变更日志) 内部: 使 ProxyConfiguration 与 configuration-as-code 插件兼容。 不再需要 configuration-as-code 插件侧边栏的解决方法。 (issue 56553) 内部: 从核心中删除未使用的 jenkins-slave.xml 文件模板。 需要 1.3.1(2017.03.14 发布)或更高版本的 WMI Windows Agents 插件。 (pull 4330) 修复\u0026rdquo;插件管理-已安装\u0026rdquo;列表中卸载列的排序。 (issue 59665) 修复构建历史记录表样式。 (issue 59631) 防止错误的子任务提供者使构建永久运行。 (issue 59793) 内部: jenkins-cli.jar 中移出未使用的远程库。 (pull 4350) 开发者: 将 maven-jenkins-dev-plugin 切换到上游的 jetty-maven-plugin。 (pull 4351) 禁用 HTTP TRACE,以防止安全扫描程序的告警。 对于 2003 年的 Web 浏览器来说,这种风险是巨大的。 现代的浏览器禁止 TRACE 请求来防止跨站点跟踪(XST)攻击,因此没有真正的风险。 (issue 60180) 2.204 (2019-11-10) 插件管理器描述始终链接到插件站点,而不是 Jenkins wiki。 (issue 59679) 增加为多阶段时间序列图记录的数据点的数量,例如用于负荷统计的那些。 (pull 4341) 将 Remoting 从 3.35 更新到 3.36,以添加新的命令行选项 \u0026ldquo;-help\u0026rdquo; 和 \u0026ldquo;-version\u0026rdquo;。 (Remoting 发布说明) 开发者: 加强队列,以防止 NodeProperty 和 QueueTaskDispatcher 扩展点中的 canTake() 和 canRun() 实现而导致的队列挂起。 (issue 59886) 2.203 (2019-11-05) 允许按用户设置时区。 (issue 19887) 日志用户界面: 重新排列侧面板条目的顺序,添加一条注释,即\u0026rdquo;所有日志消息\u0026rdquo;将仅包含 NOTE 和更高级别的条目。 (pull 4305) 更新\u0026rdquo;插件管理器更新\u0026rdquo;选项卡,呈现有关不兼容依赖项的更多信息。 (pull 4299) 现在,构建趋势页面上的构建状态球链接到相应构建的控制台输出。 (issue 17459) 通过使 PluginManager#start() 以 SYSTEM 身份运行,可以在动态加载插件时防止权限问题。 (issue 59775) 正确处理资源根 URL token 中包含 : 字符的用户名。 (issue 59859) 防止在不发送 cookie 的情况下访问 /logout 的 NullPointerException 异常。 (issue 59904) 开发者: 使 ResourceDomainConfiguration 中的某些方法可以在插件中调用。 (pull 4335) 2.202 (2019-10-27) 在 Firefox 的 Jenkins 经典 UI 中还原表单提交的更改已导致带有\u0026rdquo;文件\u0026rdquo;输入的表单的回归。 这样做是为了预料 Firefox 中的错误修正,此错误已被撤消。 (由 2.173 引入的缺陷回归) (issue 58296, issue 53462, Firefox issue 1370630) 在\u0026rdquo;自动刷新\u0026rdquo;功能的使用中添加遥测。 (pull 3894) 将 java.util.concurrent.ConcurrentLinkedDeque 添加到 JEP-200 反序列化白名单。 (pull 4300) 开发者: 引入 Run#getBuildsOverThreshold() 方法以使超出所需的执行结果得以运行。 (pull 4259) 2.201 (2019-10-20) 由于编码问题,资源 URL 无法提供名称不重要的文件。 (issue 59849) 修复本地化标题在安装向导中跨越多行时的显示问题。 (issue 59800) 2.200 (2019-10-14) 为资源根 URL 添加一个选项,Jenkins 可以通过该选项为用户生成的静态资源(例如工作空间文件或已归档的制品)提供服务,而无需 Content-Security-Policy 标头。 (issue 41891) 删除使用用户浏览器下载更新中心元数据的功能(自 2015 年起不推荐使用)。 如果没有连接更新站点,Jenkins 将不再通知可用更新。 在这种情况下,建议使用更新站点的本地镜像,或使用 Juseppe 之类的自托管更新中心。 (pull 3970) 修复在弹出窗口中显示参考消息的管理监视器的样式。 (issue 59684) 为创建项目按钮添加缺少的\u0026rdquo;按下\u0026rdquo;样式。 (issue 34226) 将标签固定到 Atom 供稿链接。 (issue 48375) 开发者: 添加 Functions#urlEncode(String) 可以简化来自 Jelly 视图的 URL 查询参数的编码。 (pull 4278) 开发者: TarOutputStream 现在被标记为受限,因此插件中不使用它。 (pull 4272) 内部: 清理无用代码。 (issue 36720, pull 4248, pull 4258, pull 4260, pull 4256, pull 4257, pull 4261, pull 4267) 2.199 (2019-10-06) 在完成加载内存模型之前,请避免调用 Jenkins#save 持久数据。 这样可以防止 Jenkins 主配置损坏。 (issue 58993) 在基于 HTTP 的 CLI 上增加客户端保持活动 ping 的频率,以防止超时。 (issue 59267) 将默认的软终止超时从 2 分钟减少到 5 秒,以便生成其他进程的构建可以更快地完成。 (issue 59152) 停止与 Jenkins 捆绑 Maven 插件和 Subversion 插件。 在极少数情况下,尝试安装与 1.310 版本之前的 Jenkins 兼容的插件时,可能会导致问题。 Jenkins 项目目前未发布任何此类插件。 (pull 4242) 删除捆绑在一起的插件只是为了促进其使用,因为与旧插件兼容时不需要它们。 从 Jenkins 2.0 开始,默认情况下安装插件的概念已替换为安装向导。 (pull 4040) 将捆绑的脚本安全插件版本更新为 1.65 。 (pull 4245) 开发者: 如果 proc 参数为 null ,ProcessTree#killAll 不会再因 NPE 失败。 (pull 4232) 内部: 发生错误时,hudson.util.ProcessTree.OSProcess#getEnvironmentVariables 返回 null ,即使它不应该发生也是如此。 (issue 59580) 2.198 (2019-09-29) 删除构建历史记录小部件中的构建说明的 100 个字符长度限制。 (issue 19760, issue 31209) 将所需的 Remoting 客户端最低版本更新为 3.14 ,以简化实现。 (pull 4208) 临时离线状态使用不同的计算机图标。 (issue 59283) 稳定性:不允许用户使用 POST 在需要提交表单的 URL 上重新提交请求,因为那样无论如何都会失败。 (issue 59514) 来自 Computer.getLogDir 的失败消息的更好的诊断。 (pull 4226) 在少数情况下会从捆绑版本中安装 Ant 、 PAM Authentication 、 Mailer 和 Script Security 插件的捆绑版本。 (pull 4230) 将 commons-compress 从 1.10 更新为 1.19。 (pull 4221, changelog) 将 jfreechart 从 1.0.9 更新到 1.0.19,以获取最新的改进和错误修复。 (pull 4229, 变更日志) lastCompletedBuild 永久链接未缓存在 …/builds/permalinks 文件中。 (issue 56809) 开发者: 添加 TcpSlaveAgentListener#getAdvertisedHost()。 (pull 4227) 2.197 (2019-09-25) 安全修复。 (安全公告) 2.196 (2019-09-22) 现在,可以通过设置系统属性 jenkins.model.StandardArtifactManager.disableTrafficCompression=true 来禁用从节点将归档的结果件传输到主服务器时的 Gzip 压缩包。 (issue 26008, Jenkins features controlled by system properties) 使日志回传更加可靠。 (issue 58779) 修复 Atom 和 RSS 2.0 提要中格式错误的 XML 。 (由 2.94 引入的缺陷回归) (issue 59231) 无法访问名称中带有表情符号的某些项目 URL 。 (issue 59406) 2.195 (2019-09-16) 有时不正确地删除安装向导,Jenkins 仅显示空白屏幕。 (issue 59017) 2.194 (2019-09-08) 修复 RSS/Atom 提要中缺少的绝对 URL 。(由 2.190 引入的缺陷回归) (issue 59167) 将 Remoting 从 3.33 更新到 3.35 ,以允许入站 TCP 代理直接连接,而无需首先通过 HTTP 查询 Jenkins 的连接参数。 (issue 59094, issue 53461, 完整的变更日志) 将 Windows Service Wrapper 从 2.2.0 更新到 2.3.0 ,以获取修复程序和改进。 (pull 4167, WinSW 变更日志, Windows Agent Installer 模块 1.12 变更日志) 内部: 将 dom4j 库从 Jenkins 项目分支更新到上游版本 2.1.1。 (issue 53322) 内部: 用 java.util.Base64 替换了不同的 base64 实现。 (pull 4169) 2.193 (2019-09-01) 由于涉及隧道连接的问题,将 Remoting 从 3.34 降级为 3.33 。 (由 2.191 引入的缺陷回归) (issue 59094) 当提示慢触发的管理警告时, Jenkins UI 中断。(由 2.189 引入的缺陷回归) (issue 58938) 2.192 (2019-08-28) 重要的安全修复。 (安全公告) 2.191 (2019-08-25) 将 Remoting 从 3.33 更新到 3.34 ,以允许入站 TCP 代理直接连接,而无需首先通过 HTTP 查询 Jenkins 的连接参数。 (issue 53461, full changelog) 多次次要代码清理和内部修复。 (pull 4131, pull 4162, pull 4163, issue 36720) 内部: 将 Mockito 从 2.22.0 升级到 3.0.0 。 (pull 4154) 2.190 (2019-08-18) 在任务名称中添加对表情符号和其他非 UTF-8 字符的支持。 🎉 (issue 23349) RSS 和 Atom 提要不包含所有必需的元数据。(由 2.186 引入的缺陷回归) (issue 58595) 在 UI 上公开节点的真实环境变量。 (issue 54772) 使用 SHA-256 代替 MD5 来生成 crumbs/CSRF token。 (issue 58734) 截断 UI 上的长构建名称以防止对齐问题。 (issue 58157) 开发者: 现在 AbstractItem#renameTo 重命名之前检查 #isNameEditable 。 (issue 58571) 2.189 (2019-08-07) $JENKINS_HOME/jobs/*/builds/permalinks 中的文件句柄泄露可能会阻止任务在 Windows 上被删除。 (由 2.185 引入的缺陷回归) (issue 58733) 从/scriptText 终点删除多余的空格输出。(由 2.186 引入的缺陷回归) (issue 58548) install-plugin CLI 命令允许安装不是插件的文件,从而可能破坏某些功能。 (issue 29065) 当 cron 触发器的执行时间较长时,添加告警。 (issue 54854) 在安装向导中分批安装插件以提高性能。 (pull 4124) 停止在 install-plugin CLI 命令中使用 name 参数。 (pull 4123) 更新某些独立插件的版本。 从较旧的版本升级 Jenkins 时,或者未为手动管理的插件指定隐含依赖项时,通常会安装这些工具。 (pull 4125) 内部: 添加对 Jenkins 核心运行 JMH 基准测试的支持。 (pull 4135) 内部: 将 Jenkins 测试工具从 2.49 更新到 2.54 ,以增加对 JMH 基准测试的支持。 (pull 4135, 变更日志) 内部: 从 jenkins.war 干掉 WEB-INF/lib/jquery-detached-1.2.jar 。 (pull 4120) 2.188 (2019-08-07) 此版本失败。没有结果件或 Git 标签存在。 在这次发布中没有显著的变更。 2.187 (2019-07-21) 现在可以通过设置系统属性 hudson.node_monitors.AbstractNodeMonitorDescriptor.periodMinutes 来更改节点监视器的默认时间间隔(例如可用磁盘空间)。 (pull 4105, 受系统属性控制的 Jenkins 功能) 稳定性: 当 AdministrativeMonitor#isActivated 失败时不要渲染视图。 (pull 4114) Internal: 将 slf4j 从 1.7.25 升级到 1.7.26 版本。 (pull 4118) 2.186 (2019-07-17) 重要的安全修复。 (安全公告) 从 Jenkins 核心中删除 Trilead SSH 依赖。这些依赖性导致 2.185 中的 SSH 构建节点连接问题。 (issue 58483) 将 SSH CLI Auth Module 从 1.5 升级到 1.7 ,以删除 Trilead SSH 参考。 (pull 4111, issue 43669, 1.7 的变更日志, 1.6 的变更日志) 2.185 (2019-07-14) Jenkins 不再在项目或构建目录中创建符号链接。 如果需要,可以安装 Build Symlink 插件来恢复此功能。 诸如 /job/…/lastStableBuild/ 之类的 URL 不受影响,仅影响直接访问 $JENKINS_HOME 文件系统的工具。 (issue 37862) 从 Jenkins 核心中删除 Trilead SSH 库,并使其在新的 独立插件 中可用。 (issue 43610) 测试代理配置时不要抛出异常。(由 2.168 引入的缺陷回归) (issue 57383) 防止 Jenkins 重启和用户会话无效时的偶发 IllegalStateException 异常。 (issue 55945) 避免使用重复的 screenResolution cookie 进行查看。 (pull 4103) 由于新旧插件的混合使用,在某些情况下,可能有两个版本的扩展点供节点的命令启动器选项使用。 (issue 58362) 在插件管理器的\u0026rdquo;已安装\u0026rdquo;选项卡上添加警告,警告管理员禁用独立的插件可能引起的问题,此问题自 2.181 版本开始可能会触发。 (pull 4098) 如果可用节点非常快,则在云节点配置期间消除不必要的延迟。 (issue 24752) 将 commons-codec 库从 1.9 升级到 1.12。 (pull 4052, 变更日志) Developer: 即使 *.jpl 文件存在,插件兼容性测试器也不会跳过捆绑的插件安装。 (issue 58362) ", "auhtor": "jenkinsci", "translator": "zhaoying818", "original": "", "poster": "./2020-04-20-jenkins-release/great-wall.jpeg" }, { "uri": "https://jenkins-zh.cn/meeting/2020-04-15/", "title": "", "type": "meeting", "date": "2020-04-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " UCloud 服务器管理 开始部署 Jenkins 运行的位置保持不变(阿里云) 与 KubeSphaere 社区合(青云)作 技术方向 https://github.com/jenkins-zh/jenkins-formulas 内容 互相推送一些文章、投稿等等 社区激励 记录第三次社区激励的记录 @yJunS\n社区媒体账号运营情况 简书 @yJunS changelog 有定时更新 @zhaoying818 讲师征集 @linan607 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2019-04-15-effective-secret-with-vault-and-kubernetes/", "title": "使用 Vault 与 Kubernetes 为密码提供强有力的保障", "type": "wechat", "date": "2020-04-15 00:00:00 +0000 UTC", "tags": ["Kubernetes", "Vault", "Cloud Native", "Golang", "Security"], "description": "结合具体的例子讲解了 Vault 和 Kubernetes 的集成,从而为 Kubernetes 运行的应用程序更安全的使用密码", "content": " 介绍 Kubernetes 已经成为了容器编排方案的工业标准,而来自 HashiCorp 的 Vault 则是密码管理的工业标准。那问题来了: 怎样将这两项技术结合使用从而可以让你在 Kubernetes 的应用程序中使用来自于 Vault 中心实例的密码呢?\n一种解决方法是使用 AppRole 认证。Boostport 为 AppRoles 在 Kubernetes 上的使用提供了完美的集成。另一个可行的方法是使用 Kubernetes 认证。这种认证机制为 Vault 和 Kubernetes 集群创建一个可信的联系因而你可以使用一个服务账号到 Vault 进行认证。后期你可以使用 Kubernetes 的 Vault 节点获取和更新认证令牌。\n这篇实践的文章中,我会向你展示如何使用一些 Go 助手工具实现诸如认证更新令牌这些相同的工作,并且还会进一步实现-从 Vault 到 Kubernetes 同步预定义的密码子集。\n等级: 高级\n准备工作 简单起见我有一些选项:\n 用多种不同的方法启动一个 Kubernetes 集群。通常来说,minikube 用来测试或者开发。我会使用 kubeadm 因为它非常简单的就可以启动一个*真正的*集群。\n 在 Kubernetes 中,会使用 default 命名空间。\n Vault 会在*开发*模式下运行。不要像在生产环境下那样使用它! 确保在环境变量中设置了 VAULT_ADDR。\n 代码示例中会使用 Ubuntu。这些已经在 GCE 上配置为 2 vCPU 和 7.5 GB 的 Ubuntu 18.10 VM 上进行了测试。(可以看看 GCP 上 $300 的免费套餐,就是说说而已哈\u0026hellip;)\n 除非另有说明,将会使用 Bash。\n Kubernetes 让我们从一个简单的测试集群开始。下面的代码你会看到一个简单节点的安装步骤是什么样的。\n# 1) Install Kubernetes on a Ubuntu machine sudo -i curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' \u0026gt;\u0026gt; /etc/apt/sources.list.d/kubernetes.list apt update \u0026amp;\u0026amp; apt install -y docker.io kubelet kubeadm kubectl sudo systemctl enable docker.service kubeadm init --pod-network-cidr=10.244.0.0/16 # Flannel pod network, see below exit # 2) Prepare kubectl mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config echo \u0026quot;source \u0026lt;(kubectl completion bash); alias k=kubectl; complete -F __start_kubectl k\u0026quot; \u0026gt;\u0026gt; .bashrc \u0026amp;\u0026amp; exec $SHELL # 3) Finalize K8s config kubectl cluster-info kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl taint nodes --all node-role.kubernetes.io/master- kubectl get nodes -o wide # For details, see: # - https://kubernetes.io/docs/setup/independent/install-kubeadm/ # - https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/ Vault 安装 Vault 的安装非常的直接: 下载解压二进制包即可:\n# Install Vault sudo apt install -y zip curl -OL https://releases.hashicorp.com/vault/1.1.1/vault_1.1.1_linux_amd64.zip unzip vault_1.1.1_linux_amd64.zip sudo mv vault /usr/local/bin/ vault -autocomplete-install \u0026amp;\u0026amp; exec $SHELL 运行一个 Vault 服务器 我们会以*开发*模式运行一个 Vault 服务器。同样,这也非常的简单。请记住,当启动一个开发服务器的时候,一个 root 令牌会被写入到 $HOME/.vault-token 中,对 root 用户来说同样如此。使用 \u0026amp; 符号会让 Vault 进程在后台运行因此我们可以继续使用相同的 shell。\n$ vault server -dev -dev-listen-address=0.0.0.0:8200 \u0026amp; ==\u0026gt; Vault server configuration: Api Address: http://0.0.0.0:8200 Cgo: disabled Cluster Address: https://0.0.0.0:8201 Listener 1: tcp (addr: \u0026quot;0.0.0.0:8200\u0026quot;, cluster address: \u0026quot;0.0.0.0:8201\u0026quot;, max_request_duration: \u0026quot;1m30s\u0026quot;, max_request_size: \u0026quot;33554432\u0026quot;, tls: \u0026quot;disabled\u0026quot;) Log Level: info Mlock: supported: true, enabled: false Storage: inmem Version: Vault v1.1.1 Version Sha: a3dcd63451cf6da1d04928b601bbe9748d53842e 配置 Kubernetes 认证 现在我们必须确保 Kubernetes 可以通过 Kubernetes 认证与 Vault 进行通信。这将会在 Kubernetes 和 Vault 之间建立一个信任的联系。预命名的 vault-demo-role 将会映射策略以及定义一个 TTL。\n因为我们使用 kubeadm 启动的 Kubernetes 集群,它非常轻松的就可以找到 kubernetes_ca_cert 参数的证书颁发机构(CA)存储的值。如果使用一个在云安装的 Kubernetes 该过程会比较困难一些。\n# NOTE: You may need to set these addresses differently. export INTERNAL_IP=$(dig +short `hostname -f`) export VAULT_ADDR=http://${INTERNAL_IP}:8200 # Enable and configure the Kubernetes auth method. # For details, see: # - https://www.vaultproject.io/docs/auth/kubernetes.html # - https://www.vaultproject.io/api/auth/kubernetes/index.html vault auth enable kubernetes vault write auth/kubernetes/config \\ kubernetes_host=https://${INTERNAL_IP}:6443 \\ kubernetes_ca_cert=@/etc/kubernetes/pki/ca.crt vault write auth/kubernetes/role/vault-demo-role \\ bound_service_account_names=vault-serviceaccount \\ bound_service_account_namespaces=default \\ policies=vault-demo-policy \\ ttl=1h # Create a policy for demo purposes cat \u0026lt;\u0026lt;EOF | vault policy write vault-demo-policy - path \u0026quot;sys/mounts\u0026quot; { capabilities = [\u0026quot;read\u0026quot;] } path \u0026quot;secret/data/demo/*\u0026quot; { capabilities = [\u0026quot;read\u0026quot;] } path \u0026quot;secret/metadata/demo/*\u0026quot; { capabilities = [\u0026quot;list\u0026quot;] } EOF # Write some demo secret vault kv put secret/demo/most-used-password password=123456 vault kv put secret/demo/first one=1234567890 two=2345678901 vault kv put secret/demo/second green=lantern poison=ivy vault kv put secret/demo/greek/alpha philosopher=plato vault kv put secret/demo/greek/beta god=zeus vault kv put secret/demo/greek/gamma mountain=olympus 基于角色的访问控制(RBAC) 在 Kubernetes 这边,我们现在需要安装设置相匹配的 RBAC。首先我们创建一个名称为 vault-serviceaccount 的服务账号。然后我们会添加一个叫做 vault-closterrolebinding 的集群角色绑定,因而我们新创建的服务账号可以被允许使用默认的集群角色 system:auth-delegator 发送认证请求。角色 vault-secrectadmin-role 和角色绑定 vault-secretadmin-rolebinding 也绑定到了 vault-serviceaccount 上这样我们就可以同步密码了。\n--- apiVersion: v1 kind: ServiceAccount metadata: name: vault-serviceaccount --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: vault-clusterrolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: vault-serviceaccount namespace: default --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: vault-secretadmin-role rules: - apiGroups: [\u0026quot;\u0026quot;] resources: [\u0026quot;secrets\u0026quot;] verbs: [\u0026quot;*\u0026quot;] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: vault-secretadmin-rolebinding subjects: - kind: ServiceAccount name: vault-serviceaccount roleRef: kind: Role name: vault-secretadmin-role apiGroup: rbac.authorization.k8s.io 让我们应用下面的配置:\n$ k apply -f vault-rbac.yaml serviceaccount/vault-serviceaccount created clusterrolebinding.rbac.authorization.k8s.io/vault-clusterrolebinding created role.rbac.authorization.k8s.io/vault-secret-admin-role created rolebinding.rbac.authorization.k8s.io/vault-demo-secret-admin-rolebinding created 准备工作完成了。现在我们可以移步到我们的用例上了。\n用例 我们将会覆盖下面的这三个用例:\n 第一个例子会演示怎样认证到 Vault 然后使用一个初始化的容器获取一个认证令牌。\n 第二个例子会演示怎样使用 sidecar 容器更新这个令牌。\n 第三个例子将会演示怎样从 Vault 到 Kubernetes 同步密码。\n 所有这三个用例均由我在 PostFinance 的同事构建的三个 Docker 镜像上运行的。特别感谢 Marc Sauter,他在 Seth Vargo 工作的启发下编纂了最初的实现方案。创建的这三个镜像-在 Docker Hub 上均可获取到-包括了一点 Go 的助手工具,代码均可以从 GitHub 上找到。\n使用初始容器进行认证 第一个例子会展示 vault-kubernetes-authenticator (简称 *auther*)镜像的用法。auther 在一个初始容器中运行,使用服务账号 vault-serviceaccount 向 Vault 进行认证然后将 Vault 的认证令牌写入到 /home/vault/.vault-token 中。\n--- apiVersion: apps/v1 kind: Deployment metadata: name: vault-kubernetes-authenticator-demo labels: appl: vault-kubernetes-authenticator-demo spec: replicas: 1 selector: matchLabels: appl: vault-kubernetes-authenticator-demo template: metadata: labels: appl: vault-kubernetes-authenticator-demo spec: serviceAccountName: vault-serviceaccount volumes: - name: vault-token emptyDir: medium: Memory initContainers: - name: vault-kubernetes-authenticator image: postfinance/vault-kubernetes-authenticator imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token containers: - name: kuard image: gcr.io/kuar-demo/kuard-amd64:blue volumeMounts: - name: vault-token mountPath: /home/vault 我们应用这些配置然后执行一些测试来验证所有配置都能成功运行。\n$ envsubst \u0026lt; vault-kubernetes-authenticator-demo.yaml | k apply -f - deployment.apps/vault-kubernetes-authenticator-demo created $ k get all NAME READY STATUS RESTARTS AGE pod/vault-kubernetes-authenticator-demo-fc49b957c-b5bnx 1/1 Running 0 81s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 \u0026lt;none\u0026gt; 443/TCP 20h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/vault-kubernetes-authenticator-demo 1/1 1 1 81s NAME DESIRED CURRENT READY AGE replicaset.apps/vault-kubernetes-authenticator-demo-fc49b957c 1 1 1 81s $ k logs vault-kubernetes-authenticator-demo-fc49b957c-b5bnx -c vault-kubernetes-authenticator 2019/04/16 04:45:23 successfully authenticated to vault 2019/04/16 04:45:23 successfully stored vault token at /home/vault/.vault-token $ k exec vault-kubernetes-authenticator-demo-fc49b957c-b5bnx -- sh -c \u0026quot;VAULT_ADDR=${VAULT_ADDR} sh\u0026quot; ~ $ cat /home/vault/.vault-token; echo s.xrrJoCARIC0Z84vcvcwuH5XG ~ $ wget --header=\u0026quot;X-Vault-Token: $(cat /home/vault/.vault-token)\u0026quot; -q -O - ${VAULT_ADDR}/v1/secret/data/demo/most-used-password {\u0026quot;request_id\u0026quot;:\u0026quot;12660a6b-7ad0-85bc-8841-d21c7cc8248a\u0026quot;,\u0026quot;lease_id\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;renewable\u0026quot;:false,\u0026quot;lease_duration\u0026quot;:0,\u0026quot;data\u0026quot;:{\u0026quot;data\u0026quot;:{\u0026quot;password\u0026quot;:\u0026quot;123456\u0026quot;},\u0026quot;metadata\u0026quot;:{\u0026quot;created_time\u0026quot;:\u0026quot;2019-04-16T05:11:44.651116748Z\u0026quot;,\u0026quot;deletion_time\u0026quot;:\u0026quot;\u0026quot;,\u0026quot;destroyed\u0026quot;:false,\u0026quot;version\u0026quot;:1}},\u0026quot;wrap_info\u0026quot;:null,\u0026quot;warnings\u0026quot;:null,\u0026quot;auth\u0026quot;:null} ~ $ wget --header=\u0026quot;X-Vault-Token: $(cat /home/vault/.vault-token)\u0026quot; -q -O - ${VAULT_ADDR}/v1/secret/data/sensitive-password wget: server returned error: HTTP/1.1 403 Forbidden 使用 Sidecar 更新令牌 第二个例子将向你展示 vault-kubernetes-token-renewer (简称 *renewer*)镜像的使用。renewer 运行在一个 sidecar 容器中,周期性地检查 TTL 然后根据检查的情况更新认证令牌。\n--- apiVersion: apps/v1 kind: Deployment metadata: name: vault-kubernetes-token-renewer-demo labels: appl: vault-kubernetes-token-renewer-demo spec: replicas: 1 selector: matchLabels: appl: vault-kubernetes-token-renewer-demo template: metadata: labels: appl: vault-kubernetes-token-renewer-demo spec: shareProcessNamespace: true serviceAccountName: vault-serviceaccount volumes: - name: vault-token emptyDir: medium: Memory initContainers: - name: vault-kubernetes-authenticator image: postfinance/vault-kubernetes-authenticator imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token containers: - name: vault-kubernetes-token-renewer image: postfinance/vault-kubernetes-token-renewer imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token - name: kuard image: gcr.io/kuar-demo/kuard-amd64:blue volumeMounts: - name: vault-token mountPath: /home/vault 我们也同样应用一下这些配置然后做一些验证。(我删除了先前的 deployment。)\n$ envsubst \u0026lt; vault-kubernetes-token-renewer-demo.yaml | k apply -f - deployment.apps/vault-kubernetes-token-renewer-demo created $ k get all NAME READY STATUS RESTARTS AGE pod/vault-kubernetes-token-renewer-demo-694cc7dbbd-rkbbs 2/2 Running 0 4s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 \u0026lt;none\u0026gt; 443/TCP 31h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/vault-kubernetes-token-renewer-demo 1/1 1 1 4s NAME DESIRED CURRENT READY AGE replicaset.apps/vault-kubernetes-token-renewer-demo-694cc7dbbd 1 1 1 4s $ k logs vault-kubernetes-token-renewer-demo-694cc7dbbd-rkbbs -c vault-kubernetes-authenticator 2019/04/16 15:40:55 successfully authenticated to vault 2019/04/16 15:40:55 successfully stored vault token at /home/vault/.vault-token $ k logs vault-kubernetes-token-renewer-demo-694cc7dbbd-rkbbs -c vault-kubernetes-token-renewer 2019/04/16 15:40:56 start renewer loop 2019/04/16 15:40:56 token renewed 从 Vault 到 Kubernetes 同步密码 第三个例子将向你展示 vault-kubernetes-synchronizer (简称 *syncer*)的用法。syncer 可以用在多个方面。在这个 demo 里面,一个 Kubernetes 任务将被用来从预定义的路径一次性同步 Vault 密码。这些 Vault 密码将会被写入到相应的 Kubernetes 密码中。\n--- apiVersion: batch/v1 kind: Job metadata: name: vault-kubernetes-synchronizer-demo spec: backoffLimit: 0 template: spec: serviceAccountName: vault-serviceaccount restartPolicy: Never volumes: - name: vault-token emptyDir: medium: Memory initContainers: - name: vault-kubernetes-authenticator image: postfinance/vault-kubernetes-authenticator imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token containers: - name: vault-kubernetes-synchronizer image: postfinance/vault-kubernetes-synchronizer imagePullPolicy: Always volumeMounts: - name: vault-token mountPath: /home/vault env: - name: VAULT_ADDR value: ${VAULT_ADDR} - name: VAULT_ROLE value: vault-demo-role - name: VAULT_TOKEN_PATH value: /home/vault/.vault-token - name: VAULT_SECRETS value: secret/demo/first,secret/demo/second,secret/demo/first:third,secret/demo/greek/ 同样,我们也应用一下这些配置然后看看所有的配置是否如预期一样运行正常:\n$ envsubst \u0026lt; vault-kubernetes-synchronizer-demo.yaml | k apply -f - job.batch/vault-kubernetes-synchronizer-demo created $ k get all NAME READY STATUS RESTARTS AGE pod/vault-kubernetes-synchronizer-demo-m2xnz 1/1 Running 0 4s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 \u0026lt;none\u0026gt; 443/TCP 3d5h NAME COMPLETIONS DURATION AGE job.batch/vault-kubernetes-synchronizer-demo 0/1 4s 4s $ k logs pod/vault-kubernetes-synchronizer-demo-m2xnz -c vault-kubernetes-authenticator 2019/04/18 14:29:42 successfully authenticated to vault 2019/04/18 14:29:42 successfully stored vault token at /home/vault/.vault-token $ k logs pod/vault-kubernetes-synchronizer-demo-m2xnz 2019/04/18 14:29:43 read secret/demo/first from vault 2019/04/18 14:29:43 update secret third from vault secret secret/demo/first 2019/04/18 14:29:43 read secret/demo/greek/alpha from vault 2019/04/18 14:29:43 update secret alpha from vault secret secret/demo/greek/alpha 2019/04/18 14:29:43 read secret/demo/greek/beta from vault 2019/04/18 14:29:43 update secret beta from vault secret secret/demo/greek/beta 2019/04/18 14:29:43 read secret/demo/greek/gamma from vault 2019/04/18 14:29:43 update secret gamma from vault secret secret/demo/greek/gamma 2019/04/18 14:29:43 read secret/demo/first from vault 2019/04/18 14:29:43 update secret first from vault secret secret/demo/first 2019/04/18 14:29:43 read secret/demo/second from vault 2019/04/18 14:29:43 update secret second from vault secret secret/demo/second 2019/04/18 14:29:44 secrets successfully synchronized $ k get secrets NAME TYPE DATA AGE alpha Opaque 1 2m43s beta Opaque 1 2m43s default-token-ssd7f kubernetes.io/service-account-token 3 3d5h first Opaque 2 2m43s gamma Opaque 1 2m43s second Opaque 2 2m43s third Opaque 2 2m43s vault-serviceaccount-token-f6tnw kubernetes.io/service-account-token 3 2d20h $ k describe secret first Name: first Namespace: default Labels: \u0026lt;none\u0026gt; Annotations: vault-secret: secret/demo/first Type: Opaque Data ==== one: 10 bytes two: 10 bytes $ k describe secret alpha Name: alpha Namespace: default Labels: \u0026lt;none\u0026gt; Annotations: vault-secret: secret/demo/greek/alpha Type: Opaque Data ==== philosopher: 5 bytes syncer 同样可以用在 Kubernetes 的 cron 任务中从 Vault 周期性同步密码或者同步到另一个 Kubernetes deployment 的初始容器中,这样密码就会保持最新状态。\n需要注意的是 Kubernetes 密码保护不是很好。Seth Vargo 在最近的 FOSDEM 访谈中指出,默认情况下,它们仅做了 base64 编码和存储,就像在 etcd 中那样。你应该允许数据的静态加密。也请确保你只同步那些你的 Kubernetes 应用程序使用的那些密码,这些密码由相应的 Vault 策略以及命名角色保护。除此之外,该方法还允许你以云原生行为使用密码。你的应用程序不能直接访问 Vault 密码可以被注入到环境变量中。\n结论 Kubernetes 和 Vault 这两项技术在结合使用或者集成它们使用时均是很棒的组合。集成的方案看似不简单但是依旧可行。这篇文章中我已经向你展示了怎样实现这两者的集成,希望会对你有所帮助。\n你或许会问了为什么明明可以用 Vault 官方提供的镜像运行一个节点用来实现相同的事情却偏偏选择了一些第三方提供的镜像呢。原因如下: Vault 节点需要一个配置文件而不是环境变量,这也就意味着你必须去管理其他的配置映射。并且当前的节点不能同步密码。另外,第三方的镜像更轻量。官方的 Vault 镜像大概 100 MB。而 auther 和 renewer 镜像大约也就 10 MB syncer 镜像大约40 MB。\n", "auhtor": "Johann Gyger", "translator": "0N0thing", "original": "https://itnext.io/effective-secrets-with-vault-and-kubernetes-9af5f5c04d06", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-10-jcli-v0.0.27/", "title": "Jenkins CLI 命令行 v0.0.27", "type": "wechat", "date": "2020-04-10 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.27 发布", "content": " 在本次更新中,利用 GitHub Actions 和 GoReleaser 实现了自动化版本发布。为了满足更多用户的使用场景,给出了包括:.deb、.rpm 以及 arm 架构等20种不同的包格式。\n截止到编辑本文时,GitHub 上统计到的下载量为:4,985次。GitHub 上的 Star 数为146,码云上的 Star 数为87。\n另外,为了让更多的 Jenkins 用户尽快地熟悉 Jenkins CLI 的功能,并上手改进日常的工作。大家可以访问下面的交互式教程:\nhttps://www.katacoda.com/jenkins-zh\n🚀 功能 支持构建插件工程 (#355) @LinuxSuRen 增加用于清空 Jenkinsfile 中的空白字符的参数 (#363) @LinuxSuRen 支持传递给自定义 Jenkins 配方的参数 (#364) @LinuxSuRen 增加对构建自定义 Jenkins 的支持 (#340) @LinuxSuRen 支持启用、禁用 Jenkins 任务 (#352) @LinuxSuRen 增加可以直接重启 Jenkins 的参数 (#345) @LinuxSuRen 支持编辑空的流水线时,提供一份样本 (#361) @LinuxSuRen 增加 goreleaser 配置文件 (#347) @LinuxSuRen 📝 文档完善 为 jcli 增加一个交互式教程 (#362) @LinuxSuRen 增加如何通过 yum 安装 jcli 的说明 (#348) @LinuxSuRen 👻 维护 不再推送开发中的 Docker 镜像 (#371) @LinuxSuRen 利用 GitHub Actions 来发布版本 (#370) @LinuxSuRen 增加对 arm 架构的支持 (#351) @LinuxSuRen github.com/spf13/cobra 版本升级,从 0.0.6 到 0.0.7 (#369) @dependabot-preview go.uber.org/zap 版本升级,从 1.13.0 到 1.14.1 (#367) @dependabot-preview github.com/AlecAivazis/survey/v2 版本升级,从 2.0.5 到 2.0.6 (#341) @dependabot-preview github.com/golang/mock 版本升级,从 1.3.1 到 1.4.0 (#310) @dependabot-preview github.com/onsi/gomega 版本升级,从 1.8.1 到 1.9.0 (#316) @dependabot-preview github.com/fatih/color 版本升级,从 1.7.0 到 1.9.0 (#304) @dependabot-preview ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "jenkins-cli.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-09-custom-jenkins-war/", "title": "自定义 Jenkins 发行版就是这么简单", "type": "wechat", "date": "2020-04-09 00:00:00 +0000 UTC", "tags": [], "description": "你离开箱即用的自定义 Jenkins 发行版只差一个 YAML 文件", "content": "Jenkins 是一个由开源社区驱动的项目,拥有非常丰富的插件生态,任何人都可以根据社区给出的指南为之作出贡献,甚至是将自己开发的插件托管到 Jenkins 社区。从插件市场上能看到,到目前为止有超过1500个插件可供 Jenkins 的用户挑选。当我们走进 Jenkins 这个巨型超市时,有多少人曾经有过这样的感觉——看着琳瑯满目的商品,却完全无从下手?自由风格,流水线即代码,申明式流水线,多分支流水线,配置即代码,又有多少人被应接不暇的社区新概念搞得没了头绪?\n让我们暂且不去关心其他语言的用户体验如何,单看 Jenkins 简体中文插件3万左右的下载量,就足以证明 Jenkins 中文本地化工作对很多用户是有意义的。在之前的一篇博文中,我们从改善用户下载、更新插件的角度出发,发布了 Jenkins 插件中心国内源。在此,需再次对清华大学开源镜像站等组织对开源项目的支持,让更多的人得以站在巨人的肩膀上前行。在过去的四个月的时间里,插件国内源的用户在逐步上升;用户检查更新插件的峰值为931次/天。\n从上面的两个数据中,不难看出,还是有相当一部分用户还没有享受到插件国内源的益处。这可能有多个原因导致:文档不清晰、配置步骤繁杂、服务器不稳定等等。对于文档、配置等问题而言,一个杀手级的一个解决方案就是——不需要文档和配置。本文要介绍给大家的就是这么一种开箱即用的方案,就像乐高积木一样,而用户只需要提交一个订单(YAML 文件)就能拿到他所需要的 Jenkins 发行版。是的,作为用户,不仅不再需要配置国内源,甚至都不需要下载和配置插件。\nJenkins 自定义发行版项目,默认提供了几个常用的配方,并支持用户以 YAML 的格式提交配方。这里的配方,包括了发行版中 Jenkins Core 的版本、插件列表、插件配置、初始化脚本等等。一旦提交的配方 Pull Request 合并到 master 分支后,就可以自动地构建出来对应的 docker 镜像以及 jenkins.war 文件。如果 Jenkins 有了新版本的话,是否还需要重新提交配方请求呢?我们已经考虑到了这一点,一旦有新版本发布的话,会自动构建出来对应的发行版(也许会有一天的延迟)。大家如果喜欢这个方案的话,可以关注托管在码云或者 GitHub 上的项目。目前,Docker 镜像的下载量已经有3000+,心动不如行动,赶快试试吧!\n现有的配方包括:\n 配方 镜像 配置即代码 + 简体中文 jenkinszh/jenkins-zh:2.204.5 配置即代码 + 流水线 jenkinszh/jenkins-pipeline:2.204.5 配置即代码 + 流水线 + K8s jenkinszh/jenkins-k8s:2.204.5 多分支流水线 + BlueOcean jenkinszh/blueocean-zh:2.204.5 多分支流水线(GitHub、GitLab、Bitbucket) jenkinszh/jenkins-multi-pipeline-zh:2.204.5 上面的清单中没有你想要的?自己动手,丰衣足食。参考下图中的 Pull Request 来提交几个文本文件,就可以了。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-08-build-jenkins-as-a-code/", "title": "以代码的形式构建 Jenkins", "type": "wechat", "date": "2020-04-08 00:00:00 +0000 UTC", "tags": ["Jenkins", "Jcasc", "Jjb", "Cicd", "Iaac"], "description": "主要介绍了关于 Jenkins “配置即代码”模式的具体方法,结合工具以及脚本对该模式进行了说明", "content": " 在我们公司,我们尝试使用‘一切事物即代码’的模式,该模式涉及到可复制的基础架构,监控,任务等方面。但是,在这篇文章当中,我将向你展示怎样将这种模式运用到 Jenkins 上。是的,我的意思是对于 Jenkins 完全可复制的配置,以及基础架构、插件、凭据、任务以及代码中的其他东西。另外,这篇文章你将解惑下面的疑问:\n 我们的 Jenkins 已经变得更加稳定了吗?\n 我们可以频繁地改变 Jenkins 和任务配置吗?\n 升级 Jenkins 及其插件对我们来说是否不再是一种痛苦了呢?\n 我们是否已经管理了 Jenkins 上所有的变更?\n 故障发生后,是否我们可以快速的恢复 Jenkins?\n 我的名字叫 Amet Umerov 是一名 Preply.com 的DevOps 工程师。让我们开始吧!\n前期介绍 当我们谈论 DevOps 工具,脑海中首先出现的是一个 CI/CD 系统。我们在 Preply 使用 Jenkins 因为我们每天有数以百计的任务,我们使用的许多特性在其他系统里面是没法提供的,即使提供了这些功能,也会是一些简化的功能。\n我们想要让 Jenkins 以及基础架构、配置、任务和插件完全代码化。并且,我们之前有过在 Kubernetes 运行的经验,但是因为 Jenkins 架构以及我们自身的目的发现它并不适合我们。\n这是我们想要实现的目标\n为 Jenkins 构建底层架构 我们用的是 AWS 使用 Terraform 管理我们所有的基础架构还有其他一些来自于 HashiStack 的工具比如 Packer 或者 Vault。\n就像我之前提到的,我们尝试使用 Kubernetes 来托管 Jenkins,但我们在扩展 PVC,资源还有一些没有经过深思熟虑的架构时遇到了问题。\n这里,我们使用了 AWS 资源,比如 EC2 实例、SSL 认证、负载均衡、CloudFront 分配等。AMI 由完美集成了 Terraform 和 Vault 的 Packer 构建。\n{ \u0026quot;variables\u0026quot;: { \u0026quot;aws_access_key\u0026quot;: \u0026quot;{{vault `packer/aws_access_key_id` `key`}}\u0026quot;, \u0026quot;aws_secret_key\u0026quot;: \u0026quot;{{vault `packer/aws_secret_access_key` `key`}}\u0026quot;, \u0026quot;aws_region\u0026quot;: \u0026quot;{{vault `packer/aws_region` `key`}}\u0026quot;, \u0026quot;vault_token\u0026quot;: \u0026quot;{{env `VAULT_TOKEN`}}\u0026quot; }, \u0026quot;builders\u0026quot;: [{ \u0026quot;access_key\u0026quot;: \u0026quot;{{ user `aws_access_key` }}\u0026quot;, \u0026quot;secret_key\u0026quot;: \u0026quot;{{ user `aws_secret_key` }}\u0026quot;, \u0026quot;region\u0026quot;: \u0026quot;{{ user `aws_region` }}\u0026quot;, \u0026quot;type\u0026quot;: \u0026quot;amazon-ebs\u0026quot;, \u0026quot;communicator\u0026quot;: \u0026quot;ssh\u0026quot;, \u0026quot;ssh_username\u0026quot;: \u0026quot;ubuntu\u0026quot;, \u0026quot;instance_type\u0026quot;: \u0026quot;c5.xlarge\u0026quot;, \u0026quot;security_group_id\u0026quot;: \u0026quot;sg-12345\u0026quot;, \u0026quot;iam_instance_profile\u0026quot;: \u0026quot;packer-role-profile\u0026quot;, \u0026quot;ami_name\u0026quot;: \u0026quot;packer-jenkins-master-{{timestamp}}\u0026quot;, \u0026quot;ami_description\u0026quot;: \u0026quot;Jenkins master image\u0026quot;, \u0026quot;launch_block_device_mappings\u0026quot;: [{ \u0026quot;device_name\u0026quot;: \u0026quot;/dev/sda1\u0026quot;, \u0026quot;volume_size\u0026quot;: 50, \u0026quot;volume_type\u0026quot;: \u0026quot;gp2\u0026quot;, \u0026quot;delete_on_termination\u0026quot;: true }], \u0026quot;source_ami_filter\u0026quot;: { \u0026quot;filters\u0026quot;: { \u0026quot;virtualization-type\u0026quot;: \u0026quot;hvm\u0026quot;, \u0026quot;name\u0026quot;: \u0026quot;ubuntu/images/*ubuntu-bionic-18.04-amd64-server-*\u0026quot;, \u0026quot;root-device-type\u0026quot;: \u0026quot;ebs\u0026quot; }, \u0026quot;owners\u0026quot;: [\u0026quot;099720109477\u0026quot;], \u0026quot;most_recent\u0026quot;: true } }], \u0026quot;provisioners\u0026quot;: [{ \u0026quot;type\u0026quot;: \u0026quot;shell\u0026quot;, \u0026quot;environment_vars\u0026quot;: [\u0026quot;VAULT_TOKEN={{ user `vault_token` }}\u0026quot;], \u0026quot;scripts\u0026quot;: [\u0026quot;packer_bootstrap.sh\u0026quot;] }] } packer的配置是这样的\nBootstrap 文件 packer_bootstrap.sh 包含了在 AMI 预安装软件的所有命令。举个例子,我们使用 Docker、docker-compose 以及 vaultenv 或者安装 Datadog 节点用来监控。\n考虑到这个 AMI 的架构,我们可以使用 Terraform、CloudFormation、Pulumi 甚至是 Ansible。这个是在 AWS 上使用 Jenkins 的可能会使用的架构之一。\n用户通过内部 LB 访问 Jenkins,通过公共 LB 访问 GitHub webhook。\n我们使用的 Jenkins 集成了 GitHub,所以我们应该通过外部网络为 Github 提供一些 Jenkins URL。有很多可操作的方案(IP 白名单,URL 或者令牌白名单,等等)而我们则结合 Cloudfront 以允许路径以及令牌验证。\n做完这些事情之后,我们已经有一个现成的带有 AMI 的基础架构了。为监控提供了可能性以及用来获取公司凭据的 Vault 同样可以获得。\n使用 Docker 管理 Jenkins 以及它的插件版本 好的,下一步就是 Jenkins 以及插件了。我们之前在升级 Jenkins 插件时遇到了很多问题,所以主要目标就是为它们固定版本。\n这个时候 Docker 帮了我们大忙。我们使用事先构建好的 Jenkins 镜像用它作为我们安装的基础镜像。\nFROM jenkins/jenkins:2.215 ENV CASC_JENKINS_CONFIG /jenkins_configs USER root # Install additional packages RUN apt update \u0026amp;\u0026amp; \\ apt install -y python3 python3-pip \u0026amp;\u0026amp; \\ pip3 install awscli jenkins-job-builder jjb-reactive-choice-param --no-cache-dir USER jenkins VOLUME /jenkins_configs VOLUME /var/jenkins_home # Install plugins COPY plugins.txt /usr/share/jenkins/ref/ RUN /usr/local/bin/install-plugins.sh \u0026lt; /usr/share/jenkins/ref/plugins.txt 我们为 Job Builder 安装了一些额外的安装包,我们后面会用到,还传递了一个数据卷用于 Jenkins 和安装插件。\n我们在 https://our-jenkins-url/script 上得到的 Groovy 代码将其粘贴保存到 plugins.txt ,通过它我们可以很轻松的得到插件列表。\nJenkins.instance.pluginManager.plugins.each{ plugin -\u0026gt; println (\u0026quot;${plugin.getShortName()}:${plugin.getVersion()}\u0026quot;) } 最后,docker-compose 配置在 Docker 中运行 Jenkins(我们还使用了 vaultenv 用来从 Vault 到 docker-compose 传递凭据):\nversion: \u0026quot;3\u0026quot; services: jenkins: build: . container_name: jenkins restart: always ports: - \u0026quot;50000:50000\u0026quot; - \u0026quot;8080:8080\u0026quot; volumes: - ./configs/:/jenkins_configs/:ro - ./jenkins_home/:/var/jenkins_home/:rw environment: - VAULT_TOKEN - GITHUB_TOKEN - AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY - JAVA_OPTS=-Xms4G -Xmx8G -Xloggc:/var/jenkins_home/gc-%t.log -XX:NumberOfGCLogFiles=5 -XX:+UseGCLogFileRotation -XX:GCLogFileSize=20m -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCCause -XX:+PrintTenuringDistribution -XX:+PrintReferenceGC -XX:+PrintAdaptiveSizePolicy -XX:+UseG1GC -XX:+ExplicitGCInvokesConcurrent -XX:+ParallelRefProcEnabled -XX:+UseStringDeduplication -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=20 -XX:+UnlockDiagnosticVMOptions -XX:G1SummarizeRSetStatsPeriod=1 volumes: configs: driver: local jenkins_home: driver: local 记住,一些 Java 参数可以帮助我们处理一些垃圾收集以及资源限制,这是很重要的。这篇文章在调节 Jenkins 这方面写的非常棒。\n当然,我们可以在本地运行 Jenkins 安装插件,或者是新版本的 Jenkins。同样也很棒。\n现在我们有了安装了插件的 Jenkins,甚至我们可以在本地运行以及轻松将其部署到生产环境。让我们为它多添加一些配置吧。\n为主节点配置 Jenkins 即代码(JCasC)插件 Jenkins 配置即代码(JCasC)插件以一种可读性的格式存储配置。\n这个插件可以让我们描述安全配置、凭据、插件配置、节点、视图以及很多其他的一些东西。\n这个 YAML 配置文件分为 5 块:\n credentials(系统凭据描述)\n jenkins(授权、云设置、全局参数、节点、安全领域以及视图)\n security(全局安全配置,比如脚本权限)\n tool(外部工具配置,比如 git,allure等)\n unclassified(其他配置,比如 Slack 集成)\n 我们可以从现有的 Jenkins 安装过程导入配置\n它支持不同凭据提供者用来管理凭据,但是我们同样需要使用环境变量。\ncredentials: system: domainCredentials: - credentials: - usernamePassword: description: \u0026quot;AWS credentials\u0026quot; id: \u0026quot;aws-creds\u0026quot; password: ${AWS_SECRET_ACCESS_KEY} scope: GLOBAL username: ${AWS_ACCESS_KEY_ID} - string: description: \u0026quot;Vault token\u0026quot; id: \u0026quot;vault-token\u0026quot; scope: GLOBAL secret: ${VAULT_TOKEN} ... 我们还将 Amazon EC2 插件用于 AWS 上的自举代理,它的配置同样可以使用这个插件管理。基于矩阵的授权允许我们以代码的方式管理用户的权限。\njenkins: authorizationStrategy: projectMatrix: permissions: - \u0026quot;Overall/Administer:steve.a@example.org\u0026quot; - \u0026quot;Credentials/View:john.d@example.org\u0026quot; ... clouds: - amazonEC2: cloudName: \u0026quot;AWS\u0026quot; privateKey: ${EC2_PRIVATE_KEY} region: \u0026quot;${AWS_REGION}\u0026quot; templates: - ami: \u0026quot;ami-12345678\u0026quot; amiType: unixData: sshPort: \u0026quot;22\u0026quot; connectionStrategy: PRIVATE_IP deleteRootOnTermination: true description: \u0026quot;jenkins_agent\u0026quot; idleTerminationMinutes: \u0026quot;20\u0026quot; instanceCapStr: \u0026quot;100\u0026quot; minimumNumberOfInstances: 0 mode: EXCLUSIVE numExecutors: 1 remoteAdmin: \u0026quot;jenkins\u0026quot; remoteFS: \u0026quot;/home/jenkins\u0026quot; securityGroups: \u0026quot;sg-12345678\u0026quot; subnetId: \u0026quot;subnet-12345678\u0026quot; type: C52xlarge ... 我们还用了很多很酷的东西。如果我们有一个是测试 Jenkins 本地变更的流程,我们就可以在投入到生产环境之前发现和修复 bug。\n所以我们安装了一个可复用的 Jenkins 配置,最后但并非不重要的是我们的任务\n为自由风格任务集成 Job Builder 当我们讨论自由风格任务时,在 Jenkins 里有几种不同的方式来创建它们:\n 使用 GUI(最简单的方法,仅需要点击即可)\n 直接使用 REST API\n 使用类似 Job DSL 或者 JJB wrapper 的插件\n Jenkins Job Builder(JJB)可以让我们配置任务到一个可读的文本格式中(YAML 或者 JSON)。这样使用 SCM 管理这些任务时会非常舒服。基本上,我们可以使用 JJB 为我们的 CI/CD 工具创建一个 CI/CD 流程。\n. ├── config.ini ├── jobs │ ├── Job1.yaml │ | ... │ └── Job2.yaml └── scripts ├── job1.sh | ... └── job2.sh 这里,我们可以在一个 Job1.yaml 的文件里描述任务的定义,任务步骤在脚本中(比如 job1.sh)。\n- job: name: Job1 project-type: freestyle auth-token: mytoken disabled: false concurrent: false node: jenkins_agent triggers: - timed: '0 3 * * *' builders: - shell: !include-raw: ../scripts/job1.sh 这是一个配置文件的例子:\n$ cat config.ini [job_builder] ignore_cache=True exclude=jobs/Job2 [jenkins] url=https://jenkins.example.org user=some_user password=some_password $ jenkins-jobs --conf config.ini test -r jobs/ $ jenkins-jobs --conf config.ini update -r jobs/ 在 jenkins 任务升级命令中它应该会被很轻松的运行\n当然,我们的 Jenkins 用户需要有创建和配置任务的权限。我们只是需要在主节点上运行一个用来从 JJB 导入到 Jenkins 所有配置的子任务。\nJJB 并不是灵丹妙药,因为仍有一些不是很常用的插件是不支持的。但是它仍是一个非常灵活的插件。另外,它可以使用 macroses 进行配置。\n结论 现在我们已经看到了‘一切事物即代码’模式的一个大概的轮廓以及我们怎样使用 Jenkins,我们可以回到文章开头提到的那几个问题那里。你找到答案了吗?或许,显而易见了,5 个问题的答案都是 “yes”。\n我们仅仅想同你一同分享我们的经验,这篇文章中参数配置以及 Jenkins 最佳实践我们没有深入展开讲。\n", "auhtor": "Amet Umerov", "translator": "0N0thing", "original": "https://medium.com/preply-engineering/jenkins-omg-275e2df5d647", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/meeting/2020-04-01/", "title": "", "type": "meeting", "date": "2020-04-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 中文教程 在jenkins中配置钉钉通知 https://github.com/jenkins-infra/wechat/pull/333/files helm chart 的应用 https://github.com/jenkins-zh/jenkins-zh-courses/pull/5/files 会议记录页面改善 https://github.com/jenkins-zh/jenkins-zh/pull/204 UCloud 服务器管理 容器中运行 nginx 在测试 流水线更新 nginx 配置文件的在测试 https://github.com/jenkins-zh/shared-library ssh 端口的修改 ✅ ssh 证书过期的程序正在进行 python(crontab) 用户审计 ✅ 用户远程登录的操作记录都能记录下来 Jenkins 节点的挂载 需要在私有 git 仓库中记录服务区文件以及其他的配置信息 @linuxsuren 每个服务器 ssh 端口 列出一个清单,要记录哪些私有信息 @anxk 社区媒体账号运营情况 活跃的成员\n wenjunzhangp 0N0thing zhaoying818 微信公众号的文章发布以及效果都比之前要好\n 定期激励 @yJunS\n 文章 review 或者修改的不及时 @yJunS\n 建立微信翻译组 GCTT (Go Chinese Translation Team) https://studygolang.com/gctt wechat 仓库失败\n Jenkinsfile 重名了 迁移 wechat 到 jenins-zh 中 @linuxsuren\n ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/04/2020-04-01-hands-on-beautify-the-user-interface-of-jenkins-reporter-plugins/", "title": "动手实践:美化 Jenkins 报告插件的用户界面", "type": "wechat", "date": "2020-04-01 00:00:00 +0000 UTC", "tags": ["ui", "ux", "plugins", "developer"], "description": "进来看看,关于 Jenkins 新的 UI 插件介绍以及他们的教程、用法都在这里了", "content": " 对于 Jenkins 而言,可以使用大量插件来可视化各种构建步骤的结果。有一些插件可用于呈现测试结果、代码覆盖率、静态分析等。所有这些插件通常都会获取给定构建步骤的构建结果,并在用户界面中显示它们。为了呈现这些细节,大多数插件使用静态 HTML 页面,因为这种类型的用户界面是 Jenkins 自 2007 年成立以来的标准可视化。\n为了改善这些插件的外观和用户体验,有必要向前发展并合并一些现代 Java Script 库和组件。由于 Blue Ocean 的开发已经停止(请参阅 Jenkins mailing list post),因此插件作者需要自己决定,哪些 UI 技术可帮助完成该任务。但是,现代 UI 组件的种类繁多,以至于只挑选一小部分被证明是有用的并且与 Jenkins 基础 Web 技术兼容的组件是有意义的。而且,合并这样一个新组件的初始设置相当大,因此如果该工作仅需要执行一次,将会有很大的帮助。\n本指南介绍了一些 UI 组件,以后所有插件作者都可以使用这些 UI 组件,从而为 Jenkins 中的报告提供丰富的用户界面。为了简化这些库在 Jenkins 作为基于 Java 的 Web 应用程序的上下文中的使用,这些 Java Script 库和组件已打包为普通的 Jenkins 插件。\n在以下各小节中,将逐步介绍这些新组件。为了了解如何使用这些组件的插件,我将演示新功能,同时使用新的用户界面增强现有的 Forensics Plugin。由于 Warnings Next Generation 插件也使用这些新组件,因此您可以在 warnings 插件的文档中或在我们的公共 ci.jenkins.io 实例中看到其他示例,这些示例已经在 warnings 插件的详细信息视图中使用了这些组件。\n新的用户界面插件 新的 Jenkins 插件提供了以下 UI 组件:\n jquery3-api-plugin:为 Jenkins 插件提供 jQuery 3。如其首页所述,jQuery 是一个快速、小型且功能丰富的 JavaScript 库。借助易于使用的 API(可在多种浏览器中使用),使 HTML 文档的遍历和操作、事件处理、动画和 Ajax 等事情变得更加简单。兼具多功能性和可扩展性,jQuery 改变了数百万人编写 JavaScript 的方式。 bootstrap4-api-plugin:为 Jenkins 插件提供 Bootstrap 4。Bootstrap 自称是世界上最流行的前端组件库,用于在 Web 上构建响应式,移动优先的项目。它是一个用于使用 HTML、CSS 和 JS 开发的开源工具包。开发人员可以使用他们的 Sass 变量和 mixins、响应式栅格系统、大量的预构建组件以及基于 jQuery 构建的强大插件,快速构建其思想原型或整个应用程序。 data-tables-api-plugin:提供 Jenkins 插件的数据表格。DataTables 是 jQuery Javascript 库的插件。这是一个高度灵活的工具,建立在逐步增强的基础上,可将所有这些高级功能添加到任何 HTML 表中: 上一页,下一页和页面导航 通过文本搜索过滤结果 一次按多列对数据排序 DOM、Javascript、Ajax、服务器端处理 简单主题化 手机端兼容友好 echarts-api-plugin:为 Jenkins 插件提供 ECharts。ECharts 是一种开放源代码的 JavaScript 可视化工具,用于创建直观、交互式和高度可定制的图表。它可以在 PC 和移动设备上流畅运行,并且与大多数现代 Web 浏览器兼容。 font-awesome-api-plugin:为 Jenkins 插件提供 Font Awesome。Font Awesome 具有矢量图标和社交徽标,号称是网络上最受欢迎的图标集和工具包。目前,它包含 1,500 多个免费图标。 popper-api-plugin:为 Jenkins 插件提供 Popper.js。Popper 只需一行代码即可轻松定位工具提示,弹出窗口或其他任何内容。 plugin-util-api-plugin:这个小插件提供了一些帮助程序和基类,以简化 Jenkins 中报告程序的创建。该插件还提供了一组体系结构规则,这些规则可以包含在插件的体系结构测试套件中。 POM 文件必要的改变 为了使用这些插件,您需要将它们作为依赖项添加到插件 pom 中。您可以使用以下代码段将其全部添加:\npom.xml \u0026lt;project\u0026gt; [...] \u0026lt;properties\u0026gt; \u0026lt;plugin-util-api.version\u0026gt;1.0.2\u0026lt;/plugin-util-api.version\u0026gt; \u0026lt;font-awesome-api.version\u0026gt;5.12.0-7\u0026lt;/font-awesome-api.version\u0026gt; \u0026lt;bootstrap4-api.version\u0026gt;4.4.1-10\u0026lt;/bootstrap4-api.version\u0026gt; \u0026lt;echarts-api.version\u0026gt;4.6.0-8\u0026lt;/echarts-api.version\u0026gt; \u0026lt;data-tables-api.version\u0026gt;1.10.20-13\u0026lt;/data-tables-api.version\u0026gt; [...] \u0026lt;/properties\u0026gt; \u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.jenkins.plugins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;plugin-util-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${plugin-util-api.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.jenkins.plugins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;font-awesome-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${font-awesome-api.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.jenkins.plugins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;bootstrap4-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${bootstrap4-api.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.jenkins.plugins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;echarts-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${echarts-api.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.jenkins.plugins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;data-tables-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${data-tables-api.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; [...] \u0026lt;/dependencies\u0026gt; [...] \u0026lt;/project\u0026gt; 或者,您可以查看 Warnings Next Generation 插件或Forensics API 插件的 POM 文件,它们已经使用了这些插件。\n报告的总体结构 在本节中,我将解释 Jenkins 设计的一些基础知识,即 Java 模型和相关的用户界面元素。如果您已经熟悉如何实现报告插件的相应扩展点(请参阅 Jenkins 开发人员指南中的可扩展性部分),则可以跳过本节,直接进入第 3.1 节。\nJenkins 使用 图 1 所示的静态对象模型结构来组织项目。\nJenkins 用户界面中的顶级项目是工作(至少是我们感兴趣的顶级项目)。Jenkins 包含多个不同类型的任务(自由式任务、Maven任务、流水线等)。\n这些任务中的每一个都包含任意数量的构建(或更确切地说,是运行)。每个版本均由其唯一的版本号标识。Jenkins 插件可以将结果附加到这些版本中,例如生成工件、测试结果、分析报告等。为了附加这样的结果,插件在技术上需要实现并创建存储这些结果的操作。\n这些 Java 对象在几种不同的视图中可视化,以下各节将对其进行详细描述。显示所有可用任务的顶级视图如图 2 所示。\n插件还可以在这些视图中提供 UI 元素,但这超出了本指南的范围。\n每个任务都有一个详细视图,插件可以在其中扩展相应的扩展点并提供摘要框和趋势图。通常,在工作级别上不需要报告者摘要框,因此我仅更详细地描述趋势图,请参见第 5.5.2 节。\n每个版本也都有一个详细视图。在这里,插件可以提供类似于“工作详细信息”视图的框的摘要框。通常,插件在这里仅显示简短摘要,并提供指向详细结果的链接,有关示例,请参见图 4。\n视图层次结构中的最后一个元素实际上是一个专用视图,它显示特定插件的结果。例如,有些视图可显示测试结果,分析结果等。完全由给定的插件决定应在此处显示哪些元素。在接下来的几节中,我将介绍一些新的 UI 组件,这些组件可用于以愉悦的方式显示相应的结果。\n扩展 Jenkins 对象模型 由于报告程序通常以类似的方式构成,因此我用一些其他元素扩展了 Jenkins 的原始对象模型(参见图 1),因此创建或实现新的报告程序插件将更加简单。这个新模型如图 5 所示。中心元素是构建操作,它将存储插件报告程序的结果。此操作将附加到每个内部版本,并将为报告者保存(并保留)结果。每个动作的详细数据将自动存储在其他文件中,因此,如果用户从不要求提供详细信息,则 Jenkins 的内存占用空间可以保持较小。另外,该动作还用于简化项目动作和趋势图的创建,请参见第 5.5.2 节。\nGit Forensics 插件 本教程中的元素将全部在新的 Forensics API 插件中使用(实际上,该插件不是新的,它是 Warnings Next Generation 插件的依赖项)。您可以下载插件内容,并详细了解如何在实践中使用这些新组件。或者,您可以更改此插件,只是为了了解如何对这些新组件进行参数设置。\n如果您将 Git 用作源代码管理系统,则此插件将以犯罪现场代码的样式(Adam Tornhill,2013 年 11 月)挖掘存储库,以确定所包含源代码文件的统计信息:\n 提交总数 不同作者总数 创建时间 最后一次编辑时间 该插件提供了一个新的步骤(或发布后的发布者)该步骤开始了存储库挖掘并将收集的信息存储在 Jenkins 操作中(请参见图 5)。然后,您将获得一个新的构建摘要,该摘要显示扫描文件的总数(趋势和构建结果)。从这里,您可以导航到详细信息视图,该视图在可以简单排序和过滤的表中显示扫描的文件。您还将获得一些饼图,这些饼图显示提交历史记录的重要方面。\n请注意,插件的此功能仍是概念证明:此步骤的性能在很大程度上取决于 Git 存储库的大小和提交次数。当前,它会扫描每个版本中的整个存储库。在不久的将来,我希望找到一个有志于用增量扫描仪替代这种愚蠢算法的志愿者。\n引入新的 UI 组件 如第 3 节所述,详细信息视图特定于插件。显示的内容以及这些元素的显示方式取决于各个插件作者。因此,在接下来的部分中,我将提供一些示例和新概念,插件可以将这些示例和新概念用作其自身内容的构建块。\n现代化图标 Jenkins 插件通常不经常使用图标。大多数插件都提供了操作图标,仅此而已。如果您打算在其他地方使用图标,那么插件作者将自己留着:推荐的 Tango 图标集已有 10 多年的历史了,如今太有限了。有几个选项可用,但最受欢迎的是 Font Awesome Icon Set。它提供超过 1500 个遵循相同设计准则的免费图标:\n为了在插件中使用 Font Awesome 图标,您只需要依赖于相应的 font-awesome-api-plugin 即可。然后,您可以在果冻视图中使用新标签 svg-icon 来使用任何实心图标:\nindex.jelly 1 \u0026lt;j:jelly xmlns:j=\u0026quot;jelly:core\u0026quot; xmlns:st=\u0026quot;jelly:stapler\u0026quot; xmlns:l=\u0026quot;/lib/layout\u0026quot; xmlns:fa=\u0026quot;/font-awesome\u0026quot;\u0026gt; 2 3 [...] 4 \u0026lt;fa:svg-icon name=\u0026quot;check-double\u0026quot; class=\u0026quot;no-issues-banner\u0026quot;/\u0026gt; 5 [...] 6 7 \u0026lt;/j:jelly\u0026gt; 如果要使用 Java 代码生成视图,则也可以使用 SvgTag 类为此类图标生成 HTML 标记。\n栅格布局 目前,Jenkins 在所有视图中都包含 Boostrap 栅格系统的旧版本和补丁版本(24 列)。该版本与 Boostrap4 或任何依赖 Bootstrap4 的 JS 库不兼容。为了使用 Bootstrap4 功能,我们需要用补丁版本替换 Jenkins 提供的 layout.jelly 文件,该文件不会加载损坏的栅格系统。我打算创建一个PR,以修复 Jenkins 核心中的栅格,但这将需要一些时间。在此之前,您将需要使用 Boostrap4 插件提供的 layout.jelly,请参见下文。\n首先要确定的是,哪些元素应显示在插件页面上以及每个元素应占用多少空间。通常,所有可见组件都使用简单的栅格映射到可用空间上。在 Jenkins 视图中,我们具有固定的页眉和页脚以及左侧的导航栏(水平空间的20%)。屏幕的其余部分可由详细信息视图使用。为了简化剩余空间中元素的分布,我们使用 Bootstrap 的栅格系统。\n这意味着,一个视图被分为 12 列和任意数量的行。此栅格系统易于使用(但足够复杂,还可以支持精美的屏幕布局)-我在这里不做详细介绍,请参考 Bootstrap 文档。\n对于取证详细视图,我们使用两行两列的简单栅格。由于列数始终为 12,因此我们需要创建两个宽列以填充 6 个标准列。为了在我们的插件中创建这样的视图,我们需要创建一个以果冻文件和相应的 Java 视图模型对象形式给出的视图。以下代码段显示了具有这种布局的视图:\nindex.jelly 1 \u0026lt;?jelly escape-by-default='true'?\u0026gt; 2 \u0026lt;j:jelly xmlns:j=\u0026quot;jelly:core\u0026quot; xmlns:st=\u0026quot;jelly:stapler\u0026quot; xmlns:l=\u0026quot;/lib/layout\u0026quot; xmlns:bs=\u0026quot;/bootstrap\u0026quot;\u0026gt; 3 4 \u0026lt;bs:layout title=\u0026quot;${it.displayName}\u0026quot; norefresh=\u0026quot;true\u0026quot;\u0026gt; 5 \u0026lt;st:include it=\u0026quot;${it.owner}\u0026quot; page=\u0026quot;sidepanel.jelly\u0026quot;/\u0026gt; 6 \u0026lt;l:main-panel\u0026gt; 7 \u0026lt;st:adjunct includes=\u0026quot;io.jenkins.plugins.bootstrap4\u0026quot;/\u0026gt; 8 \u0026lt;div class=\u0026quot;fluid-container\u0026quot;\u0026gt; 9 10 \u0026lt;div class=\u0026quot;row py-3\u0026quot;\u0026gt; 11 \u0026lt;div class=\u0026quot;col-6\u0026quot;\u0026gt; 12 Content of column 1 in row 1 13 \u0026lt;/div\u0026gt; 14 \u0026lt;div class=\u0026quot;col-6\u0026quot;\u0026gt; 15 Content of column 2 in row 1 16 \u0026lt;/div\u0026gt; 17 \u0026lt;/div\u0026gt; 18 19 \u0026lt;div class=\u0026quot;row py-3\u0026quot;\u0026gt; 20 \u0026lt;div class=\u0026quot;col\u0026quot;\u0026gt; 21 Content of row 2 22 \u0026lt;/div\u0026gt; 23 \u0026lt;/div\u0026gt; 24 25 \u0026lt;/div\u0026gt; 26 \u0026lt;/l:main-panel\u0026gt; 27 \u0026lt;/bs:layout\u0026gt; 28 \u0026lt;/j:jelly\u0026gt; 使用基于 Bootstrap 的自定义布局:由于 Jenkins 核心包含旧版本的 Bootstrap,因此我们需要替换标准的 layout.jelly 文件。 导入 Bootstrap4:使用辅助概念完成 JS 和 CSS 组件的导入,这是在 Jenkins 的 Stapler Web 框架中引用静态资源的首选方式。 整个视图将被放入一个充满整个屏幕(宽度为100%)的流体容器中。 视图的新行由类 row 指定。附加类 py-3 定义了用于此行的填充,有关更多详细信息,请参见 Bootstrap Spacing。 由于 Bootstrap 会自动将一行分成 12 个相等大小的列,因此我们在此定义第一列应占据这 12 列中的 6 列。您也可以省略详细编号,然后 Bootstrap 将自动在可用空间中分发内容。请注意,在大多数情况下这不是您想要的。 第二列使用剩余空间,即 12 列中的 6 列。 第二行使用与第一行相同的布局。 第 1 行只有一列,它将填满整个可用空间。 您还可以根据屏幕的实际可见大小为一行指定不同的列布局。这有助于改善大屏幕的布局。在警告插件中,您将找到一个示例:在小型设备上,有一张可见的卡片可以在轮播中显示一张饼图。 如果要在较大的设备上打开同一页面,则会并排显示两个饼图,并且轮播会被隐藏。\n卡片 当将插件信息显示为一个块时,通常会显示纯文本元素。通常,这将导致某些无关紧要的网页。为了创建一个更具吸引力的界面,在具有边框、标题、图标等的卡片中显示此类信息是有意义的。为了创建这样的 Bootstrap 卡片,新的 Bootstrap 插件提供了一个小的果冻标签,该标签简化了插件的此任务。可以通过以下方式在果冻视图中轻松创建此类卡片:\n1 \u0026lt;bs:card title=\u0026quot;${%Card Title}\u0026quot; fontAwesomeIcon=\u0026quot;icon-name\u0026quot;\u0026gt; 2 Content of the card 3 \u0026lt;/bs:card\u0026gt; 在图 8 中显示了此类卡的示例。上排的卡片包含饼图,这些饼图显示了整个存储库中作者和提交数量的分布。底部的卡在数据表中显示详细信息。可视化不仅限于图表或表格,您可以在其中显示任何类型的 HTML 内容。您可以在这些卡中显示插件的任何图标,但是建议使用现有的 Font Awesome 图标之一,以在 Jenkins 的插件生态系统中获得一致的外观。\n注意,卡片的大小由网格配置决定,请参见第 5.2 节。\n表格 用于显示插件详细信息的常见 UI 元素是表格控件。大多数插件(和 Jenkins 核心)通常使用纯 HTML 表格。但是,如果表格应显示大量行,则使用像 DataTables 这样的更复杂的控件更有意义。使用此基于 JS 的表控件可免费提供其他功能:\n 通过文本搜索过滤结果 提供结果集的分页 一次按多列排序数据 使用 Ajax 调用获取表行 根据屏幕分辨率显示和隐藏列 为了在视图中使用 DataTables,有两个选项,您可以装饰现有的静态 HTML 表(请参见第 5.4.1 节)或使用 Ajax 填充表内容(请参见第 5.4.2 节)。\n静态 HTML 内容的表格 使用 DataTables 的最简单方法是创建一个静态 HTML 表格,只需调用 datatable 的构造函数即可对其进行修饰。这种方法在 Java 和 Jelly 方面不涉及任何特殊处理,因此我认为只需遵循 DataTables 文档中的示例即可。只需确保在您的 Jelly 文件中构建了表之后,您需要使用以下代码装饰表:\n\u0026lt;j:jelly xmlns:j=\u0026quot;jelly:core\u0026quot; xmlns:st=\u0026quot;jelly:stapler\u0026quot; \u0026gt; \u0026lt;st:adjunct includes=\u0026quot;io.jenkins.plugins.jquery3\u0026quot;/\u0026gt; \u0026lt;st:adjunct includes=\u0026quot;io.jenkins.plugins.data-tables\u0026quot;/\u0026gt; [...] \u0026lt;div class=\u0026quot;table-responsive\u0026quot;\u0026gt; \u0026lt;table class=\u0026quot;table table-hover table-striped display\u0026quot; id=\u0026quot;id\u0026quot;\u0026gt; [...] \u0026lt;/table\u0026gt; \u0026lt;/div\u0026gt; [...] \u0026lt;script\u0026gt; $('#id').DataTable(); \u0026lt;/script\u0026gt; \u0026lt;/j:jelly\u0026gt; 用您的 HTML 表格元素的 ID 替换上面代码中的 ID 到目前为止,在 Forensics 插件中还没有使用过此类静态表格,但是您可以查看警告插件中显示固定警告的表,以了解如何装饰此类表。\n具有基于动态模型内容的表 尽管静态 HTML 表格易于实现,但它们有一些限制。因此,遵循更复杂的方法是有意义的。通常,用户界面中的表是通过使用相应的表(和行)模型定义的。自 Java 成立以来,Java Swing 成功地提供了这样的表模型概念。我也为 Jenkins 和 DataTables 修改了这些概念。为了在 Jenkins 视图中创建表,插件需要提供一个表模型类,该类提供以下信息:\n 表的 ID(因为视图中可能有多个表) 列的模型(即列的编号,类型和标题标签) 表格的内容(即各个行对象) 您可以在 Forensics 插件中找到此类表格的示例:此处的表格列出了 Git 存储库中的文件以及相应的提交统计信息(作者数量、提交数量、最后修改、首次提交)。该表的屏幕截图如图 9 所示。\n为了在 Jenkins 中创建这样的表,您需要创建一个从 TableModel 派生的表模型类。在图 10 中,显示了取证插件中相应类的图。\n表格栏模型\n表格模型类定义的第一件事是通过创建相应的 TableColumn 实例来创建可用列的模型。对于每一列,您需要指定标题标签和应在相应列中显示的 bean 属性的名称(行元素实际上是 Java bean:每一列将显示此类 bean 的一个独特属性,请参阅下一节)。您可以通过简单地提供基于 String 或 Integer 的列来使用任何受支持的列类型。\n表格行内容\n此外,表模型类提供行的内容。此 getRows() 方法将使用 Ajax 调用异步调用。通常,此方法仅返回 Java Bean 实例的列表,该列表提供每一列的属性(请参见上一节)。这些对象将自动转换为 JSON 对象数组,这是 DataTables API 所需的基本数据结构。您可以在 ForensicsTableModel 类的取证插件的 Git 存储库中找到一个可以正常工作的示例表模型实现。\n为了在插件视图中使用这样的表,您需要使用新的 table 标签在关联的 Jelly 文件中创建表:\nindex.jelly \u0026lt;j:jelly xmlns:j=\u0026quot;jelly:core\u0026quot; xmlns:dt=\u0026quot;/data-tables\u0026quot; \u0026gt; [...] \u0026lt;st:adjunct includes=\u0026quot;io.jenkins.plugins.data-tables\u0026quot;/\u0026gt; \u0026lt;dt:table model=\u0026quot;${it.getTableModel('id')}\u0026quot;/\u0026gt; [...] \u0026lt;/j:jelly\u0026gt; 用自己的 ID 替换上面代码的 ID 您需要为表提供的唯一参数是 model,它通常是对应的 Jenkins 视图模型类的一部分(此对象在视图中用${it}引用)。为了将对应的 Jenkins 视图模型类与表连接,视图模型类需要实现 AsyncTableContentProvider 接口。甚至更简单,让您的视图模型类派生自 DefaultAsyncTableContentProvider。此关系是必需的,以便 Jenkins 可以自动创建和绑定 Ajax 调用的代理,该代理将在创建 HTML 页面后自动填充表内容。\n如果将所有这些部分放在一起,则需要定义一个类似于 Forensics 插件的模型的模型,如图 11 所示。\n如在图 5 中已经描述的,插件需要将 BuildAction 附加到每个构建。Forensics 插件将 ForensicBuildAction 附加到构建。该操作存储一个 RepositoryStatistics 实例,该实例包含给定构建的存储库结果。该操作将所有 Stapler 请求委派给新的 Stapler 代理实例,因此我们可以使该操作清除用户界面代码。然后,此 ForensicsViewModel 类充当视图模型,为文件 index.jelly 给出的相应 Jelly 视图提供服务器端模型。\n虽然这种方法在第一眼看上去很复杂,但是您会看到实际的实现部分很小。基本类已经提供了大多数样板代码,您只需要实现一些方法即可。使用此概念还提供了一些其他功能,这些功能是 DataTables 插件的一部分:\n 列的顺序会自动保存在浏览器本地存储中。 分页大小会自动保存在浏览器本地存储中。 仅当表格可见时才实际调用 Ajax 调用。因此,如果选项卡中隐藏了几个表,则仅按需加载内容,从而减少了要传输的数据量。 有一个选项可用于提供其他详细信息行,该行可以用 + 符号扩展,有关详细信息,请参阅 warnings plugin table。 图表 插件报告程序通常还会报告从构建到构建的某种趋势。到目前为止,Jenkins 核心仅提供了一个非常有限的概念来呈现诸如趋势图之类的趋势。Jenkins 核心提供的 JFreeChart 框架是服务器端渲染引擎,可将图表创建为静态 PNG 图像,并将其包含在任务和详细信息页面中。如今,有几个功能强大的基于 JS 的图表库可供使用,它们在客户端完成相同的工作(实际上甚至做得更好)。这样做的好处是可以在每个客户端上自定义这些图表,而不会影响服务器性能。此外,您还可以免费获得许多其他功能(例如缩放,动画等)。此外,这些图表库不仅支持典型的构建趋势图,而且还支持许多其他图表类型,可用于改善插件的用户体验。这些图表库之一是 ECharts:该库具有强大的 API,并且实际上支持一个人可以想象的每种图表类型。您可以在库的示例页面上获得一些功能印象。\n为了使用这些图表,可以通过导入相应的 JS 文件并在相应的 Jelly 文件中定义图表来嵌入使用该库的图表。尽管这已经很好地工作了,但是从詹金斯的构建结果中为这些图表提供相应的模型仍然有些麻烦。因此,我添加了功能强大的 Java API,可帮助在 Java 端为这些图表创建模型。该 API 提供以下功能:\n 根据构建结果的集合创建趋势图。 将图表类型与聚合分开,以简化图表模型的单元测试。 在内部版本号或内部版本日期之间切换 X 轴的类型(自动汇总当天记录的结果)。 将 Java 模型自动转换为 JS 端所需的 JSON 模型。 支持饼图和折线图(更多内容即将推出)。 这些图表可以在项目页面中用作趋势图(请参见图 3),也可以在插件的详细信息视图中用作信息图(请参见第 5 节)。\n饼状图 一个简单但仍然有用的图表是一个饼图,它说明了插件数据的数字比例。在 Forensics 插件中,我使用此图表来显示 Git 存储库中源代码文件的作者或提交数量的数字比例(请参见图 8)。在警告插件中,我使用此图表显示新警告,突出警告或固定警告的数字比例,请参见图 12。\n为了在您的详细信息视图中包括这样的图表,您可以使用提供的 pie-chart 标签。在以下代码片段中,您可以看到此标签的使用情况(嵌入在 Bootstrap 卡片中,请参见第 5.3 节):\nindex.jelly 1 \u0026lt;?jelly escape-by-default='true'?\u0026gt; 2 \u0026lt;j:jelly xmlns:j=\u0026quot;jelly:core\u0026quot; xmlns:c=\u0026quot;/charts\u0026quot; xmlns:bs=\u0026quot;/bootstrap\u0026quot;\u0026gt; 3 4 [...] 5 \u0026lt;bs:card title=\u0026quot;${%Number of authors}\u0026quot; fontAwesomeIcon=\u0026quot;users\u0026quot;\u0026gt; 6 \u0026lt;c:pie-chart id=\u0026quot;authors\u0026quot; model=\u0026quot;${it.authorsModel}\u0026quot; height=\u0026quot;256\u0026quot; /\u0026gt; 7 \u0026lt;/bs:card\u0026gt; 8 [...] 9 10 \u0026lt;/j:jelly\u0026gt; 您需要为此图表提供唯一的 ID 和相应的模型值。该模型必须是对应的 PieChartModel 实例的 JSON 表示形式。可以使用以下几行来创建这样的模型:\nViewModel.java 1 [...] 2 PieChartModel model = new PieChartModel(\u0026quot;Title\u0026quot;); 3 4 model.add(new PieData(\u0026quot;Segment 1 name\u0026quot;, 10), Palette.RED); 5 model.add(new PieData(\u0026quot;Segment 2 name\u0026quot;, 15), Palette.GREEN); 6 model.add(new PieData(\u0026quot;Segment 3 name\u0026quot;, 20), Palette.YELLOW); 7 8 String json = new JacksonFacade().toJson(model); 9 [...] 任务级别视图上的趋势图 为了显示在任务页面上呈现折线图的趋势(请参见图 3),您需要提供一个所谓的浮动框(存储在任务操作的 floatBox.jelly 文件中(请参见第 3 节))。该文件的内容非常简单,仅包含一个 trend-chart 标签:\nfloatingBox.jelly 1 \u0026lt;?jelly escape-by-default='true'?\u0026gt; 2 \u0026lt;j:jelly xmlns:j=\u0026quot;jelly:core\u0026quot; xmlns:c=\u0026quot;/charts\u0026quot;\u0026gt; 3 4 \u0026lt;c:trend-chart it=\u0026quot;${from}\u0026quot; title=\u0026quot;${%SCM Files Count Trend}\u0026quot; enableLinks=\u0026quot;true\u0026quot;/\u0026gt; 5 6 \u0026lt;/j:jelly\u0026gt; 在 Java 方面,需要在 JobAction 的相应子类(浮动框的所有者)中提供图表的模型。由于趋势图的计算在服务器端也非常昂贵(需要从磁盘读取多个构建,并且需要计算有趣的数据点),因此该过程已放入单独的后台任务中。一旦计算完成,将通过 Ajax 调用显示结果。为了为插件作者隐藏这些详细信息,您应该简单地从相应的 AsyncTrendJobAction 类派生 JobAction 类,该类已经包含样板代码。因此,您的静态插件对象模型实际上会变得有些复杂:\n基本上,您需要实现 LinesChartModel 方法 createChartModel() 来创建折线图。该方法的实现非常简单,因为大多数艰苦的工作都是由库提供的:从最新的构建开始,您将使用构建动作的迭代器进行调用。迭代器从一个版本开始构建,直到没有更多可用结果为止(或已达到要考虑的最大构建数量)。在插件中实现的最重要的事情是如何为给定的 BuildAction 计算数据点。这是取证插件中此类 SeriesBuilder 实现的示例:\nFilesCountSeriesBuilder.java 1 package io.jenkins.plugins.forensics.miner; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import edu.hm.hafner.echarts.SeriesBuilder; 7 8 /** 9 * Builds one x-axis point for the series of a line chart showing the number of files in the repository. 10 * 11 * @author Ullrich Hafner 12 */ 13 public class FilesCountSeriesBuilder extends SeriesBuilder\u0026lt;ForensicsBuildAction\u0026gt; { 14 static final String TOTALS_KEY = \u0026quot;total\u0026quot;; 15 16 @Override 17 protected Map\u0026lt;String, Integer\u0026gt; computeSeries(final ForensicsBuildAction current) { 18 Map\u0026lt;String, Integer\u0026gt; series = new HashMap\u0026lt;\u0026gt;(); 19 series.put(TOTALS_KEY, current.getNumberOfFiles()); 20 return series; 21 } 22 } 您不仅限于单个折线图。您可以在一个图表中显示多条线,可以显示堆叠的值,甚至可以显示某些值之间的差异。您也可以查看 charts of the warnings plugin,以详细了解其中一些功能。\n", "auhtor": "Ullrich Hafner", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2020/03/17/ui-plugins/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-27-jenkins-tutorial-configure-scm-github-triggers-and-git-polling-using-ngrok/", "title": "Jenkins 教程:使用 Ngrok 配置(SCM)Github 触发器和 Git 轮询", "type": "wechat", "date": "2020-03-27 00:00:00 +0000 UTC", "tags": ["Ngrok", "SCM", "Github", "Git"], "description": "教你如何在作业上配置 Github 触发器以及如何使用 Webhook 与 Github 相通", "content": " 总览 Jenkins 是领先的开源自动化服务。它提供了 1500+ 个插件来支持构建,部署和自动化任何项目。在本文中,我们将研究如何在作业上配置 Github 触发器,以及如何使用 Webhook 与 Github 相通,该 Webhook 指示何时轮询作业以构建对项目进行的更改。\n前提条件 您需要在 Github 中有一个项目。\n您将需要启动并运行 Jenkins 服务。\n入门 安装和运行 Ngrok Ngrok 是一个反向代理,它接受公共地址上的流量,并将该流量中继到计算机上运行的 ngrok 进程,然后再中继到您指定的本地地址。\n因此,通过您选择的任何一种方法,前往 Ngrok 并注册一个帐户。然后,您应该会看到下面的截图,其中显示了如何解压缩和运行它。\n运行./ngrok http 8080,它将指向我们的 Jenkins 服务。\n运行该命令后,您将收到代理主机名,如下所示:\n转发 http://xxxxx.ngrok.io -\u0026gt; http://localhost:8080\n转发 https://xxxxx.ngrok.io -\u0026gt; http://localhost:8080\n设置 Github Webhook 因此,跳转到 Github 项目并单击设置,在左侧面板上应该会看到 webhooks,现在单击该按钮。\n添加我们的 webhook:\n设置 Jenkins 项目或流水线作业 选择 Github 挂钩触发器进行 GitScm 轮询:\n然后,使用您的 GitHub 帐户设置 Jenkins Pipeline:\n开始准备测试我们的工作!使用您指定的 develop,master 等分支将提交提交到您的项目。\n推送完成后,您应该开始看到您的工作建立了最新的推送,您可以跳转到 Github Hook Log 并检查 Webhook 是否通过 Ngrok 进行了代理。\n", "auhtor": "Kiley Nichols", "translator": "wenjunzhangp", "original": "https://www.previous.cloudbees.com/blog/jenkins-tutorial-configure-scm-github-triggers-and-git-polling-using-ngrok", "poster": "cover.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-26-thanks-ucloud/", "title": "致 UCloud 的一封感谢信", "type": "wechat", "date": "2020-03-26 00:00:00 +0000 UTC", "tags": [], "description": "Jenkins 中文社区会在 UCloud 的帮助下为用户提供给好的服务", "content": "故事要从社区服务器的几起故障说起。某天,在微信群、公众号后台等几个渠道中,有用户反馈说 Jenkins 中文社区提供的插件更新中心国内镜像源无法访问。为了避免影响到更多的人,我们赶紧在社区的管理群中同步了该消息。在没有专业运维人员帮助的情况下,我们也必须量快地排除服务器故障。从服务器资源使用的图表上,我们看到 CPU、网络都已经跑满了,此时,已经是无法远程登录到服务器上做任何操作。对于社区的现状而言,确实有一些窘迫,只有1M带宽、1核CPU、1G内存。先不去考虑并发量的问题,单个用户的请求都无法得到较好的体验。这对于完全是由小伙伴自发、志愿组成的开源、公益社区,唯一的出路就是寻找外部的资源和支持,尤其是对开源愿意扶持、有社会责任感的企业。\n此时,我想要分享给社区小伙伴的好消息是:在去年11月份收到了来自霍格沃兹测试学院给予的无私赞助外,今年3月份再次收到了长期专注于移动互联网领域的基础云计算服务提供商 UCloud 的大力支持。UCloud 将会为 Jenkins 中文社区提供1年免费的服务器的使用权,社区的基础设施也会因此得到增强。我们相信,Jenkins 中文社区将会在 UCloud 的帮助下,可以继续带来更多的社会价值,服务更多的个人以及团体用户。\n关于 UCloud,如果大家稍微留意下的话,就会发现很多社区网站和个人博客的底部有 UCloud 的 Logo。这都是对 UCloud 提供的云服务的稳定性的极大肯定,社区希望能以这种方式向大家传递一个这样的消息——我们的网站运行在 UCloud 上很放心。首先,是从客服方面,总是可以及时地得到响应;然后,在创建云主机时,在国内外的很多主要城市都有节点可供选择,引导界面清晰、简洁;对于社区而言非常重要的一个部分,权限管理也完全可以满足我们多个不同角色运维人员的权限分配。其他的云产品,我们虽然目前还没有需求,但随着社区的发展壮大,相信未来也一定可以祝我们一臂之力!加油 UCloud!\n自打发布了Jenkins 插件中心国内镜像源后,我们收到了很多的来自社区论坛以及 GitHub Issues 上的反馈。根据反馈社区也做了很多的改进措施,包括:Jenkins CLI 对切换镜像源的支持、无需任何配置即可使用 Jenkins 中国镜像源的开箱即用的方案。当然,除了软件方案上的改进措施外,我们今天想要特别提到的就是社区基础设施的增强——我们会把 Jenkins 国内镜像源相关的服务全部迁移到 UCloud 的云服务器上。如果您对国内源的访问情况感兴趣,可以查看这里的统计图表。\n公开透明,对于开源社区是非常重要的,我们会把所有收到的赞助以及资源的使用情况,全部记录到 Jenkins 中文社区官网。我们欢迎每一位关注社区的人来监督,同时也希望有更多的个人、企业给予社区赞助,我们将尽自己最大的努力为开源社区带来更大的价值。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“./2020-03-26-thanks-ucloud/ucloud-logo.png”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-24-7-devops-toolchains-orchestration-solutions-you-may-not-know/", "title": "7 款你或许不知道的 DevOps 工具链编排解决方案", "type": "wechat", "date": "2020-03-24 00:00:00 +0000 UTC", "tags": ["DevOps", "toolchains"], "description": "介绍了 7 种在现代软件开发过程中使用到的工具链编排解决方案", "content": " 这七款 DevOps 工具将会帮助你用来考虑将哪个工具包含到你的工具链中。\n团队之间的透明化沟通在应用程序开发过程中成为了一项巨大的挑战。一个组织中的大部分团队的独立性已经有相当长时间了。这也就意味着开发团队、业务分析团队、QA 以及业务运营团队之间的工作距离越来越疏远。\n在交付结果的时候,公司也因此遭受了不少损失。太长的软件交付流程导致了大多数操作的延迟。业务领域的任何人都能理解这意味着什么。仅仅是没有足够的产品创新。似乎这还不够,对市场需求的反应还不是那么令人满意。\n根据一位来自于提供安全编排解决方案的著名公司 Siemplify 的 CEO,Amos Stern 的说法,“使用带有安全编排解决方案的 DevOps 方法可以让你的公司在提高生产力这件事上变得一切皆有可能。”\n这些实践尝试将团队凝聚在一起从而避免各自为战。它们以在应用交付时确保高效为目标。这种方法提升了公司软件交付的功能性并且确保产生更少的风险。它们同样负责消除在 IT 响应中出现的各种障碍。\n但是这些实践没有工具是不能正常运转的。在不同 DevOps 环境下使用不同的控制工具的解决方案称为“DevOps 工具链编排解决方案”。主要有以下工具组成。\n或许你同样感兴趣: 2019 年你应该知道的 5 款 DveOps 工具\n1. 源码管理(SCM) 你为公司构建的所有公司想要表达的东西都是通过代码实现的。但是代码同样有窍门的,你必须确保它能尽可能容易地被理解。你必须对它们进行控制和操作分支。如果做不到这些,就有可能面临乱糟糟的情况。\n为此,它们拥有的 SCM 包括 GitHub 和 Gitlab。\n2. 持续集成(CI) 现在软件开发已经完全需要依赖 CI。这项可操作的技术可以让开发任何东西变得容易。安装一个可设置的 CI 是很重要的,这可以:\n 减少与集成相关的任何问题\n 提升代码质量\n 提升沟通交流\n 提高发布速度\n 减少 bug\n 3. 构建工具 在继续构建组织时,你需要确定哪些工具是重要的哪些又不是你需要的。这不仅仅是重要的,如果你想削减开销这也是必须的。记住,一个公司不注意开支花销的话是很容易出现财务问题的。为此,你需要最好的构建工具来发展你的公司。\n4. 测试 任何业务都存在风险。除了危险的风险之外,还有质量保证的整个方面。如果你想实现你的业务目标的话,拥有准确实时这两方面的考量就变得至关重要。\n例如 JUnit 和 Mocha 以及其他的一些测试工具可以在追踪它们怎样运行这方面成为可能。\n5. 制品管理 一旦你的项目能顺利推进,你需要存储你在流水线中生成的产物。它们需要跟源码存放在 SCM 一样的方式进行保存。存储制品是在需要获取过去产品版本并进行优化时最可靠的方法。\n6. 配置管理 你需要一条标准化资源配置途径。之后,你需要在整个 IT 开发过程中强制使用这个状态。最好的办法是通过一条自动化途径以及敏捷的方式。这种方法叫做配置管理。例如 Ansible、Chef 以及 Puppet 之类的都是此过程最推荐使用的工具。\n7. 部署 实践持续部署同样很关键。这方面的解决方案,每次代码变更会贯穿于整个流水线之中。它会自动放进产品中。这样能够确保每天会有很多次产品的部署。有这些工具可供参考 Supervisor、PM2、Forever。\n结束语 许多工具为 DevOps 的各个方面提供便利。上述的七类工具是一些必须设备。为了充分利用它们,你需要确保使用正确的方法和出于正确的理由使用这些工具。如果你发现任何导致你不能正常使用它们的理由,你可以让这方面服务的专家帮助你使用这些工具轻松管理你在公司中的这些活动。\n进一步阅读 怎样为你的业务找到最棒的 DevOps 工具\nDevOps 工具“暴政”\n", "auhtor": "Souvik Banerjee", "translator": "0N0thing", "original": "https://dzone.com/articles/7-devops-toolchain-orchestration-solution-you-may", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/meeting/2020-03-18/", "title": "", "type": "meeting", "date": "2020-03-18 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 案例 构建 maven 项目,推送镜像 @donhui https://github.com/jenkins-zh/jenkins-zh-courses/pull/3/files 构建 gradle 项目,推送镜像 @donhui 构建 golang 项目,推送镜像 @zhaoying818 构建 nodejs 项目,推送镜像 @yJunS 构建 helm chart 项目 @linuxsuren 自定义发行版 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-17-jenkins-release/", "title": "Jenkins 长期支持版更新", "type": "wechat", "date": "2020-03-17 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "本次更新的版本包括:2.176.2~2.204.5、2.180~2.184", "content": " 2.176.2 (2019-07-17) 用于等待外部进程完成的线程池可能会使类加载器泄露。 当分离的插件(其插件功能曾经是 Jenkins 本身的一部分)作为已经存在的其他插件的隐含依赖时,确保 Jenkins 在启动时对其进行安装。这简化了不使用更新中心的专用安装方案的兼容性,例如当从带有某些插件的预包装 Docker 镜像运行 Jenkins 时。 更新 WinP 从 1.27 到 1.28 ,以修复 Windows 正常进程关闭逻辑中缺少 DLL 和控制台窗口闪退的问题 用更简单的消息替换一些与代理通道有关的异常堆栈跟踪。 2.176.3 (2019-08-28) 当其他插件对其仅具有可选依赖时,插件管理器 UI 不再阻止禁用插件。 解决使用 \u0026ldquo;记住我\u0026rdquo; 时的性能问题。 (由 2.160 引入的缺陷回归) 测试代理配置时不要抛出异常。 (由 2.168 引入的缺陷回归) 防止 Jenkins 重启和用户会话无效时的偶发 IllegalStateException 异常。 2.176.4 (2019-09-25) 2.176.4 和 2.190.1 包含相同的安全修复程序。我们将提供 2.176.x LTS 系列的附加版本,以允许管理员应用安全更新,而无需进行重大升级。 2.190.1 修复 RSS / Atom 提要中缺少的绝对 URL 。 (由 2.190 引入的缺陷回归) 当提示慢触发的管理警告时,Jenkins UI 中断。(由 2.189 引入的缺陷回归) Jenkins 不再在项目或构建目录中创建符号链接。如果需要,可以安装 Build Symlink 插件来恢复此功能。诸如 /job/…/lastStableBuild/ 之类的URL不受影响,仅影响直接访问 $JENKINS_HOME 文件系统的工具。 从 Jenkins 核心中删除 Trilead SSH 库,并使其在新的独立插件中可用。 在任务名称中添加对表情符号和其他非 UTF-8 字符的支持。 🎉 更新 Windows Agent Installer 从 1.10.0 到 1.11 ,以 .NET 4.6 或更高版本运行时,在代理下载上启用 TLS 1.2 。 更新 Winstone-Jetty 从 5.2 到 5.3 ,以更新 Jetty 到 9.4.18 。 更新 JNA 从 4.5.2 到 5.3.1 ,以解决使用 OpenJDK 时在 AIX 上加载共享库的问题。 更新 Remoting 到 3.33 。 支持在流水线和其他任务类型的 fingerprint() 构建步骤中设置排除和大小写敏感。 提升 ListView 中 Configuration-as-Code 的兼容性。 停止在 install-plugin CLI 命令中使用 name 参数。 注销时删除超时的会话 cookie ,以防止与 header 太大等相关的错误。 在 Jenkins URL 配置中添加对 IPv6 地址的支持。 通过不同阴影的构建球,可以区分新项目、禁用项目和已中止构建的项目。 当 cron 触发器的执行时间较长时,添加告警。 在安装向导中分批安装插件以提高性能。 现在可以通过设置系统属性 hudson.node_monitors.AbstractNodeMonitorDescriptor.periodMinutes 来更改节点监视器的默认大小(例如可用磁盘空间)。 2.190.2 (2019-10-28) 无法访问名称中带有表情符号的某些项目 URL 。 在基于 HTTP 的 CLI 上增加客户端保持活动 ping 的频率,以防止超时。 内部: 发生错误时,hudson.util.ProcessTree.OSProcess#getEnvironmentVariables 返回 null ,即使它不应该发生也是如此。 2.190.3 (2019-11-20) 稳定性: 不允许用户使用 POST 在需要提交表单的 URL 上重新提交请求,因为那样无论如何都会失败。 lastCompletedBuild 永久链接未缓存在 …/builds/permalinks 文件中。 将标签固定到 Atom 供稿链接。 在 Firefox 的 Jenkins 经典 UI 中还原表单提交的更改。更改导致了带有\u0026rdquo;文件\u0026rdquo;格式的内容提交的表单的缺陷回归。这样做是为了预料 Firefox 中的错误修正,此错误已被撤消。(由 2.164.3 引入的缺陷回归) 2.204.1 (2019-12-18) 将鼠标悬停在侧栏链接上时,显示带有完整链接名称的工具提示。 防止错误的子任务提供者使构建永久运行。 修复\u0026rdquo;插件管理-已安装\u0026rdquo;列表中卸载列的排序。 在完成加载内存模型之前,请避免调用 Jenkins#save 持久数据。 这样可以防止 Jenkins 主配置损坏。 删除使用用户浏览器下载更新中心元数据的功能(自 2015 年起不推荐使用)。如果没有连接更新站点,Jenkins 将不再通知可用更新。在这种情况下,建议使用更新站点的本地镜像,或使用 Juseppe 之类的自托管更新中心。 允许按用户设置时区。 为资源根 URL 添加一个选项,Jenkins 可以通过该选项为用户生成的静态资源(例如工作空间文件或已归档的制品)提供服务,而无需 Content-Security-Policy 标头。 停止绑定 Maven 插件、 Subversion 插件和 Jenkins war 文件中的一些其他插件。在极少数情况下,尝试安装与 1.310 版本之前的 Jenkins 兼容的插件时,可能会导致问题。Jenkins 项目目前未发布任何此类插件。 弃用 macOS 本地安装程序以使用 Homebrew。 还原在 Firefox 的 Jenkins 经典 UI 中对表单提交的更改(此更改导致了带有\u0026rdquo;文件\u0026rdquo;输入的表单的缺陷回归)。这样做是为了预料 Firefox 中的错误修正,此错误已被撤消。(由 2.173 引入的缺陷回归) 删除构建历史记录小部件中关于构建说明的 100 个字符长度限制。 将 Remoting 从 3.33 更新到 3.36。为入站 TCP 代理添加新的连接模式。将最低必需的 Remoting 版本更新为 3.14。添加命令行选项 \u0026ldquo;-help\u0026rdquo; 和 \u0026ldquo;-version\u0026rdquo;。 2.204.2 (2020-01-29) 验证另一个用户时,当前用户不再注销。 安全增强:在 REST API 响应中将 X-Content-Type-Options 设置为 nosniff 如果 hudson.Util.maxFileDeletionRetries 为零,禁用多次删除尝试。 通过在 Computer.removeExecutor 中删除一次性执行器来防止 master 上的“僵尸”执行器。 修复在 CephFS 上创建空文件时的 AtomicFileWriter 性能问题。 开发者: ViewGroupMixIn#getPrimaryView() 可能返回 null,需要基于这个周版本及以后的版本在插件中进行检查。这是一个过渡状态,直到实现默认视图为止。 2.204.3 (2020-02-28) 内部: Winstone 5.7: 将 Jetty 线程池名称更改为 “Jetty(winstone)”。 如果在运行安装向导之前已经通过脚本配置了 Jenkins 根 URL,即使跳过了创建 admin 用户的选项,也要跳过配置面板。 在安装 Monitoring 插件时,防止有关 Java 11 缺少的、由 JavaMelody 触发的类的错误告警。 当构建连续失败时,在系统日志中包括详细信息。 修复 AdoptOpenJDK 11 的 Java 版本检查。 防止更新中心在进行数据解析时 Jenkins 页面卡住。 Winstone 5.7: 修复对系统日志记录定制的支持 (由 2.177 引入的缺陷回归)。 修复代理脱机时代理 API 中的空指针异常(例如查询代理版本或操作系统说明)。 2.204.4 (2020-03-03) 传递某些类型(例如域通配符)的证书时,修复 Jetty 不支持包含多个证书的密钥库的错误(由 2.204.3 引入的缺陷回归)。 2.204.5 (2020-03-07) 此版本重新引入了 Jenkins 2.177 到 2.203.3 的系统日志记录自定义缺陷(JENKINS-57888 - 系统日志记录自定义),因为它不如其它被修复的缺陷那么严重。计划在 2.22.1 版本中修复。 修复最大表单内容大小和表单内容密钥的传递(由 Jenkins 2.204.3 和 Jetty 9.4.20 引入的缺陷回归)。 修复由于 X-Forwarded-Host 和 X-Forwarded-Port 订阅问题而导致的将不正确的反向代理重定向到 127.0.0.1 的问题(由 Jenkins 2.204.3 和 Jetty 9.4.20 引入的缺陷回归)。 将 Winstone 从 5.8 还原到 5.3,以解决 Winstone 更高版本中嵌入的 Jetty Web 容器引入的问题。默认最大表单大小限制和反向代理重定向被还原(由 2.204.3 引入的缺陷回归)。 ", "auhtor": "jenkinsci", "translator": "zhaoying818", "original": "", "poster": "“./2020-03-17-jenkins-release/great-wall.jpeg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-16-pipeline-authoring-sig-update/", "title": "流水线编撰 SIG 公告", "type": "wechat", "date": "2020-03-16 00:00:00 +0000 UTC", "tags": ["Pipeline-Authoring", "SIG", "community", "opensource"], "description": "带你了解公告 SIG 的变化,从而更好地利用 Jenkins 流水线", "content": " 什么是流水线撰写特别兴趣小组 这个特别的兴趣小组旨在改善和策划 Jenkins Pipelines 的创作经验。这包括 Jenkinsfile、共享库的语法、代码共享、重用、流水线、共享库的测试、IDE 集成、其他开发工具、文档、最佳实践、示例。\n流水线撰写特殊兴趣小组的重点领域是什么 语法-如何编写 Jenkinsfiles 和共享库。 代码共享和重用-共享库和未来的改进。 测试-Jenkinsfile 和共享库的单元和功能测试。 IDE 集成,编辑器和其他开发工具-IDE 插件,可视化编辑器等。 文档-参考文档,教程等。 最佳做法-在 Jenkins Pipeline 中定义,维护和宣传最佳做法。 示例-现实世界中的 Jenkinsfile 和共享库演示了如何利用流水线的各种功能,以及基本或入门版的 Jenkinsfile 用于常见模式,新用户可以将其用作起点。 我们已经做了哪些 新年伊始,成员们聚在一起讨论 2020 年的路线图。在最初的讨论中,我们认为最好检查一下先前会议的目标并确定最佳的前进道路。\n双方共同决定要更好地制定路线图。我们需要更好地了解我们打算帮助谁。我们认为创建角色非常有益。角色是虚构的角色,我们根据研究结果创建了这些角色,以代表可能使用 Jenkins 流水线的不同用户类型。创建角色可以帮助我们走出自我。它可以帮助我们认识到不同的人有不同的需求和期望,也可以帮助我们确定要为其制定路线图的用户。角色使当前的任务变得不那么复杂,可以指导我们的构思过程,并且可以帮助我们实现为目标用户组创造良好用户体验的目标。许多工作可以在这里找到:https://docs.google.com/document/d/1CdyzJwt50Wk3uUNsLMl2d4w2MGYss-phqet0s-KjbEs/edit。这个想法是将角色映射到成熟度模型,然后再将成熟度模型映射到实际文档。该成熟度模型可以在这里找到:https://drive.google.com/file/d/1ByzWlPU0j1qM_gqspJppkNKkR5ZVLWlB/view。\n我如何参与其中 我们一直定期开会以定义角色,以帮助我们更好地创建 SIG 路线图。我们每周开会两次,一次在星期四(EMEA)时区,另一次在星期五(美国)时区。会议记录可以在这里找到:https://docs.google.com/document/d/1EhWoBplGl4M8bHz0uuP-iOynPGuONjcz4enQm8sDyUE/edit#,如果您想参与的话,可以查看日历在这里:https://jenkins.io/event-calendar/。会议的先前记录位于:https://www.youtube.com/watch?v=pz_kPpb9C1w\u0026amp;list=PLN7ajX_VdyaOKKLBXek6iG8wTS24Ac7Y3。\n下一步 我们有很多工作要做,期待您的帮助。如果您想加入我们,请查看会议链接。如果您想查看角色并提供反馈,请查看链接。完成角色配置工作后,我们将开始确定可用的文档,并在 Doc SIG 的帮助下确保我们有足够的文档。然后,我们最终将开始着手构建工具,以帮助社区更好地利用 Jenkins 中的流水线。\n联系我们 如果您想与 Pipeline-Authoring SIG 取得联系,可以通过加入 Pipeline-Authoring SIG gitter channel 或通过 Pipeline-Authoring SIG mailing list 来进行联系。\n", "auhtor": "Marky Jackson", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2020/03/02/pipeline-authoring-sig-update/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/meeting/2020-03-14/", "title": "", "type": "meeting", "date": "2020-03-14 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " Jenkins 中文社区教程编写讨论\n介绍 https://github.com/jenkins-zh/jenkins-zh-courses\n交互式教程,可以有 UI 访问\n案例 构建 maven 项目,推送镜像 @donhui 构建 gradle 项目,推送镜像 @donhui 构建 golang 项目,推送镜像 @zhaoying818 构建 nodejs 项目,推送镜像 @yJunS 构建 helm chart 项目 @linuxsuren 下次会议时间:下周六8pm 03-21\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/meeting/2020-03-13/", "title": "", "type": "meeting", "date": "2020-03-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " Jenkins 中文社区基础设施运维\n项目 https://github.com/jenkins-zh/jenkins-cli/ https://github.com/jenkins-zh/wechat-backend https://github.com/jenkins-zh/docker-zh https://github.com/jenkins-zh/mirror-proxy https://github.com/jenkins-zh/jenkins-zh https://updates.jenkins.io/update-center.json https://updates.jenkins-zh.cn/update-center.json\n服务器 阿里云2台 其中一台有外网 UCloud 规划中 告警 安全 优化 考虑 HA\n自动化运维 人员要求 自我驱动 git linux 目标 近期 把服务器的告警做起来,增加服务器的稳定性(HA或者其他方案)@anxk 如何确保账号的安全性(服务器、阿里云等等) 长期 自动化运维以及运维团队的培养 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-10-create-a-ci-cd-pipeline-with-kubernetes-and-jenkins/", "title": "使用 Kubernetes 和 Jenkins 创建一个 CI/CD 流水线", "type": "wechat", "date": "2020-03-10 00:00:00 +0000 UTC", "tags": ["DevOps", "Kubernetes", "Deployment", "Configuration", "K8s", "CI/CD"], "description": "文章主要说明了关于 CI/CD 的知识,通过实验结合 Jenkins,Ansible,Kubernetes 将应用程序部署到 k8s 上。", "content": " CI/CD 尝试解决什么问题? CI/CD 同 DevOps、Agile、Scrum、Kanban、自动化以及其他术语一样,是一个一起被经常提及的专用术语。有时候,它被当做工作流的一部分,但是并没有搞清楚这是什么或者为什么它会被采用。对于年轻的 DevOps 工程师来说,使用 CI/CD 理所当然已经成为了常态,可能他们并没有看到“传统”的软件发布流程而因此不欣赏 CI/CD。\nCI/CD 表示持续集成/持续交付和/或部署。如果一个团队不接入 CI/CD 流程就必须要在产生一个新的软件产品时经历如下的阶段:\n 产品经理(代表了客户利益)提供了产品需要有的功能以及产品需要遵从的行为。文档必须要越详实越好。\n 具有业务分析能力的开发人员开始对应用进行编码,执行单元测试,然后将结果提交到版本控制系统(例如 git)。\n 一旦开发阶段完成,项目移交到 QA。对产品进行多轮测试,比如用户验收测试,集成测试,性能测试。在此期间,直到 QA 阶段完成之前都不会有任何代码上的改动。如果有任何 bug 被发现,需要回退给开发人员做修改,然后再将产品移交给 QA。\n 一旦 QA 完成,操作团队会将代码部署到生产环境中。\n 上述工作流存在一些弊端:\n 首先,从产品经理提出需求到产品具备开发条件中间会消耗太多时间。\n 对开发人员来说,从写了一个月甚至更长时间的代码中去定位问题真的很困难。请记住,bug 只能是在开发阶段完成 QA 阶段开始后被发现。\n 当有一个*紧急的*代码修复比如像一个严重的 bug 需要热修复时,QA 阶段可能会因为需要尽快部署而被缩短。\n 不同的团队之间很少会有协作,当 bug 出现的时候,人们就开始互相甩锅互相指责。每个人从一开始只是关心项目中自己的那部分工作而忽视了共同的目标。\n CI/CD 通过引入自动化来解决上述的问题。代码中的每次改动一旦推送至版本控制系统,进行测试,然后在部署到用户使用的生产环境之前部署至预生产/UAT 环境进行进一步的测试。自动化确保了整体流程的快速,可信赖,可重复,以及不容易出错。\n所以,什么是 CI/CD 呢? 关于这个主题已经有著作撰写完毕。如何,为什么,以及什么时候在你的架构中使用。然而,我们总是倾向于轻理论重实践。话虽如此,下文简单介绍了一下一旦修改的代码被提交后会执行哪些自动化步骤:\n 持续集成(CI):第一步不包括 QA。换句话说,它不关注代码是否提供了用户需要的功能。相反,它确保了代码的质量。通过单元测试,集成测试,开发人员能很快的就会发现代码质量中的缺陷。我们可以增加代码覆盖率的检查以及静态分析让代码质量保证做的更加完善。\n 用户验收测试:这是 CD 流程的第一部分。这个阶段,会对代码执行自动化测试从而确保代码符合用户的期望。比如说,一个 web 应用没有任何报错产生能正常运行,但是客户想让访问者在导航到主页之前先进入到登录页面。但是当前的代码直接让访问者导航到了主页面,这与客户的需求不相符。这种问题会在 UAT 测试时被指出。而在非 CD 环境,就成了人工的 QA 测试人员的工作。\n Deployment:这是 CD 流程的第二部分。它包括在托管应用的服务器/ pods /容器上面执行更改来应用更新的版本。这会在自动化的方法下完成,最好通过一个配置管理工具来做这些事情,比如 Ansible、Chef 或者 Puppet。\n 什么是流水线? 流水线是一个有着简单的概念的花哨术语;当你有一些需要按照顺序依次执行的脚本用来实现一个共同的目标时,这些组合起来可以称为“流水线”。比如说,在 Jenkins 里,一个流水线包含了一个或多个一次构建需要成功必须全部执行的 stages 。使用 stages 能够可视化整个流程,能够看到每个阶段使用了多长时间,然后能够准确得出构建过程的哪个地方是失败的。\n实验:为一个 Golang 应用创建一个流水线 在这个实验中,我们构建一个持续交付(CD)的流水线。我们使用一个用 Go 语言编写的简单的小程序。为了简单起见,我们只对代码运行一种类型的测试。实验的前期工作如下:\n 一个运行的 Jenkins 实例。它可以是一个云实例,一个虚拟机,一个裸机或者是一个 docker 容器。必须是从互联网上可获得的,这样仓库才可以通过 web-hooks 连上 Jenkins。\n 镜像系统:你可以使用 Docker Registry,一款基于云的产品它提供了 ECR,GCR, 甚至一个定制的系统。\n 一个 GitHub 账号。尽管我们在这个例子中使用 GitHub,程序使用其他仓库同样可以,例如少量修改后的 Bitbucket。\n 流水线可以用下图做一个说明:\n第一步:应用程序文件 我们的实验程序会对任意的 GET 请求回复 ‘Hello World’。创建一个名称为 main.go 的文件然后添加如下的代码:\npackage main import ( \u0026quot;log\u0026quot; \u0026quot;net/http\u0026quot; ) type Server struct{} func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Header().Set(\u0026quot;Content-Type\u0026quot;, \u0026quot;application/json\u0026quot;) w.Write([]byte(`{\u0026quot;message\u0026quot;: \u0026quot;hello world\u0026quot;}`)) } func main() { s := \u0026amp;Server{} http.Handle(\u0026quot;/\u0026quot;, s) log.Fatal(http.ListenAndServe(\u0026quot;:8080\u0026quot;, nil)) } 当我们构建一个 CD 流水线时,我们应该进行一些测试。我们代码是如此的简单以至于它仅仅只需要一个测试用例;能够确保我们在输入根 URL 时得到正确的字符串。在同目录下创建名为 main_test.go 的文件然后添加如下代码:\npackage main import ( \u0026quot;log\u0026quot; \u0026quot;net/http\u0026quot; ) type Server struct{} func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Header().Set(\u0026quot;Content-Type\u0026quot;, \u0026quot;application/json\u0026quot;) w.Write([]byte(`{\u0026quot;message\u0026quot;: \u0026quot;hello world\u0026quot;}`)) } func main() { s := \u0026amp;Server{} http.Handle(\u0026quot;/\u0026quot;, s) log.Fatal(http.ListenAndServe(\u0026quot;:8080\u0026quot;, nil)) } 我们同样有一些其他用来帮助我们部署应用程序的文件,称为:\nDockerfile\n这就是我们对我们的应用进行打包的地方:\nFROM golang:alpine AS build-env RUN mkdir /go/src/app \u0026amp;\u0026amp; apk update \u0026amp;\u0026amp; apk add git ADD main.go /go/src/app/ WORKDIR /go/src/app RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags \u0026quot;-static\u0026quot;' -o app . FROM scratch WORKDIR /app COPY --from=build-env /go/src/app/app . ENTRYPOINT [ \u0026quot;./app\u0026quot; ] Dcokerfile 是一个多阶段的文件能让镜像保持的越小越好。它从基于 golang:alpine 构建镜像开始。生成的二进制文件在第二个镜像中使用,它仅仅是一个临时的镜像,这个镜像没有依赖或者库文件,只有用来启动应用的二进制文件。\nService\n由于我们使用 Kubernetes 作为托管该应用程序的平台,我们需要至少一个 service 和一个 deployment。我们的 service.yml 长这样:\napiVersion: v1 kind: Service metadata: name: hello-svc spec: selector: role: app ports: - protocol: TCP port: 80 targetPort: 8080 nodePort: 32000 type: NodePort 这个文件的定义没有什么特别的地方,只有一个 NodePort 作为其类型的 Service。它会监听任何 IP 地址的集群节点上的 32000 端口。传入的连接将中继到 8080 端口上。而作为内部通信,这个服务在 80 端口上进行监听。\ndeployment\n应用程序本身,一旦容器化了,就可以通过一个 Deployment 资源部署到 Kubernetes。deployment.yml 如下所示:\napiVersion: apps/v1 kind: Deployment metadata: name: hello-deployment labels: role: app spec: replicas: 2 selector: matchLabels: role: app template: metadata: labels: role: app spec: containers: - name: app image: \u0026quot;\u0026quot; resources: requests: cpu: 10m 这个部署文件里的定义最有意思的地方就是 image 部分。不同于硬编码镜像名称和标签的方式,我们使用了一个变量。后面的内容,我们会看到怎样将该变量用作 Ansible 的模板以及通过命令替换镜像名称(以及部署用的其他参数)。\nPlaybook\n这个实验中,我们使用 Ansible 作为部署工具。还有许多其他的方式用来部署 Kubernetes 资源包括 Helm Charts,但是我认为 Ansible 是一个相对简单一些的选择。Ansible 使用 playbooks 来组织它的操作。我们的 playbook.yml 文件如下所示:\n- hosts: localhost tasks: - name: Deploy the service k8s: state: present definition: \u0026quot;\u0026quot; validate_certs: no namespace: default - name: Deploy the application k8s: state: present validate_certs: no namespace: default definition: \u0026quot;\u0026quot; Ansible 已经包括了 k8s 模块用来处理和 Kubernetes API 服务器的通信。所以我们不需要安装 kubectl 但是我们需要一个有效的 kubeconfig 文件来连接到集群(后面会详细介绍)。让我们快速讨论一下这个 playbook 重要的部分:\n 这个 playbook 用来部署服务以及部署资源到集群上。\n 当我们需要在动态执行的过程中向定义文件中注入数据时,我们需要使用定义文件作为模板这样变量可以应用到外部环境。\n 为此,Ansible 具有查找功能,你可以在其中传递一个有效的 YAML 文件作为模板。Ansible 支持许多将变量注入模板的方法。在这个实验中,我们使用命令行的方法。\n 学习怎样持续优化您的 k8s 集群\n第二部:安装 Jenkins、Ansible 和 Docker 让我们开始安装 Ansible 然后使用它自动部署一个 Jenkins 服务器以及 Docker 运行环境。我们同样需要安装 openshift Python 模块用来将 Ansible 连接到 Kubernetes。 Ansible 的安装非常简单;只需要安装 Python 然后使用 pip 安装 Ansible:\n 登录 Jenkins 实例。\n 安装 Python3,Ansible,以及 openshift 模块:\n sudo apt update \u0026amp;\u0026amp; sudo apt install -y python3 \u0026amp;\u0026amp; sudo apt install -y python3-pip \u0026amp;\u0026amp; sudo pip3 install ansible \u0026amp;\u0026amp; sudo pip3 install openshift 默认情况下,pip 会将二进制安装到用户主文件夹的隐藏目录中。我们需要添加这个路径到 $PATH 环境变量中因此我们可以很轻松调用如下命令:\n echo \u0026quot;export PATH=$PATH:~/.local/bin\u0026quot; \u0026gt;\u0026gt; ~/.bashrc \u0026amp;\u0026amp; . ~/.bashrc 安装必要的 Ansible 角色用来部署一个 Jenkins 实例。 ansible-galaxy install geerlingguy.jenkins 安装 Dcoker 角色: ansible-galaxy install geerlingguy.docker 创建一个 playbook.yml 添加下面的代码: - hosts: localhost become: yes vars: jenkins_hostname: 35.238.224.64 docker_users: - jenkins roles: - role: geerlingguy.jenkins - role: geerlingguy.docker 通过下面的命令运行这个 playbook:ansible-playbook playbook.yaml。注意到我们使用实例的公共 IP 地址作为 Jenkins 的主机地址。如果你使用 DNS,你或许需要将该实例更换成 DNS 域名。另外,注意你必须在 playbook 运行之前允许 8080 端口通过防火墙(如果有的话)。\n 过几分钟,Jenkins 应该会被安装完成,你可以通过这台机器的 IP 地址(或者是 DNS 域名)还有端口8080访问到 Jenkins:\n 点击登录链接使用 “admin” 作为用户名,“admin” 作为登录密码。这些都是通过 Ansible 角色创建的默认凭据。当 Jenkins 在生产环境中使用时,你可以(应该)修改这些默认值。这个可以通过设置角色变量来进行设置。你可以参考角色官方页面。\n 你需要做的最后一件事情就是安装下面这些我们这个实验中用到的插件:\n git pipeline CloudBees Docker Build and Publish GitHub 第三步:配置 Jenkins 用户来连接到集群上 之前我们提到了,这个实验假设你已经有一个启动的 Kubernetes 集群。为了让 Jenkins 连接到这个集群上,我们需要添加必要的 kubeconfig 文件。在这个特定的实验中,我们使用主机在 Google Cloud 的 Kubernetes 集群所以我们可以使用 gcloud command。因环境而异。但是不管什么情况,我们都必须拷贝 kubeconfig 文件到 Jenkins 的用户目录下,如下所示:\n$ sudo cp ~/.kube/config ~jenkins/.kube/ $ sudo chown -R jenkins: ~jenkins/.kube/ 需要记住的是你使用的账号必须要有必要的权限用来创建管理 Deployment 和 Service。\n第四步:创建 Jenkins 流水线任务 创建一个新的 Jenkins 任务选择流水线类型的任务。任务的设置如下图所示:\n我们修改的配置有:\n 我们使用 Poll SCM 作为构建触发器;设置这个选项来让 Jenkins 定期检查 Git 仓库(按 * * * * 指示的每分钟进行检查)。如果仓库从上次轮询后做了修改,任务就会被触发。\n 从流水线本身来说,我们指定了仓库的 URL 以及凭据。分支是 master 分支。\n 这个实验中,我们在一个 Jenkinsfile 中添加了所有的任务的代码,Jenkinsfile 跟代码一样存放在同一个仓库当中。Jenkinsfile 我们会在后面的文章中进行讨论。\n 第五步:配置 GitHub 和 Docker Hub 的 Jenkins 凭据 转到 /credentials/store/system/domain/_/newCredentials 链接下然后添加目标凭据。请确认你每个凭据均提供一个有意义的 ID 和描述信息因为你会在后面使用到它们。\n第六步:创建 Jenkinsfile Jenkinsfile 是用来指导 Jenkins 如何构建,测试,容器化,发布以及交付我们的应用程序的文件。我们的 Jenkinsfile 长这样:\npipeline { agent any environment { registry = \u0026quot;magalixcorp/k8scicd\u0026quot; GOCACHE = \u0026quot;/tmp\u0026quot; } stages { stage('Build') { agent { docker { image 'golang' } } steps { // Create our project directory. sh 'cd ${GOPATH}/src' sh 'mkdir -p ${GOPATH}/src/hello-world' // Copy all files in our Jenkins workspace to our project directory. sh 'cp -r ${WORKSPACE}/* ${GOPATH}/src/hello-world' // Build the app. sh 'go build' } } stage('Test') { agent { docker { image 'golang' } } steps { // Create our project directory. sh 'cd ${GOPATH}/src' sh 'mkdir -p ${GOPATH}/src/hello-world' // Copy all files in our Jenkins workspace to our project directory. sh 'cp -r ${WORKSPACE}/* ${GOPATH}/src/hello-world' // Remove cached test results. sh 'go clean -cache' // Run Unit Tests. sh 'go test ./... -v -short' } } stage('Publish') { environment { registryCredential = 'dockerhub' } steps{ script { def appimage = docker.build registry + \u0026quot;:$BUILD_NUMBER\u0026quot; docker.withRegistry( '', registryCredential ) { appimage.push() appimage.push('latest') } } } } stage ('Deploy') { steps { script{ def image_id = registry + \u0026quot;:$BUILD_NUMBER\u0026quot; sh \u0026quot;ansible-playbook playbook.yml --extra-vars \\\u0026quot;image_id=${image_id}\\\u0026quot;\u0026quot; } } } } } 这个文件比它本身看起来要简单的多。基本上,这个流水线包括了 4 个阶段:\n 在哪里构建我们的 Go 二进制文件从而确保构建过程中无错误出现。\n 在哪里进行一个简单的 UAT 测试能确保应用程序如预期运行。\n 发布,在哪里构建 Docker 镜像然后推送到仓库。在这之后,任何环境都可以使用它。\n 部署,这是流水线的最后一步, Ansible 会与 Kubernetes 通信然后应用这些定义文件。\n 现在,让我们讨论下这个 Jenkinsfile 中重要的部分:\n 一开始的两个阶段大致差不多。它们都是使用 golang Docker 镜像来构建/测试应用程序。让阶段在所有构建和测试均已准备就绪的容器中运行始终是一个很好的实践。另外的选择就是安装这些工具到 master 服务器上或者是其中一个节点上。当你需要测试不同版本的工具时问题容易显现出来。例如,或许你想使用 Go 1.9 构建测试你的代码,但是我们的应用尚未准备好支持最新版本的 Golang。所有的东西都放在镜像中的话修改版本号或者甚至是镜像类型会和修改字符串一样简单。\n 在发布阶段(从42行开始)开头定义了一个环境变量,这个环境变量会在后面的步骤中使用到。这个变量指向的是我们先前步骤在 Jenkins 中添加的 Docker Hub 凭据。\n 48 行:我们使用 docker 插件来构建镜像。它默认使用我们 registry 中的 Dockerfile 然后添加构建号作为镜像的 tag。后面,当你需要决定哪次 Jenkins 构建作为当前运行容器的来源时这会非常的重要。\n 49-51行:镜像构建成功后,我们使用构建号将其推送到 Docker Hub。另外,我们在镜像上添加了 “latest” 的标签(一个第二标签)因此我们允许用户不需要指定构建号即可拉取镜像\n 56-60行:在部署阶段,我们将部署和服务定义文件应用到集群上。我们使用之前讨论过的 Ansible 的 playbook。记住,我们传递 image_id 作为命令行的参数。该值将自动替换部署文件中的镜像名称。\n 了解更多关于配置模式的知识\n测试我们的 CD 流水线 这部分是真正将我们的工作进行测试的内容。我们将会提交代码到 GitHub 上确保我们的代码直到到达集群之前都是经过流水线操作的。\n 添加我们的文件:git add *\n 提交我们的改动:git commit -m “Initial commit”\n 推送到GitHub:git push\n 在 Jenkins 中,我们可以等待任务自动被触发,或者我们只需要点一下“立即构建”。\n 如果任务成功了,我们可以使用下面的命令验证我们部署好的的应用程序:\n 获取节点的 IP 地址:\nkubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME gke-security-lab-default-pool-46f98c95-qsdj Ready 7d v1.13.11-gke.9 10.128.0.59 35.193.211.74 Container-Optimized OS from Google 4.14.145+ docker://18.9.7 现在让我们向应用程序发起一个 HTTP 请求:\n$ curl 35.193.211.74:32000 {\u0026quot;message\u0026quot;: \u0026quot;hello world\u0026quot;} OK,我们可以看到应用程序工作正常。让我们在代码中故意制造一个错误以确保流水线不会将错误的代码应用到目标环境中:\n将应显示的信息修改为“Hello World!”,注意到我们将每个单词的首字母大写并在末尾添加了一个感叹号。然而客户或许不想让信息这样显示,流水线应该在 Test 阶段停止。\n首先,让我们做一些改动。main.go 文件现在看起来是这样的:\npackage main import ( \u0026quot;log\u0026quot; \u0026quot;net/http\u0026quot; ) type Server struct{} func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Header().Set(\u0026quot;Content-Type\u0026quot;, \u0026quot;application/json\u0026quot;) w.Write([]byte(`{\u0026quot;message\u0026quot;: \u0026quot;Hello World!\u0026quot;}`)) } func main() { s := \u0026amp;Server{} http.Handle(\u0026quot;/\u0026quot;, s) log.Fatal(http.ListenAndServe(\u0026quot;:8080\u0026quot;, nil)) } 下一步,让我们提交和推送我们的代码:\n$ git add main.go $ git commit -m \u0026quot;Changes the greeting message\u0026quot; [master 24a310e] Changes the greeting message 1 file changed, 1 insertion(+), 1 deletion(-) $ git push Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 319 bytes | 319.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To https://github.com/MagalixCorp/k8scicd.git 7954e03..24a310e master -\u0026gt; master 回到 Jenkins,我们可以看到最后一次构建失败了:\n点击失败的任务,我们可以看到这个任务失败的原因:\n这样我们错误的代码永远不会进入到目标环境上。\n内容提要 CI/CD 是一个遵循敏捷方法论的任何现代环境的一部分。\n 通过流水线,你可以确保从版本控制系统到目标环境(测试/预生产/生产/等等)的平稳过渡,同时应用所有必要的测试以及质量控制实践。\n 这篇文章中,我们有一个实践性的实验来构建一个持续交付的流水线来部署一个 Golang 应用程序。\n 通过 Jenkins,我们可以从仓库拉取代码,构建以及使用一个相关联的 Docker 镜像进行测试。\n 下一步,我们进行容器化进而将已通过我们的测试的应用程序推送到 Docker Hub。\n 最后,我们使用 Ansible 将应用程序部署到运行在 Kubernetes 上的目标环境当中。\n 使用 Jenkins 流水线和 Ansible 可以非常轻松灵活地修改工作流。例如,我们可以在 Test 阶段增加更多的测试,我们可以修改用来构建和测试代码的 Go 的版本号,另外我们还可以使用更多的变量在其他诸如部署和服务定义的地方进行修改。\n 最好的部分是我们使用 Kubernetes 部署,这能够确保当我们在零停机时间的情况下改变容器镜像。因为在默认情况下部署使用滚动更新的方式来一次性终止和重建容器。只有在新的容器启动和健康后旧的容器才会终止。\n ", "auhtor": "Mohamed Ahmed", "translator": "0N0thing", "original": "https://www.magalix.com/blog/create-a-ci/cd-pipeline-with-kubernetes-and-jenkins", "poster": "cover.png" }, { "uri": "https://jenkins-zh.cn/meeting/2020-03-09/", "title": "", "type": "meeting", "date": "2020-03-09 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 社区培训教程\n为了让使用 Jenkins 用户有一个清晰的学习路线。\n下次会议时间:下周一\n宣传 志愿者征集\n文档 https://jenkins-zh.cn/tutorial/ 作为基础,继续完善\n 结构 针对不同层次的用户 下次讨论具体内容的会议 内容 比较少 格式 生成来一个 PDF 文件(流水线自动完成),需要调研工作 @lisong 教程结构 最佳实践 流水线+共享库 @cuidan 视频 https://space.bilibili.com/433584098\n 剪辑 需求 初学者 环境搭建 jenkins+kubernetes jenkins 运行机制 master、agent 之间是如何通讯的 插件扩展机制 devops 的思路、流程、案例 自由风格转流水线 流水线+共享库 测试环境 生产环境发布 如何与现有系统集成 API http://surenpi.com/blog/devops/jenkins/api/ 参考的项目(k8s) 演练场(playground)@yJunS https://kubernetes.io/zh/docs/tutorials/configuration/configure-redis-using-configmap/ 需要协调外部资源 https://www.katacoda.com/ https://www.katacoda.com/courses/cicd/build-docker-images-using-jenkins ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-09-feature-flags-and-gitops-5-use-cases-to-help-you-git-r-done-45ga/", "title": "特性开关和 GitOps, 5个用例帮您搞定。", "type": "wechat", "date": "2020-03-09 00:00:00 +0000 UTC", "tags": ["devops", "cloudbees"], "description": "特性开关和 GitOps 以及 CloudBees Rollout", "content": " GitOps 的实践是持续交付的下一个替代。它允许开发人员进入 IT 运维的传统工作范围-许多历史关卡的所在地-自动更新生产环境的应用程序和运行程序的基础设施。在 GitOps 中,所有变更管理和版本控制的唯一可信来源是软件配置管理(SCM)。GitOps 抛弃了传统 ITIL 类型的管理,将基础设施和应用程序视为版本化的制品,包括在软件开发期间捕获的相同粒度的审计轨迹(提交 ID,时间戳等)。\n我的看法 GitOps 的思想是通过 Git 提交将整个系统的期望状态存储在版本控制系统中。从本质上,您可以将 GitOps 视为一个文件版本控制系统。GitOps 一个关键的原则是通过使用遵守声明式规范的配置文件描述应用程序和环境的期望状态。\n这意味着配置根据实际情况而不是操作指南列表管理。它给你一个规则来检查结果是否正确,而不是给你一个配置清单去创建一个系统。你可以用这种方式描述你整个的 CI/CD 流水线并将其放在代码仓库中。为了变更到期望的状态,开发人员发出一个 Pull rquest ,这基本上告诉所有人您已发布到仓库的变更,并告知仓库将变更拉入。通过使用Git,您可以获得版本历史记录、审核日志、回滚功能以及查看谁更改了什么以及何时更改的功能。\n特性开关 + GitOps 当我们考虑 GitOps 时,会立即想到的用例是容器编排和集群管理—特别是使用声明性工具 Kubernetes。没有多少人会立即想到[特性标志][1]。那么为什么我们认为特性标志这么重要?这很重要,因为 GitOps 的愿景是对整个系统的全面控制。特性开关通常被视为“规则之外”的活动。我们相信,特性开关-尤其是达到一定规模-将成为一个非常强大的工具,如果它们的管理方式与代码的其他部分一样严格、管理和受重视。如果要使用 GitOps 来管理特性开关,则必须使用配置文件描述它们所需的状态。但这还不是全部。\n有一种正确的方法可以将 GitOps 应用于特性开关 特性开关是一个粘性的小窗口。它们拥有进行生产变更的能力,但它们不会像其他代码一样承担生产准备就绪的检验的责任。如果它要成为软件交付生命周期的一部分,就需要不断发展。\n如果我们想用 GitOps 管理特性标志,那么所需的状态(由声明性规范描述)必须保存到配置文件中。我们使用 YAML,以便它是人类可读和可编辑的。当需要更新到期望的状态时,只需简单的合并配置即可。此变更通过建立了审核跟踪的PR提交,并确保正确的人员正在验证更改—这正是当有人更改应用程序中的代码或更新基础设施设置时所发生的更改。我们相信这是用 GitOps 管理特性开关的正确方法。这也是最符合供应商中立的愿望的做法。\n据我们所知,只有[ CloudBees Rollout ][2]能够支持这一点。我们的一些竞争对手也有一个配置文件,他们的SDK知道如何读取和更改它。但是,它不是可编辑的。它也不会自动保存在像 GitHub 这样的 SCM 中。它们迫使用户绕过管理代码的既定过程,以便管理特性开关。例如,如果需要功能回滚,客户将被迫使用第三方仪表板,而不是 Git。\n使用 CloudBees Rollout 管理特性开关的一些‘Git’用例 [配置即代码][3],这个术语经常与基础设施作为代码(IaC)互换使用,但它实际上是不同的。IaC 是关于基础设施栈的管理和配置,而 CaC 是关于在环境之间自动迁移配置。这都是为了进行环境配置的有力工具。不允许有雪花。我们对待特性开关的方式与配置对待应用程序的方式相同(我们在这里使用 CaC 术语而不是 IaC,因为特性开关不是基础设施的一部分,而是在软件应用程序上)。当我们讨论 GitOps 时,这意味着我们可以用 PR 跟踪 SCM 中应用程序的变更和版本控制的方式,记录特性开关中发生的更改和版本控制。将更改推送到主分支通过 SDK 触发一个待处理的事件。然后,系统知道如何将特性开关更新到 YAML 文件配置所期望的状态。\nCloudBees Rollout 将所有特性开关和目标数据存储为保存在 Git 存储库中的本地 YAML 文件。对本地 YAML 文件进行更改将更新 CloudBees Rollout 功能标记数据。我们利用 Git 的分布式版本控制系统的特性,即使在本地工作,也允许您有完整的可追溯性和修订历史的能力。如果直接在 GitHub 中编辑特性开关并将更改提交到主分支,则事件将被触发回仪表板,并反映在 Rollout 的审核日志中。如果更改是通过仪表板完成的,仪表板就像一个 Git 客户机,并将更新 GitHub 上的 YAML 文件。\n一旦你用配置即代码来处理你的特性开关,你就可以实现这些很棒的用例;\n1. 治理和责任感:因为所有更改都在Git中,所以每次提交都会产生审计跟踪。你知道谁更改了你的特性开关中的内容和时间。因为所有的事情都是由 PR(Pull Rquest)管理的,所以你可以让团队成员批准你的变更,以增加责任感。\n2. 渐进式交付、变更和版本控制:特性开关允许您将功能部署与代码发布分离。当将功能提交到主分支时,通过将功能包装到特性开关中,消除长期的分支。特性可以保持“关闭”状态,直到代码完成。在 Git 中减少分支可以让你做渐进式发布(通过少量发布,增加发布速度)。基于 GitOps 的特性开关方法可以确保每一个变更都被考虑在内。\n3. 克隆环境:通过配置及代码,您可以克隆环境(dev、QA、prod、功能 X、Y、Z)之间的功能配置,通过跟踪功能切换变更。\n4. 特性开关自动化:当您有描述系统期望状态的可编辑的配置文件时,您很容易基于各种期望状态运行自动化(用于测试或部署目的)。您可以使用 GitOps 方法将特性开关标记的功能自动部署到用户群的一个子集或各种分段。当将特性开关作为一个配置文件时,很容易将系统迁移到新的期望的状态。其他替代方法,如使用 rest API 更改特性标志的传统 CI 过程,则更为复杂。与等待对服务器的身份验证,等待网络向服务器报告然后。。。然后。。。相比,使用 GitOps 管理特性开关就像更改 Git 仓库中的配置文件以更改状态一样简单。\n5. 通过 Git 命令回滚功能变更: 每个开发人员都曾经遇到过,需要回滚某个提交。您可以通过一个简单的 git revert 命令使用特性开关来实现这一点。由于 CloudBees Rollout 将配置代码保存在 Git 中,因此您可以使用分支隔离更改以及时回滚,并在并行流中工作,而不会影响生产/预备环境。\n尽管采用 GitOps 仍然是团队的理想选择,您也可以使用 CloudBees Rollout 来管理您的特性开关。API集成允许您链接到您最喜欢的性能、分析、监控和 APM 工具,使之更容易适应,而不管您如何管理 Dev 和 Ops 之间的桥梁。\n", "auhtor": "Kristin Baskett", "translator": "cycwll", "original": "https://dev.to/cloudbees/feature-flags-and-gitops-5-use-cases-to-help-you-git-r-done-45ga", "poster": "gitops.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-06-validating-jcasc-configuration-files-using-visual-studio-code/", "title": "使用 Visual Studio Code 验证 JCasC 配置文件", "type": "wechat", "date": "2020-03-06 00:00:00 +0000 UTC", "tags": ["community-bridge", "JCasC", "VSCode", "community"], "description": "介绍 Visual Studio Code 新的 JCasC 插件以及如何使用该插件来验证您的 YAML 配置文件", "content": " 配置即代码插件 问题陈述:将现有的模式验证工作流程脚本语言 Jenkins 配置即代码插件转换为基于 Java 的重写,从而增强其可读性和可测试性,并由该测试框架提供支持。通过开发 VSCode 插件来促进自动完成和验证,从而增强开发人员的经验,这将有助于开发人员在应用到 Jenkins 实例之前编写正确的 yaml 文件。\n配置即代码插件已被设计为 Jenkins 基于声明式配置文件配置的基本方式,无需成为 Jenkins 专家亦可编写这样的文件,只需将配置过程中转换成用于在 web UI 中执行的代码即可。该插件使用此类模式来验证要应用于 Jenkins 实例的文件。\n启用了新的 JSON 模式后,开发人员现在可以针对其测试 yaml 文件。该模式检查 descriptors,即可以应用于插件或 Jenkins 核心的配置,使用正确的类型并在某些情况下提供帮助文本。 VSCode 允许我们通过一些修改立即测试架构。该项目是 Community Bridge 计划的一部分,Community Bridge 计划是 Linux 基金会创建的一个平台,旨在使开发人员以及支持他们的个人和公司提高开源技术的可持续性、安全性和多样性。您可以看一下Jenkins Community Bridge 项目。\n启用架构验证的步骤 第一步安装 Visual Studio Code 的 JCasC 插件,并通过扩展列表打开扩展。使用 Ctrl + Shift + X 在 VSCode 编辑器中打开扩展列表的快捷方式。\n 为了启用验证,我们需要将其包括在工作空间设置中。依次导航到 File,Preference 和 Settings。内部设置中搜索 json,内部 settings.json 中包含以下配置。\n { \u0026quot;yaml.schemas\u0026quot;: { \u0026quot;schema.json\u0026quot;: \u0026quot;y[a]?ml\u0026quot; } } 您可以将全局模式指定为 schema.json 的值,schema.json 是模式的文件名。这会将架构应用于所有 yaml 文件。例如:.[y [a]?ml]\n 使用 VSCode 可以完成以下任务:\n 自动完成(Ctrl + Space):自动补全所有命令。 文档大纲(Ctrl + Shift + O):提供文件中所有已完成节点的文档概述。 在工作目录下创建一个名为 jenkins.yml 的新文件。例如,参考以下文件的内容:\n jenkins: systemMessage: “Hello World” numExecutors: 2 上面的 yaml 文件根据架构有效,vscode 为您提供验证和自动完成功能。 截图 我们于 2 月 26 日举行了在线 meetup(译注:该 meetup 已举办,Video 及 Slides 链接见最下方),讨论该插件以及如何使用它来验证您的 YAML 配置文件。对于有关架构的任何建议或讨论,请随时加入我们的 gitter 频道。可以在 Github 上提交问题。\n链接 Video Slides ", "auhtor": "Sladyn Nunes", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2020/02/25/vscode-caseStudy/", "poster": "cover.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-05-screwdriver-joins-cd-foundation/", "title": "Screwdriver 作为 CD 基金会的第一个孵化项目加入 CD 基金会", "type": "wechat", "date": "2020-03-05 00:00:00 +0000 UTC", "tags": ["cdf", "Screwdriver"], "description": "Screwdriver 将持续交付视为构建流水线中的一等公民", "content": "持续交付基金会(CDF),在持续交付领域对许多增长最快的项目来说是一个供应商中立的家,宣布 Screwdriver 成为其最新的孵化项目。 Screwdriver 是一个独立的、可插拔的服务,用于帮助开发人员使用最新的容器化技术构建、测试以及持续交付软件。 Screwdriver 最初是由 Yahoo(现在的 Verizon Media)开发的,用于简化 Jenkins 的接口。 它于2016年开源,并经过完全重写以应对大规模部署以及 CI/CD 目标。\nScrewdriver 与 DevOps 团队的日常习惯直接相关。它测试 pull request,构建合并提交并部署到任何环境。它还轻松定义了负载测试、金丝雀部署和多环境部署流水线。\n立即开始为 Screwdriver 做贡献吧。时刻欢迎提 pull request。从浏览 Screwdriver 贡献指南 开始吧。\n“CD 基金会欢迎 Screwdriver。我们相信 Screwdriver 开创了一个良好的开端,我们很高兴能一起工作。通过加入 CD 基金会,Screwdriver 将能够更快地扩展规模,在开发和部署方面取得更大的进步。” CDF 项目经理 Dan Lopez 说。“有了如此多支持的集成,Screwdriver 提供了 DevOps 团队所需要的开放性和灵活性。”\n“Screwdriver 团队和平台是 Yahoo 和 Verizon Media 的英雄,他们可以帮助我们运行大规模的软件工程业务。我们在一起也可以使您的 CI/CD 团队英雄成为您公司的英雄。我们邀请您在这个中立的家中与我们合作,以实现卓越的开源。” Verizon Media/Yahoo开 源高级总监 Gil Yehuda 这样说。\n“很高兴看到 Screwdriver 加入 CDF。我知道该项目的幕后工作人员与我们一样对同一件事充满热情,并且我们可以一起共同更快地产生更大的影响。事实证明,开源具有实现跨项目边界的独特能力。” Launchable,Inc. 联合首席执行官 Kohsuke Kawaguchi 这样说。\nCD Foundation 为项目提供广泛的服务,第一步是从孵化项目开始。有关将开源 CI/CD 项目引入 CDF 的完整详细信息,请参见此处。\n“我们的团队很高兴加入 CDF。与我们来自 Yahoo 的合作伙伴一起!日本和我们所有的外部贡献者将继续快速提供解决方案,以支持开发人员的工作流程以及与各种持续交付解决方案的互操作性。” Verizon Media/Yahoo 资深工程经理兼 Screwdriver 产品负责人 Jithin Emmanuel这样说。\n有关参与 Screwdriver 的更多信息,请访问:\n Screwdriver 首页 Screwdriver 贡献指南 Screwdriver GitHub Screwdriver Twitter Screwdriver Slack Screwdriver Meetup Screwdriver 博客 CD 基金会资源:\n 加入 CDF 联系 CDF CDF 项目 CDF FAQ CDF Twitter CDF 博客 ", "auhtor": "cdfoundation", "translator": "donhui", "original": "https://cd.foundation/blog/2020/02/19/screwdriver-joins-cd-foundation-as-its-first-incubation-project-treating-continuous-delivery-as-a-first-class-citizen-in-the-build-pipeline/", "poster": "screwdriver.png" }, { "uri": "https://jenkins-zh.cn/meeting/2020-03-04/", "title": "", "type": "meeting", "date": "2020-03-04 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " GSoC\n Jenkins 发行版(https://community.jenkins-zh.cn/t/jenkins/241) 有两个印度的学生有兴趣 每个人的配置保存到哪里? 官方 用户 https://github.com/jenkins-zh/jenkins-cli/pull/340/files 下次在线研讨会\n 时间,提前到八点半 修改社区的日历为:每周八点半,持续一个半小时 直播 对带宽+电脑资源要求比较高 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/03/2020-03-02-good-to-great-with-devops/", "title": "DevOps 的出色表现", "type": "wechat", "date": "2020-03-02 00:00:00 +0000 UTC", "tags": ["DevOps", "DevOps 状态", "DevOps 状态报告", "精英绩效", "DevOps 指标", "J 转换曲线"], "description": "重点介绍了 2019 年 DevOps 状态报告的一些发现,包括 DevOps 的出现和盛行", "content": " DevOps 不断发展,自从2009年提出此术语以来,DevOps 的状态每年都呈指数级增长。在2019年飞速发展的过程中,各种规模和形态的组织(从企业到初创公司)在 DevOps 方面都展现了极大的热情。每个组织都有其自己的 DevOps故事,其中一些故事尚未开始,一些故事还处于婴儿期,有些故事已经成熟,有些故事已经达到顶峰。 不同于其他故事,DevOps 故事源于不断改进。\n随着企业逐渐变得数字化和软件驱动,人们对 DevOps 旅程的本质和可能性有了更大的认识。不仅工程师或技术领导者,甚至商业领导者都对 DevOps 的概念、实践和应用非常感兴趣。对于实现商业成功的 DevOps 的需求已得到越来越广泛的接受。\n《 2019 年 DevOps 状态报告》作为大量在线资源的提供者之一,可用于解和学习 DevOps 如何塑造跨行业的软件交付。该报告极大地总结了软件交付的趋势和挑战,它可以帮助团队研究可用于提升软件交付能力并最终成就卓越。\n在此报告中,IT 性能称为软件交付能力,以区分软件交付工作与 IT 服务台和其他支撑功能。这是一个期待已久的可喜变化。我也喜欢的关键更改之一是增加了运营指标以完成软件交付周期。该报告重点介绍了五个被称为“软件交付和运营(SDO)性能指标”的度量或指标,它们侧重于系统级结果。这有助于避免软件度量标准的常见陷阱,后者常常使不同的功能相互冲突,并导致以牺牲总结果为代价的局部优化。\n该报告重点介绍了软件交付能力的四个方面,如下所示:\n 部署频率 – 对于您从事的主应用程序或服务,您的组织多久部署一次代码? 变更的前置时间 – 对于您从事的主应用程序或服务,您的变更前置时间是多少(即,从代码提交到成功在生产中运行的代码需要多长时间)? 恢复服务的时间 – 对于您正在使用的主应用程序或服务,发生服务事件(例如计划外中断或服务受损)时,恢复服务通常需要多长时间? 变更失败率 – 对于您使用的主应用程序或服务,导致服务质量下降或随后需要修复(例如,导致服务受损、服务中断,需要修改程序、回滚、向前修复、修补程序)的变更的百分比? 然后对这四个方面进行度量,以对四个类别的性能进行排名:精英、高级、中级和低级。下表(从报告中引用)指示了各个方面的详细信息。\n我强烈建议添加到此列表中的另一个方面是“团队敬业度指数”,即团队的快乐程度和参与度。我认为团队绩效与团队敬业度成正比。团队敬业度越高,即团队越快乐越敬业,他们产生的结果就越好。\n报告中的另一个主题是“ J 转换曲线”。下图突出显示了自动化如何帮助绩效低下的人员提升到中等性能水平,然后测试需求、技术负担和复杂性增加导致手动操作,从而导致进度变慢。这是一个有趣且值得注意的观察。它强调了自动化并不总是答案。如果您使错误的流程自动化,那么您得到的只是错误的结果,而且更快。\n无休止的改进、学习、共享和利用专业知识可将您带到高水平或精英绩效水平 – 将团队提升为精英绩效的旅程需要的不仅仅是工具。在各个级别(即团队级别、领导级别和赞助者级别)的坚持、恒心和毅力对于从低绩效水平或中绩效水平取得突破以发挥团队最大潜力至关重要。如果我们踏上精英绩效之旅,您会发现自动化、技术实践和持续改进计划是您旅途的催化剂。鉴于测试需求、技术债务和日益增加的复杂性将成为您的阻碍,我发现锚定和引擎(帆船回顾展)格式提供了一种快速而有趣的方法,可在一幅图片中(如下所示)可视化催化剂(引擎)和阻滞剂(锚定)。\n行业看到了更高的精英绩效 该报告证实,精英表演者的比例几乎增加了两倍,低表现者的比例下降了,中等表演者的比例上升了。要注意的一项主要观察结果是,从低性能到中性能再到高性能的移动不是单向的。当面对复杂性增加时,团队(从 J 曲线中突出显示)可以从高位降为中级,也可以从中级降为低级。总体而言,很高兴看到向上增加。\n前进之路 软件交付性能可以通过多种方式确定业务成果。 组织推动软件交付绩效的能力包括文化,技术实践,清晰的变更流程,持续交付和基于价值的成果。 这些功能并不是一蹴而就的,需要对组织 DNA 进行根本性的改变。\n根据我在不同行业和公司中工作的经验,我可以确认这些软件交付能力集群不是静态的。上面列出的任何功能的更改都会对软件交付能力产生影响,您可能会发现能力集群在两个方向上都从一个级别波动到另一个级别。关键是要保持专注并通过定期将其嵌入组织的工作方式中来维持它。\n", "auhtor": "Sandeep Joshi", "translator": "zhaoying818", "original": "https://dzone.com/articles/good-to-great-with-devops", "poster": "img1.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-28-t-mobile-and-jenkins-case-study/", "title": "T-Mobile 和 Jenkins 案例研究", "type": "wechat", "date": "2020-02-28 00:00:00 +0000 UTC", "tags": ["Jenkins", "T-Mobile"], "description": "聊聊 POET Pipeline 对流水线的改变以及给您带来的巨大的价值", "content": " Jenkins 在 T-Mobile 节省数千小时和数百万美元 大多数人都知道 T-Mobile 是无线服务提供商。毕竟,我们拥有国际化的业务,并且是美国第三大移动运营商。但是我们还是一家技术公司,提供的新产品包括 TVision 家庭电视服务,T-Mobile Money 个人银行产品以及 SyncUp Drive 车辆监控和路边辅助设备。\n在幕后,T-Mobile 还是开源社区的领导者。我们已经在 GitHub 上共享了 35+ 个代码存储库(包括我们的 POET 流水线框架自动化库),以通过采用健壮和智能的做法来加快 CI/CD 周期,从而帮助其他组织支持内部和外部客户。\n我是 T-Mobile 系统可靠性工程(SRE)部门的高级系统可靠性工程师。我们的团队成功地将 POET 实施的第一阶段推广到了 30 多个团队。这是一个巨大的成功,并且计划使用结合在 Kubernetes 集群上运行的 Jenkins 和 CloudBees Core 的稳定、可靠的 CI/CD 流水线,将其扩展到我们的 350 个开发团队和 5,000 个活跃用户。\n更少的插件,更多的 Master 我们从构建简化的基于容器的流水线基础结构开始,该基础结构可以集中管理并易于适应开发方法。结果使我们的开发团队有更多的精力专注于开发和测试应用程序,而不是维护 Jenkins 环境。\n然后,我们将在 master 中使用的 Jenkins 插件的数量从 200 个减少到了 4 个。有超过 1,000 种此类附加组件,包括构建工具,测试实用程序和云集成资源。它们是扩展平台的绝佳方法,但它们也是 Jenkins 的致命弱点,因为它们可能引起冲突。\n接下来,我们从一个单一的 Master 给我们所有的 Jenkins slave 提供动力变成了多个 Master,现在拥有 30 个流水线引擎,每个引擎为大约 10 个团队提供动力。此设置减少了 CPU 负载和其他瓶颈,同时允许 T-Mobile 的 DevOps 团队继续享受水平扩展的优势。\n在两分钟内启动 Jenkins 流水线 这项工作的成果是,我的 SRE 团队现在可以在大约两分钟的时间内从 Docker 镜像启动 Jenkins 主机,对其进行测试并将其推广到我们的生产环境。然后,各个团队可以自定义其 CI/CD 流水线,以满足特定项目的需求。我们允许这些团队扩展平台,但我们将加载项列表限制为 16 个核心插件。这些插件是在 Docker 容器中预先配置的,每个团队都以相同的 CI/CD 流水线开始,然后可以在文件夹级别根据自己的喜好对其进行设置。\n这种简化且集中的方式来部署我们的流水线,使 SRE 团队能够将所有事情付诸行动,然后再加以解决。但这只是故事的一半。当我们的开发团队拥有简化的 CI/CD 流水线时,真正的魅力就会展现出来。他们不再需要担心底层的 Jenkins 技术,而可以将注意力转移到采用其解决方案上。\nPOET 流水线最大程度地减少了对 Jenkins Groovy 代码的需求,该代码繁琐,容易出错并且难以集成到第三方库中。相反,一切都从位于流水线源代码中的流水线定义文件开始,并创建步骤容器以执行构建,部署和其他流水线功能。\n我们在 POET 流水线中引入 40 个通用容器,因此我们的开发人员不必从头开始。当然,他们必须知道如何创建 Docker 容器以及如何编写 YAML 文件以扩展流水线功能。通过简化基础架构,减少插件数量并消除对 Groovy 的需求,我们使开发人员可以自由定义自己的流水线,而不必依赖集中的管理团队。\n我们的开发人员不再是基础架构工程师 为了进一步增强我们的开发人员的能力,我们编写了全面的 POET Pipeline 文档,包括易于理解的帮助文件,教程和视频,以进行自学成才和自助服务。这种宝贵的资源还释放了我们的流水线管理团队和开发人员的精力,使其可以专注于创新。\n本文档是我们采用的“以客户为中心”方法的一部分。我们将内部开发团队视为客户,而 POET Pipeline 是我们的产品。您能想象 T-Mobile 要求订户在每次通话时重建智能手机吗?还是让他们在发送短信之前与 CSR 对话?那我们为什么要要求我们的开发商兼任基础设施工程师呢?\n减少停机时间 除了使开发人员满意并简化管理任务之外,我们简化的 POET Pipeline 框架还大大减少了停机时间。我们的插件繁重的、单主机的 Jenkins 环境占用了 CPU 周期,引起了各种配置难题,并且不断下降。\n在任何给定的一周内,我们必须重新启动 Jenkins 两到三次。有时,我们的构建会对我们的环境造成很大的压力,以至于我们不得不在一夜之间重新启动它,并在团队无法工作时重置所有内容。借助 POET Pipeline,我们将停机时间减少到每年一次此类事件。\n扩大我们的成功 通过消除每个开发团队对流水线专家的需求,由于与 Jenkins 和 CloudBees Core 的合作,我们还节省了大量人工和成本。如果您将一个典型的工作年数定为 2,000 个小时,再乘以 350 个团队,那么您要计算的是数十万个小时和数千万美元。现在,我们可以将这些资源重新定向到构建收益产品中,从而更好地为 T-Mobile 的外部客户提供服务。\n这些数字很大,但不要让他们以为 POET 流水线不适合您。我们可能有数百个团队和数千名开发人员,但是 Jenkins 具有可扩展性,任何规模的组织都可以使用我们开发的工具。因此,我们选择与 GitHub 上的开源社区共享流水线。\n与世界一起创新 创新不是凭空发生的。通过将我们的代码发布给其他人使用和修改,我们正在帮助世界各地的开发人员将重点从管理流水线转移到构建更好的应用程序。反过来,我们将从更广泛的社区的智慧应用于我们的内部项目中受益。\n每个人都获得了一定的成果,但真正的赢家是 T-Mobile 的客户。他们可以期待提供新的和改进的产品,因为我们将花费更少的时间来管理流水线框架,而将更多的时间用于简化和改善生活的产品和服务上。\n", "auhtor": "Alyssa Tong and Ravi Sharma", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2020/02/10/t-mobile-case-study/", "poster": "t-mobile-and-jenkins.png" }, { "uri": "https://jenkins-zh.cn/tutorial/management/agent/docker-jnlp/", "title": "基于 JNLP 协议的 Docker 代理节点", "type": "tutorial", "date": "2020-02-27 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "Jenkins 支持多种类型的代理节点,本篇教程介绍的是基于 JNLP 协议的 Docker 代理节点。\n步骤如下:\n 在节点管理界面,新增一个代理节点;启动方式为:通过 Java Web 启动代理 点击保存后,进入到该节点的状态页面 参考下面的启动命令来启动 Docker 容器 注意替换 IP 为你的服务器地址,不能使用127.0.0.1或者 localhost secret 可以从节点状态页面找到 docker run -u root -d --rm jenkins/slave:4.0.1-1-alpine java -jar /usr/share/jenkins/agent.jar -jnlpUrl http://192.168.31.239:8080/computer/jnlp/slave-agent.jnlp -secret ad36ea3aff1fea65a803f32e7020bd6c6b5866db9f587fb2079d308661691911 -workDir \u0026quot;/tmp\u0026quot; 如果希望了解更多这种代理节点的话,可以参考官方源码。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-24-jcli-v0.0.26/", "title": "Jenkins CLI 命令行 v0.0.26", "type": "wechat", "date": "2020-02-24 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.26 发布", "content": " 本次版本发布,增加了两种包发行版:snapcraft、Chocolatey。snapcraft 是由 Ubuntu 提供的一个全新的 包管理器,它可以在 CentOS、Ubuntu、SUSE 等12种操作系统下使用。因此,Linux 用户可以更加方便地使用 jcli。 命令行自动补全的特性可以大幅提高用户的工作效率,除了 bash 的用户外,zsh 以及 powerShell 的用户,现在也可以使用 jcli 的命令补全特性了。\n🚀 功能 支持查看 jcli 的变更日志 (#328) @LinuxSuRen 支持根据父目录搜索任务 (#327) @LinuxSuRen 支持升级所有的插件 (#258) @yJunS 增加对 zsh 和 powerShell 的命令行补全的支持 (#296) @LinuxSuRen 🐛 缺陷修复 修复了无法启动非 LTS 的 Jenkins (#322) @LinuxSuRen 修复无法创建凭据的问题 (#325) @LinuxSuRen 📝 文档完善 增加对 snapcraft 的支持 (#321) @LinuxSuRen 增加对 Chocolatey 的支持 (#312) @LinuxSuRen 增加从 bintray 下载 jcli 的文档描述 (#299) @LinuxSuRen 👻 维护 在构建过程中,通过 GitHub Action 对临时文件的归档 (#333) @LinuxSuRen 升级依赖 github.com/spf13/cobra 从 0.0.5 到 0.0.6 (#332) @dependabot-preview 修复拼写错误 (#303) @afkbrb 🚦 测试 增加对交互式命令的测试用例 (#297) @LinuxSuRen ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "jenkins-cli.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-21-the-abc-of-devops-implementation-with-containerization-and-docker/", "title": "使用容器化和 Docker 实现 DevOps 的基础知识", "type": "wechat", "date": "2020-02-21 00:00:00 +0000 UTC", "tags": ["容器化", "Docker", "DevOps"], "description": "通过 Docker 和容器化,DevOps 可以更轻松、更快和更安全", "content": " DevOps 在 IT 行业中风靡一时。维基百科中阐述 DevOps 是将软件开发(Dev)和信息技术维护(Ops)结合在一起的一组实践,旨在缩短系统开发生命周期并提供高质量的持续交付。 DevOps 普及的主要原因是,它使企业可以比传统软件开发方法更快地开发和改进产品。\n随着我们工作环境的变化越来越快,对软件开发市场中的快速交付和修复的需求正在上升。 因此,对在短时间内生产高质量输出且有限的后期错误需求催生了 DevOps。\n你可能感兴趣:Docker 和 DevOps:开发有状态的应用程序并在 Docker 中进行部署\n正如我们已经讨论了转变为 DevOps 软件开发方式的重要性一样,我们现在将对话更改为容器化,这是一种易于使用的技术,经常被用来使 DevOps 的实现更流畅、更便捷。 容器化是一项使 DevOps 实践更容易遵循的技术。 但是容器化到底是什么? 让我们一探究竟!\n什么是容器化? 容器化是将应用程序及其所需的库、框架和配置文件打包在一起的过程,以便可以在各种计算环境中高效运行它。简单来说,容器化就是应用程序及其所需环境的封装。\n近来,它克服了运行虚拟机所带来的挑战,从而获得了广泛的关注。虚拟机模拟主机操作系统内部的整个操作系统,并且需要固定比例的硬件分配才能运行操作系统的所有进程。因此,由于很大的开销,这导致不必要的计算资源浪费。\n同时,设置虚拟机需要花费时间,在每个虚拟机中设置特定应用程序的过程也需要时间。这导致仅在设置环境时就花费了大量时间和精力。由开源项目 “Docker” 普及的容器化解决了这些问题,并且通过将所有必需的依赖项与软件一起打包在便携的镜像文件中,从而提高了可移植性。\n让我们更深入地研究容器化,它的好处、它的工作原理、选择容器化工具的方式以及它如何胜过虚拟机(VM)的使用。\n一些流行的容器提供程序如下:\n Linux 容器,例如 LXC 和 LCD Docker Windows Server 容器 什么是 Docker? Docker 已经成为 IT 行业中的一个流行术语。 Docker 可以定义为一个开源软件平台,它提供了一种在容器内构建、测试、保护和部署应用程序的简化方法。 Docker 鼓励软件开发人员与云、Linux 和 Windows 操作系统进行协作,以轻松、快速地交付服务。\nDocker 是提供容器化的平台。它允许将应用程序及其依赖项打包到一个容器中,从而有助于简化开发并加快软件的部署。它消除了在应该测试解决方案的每台机器上复制本地环境的需求,从而帮助实现了输出的最大化,从而节省了宝贵的时间和精力,而这些宝贵的时间和精力将用于进一步的开发。\nDockerfile 可以在工作人员之间快速传输和测试。 Docker 还简化了容器镜像管理的过程,并迅速改变了我们大规模开发和测试应用程序的方式。\n容器化——实现 DevOps Docker 已普及了容器化的概念。 Docker 容器中的应用程序具有能够在多种操作系统和云环境(例如 Amazon ECS 等)上运行的能力。没有技术或供应商局限。\n让我们了解使用容器化实现 DevOps 的需求。\n最初,所需的软件开发、测试、部署和监督是分阶段进行的,其中一个阶段的完成将导致另一个阶段的开始。\n像 AWS ECS 一样,DevOps 和 Docker 镜像管理技术使软件开发人员可以轻松地进行 IT 运营、共享软件以及彼此协作,并提高生产力。除了鼓励开发人员一起工作之外,他们还成功地消除了以前影响应用程序的不同工作环境之间的冲突。简单来说,容器是动态的,它使 IT 专业人员可以毫无复杂地构建、测试和部署流水线,同时弥合基础架构和操作系统发行版之间的鸿沟,从而形成 DevOps 的文化。\n软件开发人员可以通过以下方式从容器中受益:\n 可以更改容器的环境,以更好地进行生产部署。 快速启动并轻松访问操作系统资源。 与传统系统不同,它们为应用程序提供了足够的空间以适合一台机器。 为 DevOps 提供了敏捷性,可以帮助轻松地在多个框架之间切换。 有助于更有效地运行工作流程。 下面阐明了使用 Docker 成功实现容器化所要遵循的步骤:\n 开发人员应确保代码在存储库中,例如 Docker Hub。 该代码应正确编译。 确保正确打包。 确保满足所有插件要求和依赖项。 使用 Docker 创建容器镜像。 将其转移到您选择的任何环境。 为了易于部署,请使用 Rackspace、AWS 和 Azure 等云。 使用容器的好处 许多公司选择容器化来带来各种好处。以下列出了使用容器化技术将享受的优势:\n1. DevOps友好 容器化将应用程序及其环境依赖性打包在一起,以确保在一个环境中开发的应用程序可以在另一个环境中工作。这有助于开发人员和测试人员在应用程序上协同工作,这正是 DevOps 文化的全部内容。\n2. 多云平台 容器可以在 GCS、Amazon ECS(弹性容器服务)和 Amazon DevOps Server 等多个云平台上运行。\n3. 天生便携 容器易于携带。 容器镜像可以轻松部署到新系统,然后可以以文件形式共享。\n4. 更快的可伸缩性 由于将环境打包到隔离的容器中,因此可以更快地进行伸缩,这对于分布式应用程序非常有帮助。\n5. 无需单独的操作系统 在 VM 系统中,裸机服务器的主机操作系统与 VM 不同。相反,在容器中,Docker 镜像可以利用裸机物理服务器的主机 OS 的内核。 因此,容器比虚拟机具有更高的工作效率。\n6. 资源利用最大化 容器化可以最大程度地利用内存和 CPU 等计算资源,并且所使用的资源比 VM 少得多。\n7. 应用程序的快速更新 随着应用程序的快速更新,交付在更少的时间内发生,从而使该平台便于执行更多的系统开发。机器无需重新启动即可更改资源。\n借助容器的自动缩放,可以在考虑当前负载的情况下完成 CPU 使用率和机器内存优化。而且与虚拟机的扩展不同,无需重新启动计算机即可修改资源限制。\n8. 简化的安全更新 由于容器提供了进程隔离,因此维护应用程序的安全性变得更加方便。\n9. 物有所值 就支持单个基础结构上的多个容器而言,容器化是有利的。因此,尽管在工具、CPU、内存和存储上进行了投资,但对于许多企业而言,它仍然是一种经济高效的解决方案。\n具有实现容器的完整 DevOps 工作流程可以通过以下方式使软件开发团队受益:\n 它提供了在每个步骤中自动执行测试以检测错误的功能,因此最终产品中出现缺陷的机会更少。 更快、更方便地交付功能和更改。 该软件的性质比基于 VM 的解决方案更加用户友好。 可靠且多变的环境。 促进团队成员之间的协作和透明度。 本质上具有成本效益。 确保正确利用资源并减少浪费。 容器与虚拟机(VMS)之间的区别 虚拟机可以在主机上运行多个操作系统的多个实例,而不会出现重叠。主机系统允许 Guest OS 作为单个实体运行。Docker 容器不会像虚拟机那样给系统带来太多负担,因为运行OS需要额外的资源,这会降低计算机的效率。\nDocker 容器不会给系统增加负担,并且仅使用运行解决方案所需的最少资源,而无需模拟整个操作系统。由于运行 Docker 应用程序所需的资源较少,因此它可以允许大量应用程序在同一硬件上运行,从而降低了成本。\n但是,它减少了 VM 提供的隔离。它还增加了同质性,因为如果应用程序在一个系统上的 Docker 上运行,那么它也将在其他系统上的 Docker 上运行而不会出现任何故障。\n容器和 VM 都具有虚拟化机制。但是对于容器而言,会进行操作系统的虚拟化。在后者中,进行硬件虚拟化。\nVM 性能有限,而带有 Docker 的紧凑型和动态容器则性能更优。\nVM 需要更多内存,因此具有更多开销,与 Docker 容器相比,它们的计算量很大。\nDocker术语 以下是一些常用的 Docker 术语:\n 依赖 – 包含形成环境所需的库,框架和软件,可以模拟执行应用程序的介质。 容器镜像 – 一种软件包,提供创建容器所需的所有依赖关系和信息。 Docker Hub – 一个公共镜像托管注册表,您可以在其中上传镜像并对其进行处理。 Dockerfile – 包含有关如何构建 Docker 镜像的文本说明文件。 仓库 – 一种基于网络或基于 Internet 的服务,用于存储 Docker 镜像,有私有和公共的 Docker 仓库。 注册表 – 一种存储来自多个源的仓库的服务。它可以是公共的也可以是私人的。 Docker Compose – 一种工具,可帮助定义和运行多个容器 Docker 应用程序。 Docker Swarm – 为运行 Docker 而创建的机器集群。 Azure 容器注册表 – 用于存储 Docker 镜像的注册表提供程序 Orchestrator – 一种有助于简化集群和 Docker 主机管理的工具。 Docker 社区版(CE) – 为 Linux 和 Windows 容器提供开发环境的工具。 Docker 企业版(EE) – 用于 Linux 和 Windows 开发的另一套工具。 Docker 容器、镜像和注册表 使用 Docker 创建服务,然后将其打包到容器镜像中。Docker 镜像是服务及其依赖关系的虚拟表示。\n该镜像的实例用于创建一个容器,使其在 Docker 主机上运行。 然后将镜像存储在注册表中。需要一个注册表才能部署到生产协调器。Docker Hub 用于在框架级别将其存储在其公共注册表中。然后将镜像及其依赖项部署到自己选择的环境中。重要的是要注意,有些公司还提供私人注册表。\n商业组织还可以创建自己的私有注册表来存储 Docker 镜像。如果镜像是机密的,并且组织希望镜像与部署镜像的环境之间的延迟有限,则可以提供私人注册表。\nDocker 如何执行容器化? Docker 镜像容器或应用程序可以在 Windows 和 Linux 上本地运行。只需通过 Docker 引擎直接与操作系统交互,即可利用系统资源来实现。\n为了管理集群和组合,Docker 提供了 Docker Compose,它有助于运行多个容器应用程序而不会彼此重叠。开发人员还可以通过 Docker Swarm 模式将所有 Docker 主机连接到单个虚拟主机。之后,使用 Docker Swarm 将应用程序扩展到多个主机。\n多亏了 Docker 容器,开发人员可以访问容器的组件,例如应用程序和依赖项。开发人员还拥有该应用程序的框架。单个平台上并相互依赖的多个容器称为“部署清单”。但是,与此同时,专业人员可以更加注意选择合适的环境进行部署,扩展和监视。 Docker 有助于限制错误的机会,错误的机会可能在应用程序传输期间发生。\n本地部署完成后,它们将进一步发送到 Git 存储库之类的代码存储库。代码存储库中的 Dockerfile 用于构建持续集成(CI)流水线,以提取基础容器映像并构建 Docker 镜像。\n在 DevOps 机制中,开发人员致力于将文件传输到多个环境,而管理专业人员则负责管理环境以检查缺陷并将反馈发送给开发人员。\n面向未来的容器化战略 预测未来并根据项目需求做好可伸缩性的准备总是一个好主意。 随着时间的流逝,项目变得越来越复杂,因此有必要实施大规模的自动化并提供更快的交付。\n密集且复杂的容器化环境需要适当的处理。 在这种情况下,软件开发人员可以采用 PaaS 解决方案,以将更多精力放在编码上。 选择最方便的平台以提供更好和先进的服务时,有多种选择。因此,根据组织的应用程序确定正确的平台非常麻烦。\n为了方便您,我们在选择最佳的容器化平台之前已经列出了一些要考虑的参数:\n1. 灵活自然 为了获得平稳的性能,重要的是手动拾取一个平台,该平台可以根据需求的性质轻松地进行调整或更改,并且可以自动进行。\n2. 锁定级别 实际上,PaaS 解决方案供应商通常是专有的,因此倾向于将您锁定在一个基础架构中。\n3. 创新空间 选择一个平台,该平台应具有广泛的内置工具以及第三方集成技术,以鼓励开发人员为进一步的创新让路。\n4. 云支持选项 在选择正确的平台时,至关重要的是找到一个支持私有,公共和混合云部署的平台,以应对新变化。\n5. 定价模型 由于选择支持长期承诺的集装箱化平台是很自然的,因此了解提供哪种定价模式非常重要。有很多平台可以在不同的运营规模上提供不同的定价模型。\n6. 时间和精力 要记住的另一个关键方面是容器化不是一蹴而就的。专业人士需要花费时间来重组架构基础架构。应该鼓励他们运行微服务。\n为了从传统结构转变,需要将大型应用程序分解为较小的部分,再将这些部分进一步分布到多个连接的容器中。因此,建议聘请专家,他们会尽一切努力找到一种方便的解决方案来在单个平台上处理虚拟机和容器,因为使组织完全依赖于容器需要时间。\n7. 兼容旧版应用程序 当涉及现代化时,不应忽略旧式 IT 应用程序。在容器化的帮助下,IT 专业人员可以利用这些经典应用程序的收益,以适当地利用对旧框架的投资。\n8. 多应用程序管理 通过在容器平台上运行多个应用程序来充分利用容器化。以最低的成本投资新应用程序,并通过使其对当前和旧版应用程序友好而对每个平台进行修改。\n9. 安全性 由于容器化环境具有比传统环境更快的更改能力,因此它具有一些主要的安全风险。敏捷性可以通过提供快速访问来使开发人员受益。但是,如果不能确保所需的安全级别,它将失败。\n处理容器时遇到的一个主要问题是,处理由第三方或不受信任的来源打包的容器模板可能会带来很大的风险。因此,最好在使用之前验证公开可用的模板。\n组织需要增强和集成其安全流程,以无忧地开发和交付应用程序和服务。随着平台和应用程序的现代化,安全性应成为企业的首要任务。\n结论 为了与瞬息万变的 IT 行业保持同步,专业人员应该不断追求更好,因此,应利用市场上可用的新工具来增强安全性。\n这标志着第2部分的结论!在第3部分中,我们将讨论关键的 DevOps 工具和 DevOps 的实现策略。\n进一步阅读 Docker Swarm 的乐趣\n用于开发到部署的 Docker 命令\n", "auhtor": "Mitul Makadia", "translator": "zhaoying818", "original": "https://dzone.com/articles/the-abc-of-devops-implementation-with-containeriza", "poster": "12751943-abcs.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-18-google-summer-of-code-2019-report/", "title": "2019 年 Google 编程之夏活动报告", "type": "wechat", "date": "2020-02-18 00:00:00 +0000 UTC", "tags": ["Jenkins", "gsoc2019", "gsoc", "community", "events"], "description": "主要介绍了 GSoC 2019 活动的几个课题并讲述了整个活动的组织过程", "content": " Google 编程之夏活动不仅仅是一个夏日的实习项目,对于组织和一些社区的成员来说,这个活动是他们一整年努力的成果。现在,在里斯本举行的 Devops World | Jenkins World 会议以及最后的回顾会议之后,我们宣布 GSoC 2019 正式画上结束的句号。首先我们感谢所有的参与者:学生们、导师们、主题专家、以及其他一些提出课题构想,参与学生选择,社区联系以及一些后期的讨论与回顾的贡献者们。Google 编程之夏活动是一个大型的活动,如果没有 Jenkins 社区的积极参与此次活动也就无法成行。\n在这篇博客里我们想要与各位分享这次活动的成果以及我们从这一年总结的一些经验。\n成果 今年成功完成了 5 个 GSoC 课题:角色策略插件性能优化,插件安装管理 CLI 工具/库,working-hours 插件 - UI 优化,具有 Kubernetes 功能的 Apache Kafka 远程处理,GitLab SCM 多分支流水线支持。我们会在后面的内容中讨论一下上面提到的这几个课题。\n项目细节 我们在 8 月底举行了最后一次 Jenkins 线上例会的演讲然后 Google 在 9 月 3 日发布了这些成果。最后的这些演讲内容可以从这里找到:第一部分,第二部分,第三部分。我们也在 DevOps World | Jenkins World 旧金山以及 DevOps World | Jenkins World 2019 里斯本会议中发布了2019 Jenkins GSoC 报告。\n在下面的章节中,我们对每一个项目做一个简单的总结,第三阶段编码演示文稿的链接以及最后的成品。\n角色策略插件性能优化 角色策略插件是 Jenkins 中最广泛被使用的认证插件之一,但因为其架构问题以及对项目角色的正则表达式检查使其没有因性能著称。Abhyudaya Sharma 与他的几位导师:Oleg Nenashev,Runze Xia,Supun Wanniarachchi 一起进行该项目。他为 Jenkins 插件创建了一个基于 JMH 的微基准测试框架,创建微基准测试然后在一些真实场景中得到了 3501% 的提升。然后他继续深入研究创建了一个基于目录的认证策略插件,当权限范围为目录时该插件为 Jenkins 实例提供了更佳的性能。在他的项目中 Abhyudaya 还修复了对 Jenkins 组策略的配置即代码的支持并为 JCasC 插件贡献了一些优化与修复的代码。 - 项目页面 - 发布的博客:Jenkins 微基准测试框架, 引入一个新的目录认证插件,角色策略插件性能优化 - 最终评估:幻灯片,视频 - 源码:角色策略插件,目录认证插件\n插件安装管理 CLI 工具/库 Natasha Stopa 正在研究一个新的插件管理 CLI 工具 ,该工具可以统一其他例如 Docker 镜像中的 install-plugin.sh 这样的工具。它还引入了许多新的特性比如 YAML 配置的格式支持,列出可用的升级以及安全性修复。这个新开发的工具最终可以取代刚才提到的的那个工具。Natasha 的导师:Kristin Whetstone,Jon Brohauge,Arnab Banerjee 与许多来自 Platform SIG和 JCasC 插件团队的贡献者们作为利益相关者和项目专家一同参与了这个课题。 - 项目页面 - 发布的博客:alpha 版本发布,第二阶段编码更新 - 最终评估:幻灯片,视频 - 源码:插件管理工具\nworking-hours 插件 - UI 优化 Jenkins UI 和前端框架在Jenkins项目中成为了一个共同的话题,特别是最近这几个月发布了新的 UX SIG 之后。Jack Shen 与他的导师 Jeff Pearce 正在探索一种新的途径来统一构建 Jenkins 的 Web UI。Jack 更新了运行时间插件 使用的 UI 控件是由标准的 React 库提供的。然后他将他的这些工作经验文档化并创建了使用基于 React UI 的插件模板 - 项目页面 - 发布的博客:working-hours 的 UI 更新,React 插件模板 - 最终评估:幻灯片,视频 - 源码:working-hours 插件,基于 React UI 的 Jenkins 插件模板\n具有 Kubernetes 功能的 Apache Kafka 远程处理 Long Le Vu Nguyen 正在为 Apache Kafka 远程插件扩展 Kubernetes 支持。他的导师 Andrey Falco和 Pham vu Tuan 是我们 GSoC 2018 的学生和插件发明者。在这个项目过程中 Long 添加了一个新的代理启动器,该启动器规定了在 Kubernetes 中的 Jenkins 节点使其让它们连接到 master 节点。他还为其创建了一个 Cloud API 接口以及一个新的 Helm 图表,该图表可以将 Jenkins 作为 Kubernetes 中的一个完整的系统,默认启用 Apache Kafka。所有这些特性都发布在了 Apache Kafka 远程插件 2.0 中。 - 项目页面 - Apache Kafka 远程插件 2.0 发布的博客 - 最终评估:幻灯片,视频 - 插件源码\nGitlab SCM 支持多分支流水线 Parichay Barpanda 正在开发具有多分支流水线任务以及基于文件夹组织支持的新的 GitLab 分支源码插件。他的导师是 Marky Jackson-Taulia,Justin Harringa,Zhao Xiaojie 和 Joseph Petersen。该插件扫描项目,并根据提供的的条件导入流水线任务。项目导入后,Jenkins 立即运行基于 Jenkinsfile 脚本的任务然后发送通知到 GitLab 流水线状态。该插件同样提供了 GitLab 服务器配置可以在系统配置或者通过 Jenkins 配置即代码进行配置(JCasC)。在 GitLab 分支源码 1.0 声明获取更多内容。 - 项目页面 - 第三阶段编码演示 - GitLab 分支源码插件,GitLab API 插件\n没有完成的项目 今年并非所有的项目都完成了。我们也在 Jenkins 流水线 artifact-promotion 插件和云特性的外部工作区管理插件进行了尝试,但不幸的是这两个项目都在第一阶段编码后即停止了。无论如何,我们在这些领域得到了许多经验与收获。(请参阅链接的 Jira ticket!)我们希望这些故事的某一点能够被 Jenkins 贡献者实现出来。或许 Google 编程之夏 2020 可以?\n以组织层面运营 GSoC 项目 这里有一些在我们组织 GSoC 前后的一些幕后的小故事跟大家分享。为了给即将涌入进来的学生们做好准备,我们更新了所有的 GSoC 页面,收录进去了我们这几年运营这个项目的所有知识。我们从 2018 年 10 月份开始准备,此时离项目开始还有很长一段时间。主要的目标是解决在 GSoC 2018 期间得到的一些反馈。\n课题构想。我们在 2018 年的最后一个月开始收集课题的构想。我们在 Google 文档准备了课题构想清单,并在文档的表格中追踪了每个课题的所有权情况。每个课题构想都在其 Google 文档中作进一步阐述。我们发现每个课题在定义阶段都非常的复杂,也许他们本身就太复杂了并且也应该完成不了。\n自从我们想让所有的课题构想都能用相同的方法编写成文档时,我们创建了一个模板来指导这些贡献者们。大多数课题构想的文档是由组织的管理员或者导师来编写的,但是偶尔也有一个学生提出一个极妙的点子。我们也在那个文档中获取了一些其他信息比如 GitHub 以及 Gitter 账号以及课题的潜在导师清单。我们将所有的课题文档放到了我们的网站上。\n导师与学生指导。我们更新了导师信息页面的一些细节是关于我们希望导师们在项目中做哪些事情,包括导师们工作的小时数,甚至我们有一部分专门写了避免利益冲突的内容,当招募了导师之后,我们引导他们访问导师信息页面。\n我们同样更新了学生信息页面。我们发现当每一位学生咨询我们相同的问题都是关于报名和参与项目时这个页面节省了我们很大一部分时间。我们只是把这些页面的链接发给他们而不是每次都要去解释这个项目。\n应用阶段。在 GSoC 正式开始的几周前,学生们就已经开始接触这个项目。这真的很振奋人心。一些学生甚至在项目官方开始之前就开始着手课题构想了。\n课题选择。这一年组织管理团队做了一些非常艰难的决定。面对众多的学生,导师和课题,我们必须要正确数量的并且尝试匹配最有可能成功的课题。我们尝试通知导师团队的同时也在寻求课题的数量,在截止时间之前得到所有导师们的回复是困难的。最终我们寻求的课题数量要少于我们可以添加进来的数量。当我们寻求课题时我们提交了两个数字:一个最小值一个最大值。GSoC 指南说明如下: - 最小值基于一些非常棒的课题数量,他们非常想要在一个夏天的时间内看到这些项目可以取得成功。 - 最大值是一些他们想要这一整个夏天可以指导的可信赖并且非常棒项目的数量。\n我们选择了最小数量的课题。所以我们必须做非常艰难的决定:我们必须在“很棒”与“可信赖”的原则之间进行选择。一些原则上来说,非常好的那一个,选择起来很简单,但是对其他的来说,这很困难。我们知道我们无法做到真正的完美,过往的经验中,我们也知道一些学生或者一些导师会因为一些不可控的生活琐事而无法完成整个项目,即使是一些出色的提案亦如是。所以我们必须做出最好的决定,要知道我们选择的一些项目可能不会完成。\n社区联系。我们发现社区联系阶段对于每一个课题的成功至关重要。社区联系有困难的课题通常来说不会做的很好。为了让学生们更好的融入进社区中,几乎所有的课题都在特别兴趣小组的指导下进行,这样可以与更多相关人士交流。\n沟通。每年我们都有学生通过个人社交工具与导师进行交流。学生们,如果你们正在读这篇文章,请不要给我们通过个人社交工具发送有关课题方面的内容,你不会收到任何额外的照顾。显然,开源化的目的是我们希望所有的讨论都是公开化的,所以学生们需要时刻牢记这一点。2019 年我们使用 Gitter 处理了最多的聊天信息,但是从一名管理员角度来说相比邮箱沟通来说这样有点太碎片化了。并且它很难去搜索消息。聊天室很方便毕竟消息集中一些,但是从一名管理员角度来说,缺少话题功能很难从 Gitter 获得概要信息。最近 Gitter 添加了话题功能(2019 年 11 月)但是在 Android 和 iOS 上并不能使用。在项目尾声我们使用 Zoom 会议并且我们发现使用它工作要比 Google 的 Hangouts 要容易一些。\n状态跟踪。另一个很麻烦的事情就是一旦开始后获取每一个课题运行的概况。我们扩展了 Google 表格的用途,在项目期间跟踪表单中的课题与参与者来为课题排名以及追踪课题各阶段的状态(社区联系,编码,等等。)。让这些表格持续更新是一件很有挑战性的工作,每一个课题包括了好几位参与者以及好几个链接。在这件事上消耗的时间让我们发现让这些表格保持更新,准确,完整有一点困难,直到编码阶段开始之前都是这样。\n或许一些状态跟踪工具可以帮上忙。我们使用 Jenkins Jira 来跟踪这些课题,每个阶段代表了一个独立的冲刺竞赛。这给成功的课题帮了大忙。在我们的组织里,我们尝试让每个人都在提前截止日的几天完成,因为我们知道会有一些意外因素比如停电,糟糕的天气(甚至在西雅图都有这事儿!),或者其他无法控制的事情,这些或多或少会影响课题数据的提交。我们同样想到截止日跟周末“撞车”的话人们会忘记这些事情,这同样也是危机所在。\n回顾。课题尾声,我们同样会举行一个回顾来为以后获取一些新的构想。你可以在这里找到这些笔记。我们已经处理了文档中最重要的一些评论以及明年课题的构想。\n奖励 去年,我们想要通过发送纪念品的方式感谢每一位在项目中参与的人。今年,我们收集了所有我们能找到的邮寄地址准备给每一位送上 Jenkins 15 周年纪念版 T 恤以及一些贴纸。这是一个非常棒的时刻。我也同样以个人名义感谢 Alyssa Tong 对我们 T 恤以及贴纸设计上的一些帮助。\n导师峰会 每年 Google 会邀请每个组织的两位或多位导师参加 Google 编程之夏导师峰会。这个活动中,数以百计的开源项目维护者以及导师们齐聚一堂对 GSoC,社区管理以及各种工具进行一些非正式会议。今年峰会在慕尼黑举办,Marky Jackson 和 Oleg Nenashev 作为代表参与了此次会议。 除了探讨课题和分享巧克力,我们在那里展示了 Jenkins,发表了简短的讲话以及主持了一个有关 GitHub 自动机器人的非正式会议,我们不能在那里拍摄团队照片,所以试着在这张照片里找到 Oleg 和 Marky 吧:\nDevOps World | Jenkins World 中的 GSoC 团队 一般来说我们使用 GSoC 组织的经费和差旅经费来赞助学生们的旅行以及主要跟 Jenkins 相关的活动。今年四名学生参加了在旧金山与里斯本的 DevOps World | Jenkins World 会议。这些学生在社区展位和贡献者峰会上展示了他们的课题,他们的作品在社区获得了非常多的关注! 非常感谢 Google 和 CloudBees 能让此次旅行能够成行。你可以在这里找到来自 Natasha Stopa 的报告,更多的旅行报告后期奉上。\n结论 今年,5 个课题成功完成。我们从其他参加的组织那里得到的消息也说明这是一个正常的数字。 早些时间更新 GSoC 页面为我们后期的工作节省了很多时间因为有人联系我们的时候我们不能每次都重复所有的信息。我们发现保持跟进所有的导师们,学生们,课题以及元信息是必须的但又耗时的工作。我们希望有一个工具用来帮我们做这些事情。协调会议以及提醒参与者截止日之前需要完成的工作也是 GSoC 组织工作的一方面,我们需要持续做这件事。 最后,我想再次感谢所有的参与者,没有你们我们不能做到这些。每年都有一些做的很棒工作以及为 Jenkins 社区贡献一些很棒作品的学生给我们留下了很深刻的印象。\nGSoC 2020? 是的,会有 Google 编程之夏 2020 这个活动的!我们计划参加也在寻找课题构想,导师以及学生。Jenkins GSoC 页面已经更新了,我们邀请每一个人明年都能参与进来。 - 活动主页面 - GSoC 2020 课题构想 - GSoC 2020 导师招募与课题构想收集 - 学生与导师信息页面\n", "auhtor": "Martin d'Anjou,Jeff Pearce,Oleg Nenashev,Marky Jackson", "translator": "0N0thing", "original": "https://jenkins.io/blog/2020/01/29/gsoc-report/#google-summer-of-code-2019-report", "poster": "cover.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-17-happy-second-birthday-jenkins-x/", "title": "Happy Second Birthday Jenkins X!", "type": "wechat", "date": "2020-02-17 00:00:00 +0000 UTC", "tags": ["jenkins-x", "ci", "cd"], "description": "Jenkins X 2019 年终回顾", "content": " 始于 2019 年初的 Jenkins X 项目在去年的1月14号庆祝了它的第一个生日,这对任何开源项目来说都是一件大事,我们刚刚又庆祝了它的第二个生日。\nJenkins X 的两周年! Jenkins X 已经从一个关于 CI/CD 如何在云原生世界中被重新设计的愿景,进化到了一个快速发展、创新并迅速成熟的开源项目。\nJenkins X 是为了帮助开发者们能够快速的将代码发布到 Kubernetes 上而创建的。从一开始,Jenkins X 就致力于改善开发者的开发体验。使用一个命令行工具,开发者就能构建 Kubernetes 集群,部署流水线,创建应用,新建 Github 仓库,将应用推送至 Github 仓库,新建 Pull Request,构建容器,在 Kubernetes 中运行该容器并最终合并到产品中。为了做到这些,Jenkins X 对一系列同类最佳开源工具进行了自动化安装与配置,并且自动化了所有流水线的生成。Jenkins X 还通过测试、过渡和生产环境对应用程序的升级进行了自动化改造,使开发人员能够获取大量到的变更反馈。例如,Jenkins X 的预览环境容许快速与及早的反馈,这样开发者便能在自动构建的环境中查看应用的实际功能。我们发现,由 Jenkins X 在流水线中自动创建的预览环境在开发者中十分流行,因为他们能够在将代码合并到 master 分支之前查看变更情况。\nJenkins X 本身是功能专一的,但是却极易拓展。Jenkins X 是为实现 DevOps 最佳实践而创建的,旨在跨团队的可重复、可管理的方式中,能够完成大量分布式微服务的部署工作。Jenkins X 促进了大量已被检验的最佳实践,如基于主干的开发和 GitOps。为了让您能够快速上手与使用,Jenkins X 提供了许多快速入门的例子。\n属于 Jenkins X 的 2019 高光时刻 2019 年 2 月:Tekton 的崛起! 在 2018 年的后半年,Jenkins X 开始了一趟提供 Serverless Jenkins 与仅在需要时运行流水线引擎的旅程。这种流水线引擎基于 knative build-pipeline 项目,该项目进化成为了受到 Jenkins 和 Jenkins X 社区众多帮助与热爱的 Tekton 。Jenkins X 项目在 2019 的 2 月完成了与 Tekton 的初次集成。Tekton 是一个强大和灵活的 Kubernetes 原生开源框架,用于创建 CI/CD 流水线、管理制品和渐进部署。\n2019 年 3 月:Jenkins X 加入了持续交付基金会! Jenkins X 加入了 Continuous Delivery Foundation (CDF),与 Jenkins、Spinnaker 和 Tekton 一起作为创始项目。加入一个专注于持续交付的中立供应商基金会对于 Jenkins X 社区意义重大。\n2019 年 6 月:Lighthouse 项目 当 Jenkins X 开始它的 serverless jenkins 旅程时,它选择了使用 Prow,一个用于 Github 事件和 ChatOps 的事件处理器。Prow 被 Kubernetes 项目用于构建所有的仓库,除此以外,它还包含了一个强大的 webhook 事件处理器。Prow 已久经考验,但它却严重的依赖于 Github,并且难以拓展至其他的 SCM 提供商上。 在 2019 年 6 月末,一项轻量级、可拓展至 Prow 的项目开始了,它叫做 Lighthouse。Lighthouse 跟 Prow 支持同样的插件(因此你仍然可以通过 ChatOps 请求各种各样的东西)和配置 —— 这使得 Prow 和 Lighthouse 间的迁移变得极其容易。\n2019 年 6 月:Jenkins X Boot! 我们在整个六月都十分的忙碌 —— 暑期到来前一个疯狂的活动爆发期。Jenkins X 用户面临的一个常见问题便是在不同的 Kubernetes 集群上安装 Jenkins X 。按照正确的顺序安装服务和确保 DNS 和 Secrets 正确性的工作是因供应商的不同而完全不同,有时也因集群的不同而不同。我们意识到,要简化安装,我们确实需要一个流水线,虽然这听起来有点像一个电影情节,但运行 Jenkins X 流水线来安装 jx 确实是最好的选择。jx boot 命令使用本地 jx 二进制文件解释引导流水线。jx boot 命令也可以用于更新你的集群。\n2019 年 7 月:一个新的 Logo! 作为转移到 CDF 的一部分,Jenkins X 项目利用这个机会重新设计了它的标志。一个机器人就代表了 Jenkins X 在 Kubernetes 上提供自动化 CI/CD 的能力等等!\n2019 年的后半年:聚焦于稳定性和可靠性 Jenkins X 项目与很多不同的组件和活动部件一起进展的很快。不幸的是,这一快速的发展招致了一些不稳定性和导致了严重 issue 的增长,这些问题有可能破坏我们已经在 Jenkins X 上所做的所有杰出工作。于是,社区一直在努力提高稳定性和解决显著的 issue —— 下图展示了去年 issue 数量的走势,可以看出,在最后6个月内,创造的 issue 数量有一个显著的下降趋势。\nCloudBees 还通过引入 CloudBees Jenkins X 发行版帮助了这项工作,该发行版增加了围绕稳定配置和部署的测试,并且在每月定期发布。\n2019 年 10 月:Jenkins X Steering Committee 成立会议 Jenkins X Bootstrap Steering Committee 的任务是组织其向选举制 Steering Committee 的过渡工作,并确定 Steering Committee 在指导 Jenkins X 项目方面将承担的责任。\n2019 年 12 月:第一个 Jenkins X Outreachy 学员 Neha Gupta 正在向 Jenkins X 中添加对 Kustomize 的支持以确保 Kubernetes 本机配置管理功能的实现,同时将在 2019 年 12 月到 2020 年 3 月期间参与 Outreachy。我们欢迎 Neha 在 Jenkins X 上所做的工作,并且期待着我们能在持续培养的文化基础上再接再厉!\nJenkins X 在产品中的使用 尝试 Jenkins X 最简单的方法无疑是使用由 Jenkins X 驱动的 CloudBees CI/CD,它通过方便易用的 SaaS 提供 Jenkins X 。无需设置集群,无需安装 Jenkins X,这些它都已经为你完成了!目前,由 Jenkins X 驱动的 CloudBees CI/CD 已经可供预览。在这里注册试试新的 Jenkins X Saas 吧!\n下一步? Jenkins X 项目将鼓励社区参与到更多的创新活动中。同时,有很多不错的想法也将继续扩展的我们的故事,比如:集成渐进式交付(A/B 测试、Canary 和 Blue/Green 部署)、持续化验证以及更多的平台支持。我们也期待着在 Jenkins X 的 CloudBees UI 中能涌现出更多更棒的新特性。\n敬请期待 Jenkins X 将在 2020 年带来的更多令人振奋的新公告吧!\nJenkins\nJenkins 中文社区链接\n", "auhtor": "Rob Davies", "translator": "XiongKezhi", "original": "https://jenkins-x.io/blog/2020/01/14/happy-second-birthday/", "poster": "./2020-02-17-happy-second-birthday-jenkins-x/7TH_BIRTHDAY.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-14-devops-trends-to-watch-for-in-2020/", "title": "展望 2020 年 DevOps 的发展趋势", "type": "wechat", "date": "2020-02-14 00:00:00 +0000 UTC", "tags": ["DevOps"], "description": "本文展望了 2020 年 DevOps 领域的发展趋势", "content": " Netscape 的创始人 Marc Andreessen 很久之前就谈到过软件是如何吞噬整个世界的。他还说过,当今,每一家公司都可谓是软件公司,它们已经做好准备来接管广阔的经济领域。在 2020 年,您会清晰地看到 DevOps 持续不断的更新是如何改变交付方式的,将软件交付到几乎是无限的市场中。在这个技术竞争激烈的世界中,DevOps 已成为蓬勃发展的必需品了。\n导引 虽然每个企业对 DevOps 有着不同的理解,但我们仍然可以将 DevOps 定义为一个团队为了将其工程能力提升到新的高度而采用的一种心态。DevOps 的主要目的是消除工程实践上的障碍,重点是那些存在于想法和实践之间的文化障碍,从而使软件的交付过程变的更好、更快、更廉价和更安全。\n无论您怎样称呼 DevOps,它最终都应该归结为自动化,而自动化反过来又应该有助于公司的快速发展、快速交付、快速失败、快速恢复以及快速学习。\n从 SDLC(System Development Life Cycle,系统生命周期)模型的出现到今天,情况已经发生了巨大的变化。在 2009 年,DevOps 诞生了,它倡导文化的转型和一些将所有事物都视为代码的技术原则。随后出现了诸如 CI/CD 之类的理念,但是,软件曾经是作为一个巨大的单体被编写的,这个转变过程带来了许多挑战。\n因此,在 2011 年引入了微服务架构,它提倡细粒度和松耦合的组件划分方式,其中每个组件都承担特定的职责。\n遵循这种松耦合、微服务架构而编写的应用程序被称为云原生应用。当前,众多企业根据其业务需求和目标,正在从虚拟机过渡到 Kubernetes 和 Serverless。\n根据 Kelly Shortridge 和 Nicole Forsgren 博士在 Black Hat USA 2019 上发布的幻灯片,在与 DevOps 行业中卓越的实践者进行对标时,有四个因素特别关键,分别是:\n 变更前置时间 发布频率 恢复时长 变更失败率 在本文中,我们将会了解到 DevOps 在未来的发展趋势。\n云原生将成为必然 Diamanti 对 500 多位 IT 主管进行了调查。结果表明,从所有方面来看,容器技术已经远远超出了预期,它在一年内迅速成熟,并从开发者试验转向了生产环境。云原生技术将会上升到一个新的高度,尤其是对 Kubernetes 的采用。云原生为公司提供了更大的优势,使其以更快的速度将产品推向市场。\n什么是云原生 采用云原生意味着更好的创新、更先进的转型以及更丰富的客户体验。如我在的另一篇文章“ Cloud-Native DevOps”中所述,云原生从根本上促进了云自动化,这里指的是云计算服务的安装、配置和监控的自动化管理,它是关于使用技术在恰当的时间为您的云计算资源做出更可靠的业务决策。\n根据 Oracle 对云原生未来的预测,到 2025 年将有 80% 的 IT 企业会把业务迁移到云。CNCF 的调查结果显示,在生产环境中使用云原生技术的企业数量已经增长超过了 200%。\n去年,作为云服务提供商的 Cloud Foundry Foundation 开源平台的执行董事 Abby Kearns 在 2018 年 LinuxCon + ContainerCon + CloudOpen China( LC3)上发表了主题演讲,对云原生及其未来做了更加深入的阐释。\nKearns 说:“云原生技术和云原生应用正在增长,在接下来的 18 个月中,组织正在编写和使用的云原生应用的数量将会增加 100%。” 她补充道:“这意味着您不能再仅限于投资 IT,更需要投资云和云技术。(引自 Abby Kearns 的主题演讲塑造云原生未来)\n美国空军是她在演讲中所举的最好的例子之一,她在演讲中谈到了他们已经变得多么敏捷,并且采用了前沿技术和云原生原则。美国空军已经实施了敏捷实践,现在正在利用云技术开发在多云上运行的应用程序。\n容器注册服务将呈上升趋势 这一点本来可以包含在云原生部分中。尽管如此,我认为这仍需要特别注意,因为大多数软件公司现在都沉迷于容器注册服务,这些容器注册服务可以帮助开发人员存储、管理制品及其所有依赖,以便实现软件开发生命周期的平稳进行。\n就像在版本控制系统(例如 Git)中管理应用程序的源代码一样,管理 Docker 镜像也至关重要。 Docker 提供了类似的管理镜像的功能,这些镜像可以在开发者本地主机上甚至在远程容器注册服务(Docker Hub)上得到管理。\n但是,有时这些镜像容易出现许多与安全性相关的问题,并且黑客可以轻松访问它们。因此,现代公司需要一种安全可靠的方式来通过注册服务管理镜像。\n对于使用容器化应用和微服务架构的 DevOps 团队而言,容器注册服务已成为了必须具备的条件。随着 Docker 和云原生应用程序的日益普及,容器镜像像管理已成为现代软件开发的重要组成部分。容器注册服务简单的说就是镜像仓库的集合,这些仓库主要用于存储容器镜像。\n最近在圣地亚哥举行的 KubeCon 会议上,JFrog 宣布了自己的容器注册服务。基于 Artifactory 的强大功能,JFrog Container Registry 是市场上经过严酷考验的免费容器注册服务。它是可扩展的、混合的、具有 Artifactory 的精美用户界面并由 Artifactory 提供技术支持。\n目前市场上其他著名的容器注册服务包括:\n Amazon Elastic Container Registry (ECR) Dockerhub JFrog Container Registry Azure Container Registry Google Container Registry 私有容器注册服务允许公司实施自己对容器的管理方式,包括策略、安全、访问控制等。容器注册服务应具有的功能包括完全混合云、Docker 注册服务、Helm 注册服务、通用仓库、远程仓库、虚拟存储库以及丰富的元数据。\n哪里需要用到容器注册服务? 有几个原因可以说明容器注册服务的必要性:\n 随着云原生的发展,我们看到企业级的数字化转型正在进行,使用的工具有 Kubernetes、Docker、Artifactory、Helm 和 Istio 等。全世界都在迅速向容器注册技术过渡,这正是容器化应用快速、安全交付的未来。\n 混合云争日趋激烈,大多数云提供商都为它们的服务提供了免费的注册服务,因为它们知道注册服务的重要性。\n Docker 容器往往会占用大量存储空间,并且需要来回转移。这意味着高昂的存储成本,有时安全性也可能成为一个问题。结果,我们看到一些公司除了使用 Docker 外也使用 Artifactory,并且也使用其他的免费工具来管理容器。很高兴看到 JFrog 现在拥有自己的容器注册服务:)\n 注册服务可以充当远程、虚拟的容器仓库,其中包含丰富的元数据,这是 DevOps 中的要素之一。\n 可以获得关于制品的宝贵见解。\n Go 和 DevOps 会一起繁荣 尽管 Go 已经有些影响力,但它将对 DevOps 社区产生了更大的影响。大多数 DevOps 工具,例如 Kubernetes、Helm、Docker、etcd、Istio 等都是用 Go 编写的。 Kubernetes 的创造者 Joe Beda 曾写过为什么 Kubernetes 是用 Go 编写的。\n由于 Go 可以静态编译成独立的二进制文件,因此非常适合在您无法安装或不想安装依赖项的环境中使用。无需设置整个环境,这可以让您比使用其他编程语言更快地完成工作。\nJFrog 在最近于伦敦和圣地亚哥举行的 GopherCon 会议上对 1000 多名开发人员进行了调查,以便更好地了解 Go 社区和对 Go module 的总体看法。\n他们发现了什么?\n Go 开发人员投入程度很高 超过 82% 的 Go 开发人员使用可以使能 Go module 的 Go 版本,并且现在或预期在 2020 年中期使用该功能的人数也几乎达到了相同的比例。 Go module 的使用率很高 Go 在各行各业中得到了广泛使用 选择 Go module 很困难 另外,请看一下我的另一篇文章,其中讨论了 为什么 Go 对于 DevOps 如此适合。\n安全性将成为更高的优先事项 在软件开发生命周期中,安全性变的比以往任何时候都更为重要。安全性变成了每个人的责任,而不仅仅是安全专家。\n尽管 DevSecOps 一词似乎只是另外一个流行词汇,但仍要更加重视安全性。 DevSecOps 在组织内创建安全意识和共享的知识库,以加强软件开发过程中的安全性。今年早些时候,Capital One 漏洞使云安全成为一个令人关注的话题,因此重点是保护公有云中的数据。\n三星 Note 7 的灾难在很大程度上解释了为什么安全性在流程开始时以及开发生命周期的每个阶段都如此重要。专家推测,Note 7 手机的问题之一涉及其电池管理系统。该系统监控电流并在电池充满时停止充电过程。系统中的故障导致电池过度充电、变得不稳定并最终爆炸。\n此故障修复使三星损失了近 170 亿美元。如果较早发现此问题,他们可以节省很多钱以及品牌的声誉。\n要发展一种策略和方法以使组织中的安全性成为必须,请考虑以下几点:\n 从小处着手,从一开始就在开发生命周期的每个阶段都部署安全检查点。 对于开发人员,将安全性作为他们工作的一部分,并作为其绩效评估的一部分。 开发和运营团队都需要将安全等同于质量。 不要将 DevOps 和安全性分开,彻底地结合它们,使其成为您的工程团队的口头禅。 许多公司将采用混沌工程原理来检查系统的稳定性和可靠性,并检查安全的程度。故意破坏系统可以帮助您发现更大的错误,并确保黑客不会在系统中发现任何漏洞。这也将帮助组织先于客户发现错误。DevSecOps 目的是不断地使您的系统比以往更加健壮。\n开源将超越边界 开源给开发人员带来的优势和灵活性已引起越来越多的关注。 Synopsys 在最近进行的一项调查中发现,开放源代码正在发展中,几乎 70% 的公司组织正在为开源项目做贡献或拥有开源项目。\n为什么要开源?\n开源软件非常有助于开发人员个人提高技能。开源为开发人员提供了以下途径:\n 学习解决问题的新技术和有效方法。 在项目上进行协作并获得经验。 贡献于开源项目会产生一种归属感,它将使您成为有着相同目标和观念的大型社区的一部分。 在最近的印度开源 2019 大会上,我们对近 300 名开源专业人士进行了调查,以下是当我们询问他们喜欢开源软件的原因时的回应。定制化是大多数人喜欢开源软件的事实。\nCB Insights 的最新研究估计,开源服务行业在 2019 年将超过 170 亿美元,并且在 2022 年有望达到近 330 亿美元。\n微软、谷歌、英特尔和 Facebook 等大型巨头(它们不是开源公司)正在积极地为 GitHub 上的各种项目做出贡献。Google 的员工在 2018 年提供了 5500 次贡献,其中许多贡献已经帮助了较小的独立项目。\n对于 Google 的开源软件项目,如 Kubernetes,Istio 和 Knative 的支持有很多,需求很高。随着公司赞助的项目越来越受欢迎,独立开发人员将继续做出贡献。这表明巨人应该挺身而出,帮助开源社区发展。\n例如,Microsoft 的 Visual Studio Code 项目总共有超过 19000 个贡献者。在成千上万开发人员的参与下,这些技术巨头从免费的开发人员输入和直接的用户反馈中受益。这使组织可以更快地构建更好的软件。开源技术无疑已经成为主流,并且拥有光明的未来。\nCloud Native Foundation 生态系统主管 Cheryl Hung 在最近的欧洲 Linux Foundation 开源峰会上的演讲中明确指出,大型公司正在致力于开源项目。特别是 Kubernetes,它创建了一个庞大的社区。\nServerless 仍然是个新事物,但却有着光明的未来 毫秒级的部署是未来的趋势,许多公司已经在最大程度上利用 Serverless 架构。Serverless 市场预计到 2021 年将达到 77 亿美元。根据 RightScale 的 2018 年度云状态报告,Serverless 是当今增长最快的云服务模型,年增长率为 75%,并有望在 2020 年超过预期。\n当前的 Serverless 选则包括:\n AWS Lambda Microsoft Azure Google Cloud Platform IBM Bluemix/OpenWhisk 为什么开发者更喜欢 Serverless:\n 使开发者更有生产力 部署速度更快 扩展能力更强 用户体验更好 费用和基础设施问题更少 2017 年 5 月,微软首席执行官 Satya Nadella 指出 Serverless 的潜力及其改变云计算机制的能力。\n他说:“但是,我认为将彻底改变我们对逻辑的看法的一件事是 Serverless \u0026hellip; 因此,Serverless 将在根本上改变不仅是后端计算的经济价值,而且它将成为未来分布式计算的核心。”\n乐高的 Serverless 之旅 乐高 的 Serverless 之旅将向您展示如何从一小步开始并取得巨大成功。黑色星期五和网络星期一的灾难使他们转向了 Serverless 。 乐高拥有一个包含 Oracle ATG 的旧系统,其中八台服务器与同一个数据库进行通信,而 SAP 则在后端支持 TAX 系统。\n上述旧版系统参加了每年的黑色星期五和网络星期一的活动,当系统无法控制夜间高峰时,这变成了一场灾难。结果,发生了一系列事件,其中 TAX 系统先关闭,这又使 SAP 宕机,结果整个乐高电子商务平台停顿了 2 个小时,这使他们蒙受了巨大损失。\n此事件使他们想到了 Serverless,为什么?\n灾难发生后,乐高团队决定迁移到云中,拥有一个简单的 API,将 Lambda 置于其后,然后使用它。这是乐高转向 Serverless 的第一步。这也促使他们也转向了微服务架构,甚至转向了 DevOps 和自动化。\n乐高团队一开始只用单个 Lambda 来计算营业税,现在已经全部使用了 Lambda。\n整个话题都在这里。\n数字化转型将为他人树立榜样 我们将会看到有许多组织摆脱他们的舒适区,并尝试新技术,甚至医疗、金融机构、政府等传统行业也将通过采用云原生和 DevOps 实践来实现数字化转型,从而得到整体大幅改善。让我们看看一些近期有趣的案例研究。\n快递服务公司联邦快递是如何找到实现数字化转型方式的?联邦快递没有足够的 IT 专业人员来使用现代 Cloud-Native 和 DevOps 流程,但并它并没有止步于此。 联邦快递知道其工程师人才库中缺乏合适技能的问题,因此首席信息主管 Rob Carte 找到了解决方案。联邦快递成了一所大学,开始教自己的工程师先进的计算机技能和现代的软件开发方式。\n为此,创建团队并将其命名为 The Cloud Dojo。 Dojo 由一个跨职能的团队组成的,这个团队由专业云开发人员、安全专家和运营专家共同组成,并聚集到一个位置。其目的是培训团队,使其将传统工程与现代云实践,包括 DevOps、云原生、重写旧应用程序以在云中运行和自动化相结合。这个称为 Cloud Dojo 的土著团队已经重新培训了 2500 多名软件程序员。\n迄今为止,联邦快递已经为云化重写了 200 多个生产级的应用程序,以及 300 多个应用程序可供使用。因此联邦快递的 Cloud Dojo 团队获得了 2019 CIO 100 奖。阅读整个故事和联邦快递的首席信息主管 Carter 的提示。\nBox 的数字化转型之路 几年前,在 Box 公司,要花六个月的时间来构建新的微服务,快进到今天,则只需要几天。他们如何设法加快速度?有两个关键因素使之成为可能:\n Kubernetes 技术 DevOps 实践 Box 成立于 2005 年,是一个单体的 PHP 应用程序,随着时间的推移已经发展到数百万行代码。应用程序的整体性导致他们建立了非常紧密耦合的设计。这导致他们无法按照自己想要的速度进行创新。应用程序一部分中的错误将导致他们回滚整个应用程序。\n如此多的工程师使用数百万行代码在同一个代码库上工作,错误并不少见。越来越难及时的发布功能,甚至无法修复错误。因此,他们寻找解决方案,并决定采用微服务方法。但是后来他们又开始面临另外一些问题,这些问题随着 Kubernetes 的采用得到了解决。\n请观看 Box 高级工程经理 Kunal Parmar 的完整视频讲座。\n多云将蓬勃发展到新的高度 多云将蓬勃发展,大多数企业都有混合云策略。许多应用程序被编写为在本地和非本地运行,并可能在多个公有云环境中运行。谷歌的云服务平台 Anthos 证明了多云对于软件公司来说是灵活且经济高效的。\nAzure 和 AWS 作为该领域的领导者将决定多云的未来。\n根据最近的 RightScale 2019 云状态报告,可以看到 84% 的企业具有多云策略。\n多云与当今不断增长的市场趋势高度相关。根据 IDC 最近的一项名为多云世界中的云遣返加速的调查,多云最能描述当今的云现实。\n尽管有关云成本优化和供应商锁定的讨论很多,但多云在这里解决了一些关键性问题,例如:避免供应商锁定、成本优化、安全性、数据主权和减少停机时间等。\n拥抱 DevOps 只是对话的开始,还有很长的路要走。公司的数量每天都在增加,因此对云的依赖使 DevOps 市场成为一个很大的市场。Allied Market Research估计,到 2023 年,全球 DevOps 市场将以 18.7% 的复合年增长率达到 94 亿美元。 DevOps 将开发和运营整合在一起,为团队提供了更高的信心和自由度,使其能够以更快的速度和质量进行交付。\nDevOps 尚未完成增长,它日新月异,发展前景广阔。我们都知道,根据 Forrester 的说法,2018 年是企业 DevOps 年。实施 DevOps 实践的企业从故障中恢复的速度提高了 24 倍,并且在补救安全问题上花费的时间减少了 50%,事实证明,DevOps 可以带来更快乐、更投入的团队。\n我希望这些 DevOps 趋势可以使您对市场的发展方向以及如何为敏捷和快速发布做好准备。\n进一步阅读 Container Registries — A Battle Royale\nWhy the World Is Shifting Towards a Cloud-Native Approach\n", "auhtor": "Pavan Belagatti", "translator": "anxk", "original": "https://dzone.com/articles/devops-trends-to-watch-for-in-2020#", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-12-a-new-chapter-for-kohsuke/", "title": "Jenkins 创始人 Kohsuke 的新篇章", "type": "wechat", "date": "2020-02-12 00:00:00 +0000 UTC", "tags": ["社区", "治理", "公告"], "description": "Jenkins 创始人 Kohsuke 即将退出 Jenkins,并投身于一个新的创业公司 Launchable ", "content": "2020 年对我来说将是转变的一年。在 1 月底,我将正式退出 Jenkins,将我在 CloudBees 的角色转换为顾问,并将注意力转向我的新创业公司。这篇文章的其余部分将结合这种过渡的背景,如果您没有与我紧密合作,这可能会令您惊讶。\nJenkins 之旅充满神奇,而且从未间断。我非常喜欢这一切,尤其是与造就 Jenkins 如今成就的世界各地的用户会面与交流。作为项目的创建者,在某个时候,我开始想如何将火炬传递给下一任领导者,如何使人们继续推动它前进。如今,由于有了 CloudBees 和社区,新一代的才华横溢、有才干的领导者正在热情地推动事情向前发展,这真令人高兴。例如,新选举的董事会成员和Jenkins X 的伙伴们。这些新人带来了新的文化和新的代码,并且总的来说,这产生了积极的影响,使 Jenkins 不再局限于我所谈论的局部最优方法,他们得到我所有的支持和尊重。实际上,我最近与 Jenkins 的关系更多的是象征意义,有点像日本的天皇或英国的皇后,这就是为什么此公告对 Jenkins 的前进动力几乎没有实际影响的原因。\n几年前,我曾经觉得如果我退出的话,天就会塌下来。在 2019 年的某个时刻,我突然发现我没有这种感觉了。这种转变是渐进的、稳定的,所以我不确定自己何时跨过的这道门槛,但是在 2019 年,我显然处于另一端。这样我才知道自己终于可以结束我的这一篇章。回首与 Jenkins 在一起 15 年,与 CloudBees 合作 9 年,这真是很长的一段时间。\n我希望您会想知道我的新篇章是什么。我将与我的老伙伴 Harpreet Singh 创办一家新的创业公司,即 Launchable。自从在 Sun Microsystems 和 JavaEE 工作以来,我就认识他,他是我在 CloudBees 领域的合伙人,从头开始建立 Jenkins 业务。他去 Atlassian 经营 BitBucket 业务已有一段时间,但是现在他和我又回到了一起。许多 CloudBees 人投资了 Launchable,包括 Sacha Labourey、Bob Bickel 和 John Vrionis。\n通过 Jenkins 和 CloudBees ,我得以推动软件开发中自动化的发展。这种自动化产生了大量数据,但我们并未使用这些数据来改善我们的生活,这确实是一个浪费的金矿。Launchable 正在努力利用这些信息来提高开发人员的生产力。我写了一篇单独的博客文章,以讨论有关我的想法的更多信息。\n最后,即使离开 CloudBees 不再作为其一名全职员工,也并没有完全离开,我将继续作为 CloudBees 的顾问,我仍然在情感和财务上都对 CloudBees 进行了大量投资。我仍然是狂热的粉丝,我会继续为他们加油,只不过是在默默观望。Jenkins 也一样,我仍然在董事会中,以确保连续性。我仍在持续交付基金会的技术监督委员会任职,虽然我的主席任期将于 3 月届满。\n对于本篇章所给予的宝贵机会和特权,我深表感谢。我周围有许多出色的、鼓舞人心和才华横溢的人,从他们那里学到很多东西。我只能希望我能够产生积极的影响,并回馈他们。 我不会说出名字,但您知道您是谁,我们会保持联系。\n对我来说,今年将是令人兴奋一年。 超越无限!!\n", "auhtor": "kohsuke", "translator": "zhaoying818", "original": "https://jenkins.io/blog/2020/01/23/a-new-chapter-for-kohsuke/", "poster": "thanks-kohsuke.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/02/2020-02-10-webSocket/", "title": "WebSocket", "type": "wechat", "date": "2020-02-10 00:00:00 +0000 UTC", "tags": ["Jenkins", "WebSocket"], "description": "谈谈 Jenkins 对 WebSocket 的实验性支持", "content": "我很高兴地提出报告,JEP-222 从 Jenkins 每周更新版开始落地。此改进为 Jenkins 带来了实验性的 WebSocket 支持,可在连接入站代理程序或运行 CLI 时使用。WebSocket 协议允许通过 HTTP(S)端口进行双向交互式通信.\n尽管 Jenkins 的许多用户都可以受益,但实现该系统对 CloudBees 尤为重要,因为 现代云平台上的 CloudBees Core(即在 Kubernetes 上运行)如何配置网络。当管理员希望将入站(以前称为“JNLP”)外部代理连接到 Jenkins 主服务器(例如在集群外部运行并使用代理服务包装器的 Windows 虚拟机)时,到目前为止,唯一的选择是使用特殊的 TCP 端口。需要使用低级网络配置将此端口开放给外部流量。例如,nginx 入口控制器的用户将需要为集群中的每个 Jenkins 服务代理一个单独的外部端口。有关此操作的说明很复杂,很难调试。\n使用 WebSocket,现在可以在存在反向代理的情况下更简单地连接入站代理:如果 HTTP(S)端口已在提供流量,则大多数代理将允许 WebSocket 连接而无需其他配置。可以在代理配置中启用 WebSocket 模式,并且即将推出 Kubernetes 插件中对基于 Pod 的代理的支持。您将需要一个4.0 或更高版本的代理,该代理版本以常规方式与 Jenkins 捆绑在一起(带有该版本的 Docker 镜像即将发布)。\nJenkins 的另一个对反向代理用户造成麻烦的部分是 CLI。除了端口 22 上的 SSH 协议(这又是从外部打开的麻烦)之外,CLI 还具有使用 HTTP(S)传输的功能.不幸的是,用于实现混淆某些技巧的技巧并不十分可移植。Jenkins 2.217 提供了一个新的 webSocket CLI 模式,该模式避免了这些问题。再次说明,您将需要下载新版本的 jenkins-cli.jar 才能使用此模式。\n已经针对 Kubernetes 实现示例(包括 OpenShift)对 WebSocket 代码进行了测试,但是很可能仍然存在一些 bugs 和局限性,并且尚未测试重构建负载下代理的可伸缩性。暂时将此功能视为 Beta 版,并让我们了解其工作原理!\n", "auhtor": "Jesse Glick", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2020/02/02/web-socket/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/01/2020-01-10-the-complete-ci-cd-collection-tutorials/", "title": "完整的 CI/CD 集合[教程]", "type": "wechat", "date": "2020-01-10 00:00:00 +0000 UTC", "tags": ["CI/CD", "Blog"], "description": "我们收集了完整的 CI/CD 关于教程、工具、最佳实践的博客,分享 CI/CD 的那些事儿", "content": " 什么是 CI/CD? 什么是 CI/CD?作者:Izzy Azeri-让我们看一下 CI 和 CD,这是所有 DevOps 商店的基本基石,并看看如何利用这些概念来帮助更好地交付下一个项目。 什么是持续集成和持续交付?作者:Arnab Roy—我们深入探讨了 DevOps 环境的两个基本要素。 什么是持续交付?好处和最佳实践,作者:ATC 团队-看看持续交付如何适合 DevOps 流水线,它与持续部署有何不同以及一些最佳实践。 持续集成与持续交付,作者:Rebecca Pruess—持续集成和交付是最常见的 DevOps 术语中的两个。但是,从字面上和您的业务来讲,它们是什么意思? 持续交付与持续部署与持续集成之间的差异(以及如何最佳利用它们),作者:Angela Stringfellow—所有这些持续概念之间的真正区别是什么?从 DevOps 专家那里了解有关此内容的更多信息,以充分利用 CI 和 CD。 持续集成和工作流程简介,作者:Rekha Sree—所有这些持续概念之间的真正区别是什么?从 DevOps 专家那里了解有关此内容的更多信息,以充分利用 CI 和 CD。 CI/CD 入门 了解如何从头开始建立 CI/CD 流水线,作者:Samarpit Tuli—作为现代 DevOps 流程的基础,理解 CI/CD 并学习如何从头开始建立流水线非常重要。 持续输送流水线的各个阶段,作者:Pavan Belagatti—使用 CD 流水线是采用敏捷和 DevOps 的重要组成部分,这将提高组织的整体生产力。 AWS 提供的安全且可扩展的 CI/CD 流水线,作者:Chandani Patel—Amazon 和 DevOps 与许多工具和流程紧密结合,可实现高效的 CI/CD 流水线。 使用 Visual Studio 建立 CI/CD 流水线,作者:Mohamed Radwan—了解如何在 Visual Studio Team Services 中设置 CI/CD 流水线以自动执行代码的构建,测试和部署。 Kubernetes、Jenkins、Spinnaker 的 CI/CD,作者:Arvind Rajpurohit 和 Karan Patil—这是一个新工具,可以帮助您将新的构建不断地部署到 Kubernetes 集群。 使持续交付到数据库,作者:Matt Hilbert—无需使用不熟悉的流程和强制执行的策略将其添加到您现有的基础架构中,而是可以将数据库 CD 与现有系统一起实施。 用 Git 和 Jenkins 建立一个持续交付流水线,作者:Lyndsey Padget—了解如何利用 Git 的强大功能和简单性与 Jenkins 建立自动持续交付流水线。 使用 Jenkins、Helm、Kubernetes 轻松自动化 CI/CD 流水线,作者:Eldad Assis—了解如何使用 Jenkins、Helm、Kubernetes 设置工作流以自动化 CI/CD 流水线,以快速轻松地进行部署。 使用 Hashicorp Terraform 和 Jenkins 的不可变基础架构 CI/CD,作者:Radhakrishnan Rk—这篇内容广泛的文章应该会留下一些关于创建基础设施的问题没有得到解答。 CI/CD 工具和技术 20 种最佳持续集成工具:优化 CI/CD 流程的指南,作者:Ben Patterson—CI/CD 流水线是创建可靠的 DevOps 流程的关键,该流程可将稳定的产品更快地推向市场。 CI/CD 工具的淘汰:Jenkins vs、TeamCity vs、Bamboo,作者:Ben Putano—看看 DevOps 的三个顶级 CI/CD 工具-Jenkins、TeamCity、Bamboo-为您提供做出选择的建议。 我应该使用哪种 CI/CD 工具,作者:Anita Buehrle—了解典型的自动化 CI/CD 部署流水线的组件以及为什么需要它。 适用于 DevOps 和持续交付的最佳自动化测试工具(前 10 名),作者:Lavanya C—检查这些自动化测试工具,以在软件开发生命周期中实现持续交付。 前 8 个持续集成工具,作者:Vladimir Pecanac—如果您未来使用 C/I,Vladimir Pecanac 很好地概述了您的组织应考虑使用的 8 种持续集成工具。 Ansible 安装 CI/CD 工具:您需要知道的一切,作者:Evgeny Mekhanikov—了解如何使用 IT 自动化工具 Ansible 为 CI/CD 流水线设置工具。 Kubernetes 的 11 种持续交付工具(第 1 部分),作者:Anita Buehrle—一旦您的 Kubernetes 应用程序启动并运行,您将需要为 CI/CD 流水线构建其余部分。 CI/CD 最佳实践和关注点 CI 失败的 5 大原因,作者:Shashikant Jagtap—使用质量低下的服务器会浪费每个人的时间,因为构建时间太长,无法完成,从而导致测试结果断断续续,并使工程师感到沮丧。 降低持续交付速度的 6 个常见挑战,作者:Ben Putano—按照以下步骤进行持续交付和高质量代码,克服障碍并加速您的成功。 2019 年学习 Jenkins 和 CI/CD 的 5 门课程,作者:Javin Paul—查看这些免费课程,以帮助您了解有关使用 DevOps 工具 Jenkins 的更多信息。 CD/CI 成功所需的基本方法,作者:Ben Putano—如果您希望开始使用 CI/CD 流水线,则需要掌握一些基础知识。这篇文章将帮助您。 选择 CI 平台时应考虑的 10 件事,作者:Pavan Belagatti—持续集成是采用 DevOps 的第一步。选择 CI 平台时,请牢记这十个因素。 持续集成第 3 部分:最佳做法,作者:Deepak Karanth 和 RJ Williams—本文介绍了持续集成的最佳实践,以及采用 DevOps 原则(如自动部署等)的提示和预防措施。 ", "auhtor": "Andre Lee-Moye", "translator": "wenjunzhangp", "original": "https://dzone.com/articles/the-complete-cicd-collection-tutorials", "poster": "12682719-befunky-photo-2.jpg" }, { "uri": "https://jenkins-zh.cn/meeting/2020-01-08/", "title": "", "type": "meeting", "date": "2020-01-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 线下活动\n 北京 其他城市 GSoC\n Jenkins 发行版(https://community.jenkins-zh.cn/t/jenkins/241) 论坛\n 自动同步博客文章 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/12/2019-12-31-implement-cicd-for-multibranch-pipeline-in-jenkins/", "title": "使用 Jenkins 实现 CI/CD 多分支流水线", "type": "wechat", "date": "2019-12-31 00:00:00 +0000 UTC", "tags": ["jenkins", "multi-branch"], "description": "基于 Jenkins 多分支流水线任务类型创建 CI/CD 多分支流水线", "content": " 简介 Jenkins 是一个持续集成服务器,用于从版本控制系统(VCS)中获取最新代码,然后对其进行构建、测试并将结果通知给开发人员。除了作为一个持续集成(CI)服务器之外,Jenkins 还可以做很多其它的事情。最初它被称为 Hudson,是川口耕介(Kohsuke Kawaguchi)基于 Java 编写的一个开源项目,因此,在安装和运行 Jenkins 之前,首先需要安装 Java 8。\n多分支流水线是 Jenkins 中的一种流水线类型,它允许您在 Jenkinsfile 的帮助下为源码管理(SCM)库中的每个分支自动地创建一支流水线。\n什么是 Jenkinsfile Jenkinsfile 是一个文本文件,被用来定义一个 Jenkins 流水线。在 Jenkinsfile 中可以使用领域特定语言(DSL)编写运行 Jenkins 流水线所需要的步骤,从而将流水线实现为代码。\n来自 Jenkins 的定义 使用多分支流水线,您可以为同一项目的不同分支实现不同的 Jenkinsfile,Jenkins 将会自动发现、管理和执行那些分支中包含 Jenkinsfile 的流水线。\n创建一个简单多分支流水线任务的步骤 点击 Jenkins 工作台左上角的 New Item 选项: 在 Enter an item name 中填入任务名,向下滚动,然后选择 Multibranch Pipeline,最后点击 OK 按钮: 填写任务描述(可选)。\n 添加一个分支源(例如:GitHub)并且填写代码仓库的位置。\n 选择 Add 按钮添加凭证并点击 Jenkins。\n 键入 GitHub 用户名、密码、ID 和描述。\n 从下拉菜单中选择凭证:\n 点击 Save 保存该多分支流水线任务。\n Jenkins 会自动扫描指定的仓库并为 Organization 文件夹添加索引。Organization 文件夹使得 Jenkins 能够监视整个 GitHub Organization 或 Bitbucket Team/Project,并自动为包含分支的仓库创建新的多分支流水线,然后拉取包括 Jenkinsfile 在内的源码:\n 当前,这项功能仅适用于 GitHub 和 Bitbucket 中的仓库,分别由 GitHub Organization Folder 和 Bitbucket Branch Source 这两个插件提供。\n 一旦任务被成功创建,构建将会被自动触发:\n 配置 Webhooks 我们需要配置 Jenkins 服务器以便与我们的 GitHub 仓库通信,为此,我们要获取 Jenkins 的 Hook URL。\n 导航到 Manage Jenkins 页面,然后选择 Configure System。\n 找到 GitHub 插件配置部分,然后点击 Advanced 按钮。\n 选择 Specify another hook URL for GitHub configuration:\n 将文本框中的 URL 复制出来。\n 单击 Save,返回到 Jenkins 工作台。\n 打开浏览器,导航到 GitHub 选项卡,然后选择您的 GitHub 仓库。\n 单击 Settings,导航到仓库设置:\n 点击 Webhooks 部分。\n 点击 Add Webhook 按钮,然后将 Hook URL 粘贴在 Playload URL 中。\n 确保 Webhook 触发器已选中 Just the push event 选项。\n 点击击 Add webhook,就会把此 webhook 添加到您的仓库。\n 正确添加 Webhook 后,您将会看到带有绿勾的 Webhook:\n 返回到仓库,然后切换到对应分支并更新任何文件。在此,我们更新 README.md 文件。\n 现在将会看到 Jenkins 任务被自动触发:\n 流水线执行完成后,可以通过点击 Build History 下的构建号来验证执行过的构建。\n 点击构建号,然后选择 Console Output,您便可以看到每个构建步骤的输出日志:\n 进一步阅读 Learn How to Set Up a CI/CD Pipeline From Scratch\nAPI Builder: A Simple CI/CD Implementation – Part 1\n", "auhtor": "Krishna Prasad Kalakodimi", "translator": "anxk", "original": "https://dzone.com/articles/implement-ci-for-multibranch-pipeline-in-jenkins", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2020/01/2020-01-13-welcome-to-the-matrix/", "title": "欢迎使用流水线指令-矩阵", "type": "wechat", "date": "2019-12-29 00:00:00 +0000 UTC", "tags": ["Jenkins", "pipeline"], "description": "介绍了声明式流水线中 `matrix` 指令的使用方法,并介绍了 `matrix` 指令在pipeline中的句式", "content": " 我经常发现自己需要在一堆不同的配置上执行相同的操作。到目前为止,意味着我需要在流水线上的同一阶段制作多个副本。当我需要修改时,必须在整个流水线的多个地方做相同的修改。对于一个更大型的流水线来说,即便维护很少的配置也会变得困难。 声明式流水线1.5.0-beta1(可以从Jenkins 实验性更新中心获取)添加了一个新的 matrix 部分,该部分能让我一次指定一个阶段列表,然后在多个配置上并行运行同一列表。让我们来看一看!\n单一配置流水线 开始我会使用一个带有构建和测试阶段的简单流水线。我使用 echo 步骤作为构建和测试行为的占位符。\nJenkinsfile\npipeline { agent none stages { stage('BuildAndTest') { agent any stages { stage('Build') { steps { echo 'Do Build' } } stage('Test') { steps { echo 'Do Test' } } } } } } 多平台与浏览器的流水线 我更喜欢在多系统以及浏览器结合的情况下执行我的构建和测试。新的 metrix 指令能让我定义一个 axes 的集合。每个 axis 有一个 name 以及包含了一个或多个 values 的列表。当流水线运行的时候,Jenkins 会将这些托管过来并将每个“轴”上所有可能值的组合运行在我的阶段内。一个“矩阵”上所有的元素都是并行运行的(只受限于可用的节点数量)。 我的“矩阵”有两个“轴”: PLATFORM 和 BROWSER 。PLATFORM 有三个值 BROWSER 有四个值,所以我的阶段会运行12个不同的组合。我已经修改了我的 echo 步骤用来使用每个元素中“轴”的值。\nJenkinsfile\npipeline { agent none stages { stage('BuildAndTest') { matrix { agent any axes { axis { name 'PLATFORM' values 'linux', 'windows', 'mac' } axis { name 'BROWSER' values 'firefox', 'chrome', 'safari', 'edge' } } stages { stage('Build') { steps { echo \u0026quot;Do Build for ${PLATFORM} - ${BROWSER}\u0026quot; } } stage('Test') { steps { echo \u0026quot;Do Test for ${PLATFORM} - ${BROWSER}\u0026quot; } } } } } } } 日志输出(部分内容)\n... [Pipeline] stage [Pipeline] { (BuildAndTest) [Pipeline] parallel [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'safari') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'safari') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'safari') [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'edge') (hide) [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'edge') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'edge') ... Do Build for linux - safari Do Build for linux - firefox Do Build for windows - firefox Do Test for linux - firefox Do Build for mac - firefox Do Build for linux - chrome Do Test for windows - firefox ... 排除无效的组合 现在我已经创建一个基本的“矩阵”了,我注意到我有一些无效的组合。 Edge 浏览器只在 Windows 系统上运行以及没有 Linux 版本的 Safari。 我可以使用 exclude 命令去掉我的“矩阵”中无效的元素。每个 exclude 含有一个或多个带有 name 和 values 的 axis 指令。一个 exclude 中的 axis 指令会生成一组组合(类似于生成“矩阵”中的元素)。“矩阵”中的元素匹配一个 exclude 中所有需要从“矩阵”中移出的值。如果我有不止一个 exclude 指令,每个都将分别评估来移除元素。 当需要处理一个长的排除列表时,我可以使用 notValues 而不是 values 去指定“轴”中我们不想排除的值。是的,这有点双重否定的意思,所以会有一点困惑。我只会在我真正想用的时候才会用它。 下面的流水线示例,我排除了 linux, safari 的组合同样我排除了除了 windows 之外的其他平台 和 edge 浏览器的组合。 重要 本流水线使用两个“轴”,但是没有使用 axis 指令数量的限制。 同样,在这个流水线里每个 exclude 指定这两个“轴”的值,但是这不是必须的。如果我们想只在“linux”元素中运行,我们需要使用以下的 exclude :\nexclude { axis { name 'PLATFORM' notValues 'linux' } } pipeline { agent none stages { stage('BuildAndTest') { matrix { agent any axes { axis { name 'PLATFORM' values 'linux', 'windows', 'mac' } axis { name 'BROWSER' values 'firefox', 'chrome', 'safari', 'edge' } } excludes { exclude { axis { name 'PLATFORM' values 'linux' } axis { name 'BROWSER' values 'safari' } } exclude { axis { name 'PLATFORM' notValues 'windows' } axis { name 'BROWSER' values 'edge' } } } stages { stage('Build') { steps { echo \u0026quot;Do Build for ${PLATFORM} - ${BROWSER}\u0026quot; } } stage('Test') { steps { echo \u0026quot;Do Test for ${PLATFORM} - ${BROWSER}\u0026quot; } } } } } } } 日志输出(部分内容)\n... [Pipeline] stage [Pipeline] { (BuildAndTest) [Pipeline] parallel [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'safari') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'safari') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'edge') ... Do Build for linux - firefox ... 运行时控制元素行为 在 matrix 指令中同样我可以添加“每个-元素”指令。这些相同的指令我可以添加到一个 stage 中让我可以控制“矩阵”中每一个元素的行为。这些指令可以从它们的元素的“轴”中获取值作为输入,允许我自定义每一个元素的行为以匹配它的“轴”的值。 在我的 Jenkins 服务器中我已经配置了各个节点并为各个节点配置了系统名称的标签(“linux-agent”,“windows-agent”,和“mac-agent” )。为了在正确的操作系统上运行“矩阵”中的元素,我配置了 Groovy 字符模板为元素配置标签。\nmatrix { axes { ... } excludes { ... } agent { label \u0026quot;${PLATFORM}-agent\u0026quot; } stages { ... } // ... } 有时我通过 Jenkins 的网页手动运行流水线任务。当我这样做时,我能够只选择一个运行的平台。 axis 和 exclude 指令定义了一个组成“矩阵”的一组静态的元素。这一组合的集合在运行开始之前就被创建出来,也早于任何的参数获取。也就意味着我不能在任务已经开始后从“矩阵”上添加或者移除元素。 另一方面,“每个-元素”指令,在运行时会被评估。我可以使用“每个-元素” metrix 中的 when 指令来控制“矩阵”中哪个元素会被执行。我添加了一个带有平台列表的 choice 字段,以及在 when 指令添加了判断,这样会确定是所有的平台都执行还是只执行我指定的平台的元素。\npipeline { parameters { choice(name: 'PLATFORM_FILTER', choices: ['all', 'linux', 'windows', 'mac'], description: 'Run on specific platform') } agent none stages { stage('BuildAndTest') { matrix { agent { label \u0026quot;${PLATFORM}-agent\u0026quot; } when { anyOf { expression { params.PLATFORM_FILTER == 'all' } expression { params.PLATFORM_FILTER == env.PLATFORM } } } axes { axis { name 'PLATFORM' values 'linux', 'windows', 'mac' } axis { name 'BROWSER' values 'firefox', 'chrome', 'safari', 'edge' } } excludes { exclude { axis { name 'PLATFORM' values 'linux' } axis { name 'BROWSER' values 'safari' } } exclude { axis { name 'PLATFORM' notValues 'windows' } axis { name 'BROWSER' values 'edge' } } } stages { stage('Build') { steps { echo \u0026quot;Do Build for ${PLATFORM} - ${BROWSER}\u0026quot; } } stage('Test') { steps { echo \u0026quot;Do Test for ${PLATFORM} - ${BROWSER}\u0026quot; } } } } } } } 如果我从 Jenkins 的 UI 页面上运行流水线设置 PLATFORM_FILTER 字段为 mac ,我会得到如下的输出:\n日志输出(部分内容 - PLATFORM_FILTER = \u0026lsquo;mac\u0026rsquo;)\n... [Pipeline] stage [Pipeline] { (BuildAndTest) [Pipeline] parallel [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'firefox') [Pipeline] { (Branch: Matrix - OS = 'linux', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'chrome') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'safari') [Pipeline] { (Branch: Matrix - OS = 'mac', BROWSER = 'safari') [Pipeline] { (Branch: Matrix - OS = 'windows', BROWSER = 'edge') ... Stage \u0026quot;Matrix - OS = 'linux', BROWSER = 'chrome'\u0026quot; skipped due to when conditional Stage \u0026quot;Matrix - OS = 'linux', BROWSER = 'firefox'\u0026quot; skipped due to when conditional ... Do Build for mac - firefox Do Build for mac - chrome Do Build for mac - safari ... Stage \u0026quot;Matrix - OS = 'windows', BROWSER = 'chrome'\u0026quot; skipped due to when conditional Stage \u0026quot;Matrix - OS = 'windows', BROWSER = 'edge'\u0026quot; skipped due to when conditional ... Do Test for mac - safari Do Test for mac - firefox Do Test for mac - chrome 重要 在DevOps World | Jenkins World 2019 “声明式流水线2019:知识点,技巧,以及接下来的事情”中与我一起参与。我会回顾过去的一年有哪些加入到了流水线(包括“矩阵”)以及探讨一些关于流水线下一步走向的想法。\n结论 这篇博客里面,我们已经看到了怎样使用 matrix 指令来构成简洁但又强大的声明式流水线。同样的一个不带有 matrix 的流水线会容易一些,但会消耗更多的时间同样也会更难理解和维护。\n链接 Jenkins 实验性更新中心 使用 Jenkins 实验性更新中心 ", "auhtor": "Liam Newman", "translator": "0N0thing", "original": "https://jenkins.io/blog/2019/11/22/welcome-to-the-matrix/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/12/2019-12-26-jcli-v0.0.24/", "title": "Jenkins CLI 命令行 v0.0.24", "type": "wechat", "date": "2019-12-26 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.24 发布", "content": " 本次发布,主要增加了 jcli 对凭据、计算节点的管理能力,以及通过 jcli 启动 jenkins.war。 对于部分子命令,还可以通过参数 --doctor 来实现错误诊断。\n部分数据指标 * 测试覆盖率:87.1% * 下载量:2.8k+ * 贡献者:9\n更多内容,请参考官方文档\n🚀 功能 增加对配置即代码插件的支持 (#265) @LinuxSuRen 为 jcli 增加 Docker 镜像 (#260) @LinuxSuRen 增加 Jenkins 的 go 语言客户端的文档 (#256) @1179325921 支持获取 Jenkins 的唯一标识信息 (#292) @LinuxSuRen 支持在命令行中设置 Jenkins 连接地址 (#291) @LinuxSuRen 支持通过管理员为 Jenkins 的其他用户创建令牌 (#289) @LinuxSuRen 支持创建 JNLP 类型的计算节点 (#290) @LinuxSuRen 改进命令行的数据输出 (#285) @LinuxSuRen 增强 Jenkins 任务的搜索功能 (#284) @LinuxSuRen 增加搜索 Jenkins 任务以及文件夹 (#281) @LinuxSuRen 为 casc 命令增加诊断功能 (#280) @LinuxSuRen 增加计算节点的子命令 (#278) @LinuxSuRen 支持对 Jenkins 凭据的管理 (#266) @LinuxSuRen 支持发布插件的子命令 (#276) @LinuxSuRen 增加命令行输出中对配色的支持 (#273) @LinuxSuRen 支持同时取消队列中的多个任务 (#274) @LinuxSuRen 支持在启动 jenkins.war 时传递系统配置 (#275) @LinuxSuRen 支持通过 docker 的方式下载最新开发版本的 jcli (#267) @LinuxSuRen 支持启动 Jenkins (#262) @LinuxSuRen 支持列出 Jenkins 的计算节点 (#259) @LinuxSuRen 🐛 缺陷修复 修复 PO 文件中的拼写错误 (#282) @anxk 修复了当没有配置文件时命令崩溃的问题 (#269) @LinuxSuRen 修复由 lgtm.com 发现的告警 (#293) @LinuxSuRen 修复由于代码重构导致的 bash 下的命令行无法自动补全 (#294) @LinuxSuRen 📝 文档完善 增加对开发环境要求的描述 (#263) @yJunS 增加下载 jcli 的其他方式的描述 (#264) @LinuxSuRen 👻 维护 移除 markdown 模板中的链接 (#271) @LinuxSuRen 优化 jcli 的开发版 docker 镜像,使得更小 (#268) @LinuxSuRen 增加拉取镜像数量的徽章 (#261) @LinuxSuRen 把 github.com/onsi/ginkgo 从 1.10.3 升级到 1.11.0 (#288) @dependabot-preview 把 github.com/onsi/gomega 从 1.7.1 升级到 1.8.1 (#287) @dependabot-preview 把 github.com/AlecAivazis/survey/v2 从 2.0.4 升级到 2.0.5 (#270) @dependabot-preview 🚦 测试 为 open 子命令增加测试用例 (#272) @LinuxSuRen ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "jenkins-cli.png" }, { "uri": "https://jenkins-zh.cn/meeting/2019-12-25/", "title": "", "type": "meeting", "date": "2019-12-25 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 论坛\n 邮箱没有配置好(网络超时,怀疑是由于网络代理设置的有问题) 给管理更多的管理权限 依赖邮箱的配置 把论坛的版本调整为正式版 @yJunS 介绍 Jenkins 容器发行版\n 尝试提一个 proposal 到 GSOC(https://jenkins.io/sigs/gsoc/) Jenkins 发行版的定制 jenkins+2.190.3+localization-zh-cn+++ http://custom.jenkins-zh.cn?version=2.190.3\u0026amp;plugin=localization-zh-cn 增加文章作者(译者)的统计\n 增加例会参加成员的统计\n 定期的网络研讨会(https://community.jenkins-zh.cn/t/jenkins/149)\n 媒体情况统计\n 论坛 公众号 文章翻译 https://github.com/jenkins-infra/wechat/pull/282\n ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/12/2019-12-23-generic-webhook-trigger-plugin/", "title": "Webhook 通用触发插件", "type": "wechat", "date": "2019-12-23 00:00:00 +0000 UTC", "tags": ["Jenkins", "Webhook"], "description": "介绍通用 Webhook 触发插件,使用 Webhook 插件构建 Jenkins 自动化服务", "content": " 这篇文章将介绍我在 Jenkins 上遇到的一些常见问题,以及如何通过开发通用 Webhook 触发插件来解决这些问题。\n问题 在使用 Jenkins 工作时,我经常遇到同样的问题:\n 代码重复和安全性-每个仓库中的 Jenkinsfiles。 分支不是功能-master 上的参数化任务通常会混合与不同功能相关的参数。 记录不良的触发器插件-记录正常服务但记录不佳的使用插件 代码重复和安全性 每个 Git 仓库中都有 Jenkinsfiles,使开发人员可以使这些文件分开。开发人员 push 他们的项目,并且很难维护共享代码的模式。\n我几乎用共享库解决了代码重复问题,但是它不允许我设置必须遵循的严格模式。任何开发人员仍然可以决定不调用共享库提供的功能。\n还允许开发人员运行 Jenkinsfiles 中的任何代码的安全性方面。例如,开发人员可能会打印从凭据收集的密码。让开发人员在 Jenkins 节点上执行任何代码对我来说似乎不合适。\n分支不是功能 在 Bitbucket 中有项目,每个项目都有 git 仓库的集合。像这样:\n PROJ_1 REPO_1 REPO_2 PROJ_2 REPO_3 让我们考虑一下我们要为这些仓库提供的一些功能:\n pull request 验证 构建快照(如果需要的话,也可以预发布) 构建发布 如果开发人员习惯于在 Bitbucket 中像这样组织仓库,我们是否应该在 Jenkins 中以同样的方式组织它们?而且,如果他们浏览 Jenkins,是否不应该为每种功能(例如 pull-request,snapshot 和 release)找到一份构建任务?每个具有仅与该功能相关的参数的任务。我认同!像这样:\n / - 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。\n文献资料 Webhooks 通常在提供它们的服务中有据可查。例如:\n Bitbucket Cloud Bitbucket Server GitHub GitLab Gogs 和 Gitea Assembla Jira 令我困扰的是,即使我理解了这些 webhooks,我也无法使用它们。因为我需要在所使用的插件中进行开发,以便提供从 Webhook 到构建的任何值。从 PR 到实际发布,该过程可能需要几个月的时间。这样简单的事情实际上应该不是问题。\n解决方案 我的解决方案几乎可以追溯到基本知识:我们有一个自动化服务(Jenkins),我们想在外部 Webhooks 上触发它。我们想从该 Webhook 收集信息并将其提供给我们的构建。为了支持它,我创建了通用 Webhook 触发器插件。\n仓库中提供了最新文档,并且有一个完整的示例,其中使用 configuration-as-code 实现了 GitLab。在这里查看仓库。\n代码重复和安全性 我制定了所有开发人员都必须遵循的约定。而不是让开发人员从 Jenkinsfiles 显式调用基础结构。遵循一些规则,例如:\n 所有的 git 仓库都应该从仓库的根开始构建。 如果包含 gradlew 使用 ./gradlew build 完成构建 使用 ./gradlew release 完成发布 \u0026hellip;\u0026hellip;等等 如果包含 package.json 使用 npm run build 完成构建 使用 npm run release 完成发布 \u0026hellip;\u0026hellip;等等 有了这些规则,流水线就可以完全通用,并且在仓库中不需要 Jenkinsfiles。由于某些原因,某些 git 仓库可能需要禁用测试用例。这可以通过允许仓库添加一个特殊文件,也就是 jenkins-settings.json 来解决,让基础架构发现其内容并对其采取行动。\n即使没有执行 CI,这也可以帮助开发人员。当他们克隆一个新的,未知的仓库时,他们将知道可以发出哪些命令及其语义。\n分支不是功能 我实现:\n Jenkins 任务配置-使用任务 DSL。 Jenkins 的构建过程-使用 Pipelines 和共享库。 通过与 Job DSL 中的 git 服务集成,我可以自动找到 git 仓库。我创建动态组织在文件夹中的任务。还调用 git 服务来设置触发这些任务的 webhooks。任务是普通的流水线,不是多分支,它们不使用 Git 中的 Jenkinsfile,而是使用 Job DSL 在任务中配置的 Jenksinfile。因此,所有任务配置和流水线均受版本控制。这一切都在这里发生。\n文献资料 该插件使用 JSONPath 以及 XPath 从 JSON 提取值并将其提供给构建。让用户从 webhook 中选择所需的内容。它还具有一个正则表达式过滤器,以允许在某些情况下不触发。\n该插件不是很大,只是 webhook、JSONPath/XPath 和正则表达式之间的粘合剂。所有这些部分都已被很好地记录下来,我会尽力维护该插件。这是一个非常有据可查的解决方案!\n", "auhtor": "Tomas Bjerre", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2019/12/14/generic-webhook-trigger-plugin/", "poster": "cover.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/12/2019-12-19-full-build-automation-for-java-application-using-docker/", "title": "使用 Docker 全自动构建 Java 应用", "type": "wechat", "date": "2019-12-19 00:00:00 +0000 UTC", "tags": ["docker", "jenkins", "pipeline", "java"], "description": "这个过程很长,我们的目标是让所有这些事都自动化。", "content": " 这次的流水线中,我们使用 Docker 容器来构建我们的 Java 应用。\n我们会在 Docker 容器里运行 Jenkins,再使用 Jenkins 启动一个 Maven 容器,用来编译我们的代码,接着在另一个 Maven 容器中运行测试用例并生成制品(例如 jar 包),然后再在 Jenkins 容器中制作 Docker 镜像,最后将镜像推送到 Docker Hub。\n我们会用到两个 Github 仓库。\n Jenkins-complete:这是主仓库,包含了启动 Jenkins 容器所需的配置文件。 Simple-java-maven-app:使用 Maven 创建的 简单的 Java 应用。 在搭建之前,我们先来了解一下这两个仓库。\n了解 Jenkins-complete 这是我们构建 Jenkins 镜像的核心仓库,它包含了所需的配置文件。我们通过 Jenkins 官方提供的 Docker 镜像启动 Jenkins 容器,然后完成一些动作,例如安装插件、创建用户等。\n安装好之后,我们会创建用来获取 Java 应用的 Github 凭据,还有推送镜像到 Dockerhub 的 Docker 凭据。最后,开始创建我们应用的流水线 job。\n这个过程很长,我们的目标是让所有这些事都自动化。主仓库包含的文件和详细配置会用来创建镜像。当创建好的镜像启动运行以后,我们就有了: 1. 新创建的 admin/admin 用户 2. 已经装好的一些插件 3. Docker 和 Github 凭据 4. 新创建的名为 sample-maven-job 的流水线。\n如果把源码列成树状,就看到下面的结构:\njagadishmanchala@Jagadish-Local:/Volumes/Work$ tree jenkins-complete/ jenkins-complete/ ├── Dockerfile ├── README.md ├── credentials.xml ├── default-user.groovy ├── executors.groovy ├── install-plugins.sh ├── sample-maven-job_config.xml ├── create-credential.groovy └── trigger-job.sh 我们来看看它们都是干嘛的:\n default-user.groovy - 这个文件用来创建默认用户 admin/admin。\n executors.groovy - 这个 Groovy 脚本设置 Jenkins 的执行器数量为 5。一个 Jenkins 执行器相当于一个处理进程,Jenkins job 就是通过它运行在对应的 slave/agent 机器上。\n create-credential.groovy - 用来创建 Jenkins 全局凭据的 Groovy 脚本。这个文件可以创建任意的 Jenkins 全局凭据,包括 Docker hub 凭据。我们要修改文件里 Docker hub 的用户名密码,改成我们自己的。这个文件会被复制到镜像里,然后在 Jenkins 启动时运行。\n credentials.xml - XML 凭据文件。这个文件包含了 Github 和 Docker 凭据。它看起来是这样的:\n \u0026lt;com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl\u0026gt; \u0026lt;scope\u0026gt;GLOBAL\u0026lt;/scope\u0026gt; \u0026lt;id\u0026gt;github\u0026lt;/id\u0026gt; \u0026lt;description\u0026gt;github\u0026lt;/description\u0026gt; \u0026lt;username\u0026gt;jagadish***\u0026lt;/username\u0026gt; \u0026lt;password\u0026gt;{AQAAABAAAAAQoj3DDFSH1******\u0026lt;/password\u0026gt; \u0026lt;/com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl\u0026gt; 仔细观察上面的代码,我们可以看到一个 id 为 “github” 的用户名以及加密后的密码。这个 id 很重要,我们会在后面的流水线中用到。\n怎样拿到加密后的密码呢? 想要拿到密码加密后的内容,你需要到这里去 Jenkins server -\u0026gt; Manage Jenkins -\u0026gt; Script console,然后在输入框里输入下面的代码\nimport hudson.util.Secret def secret = Secret.fromString(\u0026quot;password\u0026quot;) println(secret.getEncryptedValue()) 将 “password” 换成你自己的密码,点击运行,你就得到了加密后的内容。再把这个内容粘贴到 credentials.xml 文件里面就可以了。\nDockerHub 的密码加密过程同上。\n sample-maven-job_config.xml - 这个 XML 文件包含了流水线 job 的细节内容。Jenkins 会在 Jenkins console 里创建一个名为“sample-maven-job”的 job,这个文件包含了它的详细配置。 这个配置很简单,Jenkins 读取文件后,会先创建一个名为 “sample-maven-job” 的流水线 job,然后把仓库指向 Github。 一并设置的还有名为 “github” 的凭据 id。 看起来像是这个样子:\n配置好仓库地址以后,用来远程触发 job 的 token 也就生成了。为了设置远程触发,我们需要打开 “Trigger builds remotely” 选项, 然后把上面的 token 设置到这里。这些配置可以在流水线配置页面的 “Build Triggers” 那一节中看到。为了在后面的 shell 脚本中用这个 token 触发 job, 我们把这个 token 命名为 “MY-TOKEN”。\n trigger-job.sh - 这是一个简单的 shell 脚本,其中的 curl 命令用来触发 job。 虽然,我们在容器里创建了 Jenkins 服务和一个 job,我们还需要一个触发器来触发整个自动构建。我喜欢下面的方法:\n 启动 Jenkins Docker 容器时,完成所有需要做的事,例如创建 job、凭据、用户等。 当容器启动好后触发 job。 我写的这个简单 shell 脚本就是用来在容器启动好以后触发 job 的。shell 脚本用 curl 向 Jenkins 发送了一个 post 请求命令。内容像这样。\n Install-plugins.sh - 这是我们用来安装所有所需插件的脚本。我们会把这个脚本复制到 Jenkins 镜像,并把插件名作为它的参数。 容器启动好以后,这个脚本就会根据插件名对应的插件。\n Dockerfile - 这是自动化过程中最重要的文件。我们会用这个 Docker 文件来创建完整的 Jenkins 服务和所有配置。理解这个文件对于编写你自己的自动化构建是很重要的。\n FROM jenkins/jenkins:lts ARG HOST_DOCKER_GROUP_ID # 使用内置的 install-plugins.sh 脚本安装我们所需的插件 RUN install-plugins.sh pipeline-graph-analysis:1.9 \\ cloudbees-folder:6.7 \\ docker-commons:1.14 \\ jdk-tool:1.2 \\ script-security:1.56 \\ pipeline-rest-api:2.10 \\ command-launcher:1.3 \\ docker-workflow:1.18 \\ docker-plugin:1.1.6 # 设置 admin 用户的环境变量 ENV JENKINS_USER admin ENV JENKINS_PASS admin # 跳过初始设置向导 ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false # 启动脚本,设置执行器的数量、创建 admin 用户 COPY executors.groovy /usr/share/jenkins/ref/init.groovy.d/ COPY default-user.groovy /usr/share/jenkins/ref/init.groovy.d/ COPY create-credential.groovy /usr/share/jenkins/ref/init.groovy.d/ # 命名 job ARG job_name_1=\u0026quot;sample-maven-job\u0026quot; RUN mkdir -p \u0026quot;$JENKINS_HOME\u0026quot;/jobs/${job_name_1}/latest/ RUN mkdir -p \u0026quot;$JENKINS_HOME\u0026quot;/jobs/${job_name_1}/builds/1/ COPY ${job_name_1}_config.xml /usr/share/jenkins/ref/jobs/${job_name_1}/config.xml COPY credentials.xml /usr/share/jenkins/ref/ COPY trigger-job.sh /usr/share/jenkins/ref/ # 添加自定义配置到容器里 #COPY ${job_name_1}_config.xml \u0026quot;$JENKINS_HOME\u0026quot;/jobs/${job_name_1}/config.xml USER root #RUN chown -R jenkins:jenkins \u0026quot;$JENKINS_HOME\u0026quot;/ RUN chmod -R 777 /usr/share/jenkins/ref/trigger-job.sh # 用给定的用户组 ID 创建 'Docker' 用户组 # 将 'jenkins' 用户加到 'Docker' 用户组 RUN groupadd docker -g ${HOST_DOCKER_GROUP_ID} \u0026amp;\u0026amp; \\ usermod -a -G docker jenkins RUN apt-get update \u0026amp;\u0026amp; apt-get install -y tree nano curl sudo RUN curl https://get.docker.com/builds/Linux/x86_64/docker-latest.tgz | tar xvz -C /tmp/ \u0026amp;\u0026amp; mv /tmp/docker/docker /usr/bin/docker RUN curl -L \u0026quot;https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)\u0026quot; -o /usr/local/bin/docker-compose RUN chmod 755 /usr/local/bin/docker-compose RUN usermod -a -G sudo jenkins RUN echo \u0026quot;jenkins ALL=(ALL:ALL) NOPASSWD:ALL\u0026quot; \u0026gt;\u0026gt; /etc/sudoers RUN newgrp docker USER jenkins #ENTRYPOINT [\u0026quot;/bin/sh -c /var/jenkins_home/trigger-job.sh\u0026quot;] FROM jenkins/jenkins:lts - 我们将使用 Jenkins 官方提供的镜像。 ARG HOST_DOCKER_GROUP_ID - 需要记住的重点出现了,虽然我们在 Jenkins 容器里创建了 Docker 容器,但我们没有在 Jenkins 自身内部创建容器。 相反,我们是在它们自己的宿主机上创建了容器。确切的说,是我们让安装在 Jenkins 容器里的 Docker tool 部署一个 Maven 容器到宿主机上。为了实现这个部署,我们需要 Jenkins 容器和宿主机设置一样的用户组。 为了允许 Jenkins 这样的未授权用户访问,我们要把 Jenkins 用户加到 Docker 用户组里去。要做到这件事,我们只需要保证容器里的 Docker 用户组与宿主机上的 Docker 有一致的 GID 即可。用户组 id 可以通过命令 getent group Docker 获得。\nHOST_DOCKER_GROUP_ID 被设为了构建参数,我们要在构建时将宿主机的 Docker 用户组 id 做为参数传进来参与构建。\n# 使用内置的 install-plugins.sh 脚本安装我们所需的插件 RUN install-plugins.sh pipeline-graph-analysis:1.9 \\ cloudbees-folder:6.7 \\ docker-commons:1.14 \\ 接下来是 install-plugins.sh 脚本,把要安装的插件作为参数传给脚本。这个脚本是默认提供的,也可以从宿主机复制一份。\n给 Jenkins Admin 用户设置环境变量 ENV JENKINS_USER admin ENV JENKINS_PASS admin 我们设置了 JENKINS_USER 和 JENKINS_PASS 两个环境变量,default-user.groovy 脚本会用它们创建帐号 admin 用户(密码 admin)。\n# 跳过初始设置向导 ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false 这个使得 Jenkins 以静默模式安装\n# 设置启动器数量和创建 admin 用户的启动脚本 COPY executors.groovy /usr/share/jenkins/ref/init.groovy.d/ COPY default-user.groovy /usr/share/jenkins/ref/init.groovy.d/ COPY create-credential.groovy /usr/share/jenkins/ref/init.groovy.d/ 像我们讨论的那样,上面的脚本会设置执行器各数为 5,创建默认用户 admin/admin。\n需要注意的是,如果去看 Jenkins 官方的 Docker 镜像,你会看到有一个 VOLUME 指向了 /vars/jenkins_home 目录。这个意思是设置 Jenkins 的家目录,类似于物理机上使用包管理器安装 Jenkins 时的目录 /var/lib/jenkins。\n但是,当 volume 挂载好以后,就只有 root 用户有权限在那里编辑或者添加文件。为了让未授权的 jenkins 用户复制内容到 volume, 将所有东西复制到 /usr/share/Jenkins/ref/。 这样当容器启动后,Jenkins 会自动使用 Jenkins 用户把这个位置的文 件拷贝一份到 /vars/jenkins_home 中。\n同样,复制到 /usr/share/jenkins/ref/init.groovy.d/ 的脚本会在 Jenkins 启动后被执行。\n# 命名 job ARG job_name_1=\u0026quot;sample-maven-job\u0026quot; RUN mkdir -p \u0026quot;$JENKINS_HOME\u0026quot;/jobs/${job_name_1}/latest/ RUN mkdir -p \u0026quot;$JENKINS_HOME\u0026quot;/jobs/${job_name_1}/builds/1/ COPY ${job_name_1}_config.xml /usr/share/jenkins/ref/jobs/${job_name_1}/config.xml COPY credentials.xml /usr/share/jenkins/ref/ COPY trigger-job.sh /usr/share/jenkins/ref/ 在上面的例子中,我把我的 job 名字设置为 “sample-maven-job”,然后创建目录,复制一些文件。\nRUN mkdir -p \u0026quot;$JENKINS_HOME\u0026quot;/jobs/${job_name_1}/latest/ RUN mkdir -p \u0026quot;$JENKINS_HOME\u0026quot;/jobs/${job_name_1}/builds/1/ 这些说明很重要,它们在 Jenkins 家目录创建了一些用来存放配置文件的文件夹。latest/ 和 builds/1 存放的目录也需要与其 job 相对应。\n这些创建好以后,我们把已经复制到 /var/share/jenkins/ref 的文件 “sample-maven-job_config.xml”,再让 Jenkins 复制 到 /var/jenkins_home/jobs/,这样就有了 sample-maven-job。\n最后,我们同样把 credentials.xml 和 trigger-job.sh 文件复制到 /usr/share/jenkins/ref。 当容器启动以后, 所有这个目录下的文件都会以 Jenkins 用户的权限移动到 /var/jenkins_home。\nUSER root #RUN chown -R jenkins:jenkins \u0026quot;$JENKINS_HOME\u0026quot;/ RUN chmod -R 777 /usr/share/jenkins/ref/trigger-job.sh # 用指定的用户组组 ID 创建 'docker' 用户组 # 并将 'jenkins' 用户添加到该组 RUN groupadd docker -g ${HOST_DOCKER_GROUP_ID} \u0026amp;\u0026amp; \\ usermod -a -G docker jenkins RUN apt-get update \u0026amp;\u0026amp; apt-get install -y tree nano curl sudo RUN curl https://get.docker.com/builds/Linux/x86_64/docker-latest.tgz | tar xvz -C /tmp/ \u0026amp;\u0026amp; mv /tmp/docker/docker /usr/bin/docker RUN curl -L \u0026quot;https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)\u0026quot; -o /usr/local/bin/docker-compose RUN chmod 755 /usr/local/bin/docker-compose RUN usermod -a -G sudo jenkins RUN echo \u0026quot;jenkins ALL=(ALL:ALL) NOPASSWD:ALL\u0026quot; \u0026gt;\u0026gt; /etc/sudoers RUN newgrp docker USER jenkins 下面的指令以 root 用户执行。在 root 用户的指令下,我们使用宿主机上的 Docker group ID 在容器里创建新的 Docker 用户组。然后把 Jenkins 用户加到 Docker 组当中。\n通过这些,我们就可以使用 Jenkins 用户创建容器了。这样就能突破只有 root 用户能创建容器的限制。为了让 Jenkins 用户能创建容器,我们需要把 Jenkins 用户添加到 Docker 用户组当中去。\n在下面的指令里,我们安装了 docker-ce 和 docker-compose 工具。我们设置了 Docker-compose 的权限。最后,我们把 Jenkins 用户加到 sudoers 文件里,以给到 root 用户特定的权限。\nRUN newgrp docker 这个指令非常重要。通常我们修改一个用户的用户组,都需要重新登录以使新的设置生效。为了略过这一步,我们使用 Docker 命令 newgrp 使设置直接生效。最后,我们回到 Jenkins 用户。\n构建镜像 理解了 Docker 文件后,我们就要用它构建我们的镜像:\ndocker build --build-arg HOST_DOCKER_GROUP_ID=\u0026quot;`getent group docker | cut -d':' -f3`\u0026quot; -t jenkins1 . 在 Dockerfile 的所在目录下运行上面的 Docker 构建指令。在上面的命令中,我们传了 Docker 用户组 ID 给 build-arg。 这个值会传给 HOST_DOCKER_GROUP_ID,用来在 Jenkins 容器里创建相同 ID 的用户组。下载以及安装 Jenkins 插件会增加构建镜像的时间。\n运行镜像 镜像构建好以后,我们以下面的命令运行:\ndocker run -itd -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -p 8880:8080 -p 50000:50000 jenkins1 关于卷挂载有两件重要的事。第一是我们把 Docker 命令挂载到了容器里,当需要其它容器时,就可以在当前容器创建了。\n另一个重要的是挂载 /var/run/Docker.sock。 Docker.sock 是 Docker 守护进程监听的一个 UNIX socket。 这是访问 Docker API 的主要入口点。它也可以是 TCP 类型的 socket,但是出于安全原因,默认设定是 UNIX 类型的。\nDocker 默认通过这个 socket 执行命令。我们把它挂载到 Docker 容器里,是为了能在容器里启动新的其它容器。这个挂载也可以用于服务自省和日志目的。但这增加了被攻击的风险,使用的时候要小心。\n上面的命令执行后,我们就得到一个运行着的 Jenkins 容器。可以通过 URL\u0026lt;ip address\u0026gt;:8880 查看 Jenkins 控制台。使用 “admin/admin” 登录 Jenkins。 我们就可以看到还没有运行过的、使用 SCM,Token 和凭据创建的 sample-maven-job。\n运行 Job 要运行这个 job,我们只需要带着 containerID 以下面的方式执行 trigger-job.sh。\ndocker exec \u0026lt;Jenkins Container ID\u0026gt; /bin/sh -C /var/jenkins_home/trigger-job.sh 运行后我们就可以看到流水线的构建开始了。\n了解 Simple Java Maven App 如上面所说,这个仓库是我们的 Java 应用。它使用 Maven 打包成品,还包含一个 Dockerfile,一个 Jenkinsfile 以及源代码。源代码结构与其它 Maven 项目类似。\n Jenkinsfile - 这是 sample-maven-job 启动前的核心文件。流水线 job 使用 Github 凭据从 Github 下载源代码。 Jenkinsfile 文件里最重要事的是定义 agent。 我们使用 “agent any” 选择任何可用的 agent 来构建代码。我们也可以为某个 stage 定义 agent 环境。\nstage(\u0026quot;build\u0026quot;){ agent { docker { image 'maven:3-alpine' args '-v /root/.m2:/root/.m2' } steps { sh 'mvn -B -DskipTests clean package' stash includes: 'target/*.jar', name: 'targetfiles' } } } 在上面的 stage 中,我们设置它的 agent 环境为 Docker 镜像 “maven:3-alpine.” 这样 Jenkins 就会触发 maven:3-alpine 容器, 然后执行定义在步骤里的命令 mvn -B -DskipTests clean package。\n同样的,单元测试也是以这样的方式运行。docker 启动一个 Maven 镜像,然后执行 mvn test。\nenvironment { registry = \u0026quot;docker.io/\u0026lt;user name\u0026gt;/\u0026lt;image Name\u0026gt;\u0026quot; registryCredential = 'dockerhub' dockerImage = '' } 另一件重要的事是定义环境。我定义了名为 docker.io/jagadesh1982/sample 的仓库,意味着使用最终制品(jar 包)所创建的镜像名称也将遵循这个格式 docker.io/jagadesh1982/sample:\u0026lt;version\u0026gt;。如果你的镜像需要推送到 Dockerhub 的话,记住这一点是非常重要的。Dockerhub 希望镜像名按照 docker.io/\u0026lt;user Name\u0026gt;/\u0026lt;Image Name\u0026gt; 这样的风格命名,以方便上传。\n当构建结束后,新的镜像会被上传到 Dockerhub,本地的镜像则会被删除。\n Dockerfile - 这个仓库包含的 Dockerfile 用来创建 jar 包的镜像。它会拷贝我的 my-app-1.0-SNAPSHOT.jar 到镜像中去。它的内容是这样: FROM alpine:3.2 RUN apk --update add openjdk7-jre CMD [\u0026quot;/usr/bin/java\u0026quot;, \u0026quot;-version\u0026quot;] COPY /target/my-app-1.0-SNAPSHOT.jar / CMD /usr/bin/java -jar /my-app-1.0-SNAPSHOT.jar ", "auhtor": "Jagadish Manchala", "translator": "tomatofrommars", "original": "https://dzone.com/articles/full-build-automation-for-java-application-using-d", "poster": "Jenkins-Docker.png" }, { "uri": "https://jenkins-zh.cn/meeting/2019-12-11/", "title": "", "type": "meeting", "date": "2019-12-11 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 论坛\n 邮箱没有配置好 更换域名(ok)@yJunS 还有一些链接没有更换,不紧急 给管理更多的管理权限 依赖邮箱的配置 把阿里云域名的权限给到管理员 (ok) @linuxsuren 管理员招募 https://discourse.jenkins-zh.cn/t/topic/103 把论坛的版本调整为正式版 @yJunS 介绍 Jenkins 容器发行版\n https://github.com/LinuxSuRen/docker-zh (ok) Jenkins 发行版的定制 jenkins+2.190.3+localization-zh-cn+++ http://custom.jenkins-zh.cn?version=2.190.3\u0026amp;plugin=localization-zh-cn 及时把公共信息放在很明显的位置,还是有人不去仔细看\n ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/12/2019-12-11-jenkins-health-advisor-by-cloudbees-is-here/", "title": "Jenkins 健康检查顾问", "type": "wechat", "date": "2019-12-11 00:00:00 +0000 UTC", "tags": ["Jenkins", "CloudBees"], "description": "CloudBees 推出了一项新的免费服务:Jenkins Health Advisor,帮助您保持 master 节点的健康", "content": "管理任何软件都面临着独特的挑战。Jenkins Masters 也不例外。例如,\n 您如何掌握 Jenkins 环境中发生的所有事情?您是否正在查看问题跟踪器中打开的每个新缺陷? 您如何确保您的 master 或 agents 不会默默失效?您是否正在监控其日志?监控其所有内部组件?如果出现问题,您该如何解决? 您如何避免出现 “Angry Jenkins” 图标? 这就是我们通过 CloudBees 创建 Jenkins Health Advisor 的原因。\n在 CloudBees,我们拥有多年为使用 Jenkins 的客户提供支持的经验,其中包括基于 Jenkins 构建的专有产品,例如 CloudBees Core。因此,我们的支持团队由拥有 Jenkins 知识的自动化专家组成,您在其他任何地方都无法获得。\n当我们的工程师创建一个平台时,便会开始自动运行状况检查,以便他们可以编写规则来检测客户提供的 support bundles 中的已知问题,并将其重定向到所需的知识源以诊断和解决问题。\n经过多年的内部使用,我们决定与社区共享此服务,我们很高兴为 每个 Jenkins 用户推出一项新的免费服务:Jenkins Health Advisor by CloudBees。\nJenkins Health Advisor by CloudBees 自动分析您的 Jenkins 环境,主动识别潜在问题,并通过详细的电子邮件报告为您提供解决方案和建议。\nJenkins Health Advisor by CloudBees 可以检测到各种问题,从简单的配置问题到安全性和最佳实践问题-Jenkins 实现的所有关键要素。入门过程分为 3 个步骤,您将在 24 小时内收到第一份报告。\n我们希望您会喜欢这项服务,它将帮助您保持 masters 的健康。\n花几分钟时间阅读我们的文档,发现服务,并随时通过 Jenkins 社区渠道(Gitter、jenkinsci-users@googlegroups.com,…)与我们联系。\n也不要错过在 DevOps World|Jenkins World 2019上与我们的支持团队会面的机会。\n参考链接:\n 插件文档 Jenkins 插件网站 CloudBees Jenkins 支持 ", "auhtor": "Arnaud Héritier", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2019/11/22/jenkins-health-advisor-by-cloudbees/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-29-jenkins-cicd-with-git-secrets/", "title": "Jenkins CI/CD 集成 Git Secrets", "type": "wechat", "date": "2019-11-29 00:00:00 +0000 UTC", "tags": ["Jenkins 流水线", "Git Secrets"], "description": "本教程将 Git Secrets 与 Jenkins CI/CD 流水线联系起来", "content": " 通常,对我们在代码中使用的机密或凭据进行加密,然后将其保存在安全的地方。我们可以有很多选择来实现这一目标,例如使用 Vault 和 Git-crypt 等工具来。git-secret 是一个简单的工具,我们可以使用它在 Git 仓库中存储密钥。Git-secret 使用 gpg 加密和解密密钥。\ngit-secret 的工作方式如下。进入仓库中要加密文件的文件夹,然后,运行 git init \u0026amp;\u0026amp; git secret init。这将初始化 .gitsecret 文件夹,然后运行 git secret tell $email,如果您希望其他用户解密密钥文件,则必须导入其 gpg 公钥,然后再次运行 git secret tell $otheruseremailid。现在您可以运行 git secret add $secretfilename 和 git secret hide,这将创建名为 $secretfilename.secret 的加密的密钥文件。\n或许你会对在 Git 中存储加密的凭据感兴趣。\n现在,您可以提交 master 分支库了。git-secret 自动将 $secretfile 添加到 .gitignore,因此您只需提交 $secretfile.secret 文件。\n将 git-secret 集成到 Jenkins 中的主要挑战是 git-secret 使用 gpg 私钥和公钥。如果我们必须运行 git secret reveal,我们应该有一个 gpg 私钥。因此,我们如何在 Jenkins 上运行它,怎样使用一个从节点来拉取仓库并进行构建,如果您必须在从节点展示 git secret,则应该在从节点拥有 gpg 私钥。 我们如何在 Jenkins 流水线中实现这种加密和解密?\n这些步骤将说明在 Jenkins 流水线中使用 git-secret 的方法。\n在 Jenkins 上运行 git-secret 1.导出 gpg 私钥。\ngpg -a --export-secret-keys $keyid \u0026gt; gpg-secret.key gpg --export-ownertrust \u0026gt; gpg-ownertrust.txt 你将通过运行 gpg --list-secret-keys 获得密钥 ID。 此处的 E7CD2140FEC5B45F42860B2CC19824F8BC975ABCD 是密钥 ID。\nsec rsa4096 2019-09-17 [SC] E7CD2140FEC5B45F42860B2CC19824F8BC975ABCD uid [ultimate] Test (test gpg key) \u0026lt;test@domain.com\u0026gt; 2.将导出的 gpg 密钥和所有者信任作为 secret file 添加到 Jenkins 凭证。 下图展示了添加私钥作为 Jenkins 凭据。以相同的方式添加所有者信任文件。\n3.添加 gpg 私钥的密码短语作为 secret text。下图演示了这一点。\n4.在 Jenkins 流水线中使用添加的 gpg 私钥、所有者信任文件和密码短语。这里的 \u0026ldquo;gpg-secret\u0026rdquo;、\u0026rdquo;gpg-trust\u0026rdquo; 和 \u0026ldquo;gpg-passphrase\u0026rdquo; 是添加 Jenkins 凭据时给出的 ID。\npipeline { agent { node { label 'test_slave' } } environment { gpg_secret = credentials(\u0026quot;gpg-secret\u0026quot;) gpg_trust = credentials(\u0026quot;gpg-trust\u0026quot;) gpg_passphrase = credentials(\u0026quot;gpg-passphrase\u0026quot;) } stages { stage(\u0026quot;Import GPG Keys\u0026quot;) { steps { sh \u0026quot;\u0026quot;\u0026quot; gpg --batch --import $gpg_secret gpg --import-ownertrust $gpg_trust \u0026quot;\u0026quot;\u0026quot; } } stage(\u0026quot;Reveal Git Secrets\u0026quot;) { steps { sh \u0026quot;\u0026quot;\u0026quot; cd $WORKSPACE/$yoursecretfolder git init git-secret reveal -p '$gpg_passphrase' \u0026quot;\u0026quot;\u0026quot; } } } } 我希望本文能清楚地解释如何在 Jenkins 流水线中使用 git-secrets。\n进一步阅读 避免将安全凭据传递给 GitHub \n如何将 GitHub 仓库集成到 Jenkins 项目\n", "auhtor": "Aditya C S", "translator": "zhaoying818", "original": "https://dzone.com/articles/jenkins-cicd-with-git-secrets", "poster": "connection-netwok.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-28-jcli-v0.0.23/", "title": "Jenkins CLI 命令行 v0.0.23", "type": "wechat", "date": "2019-11-28 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.23 发布", "content": " Jenkins CLI 在参加 2019 年谁是最受欢迎的中国开源软件投票,如果您已经是 Jenkins CLI 的用户,请点击下面的链接帮忙投上一票。\nhttps://www.oschina.net/project/top_cn_2019#jenkins-cli\n如果,您还没有听说或者使用过 Jenkins CLI,欢迎阅读我们的官方文档,以及下面的 v0.0.23 版本更新内容。\nJenkins 国内镜像中心发布后,收到了很多的反馈。鉴于之前的操作步骤相对较多,本次 Jenkins CLI 给出了一键启动国内镜像源的方案: 只要执行命令:jcli center mirror 即可启动镜像源。如果希望使用原有的地址,也非常简单:jcli center mirror --enable=false\n更多有意思的玩法,请参考 Jenkins 中文社区论坛。\n🚀 功能 支持创建插件 (#255) @LinuxSuRen 支持子 shell 命令 (#253) @LinuxSuRen 支持启用(或禁用)更新中心镜像源 (#251) @LinuxSuRen 增加以键值对的形式触发参数化流水线 (#249) @LinuxSuRen 支持停止最近一次的构建任务 (#248) @LinuxSuRen 支持命令多语言的描述 (#245) @LinuxSuRen 支持选择以及移除 Jenkins 连接配置项 (#246) @LinuxSuRen 支持命令行自动补全 (#242) @LinuxSuRen 支持下载特定版本的 Jenkins war (#240) @LinuxSuRen 支持配置诊断 (#169) @yJunS 支持从镜像中心下载插件 (#222) @LinuxSuRen 支持从镜像中心下载 Jenkins war (#221) @LinuxSuRen 支持从本地或者 URL 中加载 Jenkinsfile (#220) @LinuxSuRen 支持多种方式编辑流水线 (#206) @LinuxSuRen 支持安装指定版本的插件 (#211) @sbcd90 📝 文档完善 完善 README-zh.md (#241) @donhui 👻 维护 增加关于分支策略的检查清单 (#227) @LinuxSuRen 升级 go.uber.org/zap 从 1.12.0 到 1.13.0 (#237) @dependabot-preview 升级 gopkg.in/yaml.v2 从 2.2.4 到 2.2.5 (#225) @dependabot-preview 升级 github.com/onsi/ginkgo 从 1.10.2 到 1.10.3 (#218) @dependabot-preview 升级 github.com/onsi/gomega 从 1.7.0 到 1.7.1 (#217) @dependabot-preview 🚦 测试 增加流水线参数命令的单元测试 (#232) @LinuxSuRen 增加插件检查的单元测试 (#224) @LinuxSuRen 增加任务历史命令的单元测试 (#228) @LinuxSuRen ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "jenkins-cli.png" }, { "uri": "https://jenkins-zh.cn/meeting/2019-11-27/", "title": "", "type": "meeting", "date": "2019-11-27 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 论坛\n 邮箱没有配置好 更换域名(https://discourse.jenkins-zh.cn/t/topic/86/7)@yJunS 给管理更多的管理权限 把阿里云域名的权限给到管理员@linuxsuren 管理员招募 https://discourse.jenkins-zh.cn/t/topic/103 介绍 Jenkins 容器发行版\n https://github.com/LinuxSuRen/docker-zh Jenkins 发行版的定制 jenkins+2.190.3+localization-zh-cn+++ http://custom.jenkins-zh.cn?version=2.190.3\u0026amp;plugin=localization-zh-cn ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-22-plugin-docs-on-github/", "title": "Jenkins 插件文档即代码:将文档迁移到 GitHub", "type": "wechat", "date": "2019-11-22 00:00:00 +0000 UTC", "tags": ["hacktoberfest", "developer", "documentation", "wiki", "contributors"], "description": "Jenkins 插件开发者,将你的插件文档迁移到 GitHub 吧!", "content": " 在2019年9月,我们宣布了对 GitHub 作为 Jenkins 插件站点文档来源的支持。 感谢 Zbynek Konecny 和 Olivier Vernin 以及其他贡献者, 现在可以将插件文档直接存储在插件储存库中,而不是 Jenkins Wiki 中,对于插件维护者和 Jenkins 基础设施团队来说,这在过去是很难维护的。\n这篇博文可能对插件维护者和那些想为 Jenkins 文档做贡献的人来说很有趣。 我将描述如何将插件文档迁移到 GitHub 并获得如下页面:\n为什么? 通过使用插件的 GitHub 仓库存储文档, 插件维护者可以遵循 文档即代码 的方法,将文档更改作为 pull request 的一部分,这样就不会忘记文档的后续工作。 它还提供了一个 review 文档更改以及增加文档贡献者的认可度的机会,尤其是如果 story 与 Release Drafter 结合。\n不幸的是,在2019年9月之前,GitHub 文档的使用引起了一些问题。 首先,许多插件维护者已经将他们的文档迁移到 GitHub,这导致了文档的碎片化(Wiki、GitHub、jenkins.io)。 为了解决这个问题,插件维护者仍然需要使用重定向来维护存根 Wiki 页面, 用户不得不花一些时间来找出真正的文档在哪里。 通过支持 GitHub 作为文档来源,我们允许维护者逐步淘汰插件 Wiki 页面,同时改善用户体验。\n现在进行迁移还有更紧迫的原因…… 如果你订阅了开发者邮件列表, 你可能还看到了 R. Tyler Croy 关于 Jenkins Wiki 稳定性问题的声明, 并将其设置为只读,作为稳定实例的临时措施邮件列表主题。 虽然功能后来部分恢复了, 基础架构团队一致认为,我们应该逐渐转向替代解决方案。\n例子 自从9月份宣布以来,超过50个插件已经从 Wiki 迁移到 GitHub。 几个例子:\n 配置即代码插件 Mailer 插件 Gradle 插件 角色策略插件 如何为你的插件启用 GitHub 文档? 将文档从 Wiki 转换到 GitHub Asciidoc 或 Markdown 格式,如果你还没有做。 它可以用半自动的方式完成,请看这里的指南。 更改 pom.xml 中的 \u0026lt;url\u0026gt; 字段,使其指向 GitHub(指南)。 有效链接的例子: https://github.com/jenkinsci/mailer-plugin - 插件站点将使用 GitHub REST API 来提取 README https://github.com/jenkinsci/ssh-credentials-plugin/blob/master/doc/README.md - 从自定义位置提取插件页面 可选:添加徽章到页面,以改善外观和感觉,并为用户提供快速链接。 变更日志、聊天室、插件站点和安装量都有标准的徽章。 Markdown 例子 Asciidoc 例子 发布新的插件版本 等待几个小时,直到更改传播。 之后,Jenkins 插件站点将会展示来自 GitHub 的新文档。 下一步? 这个 story 被跟踪为 WEBSITE-406,它是使用 GitHub 作为 Jenkins 插件站点和更新管理器(WEBSITE-637)数据源的更广泛子项目的一部分。 后面的步骤包括支持显示来自 GitHub release 的变更日志,从 GitHub 中提取插件标签,显示插件 logo, 以及使用 Repository Permission Updater 作为维护者信息的来源。\n如何贡献? 10月是一个贡献的好机会! 插件文档是 Hacktoberfest 活动中的一个特色项目, 我们欢迎所有对文档和代码库的贡献。\n为文档做贡献 我们正在寻找有兴趣改进插件文档并帮助我们从 Wiki 迁移到 GitHub 的贡献者。 对于几十个插件来说,文档已经在 GitHub 中,欢迎你针对任何仓库提交 pull request。\n迁移文档:\n 迁移插件文档从 Wiki 到 GitHub 迁移文档从 Jenkins Wiki 到 jenkins.io 用于插件文档迁移的 issue 模板 [新手友好的文档任务]() 如果你有任何关于贡献文档的问题, 请查看这个页面或者在 Docs SIG Gitter 聊天室联系我们。\n贡献代码 您想用 Java 或 JavaScript 编写一些代码吗? 或者你愿意致力于 CSS 样式并改进 Jenkins 的设计吗? 在这种情况下,欢迎向 Jenkins 插件站点做贡献。 这是我们自己的插件市场实现,我们邀请对这个领域的贡献。 这个插件站点很容易开发。\n WEBSITE-637 - 用于插件站点以及 GitHub 集成的 Epic jenkins-infra/plugin-site - 前端 (JavaScript、React、XSS、YARN) jenkins-infra/plugin-site-api - 插件站点 API 和 Docker 包(Java、Maven、Docker) 有用的链接 插件文档 Jenkins 插件站点 ", "auhtor": "oleg_nenashev", "translator": "donhui", "original": "", "poster": "jenkins-plugin-docs-to-github.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-20-jenkins-cli-help-you-manage-jenkins/", "title": "Jenkins CLI,助你轻松管理 Jenkins", "type": "wechat", "date": "2019-11-20 00:00:00 +0000 UTC", "tags": [], "description": "无论你是插件开发者,还是管理员或者只是一个普通的 Jenkins 用户,Jenkins CLI 都是为你而生!", "content": " Jenkins CLI,简称 jcli,一个使用 Golang 开发的开源的 Jenkins 命令行工具。 它可以帮忙你轻松地管理 Jenkins。 无论你是 Jenkins 插件开发者,还是 Jenkins 管理员或者只是一个普通的 Jenkins 用户,它都是为你而生!\nJenkins CLI 功能简介 从2019年6月份第一个 git commit 算起,经过不断迭代,截止目前 Jenkins CLI 已经对外发布了18个版本,下载量超过2000,功能也日益增多。 目前主要功能列表如下所示: * 支持多 Jenkins 实例管理 * 插件管理(查看列表、搜索、安装、上传) * 任务管理(搜索、构建触发、日志查看) * 在浏览器中打开你的 Jenkins * 重启你的 Jenkins * 支持通过代理连接\n此外,优秀的开源项目应该有着高代码质量。Jenkins CLI 始终坚持内建质量的原则,在开发过程中持续编写单元测试代码,并使用 TravisCI + SonarCloud 对代码质量持续分析,从而保证代码质量。 目前测试覆盖率为81.8%,下一个目标是将测试覆盖率提升到90%。 Go Report Card 给 Jenkins CLI 的代码质量评分为 A+。\n如何安装 Jenkins CLI? Jenkins CLI 目前支持的操作系统有:MacOS、Linux 以及 Windows。\n在 Mac 上安装 在 Mac 上可以通过 brew 来安装 jcli:\nbrew tap jenkins-zh/jcli brew install jcli 在 Linux 上安装 要在 Linux 操作系统上安装 jcli 的话,非常简单。 只需要执行下面的命令即可:\ncurl -L https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz|tar xzv sudo mv jcli /usr/local/bin/ 在 Windows 上安装 你只要点击这里就可以下载到最新版本的压缩包。然后,把解压后的文件 jcli 拷贝到你的系统目录下即可。\n其他包管理器 还可以使用一些其他的包管理器安装 jcli: * GoFish 的用户可以使用命令 gofish install jcli 来安装 * Scoop 的用户可以使用命令 scoop install jcli 来安装\nGoFish 同时支持 Linux 和 Windows,Scoop 支持 Windows。\n使用入门 安装 jcli 后,你需要提供一份配置文件。请执行命令 jcli config generate,该命令会帮助你编辑配置文件 ~/.jenkins-cli.yaml,你需要根据实际的 Jenkins 配置情况做相应的修改。\n配置文件准备好后,便可以进行一些实际操作了。 下面举几个插件管理和任务管理的例子作为说明。\n插件管理 使用 jcli 搜索插件:\njcli plugin search zh-cn 使用 jcli 下载插件,如果该插件有相关依赖插件的话,会同时下载依赖插件:\njcli plugin downlaod localization-zh-cn 使用 jcli 安装插件:\njcli plugin install localization-zh-cn 任务管理 使用 jcli 触发构建:\njcli job build pipeline-01 使用 jcli 查看构建日志,如果任务正在运行,它会实时监听日志输出,否则输出最近一次构建日志:\njcli job log pipeline-01 更多命令请查看帮助 限于篇幅原因,更多使用说明不做一一介绍,请查看帮助命令:\njcli --help jcli \u0026lt;command\u0026gt; --help jcli \u0026lt;command\u0026gt; \u0026lt;subcommand\u0026gt; --help 也可以查看官方文档: - https://github.com/jenkins-zh/jenkins-cli/blob/master/doc/README.md - https://jenkins-zh.github.io/jcli-docs/\n如果你有意愿使用 Jenkins CLI,那么赶快动手来体验吧!\n新功能路线图 Jenkins CLI 仍旧在不断发展中。 挑选了几个计划中的新功能,列表如下: - 支持自我升级 - 支持列出所有 agent 节点 - 支持更新所有插件 - 支持展示插件趋势\n如果你有希望开发的新功能,请提交 issue 到 GitHub 仓库。\n欢迎反馈与贡献 如果你在使用过程中遇到问题,欢迎在 GitHub 仓库提交 issue 来反馈; 同时,我们也非常欢迎贡献者对 Jenkins CLI 贡献自己的一份力量。 目前除了国内的主要贡献者: - LinuxSuRen - yJunS\n还有来自其他国家或地区的贡献者为 Jenkins CLI 做出过贡献,他们是: - zirmax - scottydocs - sbcd90 - oleg-nenashev\n无论是小到一个错别字的修改,大到一个新的功能的开发,或者是在使用过程中提交 issue 反馈,它们对 Jenkins CLI 发展而言都有着重要的意义。\nJenkins CLI 期待你的投票 2019 年的中国开源界,开源项目的数量也在激增。 作为中国开源界的一份子,此时此刻,Jenkins CLI 正在参加由 OSCHINA(开源中国)主办的2019年度最受欢迎中国开源软件评选活动。\n恳请占用你的一点宝贵时间,麻烦动动手指为 Jenkins CLI 投上支持的一票,不胜感激!\n投票方式:长按图片,识别图中二维码,打开投票活动页面,找到开发工具类--\u0026gt;Jenkins CLI,点击投票,再次感谢支持 Jenkins CLI !\n", "auhtor": "donhui", "translator": "", "original": "", "poster": "jenkins-cli.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-18-integration-of-c-stat-code-analysis-with-automated-jenkins-ci-build/", "title": "Jenkins CI 自动构建与 C-STAT 代码分析的集成", "type": "wechat", "date": "2019-11-18 00:00:00 +0000 UTC", "tags": ["C-STAT", "Jenkins CI"], "description": "了解如何通过与 Jenkins 集成来进一步进行静态代码分析,并且提供清晰的分析结果和生产静态的 HTML 报告。", "content": " 介绍 我们大多数人都知道,为嵌入式软件设置 CI/CD 总是有局限性或挑战性的,并且我们还看到在某些情况下仍然没有其他可用的选择,这会导致工作量加大和代码质量缺失。\n在本文中,我们将看到一个这样的嵌入式开发工具(IAR 嵌入式工作台),以及如何将 C-STAT 静态代码分析与持续集成版本 Jenkins 集成在一起,以及如何通过自动构建。\n先决条件: a. IAR 嵌入式工作台 IDE b. C-STAT 许可证 c. Jenkins 安装\nIAR 嵌入式工作台工具为我们提供了命令行执行选项,以实现 IAR 项目的静态代码分析。现在,我们将了解其工作原理。\nIAR 命令行应用程序 IAR 系统为我们提供了一个名为 IarBuild.exe 的应用程序,该应用程序用于在命令行中执行分析。您可以在安装路径中找到 IarBuild.exe 应用程序,如下所示。\nC:\\Program Files (x86) \\IAR Systems\\Embedded Workbench 8.1\\common\\bin\\ 运行代码分析: 首先切换到命令路径中的上述路径,然后执行以下命令来分析整个项目。\nIarBuild.exe D:\\sample\\project\\setup\\sample.ewp -cstat_analyze Debug D:\\sample\\project\\setup\\sample.ewp 是您的 IAR 项目文件路径 -cstat_analyze 是要执行分析的命令 设置项目模式为 Debug 通过执行上述命令,它将对整个项目执行静态代码分析,并且结果将存储在 cproject.db 文件中,位于路径 ...project\\setup\\Debug\\Obj\\ 下。\n注意下次运行代码分析时,如果自上次分析以来对源代码文件进行了任何更改,则必须首先清除数据库,以避免由于数据库文件中的新旧数据混合而引起的问题。\n清晰的分析结果 要使用命令行清除数据库文件,请执行以下命令,\nIarBuild.exe D:\\sample\\project\\setup\\sample.ewp -cstat_clean Debug 生成报告 要生成报告,我们可以使用 IAR 提供的 IREPORT 工具,您可以在同一安装目录中找到该工具。IREPORT 工具用于生成 C-STAT 执行的先前代码分析的 HTML 报告。\n该报告以数字和表格形式展示统计数据。可以生成两种不同类型的报告:\n 具有相关信息的大纲,例如有关在项目范围内启用的检查、消息总数、已取消的检查(如果有)、每个检查的消息等信息。 完整的报告,其中包含诸如轮廓之类的常量信息,以及在报告结束时有关所有已抑制和未抑制消息的其他信息。表格可以折叠和展开,列可以排序 要生成完整的 HTML 报告,我们可以执行以下命令,\nireport.exe --db D:\\sample\\project\\setup\\Debug\\Obj\\cstat.db --project D:\\sample\\project \\setup\\sample.ewp --full --output D:\\sample\\result.html 上面的命令包含四个参数:\n--db 指定报告所基于的数据库文件的路径。 --project 指定项目文件。 --full 生成完整报告,其中包含有关禁止检查和非禁止检查的信息。 --output 指定输出结果文件的名称。\n将 C-STAT 与 Jenkins CI 构建集成: 没有直接的插件或方法可用于将此 CSTAT 集成到任何 CI 工具。但是我们可以通过以下方法实现自定义集成。\n现在我们知道了用于分析、清理、生成报告文件的命令。使用这些命令,我们可以轻松地编写批处理脚本文件 (.bat) 文件,然后在 Jenkins 中调用此批处理文件,作为预构建命令执行步骤。\n设置阈值网关 我们将遇到需要通过设置“低”、“中”、和“高”问题的阈值在 CI 构建中定义网关的场景。如果该值大于设定值,则可以使构建失败。\n默认情况下,C-STAT 不向我们提供设置此值的选项。但是我们可以使用以下自定义脚本来实现此目的。\n我们可以获得包含低、中、高问题计数分析结果的 HTML 报告。这些值以格式 data: [0-9, 0-9 ,0-9] 在 HTML 结果文件中展现。\n请参阅下面的脚本,了解我是如何在一个变量中获取这些值,然后用 sea t 阈值进行验证。\nJenkins 构建结果 下面是 Jenkins CI 构建日志,供您参考。您可以看到由于标识为“中优先级”的 19 个问题而导致构建失败。\n结论 经过上面的分析,我们已经了解了如何使用 Jenkins CI 构建自动化 C-STAT 分析,以及如何设置阈值网关来确定构建状态。我希望此博客对那些使用 IAR 嵌入式工作台并希望使用您的 CI 构建系统自动执行 C-STAT 的人有所帮助。\n", "auhtor": "Sankara M", "translator": "wenjunzhangp", "original": "https://dzone.com/articles/integration-of-c-stat-code-analysis-with-automated", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-15-using-jenkins-x-updatebot/", "title": "了解如何使用 Jenkins-X UpdateBot", "type": "wechat", "date": "2019-11-15 00:00:00 +0000 UTC", "tags": ["Jenkins-X", "UpdateBot"], "description": "了解如何使用 Jenkins-X UpdateBot 自动执行对依赖版本的更新。", "content": " Jenkins-X UpdateBot 是用于在项目源代码中自动更新依赖项版本的工具。假设您正在构建两个项目 A 和 B,B 使用 A 作为依赖项。A 的发布过程可以使用 UpdateBot 更新项目 B 的源,以使用 A 的新版本。在 pull request 中使用 UpdateBot,可以测试和检查更改或自动合并更改。\n在 Jenkins-X platform 中,UpdateBot 由 Jenkinsfile 中的 UpdateBot 命令自动显示和调用。但是 UpdateBot 也可以在 Jenkins-X 之外使用,并且单独运行它可以帮助了解它可以做什么并测试版本替换。因此,让我们用一个简单的测试项目来尝试一下。\n配置演示 UpdateBot 可以为各种不同的文件类型设置版本-我们不会在这里对它们进行全部测试,但是我们希望一个项目具有多个功能。因此,我们可以使用 JHipster sample app 示例应用程序,因为它具有 Maven pom.xml,npm package.json 和 Dockerfile。我们将对其运行 UpdateBot,以查看 UpdateBot 可以替换这些资源文件中哪些内容。\n我们可以下载 UpdateBot jar file(v1.1.31),并为要更新的项目设置指向 GitHub 存储库的简单 UpdateBot 配置文件:\ngithub: organisations: - name: ryandawsonuk repositories: - name: jhipster-sample-app useSinglePullRequest: true useSinglePullRequest 标记意味着将创建一个包含我们所做的所有更改的 PR。但是我们实际上并不会进行任何更改-我们将在本地运行它,这样我们就不需要 GitHub 对存储库的写权限。通过设置环境变量,我们可以在不推送到 GitHub 的情况下运行:\nexport UPDATEBOT_DRY_RUN=true 然后,我们仍然需要使用 UPDATEBOT_GITHUB_USER 和 UPDATEBOT_GITHUB_PASSWORD(Token)的其他环境变量设置 git 凭据。\n然后,我们可以运行一些 UpdateBot 命令,并查看从 Git 克隆的项目中替换了什么。为此,我们可以在 GitHub 上使用一个包含预配置脚本的演示项目。\n运行演示 首先,脚本更新了 maven pom.xml,要求更改 Spring Boot 版本:\njava -jar updatebot-1.1.31.jar push-version --kind maven org.springframework.boot:spring-boot-starter-data-jpa 2.1.0.RELEASE 然后检查更改并输出 git diff,我们可以看到以下结果: 因此版本被替换了。请注意,在依赖项引用的属性中将其替换,在这种情况下,pom.xml 在属性中具有此版本。UpdateBot 还可以用于直接在依赖项或父项或插件中进行的更改。\n对 package.json 的更改是将 ngx-cookie 版本更改为 2.0.2:\njava -jar updatebot-1.1.31.jar push-version --kind npm ngx-cookie 2.0.2 这正是我们所期望的: 对 Dockerfile 的更改是将 openjdk 版本/标签更改为 jdk8:\njava -jar updatebot-1.1.31.jar push-version --kind docker openjdk 8-jdk 这表明我们可以抓取出来。Dockerfile 实际上使用两个不同的 openjdk 镜像,每个镜像都有一个不同的标签,并且此命令将替换这两个镜像: 我在运行命令之前没有考虑过这一点,因此在这里我需要确定我真正要替换的内容。\n实际运行 如果我们在没有 dry-run 标记的情况下运行,则将创建一个真实的 pull request,前提是我们有权创建它。\nUpdateBot 具有自动合并 pull request 的功能,例如通过轮询 GitHub 来检查 PR 状态并合并是否一切正常(命令为updatebot update-loop)。但是,GitHub 确实对这些请求进行了速率限制,因此 UpdateBot 也可以将其批准添加到 PR 中,以使其通过与 GitHub 直接集成的工具进行合并。当使用诸如 prow 或 mergify 之类的工具进行自动合并时,这可能会很好地工作。\nUpdateBot 可以尝试仅通过使用 updatebot push 而不是带有显式参数的 updatebot push-version 来推断要作为提交触发管道的一部分进行的更改。但是,通常管道作业将有权访问要推送的版本,而 push version 使更改更明确且更易于跟踪。\n本示例使用单个 UpdateBot YAML 文件将一组依赖项/版本推送到一个下游项目。YAML 文件还支持将一组更改推送到多个下游存储库。UpdateBot 推送其能够进行的所有替换,以便每个下游存储库都获得适用于它的所有更改。\n例如,在构建没有快照的 Maven 项目时,UpdateBot 可用于在 CI/CD 设置中传播版本。但是,正如我们已经看到的那样,它不仅限于 Maven,而且可以对产生各种不同类型制品的项目进行一系列更改。\n", "auhtor": "Ryan Dawson", "translator": "wenjunzhangp", "original": "https://dzone.com/articles/using-jenkins-x-updatebot", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-14-gsoc-phase-1-updates-on-working-hours-plugin/", "title": "Working Hours 插件的第一阶段更新", "type": "wechat", "date": "2019-11-14 00:00:00 +0000 UTC", "tags": ["react plugins gsoc gsoc2019"], "description": "实现了 Working Hours Plugin 和 React 集成,提供更加好用的排除日期和时间范围选择器", "content": " Working Hour Plugin 提供了一个界面,用于设置允许的构建日期和时间。在配置 Working Hour 之外运行的作业将保留到下一个允许的构建时间为止。\n在 Google Summer of Code 的第一个代码阶段,我一直在从事 Working Hours Project 项目,该项目还有待于改善可用性。\n当我们想设计一个具有大量可以使用自定义库的 UI 时,React 似乎比经典的 Jelly 页面更受青睐,尤其是日期选择器之类的开源组件。\n但是,我们目前正致力于将 React 和 Jenkins 集成在一起,这是一个挑战。\n第一阶段的成就 在第一个代码阶段,我们专注于 UI 改进,我们取得了以下主要改进: * 一个独立的 Web 应用程序,可以将其集成。 * 滑块,用于选择时间范围。 * 设置排除日期时间的更多字段。 * 用于选择排除日期的预设。 * Jenkins 样式界面\n我们如何将 React 集成到 Jenkins 中 可以在这里找到集成的解决方案文档\n最初,我们发现 BlueOcean 是在 Jenkins 中使用 React 的一个很好的例子,但是对于使用插件进行通用开发来说,它并不是一个好的选择。因此,我们需要找到另一种集成方式。\n这是进行集成的步骤: * 在你 jelly 文件中的挂载点,通常是具有唯一 ID 的元素。 * 编写您的 React Application,但需要将安装点设置为您在上面设置的 ID。 * 将构建后的插件复制到 webapp 目录。 * 在你的 jelly 文件中,使用 script 标签引入\n\u0026lt;script type=\u0026quot;text/javascript\u0026quot; src=\u0026quot;${resURL}/plugin/working-hours/js/main.js\u0026quot;\u0026gt;\u0026lt;/script\u0026gt; 使用 React 之后,传统的请求将不再可用,处理请求的另一种方法是使用 stapler。您可以定义如下的过程函数[source, java] public HttpResponse doDynamic(StaplerRequest request) { if (config == null) { config = ExtensionList.lookup(WorkingHoursPlugin.class).get(0); } String restOfPath = request.getRestOfPath(); String[] pathTokens = restOfPath.split(\u0026quot;/\u0026quot;); List\u0026lt;String\u0026gt; params = new ArrayList\u0026lt;\u0026gt;(); switch (params.get(0)) { case \u0026quot;list-excluded-dates\u0026quot;: return listExcludedDate(request); case \u0026quot;set-excluded-dates\u0026quot;: return setExcludedDates(request); case \u0026quot;list-time-ranges\u0026quot;: return listTimeRanges(request); case \u0026quot;set-time-ranges\u0026quot;: return setTimeRanges(request); } } 运行我们的应用程序 如果您想看一下我们的插件,可以查看 working-hours-plugin 的仓库。 只需阅读 README 文件,即可运行 working-hours-plugin 的副本。\n截图 当前的插件外观有点简单,插件使用起来有些不便。 比如说如果我们要输入排除的日期,它将是一个恒定格式的字符串,例如 15/9/2019,但是新的用户界面选择了 React,因此我们可以使用日期选择器进行改进。\n当前插件 新版时间范围选择器 新版排除日期 帮助链接 如果您有任何疑问或建议,我们很高兴收到您的来信。 下面列出了几个有用的链接: * Develop Repo * Main Repo * Design Doc * Doc for React Integration Solution * Gitter Chat * Slides for Phase 1 Demo * Video Recording for Phase 1\n", "auhtor": "Jack Shen", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2019/07/09/Phase1-Updates-On-Working-Hours-Plugin/", "poster": "cover.jpg" }, { "uri": "https://jenkins-zh.cn/meeting/2019-11-13/", "title": "", "type": "meeting", "date": "2019-11-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 论坛\n 管理员招募? 如何管理 国内实名验证的问题(如何保证每个人都有手机号信息) Jenkins 相关资源下载很慢,包括:容器镜像、deb 镜像源、插件等\n https://github.com/jenkins-zh/mirror-adapter ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-13-a-thanks-letter/", "title": "致霍格沃兹测试学院的一封感谢信", "type": "wechat", "date": "2019-11-13 00:00:00 +0000 UTC", "tags": [], "description": "社区大于代码,不满意就提 PR", "content": "Jenkins 虽然有着无数潜在的用户群体,但是,在国内直接参与社区的人却寥寥无几,甚至, 都没有一个集中沟通交流的场所。这是非常令人困惑不解的一点,毕竟 Jenkins 已经诞生15年之久, 这比许多人的职业生涯都要长。\n为了改善 Jenkins 在国内的使用体验,给大家一个可以集中讨论相关问的场所,Jenkins 中文社区 在一年前成立了。我们从一开始的双周例会(公开讨论社区发展相关的话题),增加了单周技术交流会 (分享交流持续交付相关的经验)。创建了一个零广告、零闲聊的技术交流微信群,目前有410+成员(有愿意 担任群2管理员的,可以与我们取得联系)。这都要感谢新老志愿者的无私贡献,不管是技术文章的翻译, 还是 issue、PR 或者代码、文档,甚至只是一个小小的建议,社区正因为有你们的存在而变得更好。 为了表示对他们的感谢和鼓励,给予贡献者一些小小的激励, 包括:图书、大会免费门票等等。这要感谢人民邮电出版社等对我们长期的大力支持。\n我们今天尤其想要表示感谢的是——下面给予 Jenkins 中文社区现金10000元捐赠的企业。\n霍格沃兹测试学院是中国领先的测试开发技术在线教育机构, 由知名测试社区 TesterHome 与测吧(北京)科技有限公司合作创办,专注于高级测试人才的培养。\n对我们而言,并没有业内专家的驻场,背后也没有大厂的光环,全部是草根个人在努力奉献自己的力量。但是,我们深深地 理解开源的意义所在,开源并不是走秀,并不是只有大佬可以玩。任何一个不只是流于口舌的同学都是社区里的主人, 不满意就提 PR,这就是开源社区所需要的人才。社区大于代码,开源不只是把代码扔到 GitHub 上就可以了。我相信, 霍格沃兹测试学院也正是出于 Jenkins 中文社区下面的行为准则才愿意支持我们的:\n 治理开源 公开例会 公开会议记录(文字、视频) 公开奖励 公开支出 活动开源 公开讨论如何组织活动 代码开源 https://github.com/jenkins-zh 文档开源 设计文档 教程 我们会把得到捐赠的资金用于社区基础设施的建设,带给更多关注 Jenkins、关注 DevOps、关注开源的同学们。资金去向请访问下面的地址:\nhttps://jenkins-zh.cn/about/sponsors-list/\n最后,我们由衷地希望霍格沃兹测试学院和开源事业发展的越来越好,得到更多人和组织的关注和支持。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "open-source.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-12-2019-jenkins-board-and-officer-elections-update/", "title": "Jenkins 2019 年 Board 和 Officer positions 选举更新", "type": "wechat", "date": "2019-11-12 00:00:00 +0000 UTC", "tags": ["community", "governance", "elections"], "description": "Jenkins 社区正在进行 2019 年 Board 和 Officer positions 的选举活动,我们诚恳的邀请您参加并且投出您宝贵的一票。", "content": " Jenkins 社区正在进行 2019 年 Board 和 Officer positions 的选举。提名征集已经结束。我们征集到了很多提名。根据愿意接受提名的人和无可争议的 Officer Positions,我们将有 3 票:\n 投票选举 3 名board members 投票选举 Jenkins security officer 投票选举 Jenkins events officer 候选人 每位候选人都提供了一份声明,以帮助指导选民为什么要为候选人投票。有关更多详细信息,请参阅候选人宣言。竞选 board members 的候选人为:\n Alex Earl Oliver Gondza Ullrich Hafner Oleg Nenashev Mark Waite 赵晓杰(Rick) 竞选 security officer 的候选人是:\n Daniel Beck Wadeck Follonier 竞选 events officer 的候选人是:\n Alyssa Tong 赵晓杰(Rick) 选民登记 这是近一段时间以来我们第一次进行 Jenkins 选举。我们正在学习。Jenkins 选举旨在实现包容性。我们不仅将选举限于代码提交者。在 2019 年 9 月 1 日之前注册了 Jenkins 帐户的任何人都有资格投票。Jenkins 是一个成功的项目,大约有 10 万个符合该标准的帐户。我们正在与符合条件的选民联系,并要求他们明确 选择性加入 以参加投票。\n如果符合条件,您将在注册的 jenkins.io 电子邮件地址中收到一封电子邮件。该邮件来自 elections@jenkins.io,标题为 2019 Jenkins Election - Invitation to Participate。该电子邮件将提供选举详细信息,并包含一个 I want to participate 按钮。\n投票确认 点击链接后,您将看到一个确认屏幕,如下所示:\n如果您在 2019 年 11 月 14 日之前仍未收到电子邮件,或者在投票时遇到任何问题,请对 Jenkins Election 2019 Jira issue 问题发表评论。\n表决 投票将于 2019 年 11 月 11 日正式开始。候选人将收到 Kohsuke Kawaguchi 发送的 Condorcet 互联网投票电子邮件。每次投票将发送一封电子邮件(因此,总共 3 票:board 1 票,events officer 1 票,security officer 1 票)。投票将要求使用以下截图对候选人进行排名:\n选举日期 以下是关键选举日期的摘要:\n Date Event Now Voter registration ongoing Nov 11, 2019 Voting begins Nov 17, 2019 Voter registration closes Nov 24, 2019 Voting closes a 5:00 PM Pacific Time Dec 3, 2019 New representatives announced 选举结果将发布到 Jenkins 开发人员的邮件列表中,然后在 jenkins.io 上发布公告博客。\n如果对建议的日期有任何延迟,我们将尽快通知您。非常感谢所有向我们的社区展示 Jenkins 服务精神的候选人。我们鼓励所有人注册投票并参与 Jenkins 社区。\n无可争议的职位 当一个 officer position 只有一个愿意接受提名的候选人时,没有理由对该职位进行投票。该人将成为该职位的唯一候选人。\n毫无争议的 Officer Positions 包括:\n Name Role Olivier Vernin Infrastructure Officer Oliver Gondza Release Officer Mark Waite Documentation Officer 参考文献 Jenkins Governance Board Jenkins Board Election Process Jenkins Officers Announcement in the developer mailing list 2019 elections proposal in the developer mailing list ", "auhtor": "Tracy Miranda", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2019/11/08/board-elections/", "poster": "cover.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-11-update-center-mirror-announcement/", "title": "Jenkins 插件中心国内镜像源发布", "type": "wechat", "date": "2019-11-11 00:00:00 +0000 UTC", "tags": [], "description": "忍受不了官方站点下载速度的速速看过来", "content": "Jenkins 社区的网络基础设施都是架设在国外的服务器上,而且,并没有在国内有 CDN 或者负载均衡的配置。 对所有的 Jenkins 用户而言,1500+的插件可以帮助他们解决很多问题。然而,我相信,对于国内的很多用户来说, 可能有过一些不太愉快的经历——插件下载速度很慢,甚至会超时。难道遇到这种情况下,我们就只能等吗?\n程序员,作为天生懒惰的人,总是希望能通过手中的键盘来解决各种各样的问题。凭什么?下载一个插件, 我还的苦苦地等待来自美国的数据包呢?数数你手里的 Jenkins 都安装了多少个插件。30个算少的吧。 经过一番搜索,发现果然已经有前人帮忙把大树种好了。让我们一起感谢“清华大学开源软件镜像站”提供的镜像服务:\nhttps://mirrors.tuna.tsinghua.edu.cn/jenkins/\n但是,当我兴冲冲地把 Jenkins 插件管理页面的更新中心的地址修改后,却发现了一个奇怪的情况,好像还是那么慢啊。 不管是换地址,还是换4G,换电脑都解决不了这个网络排队的问题。本着开源的精神(不满意就提 issue 或者 Pull Request), 我只好继续挖掘这里的秘密。下面,是我向 TUNA 提的一个 issue(可以看到貌似我并不是第一个吐槽的人):\nhttps://github.com/tuna/issues/issues/659\n是的,rsync 可以帮我们把106G的文件同步过来,免去了出国下载插件的麻烦,可没有解决最后一公里的痛。\n通过下面的 PR 我们可以大致了解到,Jenkins 是通过解析 update-center.json 文件的方式来获取插件版本, 以及下载插件的。另外,如果你认为只是修改下文件里的 URL 就能解决这个问题的话,那么,请再仔细想一下这个事情。 既然小白兔可以把地址修改为一个比较方便的值,那么,大灰狼为啥不能往那些插件里加点辣椒水呢。 Jenkins 作为一个在 CI/CD 领域里领先了15年之久的大叔,当然不会输给了一些小毛贼。简单来说呢,这个事情 是通过两把钥匙来解决的——官方用其中一把钥匙给文件做了签名,并保管起来;把另外一把钥匙对外公布(保存在发行版中)。 只有通过了公钥验证的 update-center.json 文件,才会被使用到。\nhttps://github.com/jenkins-infra/update-center2/pull/245\n知道了问题所在,解决起来自然就容易了。Jenkins 中文社区帮大家把钥匙和地址的问题解决了,按图索骥三步走:\n想了解技术细节?担心我们是大灰狼?我们欢迎喜欢学习的同学,更欢迎人民大众的检阅。 提问题,提需求,提代码,提文档,都是可以的。实际上,我们的整套方案中,所有的部分(除了拿一把钥匙以外) 都是开源的,包括还不够完善的设计文档。而且,并不需要花一分钱,完全利用现有的计算、存储资源。 此处,让我们再次感谢清华开源镜像站点、GitHub Actions、码云 Page 等。\nhttps://github.com/jenkins-zh/mirror-adapter\n最重要的事情,一定要在最后才说出来(不喜欢认真阅读文档的同学,对不起了)。想要体验极速 安装插件的同学,请认准 Jenkins 简体中文插件的版本:1.0.10\nhttps://plugins.jenkins.io/localization-zh-cn\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "flash.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-08-remoting-over-apache-kafka-plugin-with-kafka-launcher-in-kubernetes/", "title": "在 Kubernetes 中通过 Apache Kafka 插件远程处理 Kafka 启动程序", "type": "wechat", "date": "2019-11-08 00:00:00 +0000 UTC", "tags": ["kafka kubernetes helm"], "description": "在 Kubernetes 中通过 Apache Kafka 插件远程处理 Kafka 启动程序", "content": " 我是越南 FPT 大学的 Long Nguyen ,我的 Google Summer of Code 2019 项目是 Remoting over Apache Kafka with Kubernetes features 。这是我第一次为 Jenkins 做贡献,我非常兴奋地宣布在第一阶段已经完成的功能。\n项目介绍 当前版本的 Remoting over Apache Kafka plugin 远程处理需要用户手动配置整个系统,包括 zookeeper 、 kafka 和远程处理代理。它也不支持动态代理配置,因此很难实现具有伸缩性的扩展。我的项目旨在解决两个问题: 1. 提供 Apache-Kafka 集群的现成解决方案。 2. Kubernetes 集群中的动态代理配置。\n当前状态 支持凭据的 Kubernetes 连接器。 Kubernetes 功能中的 ApacheKafka 预配功能已完全实现。 Helm chart 部分实现。 Kubernetes 中的 Apache-Kafka 配置 此功能是 2.0 版本的一部分,因此尚未正式发布。您可以通过使用 Experimental Update Center 更新到 2.0.0-alpha 版本或直接从 master 分支构建来尝试该功能:\ngit clone https://github.com/jenkinsci/remoting-kafka-plugin.git cd remoting-kafka-plugin/plugin mvn hpi:run 在全局配置页面上,用户可以输入 Kubernetes 服务器信息和凭据。然后他们只需点击一个按钮就可以启动 ApacheKafka 。\n当用户点击 Start Kafka on Kubernetes 按钮时, Jenkins 将根据信息创建一个 Kubernetes 客户机,然后从 resources 中应用 zookeeper 和 kafka yaml 规范文件。\nHelm Chart Apache-Kafka 插件上远程处理的 Helm 图表基于 stable/jenkins 图表和 incubator/kafka 图表。截至目前,该图表仍在开发中,因为它仍在等待第 2 阶段的 Cloud API 实现。但是,您可以使用一个独立的远程 Kafka 代理查看演示图表:\ngit clone -b demo-helm-phase-1 https://github.com/longngn/remoting-kafka-plugin.git cd remoting-kafka-plugin K8S_NODE=\u0026lt;your Kubernetes node IP\u0026gt; ./helm/jenkins-remoting-kafka/do.sh start 命令 do.sh start 将执行以下步骤: * 安装图表(与 Jenkins 和 Kafka 一起使用)。 * 通过应用下面的 JCasC 在 Jenkins master 上启动一台 Kafka 计算机。\njenkins: nodes: - permanent: name: \u0026quot;test\u0026quot; remoteFS: \u0026quot;/home/jenkins\u0026quot; launcher: kafka: {} 启动单个 Remoting Kafka Agent pod 。 您可以通过运行 kubectl 来检查图表状态,例如: ``` $ kubectl get all -n demo-helm NAME READY STATUS RESTARTS AGE pod/demo-jenkins-998bcdfd4-tjmjs 2\u0026frasl;2 Running 0 6m30s pod/demo-jenkins-remoting-kafka-agent 1\u0026frasl;1 Running 0 4m10s pod/demo-kafka-0 1\u0026frasl;1 Running 0 6m30s pod/demo-zookeeper-0 1\u0026frasl;1 Running 0 6m30s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/demo-0-external NodePort 10.106.254.187 19092:31090/TCP 6m30s service/demo-jenkins NodePort 10.101.84.33 8080:31465/TCP 6m31s service/demo-jenkins-agent ClusterIP 10.97.169.65 50000/TCP 6m31s service/demo-kafka ClusterIP 10.106.248.10 9092/TCP 6m30s service/demo-kafka-headless ClusterIP None 9092/TCP 6m30s service/demo-zookeeper ClusterIP 10.109.222.63 2181/TCP 6m30s service/demo-zookeeper-headless ClusterIP None 2181/TCP,3888/TCP,2888/TCP 6m31s\nNAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/demo-jenkins 1\u0026frasl;1 1 1 6m30s\nNAME DESIRED CURRENT READY AGE replicaset.apps/demo-jenkins-998bcdfd4 1 1 1 6m30s\nNAME READY AGE statefulset.apps/demo-kafka 1\u0026frasl;1 6m30s statefulset.apps/demo-zookeeper 1\u0026frasl;1 6m30s ```\n下一阶段计划 实施 Cloud API 来配置 Remoting Kafka Agent 。(JENKINS-57668) 将 Cloud API 实施与 Helm 图表集成。(JENKINS-58288) 单元测试和集成测试。 发布版本 2.0 和地址反馈。(JENKINS-58289) 链接 第一阶段演示视频 第一阶段演示幻灯片 Remoting over Apache Kafka plugin 项目页面 Gitter Channel ", "auhtor": "Long Nguyen", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2019/07/11/remoting-kafka-kubernetes-phase-1/", "poster": "“./2019-11-08-remoting-over-apache-kafka-plugin-with-kafka-launcher-in-kubernetes/cover.jpg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-06-building-new-operating-model-devops/", "title": "为 DevOps 构建新的运营模型", "type": "wechat", "date": "2019-11-06 00:00:00 +0000 UTC", "tags": ["DevOps", "运营转型"], "description": "为 DevOps 构建新的运营模型", "content": " 我一直在撰写有关企业面临的 DevOps 挑战的文章。从根本上讲,它是关于规模的:当企业尝试将其扩展到大型企业通常拥有的 800 多个应用程序中时,它们正努力实现在小型 DevOps 概念验证中看到的相同收益。 如果 DevOps 能够兑现其诺言并为企业带来可观的价值,那么就必须克服这一规模挑战。\n重塑业务 今天,我想看看企业内部的关键变化,在实现 DevOps 的好处之前,这绝对是必须发生的:运营转型。\n如今,大多数企业都围绕具有单向命令和控制结构的分层模型工作。这是自去年以来建立企业的方式:公司高层的“高级主管”领导层以相当专制的方式设定了公司的目标和战略。在此模型中,经理和业务部门负责人是高级管理人员意愿的执行者,以确保公司其他所有人都可以执行其战略方向。DevOps 的发展方向相反-从开发人员和运营人员的基层运动开始,然后逐步发展到如今在董事会席位上占有一席之地。\n民主发展 为了使 DevOps 大规模发展,需要用更加有机、松散和自治的东西来代替这种结构。如果旧模式是专制的,那么新模式与现代政治革命家在松散连接和组织上“扁平”的结构中融合的方式有更多的共同点。\nDevOps 的理想运营模式是一种权力民主化的模式,并且公司中的每个人都有权发挥自己的领导作用。在这里,高级主管确定了出行的方向,但是然后相信他们熟练的开发人员会做些必要的事情。在这种模式下,管理者促进和授权,而不是直接参与;确保开发人员拥有实现目标所需的一切,同时在这里和那里轻轻地推动,以确保他们的工作与整体公司议程和战略路线图保持一致。这涉及到我们在流动的劳动力中看到的宏观变化,并逐渐过渡到非中介的世界。\n毋庸置疑,进行这种转换并不容易。这意味着要颠覆数百年来公认的惯例,放弃某些人认为晋升和任期使他们有权获得的精细控制。而且要明确一点:IT 部门将首当其冲。长期以来,控制权的守卫者需要转变为促进者。IT 将围绕应用程序开发设置指南和策略,并在需要时进行干预,但在日常工作中,IT 部门将需要退后一步,让 DevOps 开发人员继续前进,然后一定会建立信任和真正创新的文化,并蓬勃发展。\n让专家掌控 开发人员团队比公司中的其他任何人都更了解他们的业务所面临的软件工程挑战。他们是理想的解决方案,同时敏捷的 DevOps 流程将帮助他们做到这一点。但是,如果开发人员大规模利用 DevOps,则需要摆脱来自 IT 和更广泛业务的严格监督。这不是关于信任的问题-人力资源和分析技术可供企业领导者远程监视和分析开发人员的效率。它只是归结为效率:以一种更加敏捷和有效的开发方法来消除障碍。以一种可以为您提供广泛、以业务为中心并且与供应商无关的方式执行此关键操作。如果没有民主变革的能力,并根据我们的经验来衡量结果,您将永远无法完全成功并获得真正的利益。\n在我的下一个博客中,我将探讨帮助 DevOps 扩展的另一个关键因素:度量。 因此,请再次访问。\n", "auhtor": "Jon Hammant", "translator": "zhaoying818", "original": "https://www.linkedin.com/pulse/building-new-operating-model-devops-jon-hammant/", "poster": "devops.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/11/2019-11-04-jcli-v0.0.22/", "title": "Jenkins CLI 命令行 v0.0.22", "type": "wechat", "date": "2019-11-04 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.22 发布", "content": " Jenkins CLI 可以帮忙你轻松地管理 Jenkins。不管你是一名插件开发者、管理员或者只是一个普通的 Jenkins 用户,它都是为你而生的!\n项目地址:https://github.com/jenkins-zh/jenkins-cli\n本次发布的更新 本次发布,包含了三位贡献者提供的代码以及文档改进。而且,两位贡献者,以该项目的名义向 JetBrains 申请了 Goland 的开源许可证。到目前为止,包含有5位开发者的贡献。期待有更多的 Jenkins 用户参与到这个项目当中。\nWindows 用户,现在可以通过 Scoop 来很方便地安装 jcli 了。 安装命令为:scoop install jcli\n🚀 功能 支持 HTTP 请求的语言设置 (#183 ) @yJunS 支持通过拷贝的方式创建 Jenkins 任务 (#205) @LinuxSuRen 📝 文档完善 在自述文件中增加 JetBrains 开源许可证的描述 (#209) @LinuxSuRen 完善英文的自述文件 (#210) @scottydocs 在文档中增加对 scoop 的描述 (#208) @LinuxSuRen 增加 godoc 的徽章 (#201) @LinuxSuRen 👻 维护 增加 PR 模板 (#212) @LinuxSuRen 把 dependencies 添加为标签 (#203) @LinuxSuRen 把 gopkg.in/yaml.v2 从 2.2.2 升级到 2.2.4 (#202) @dependabot-preview ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“great-wall.jpeg”" }, { "uri": "https://jenkins-zh.cn/meeting/2019-10-30/", "title": "", "type": "meeting", "date": "2019-10-30 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 例会时间 双周,指的是以年为单位的,第一周为单周,第二周为双周,以此类推 论坛 管理员招募? 捐助\n 充值到阿里云账号 一周之内,发出一份公开的感谢信(测试吧)@linuxsuren 清理不活跃的账号权限\n github 百度统计 @yJunS 公众号(zhaizhijun0) 统一下其他媒体平台的关联手机号 @yJunS Jenkins 相关资源下载很慢,包括:容器镜像、deb 镜像源、插件等\n 思考如何能把这块接起来 视频,在微信公众号上发布\n 技术交流 例会 微信群\n 坏处 缺少管理员 不希望有人同时在多个群里发同样的问题 好处 希望交流的人肯定是大于500人的 方便通知(技术相关的,不会有活动类的) 能够解决管理问题的前提下,可以开群2。管理员必须参加例会,可以不做其他的 管理员需要做的事情 @zhaoying818 能够认同并严格执行群管理规则 时间上,机器人会负责拉人,管理员审批通过;或者,警告违规的人;不听警告的踢出 流量的导向?\n 新人介绍\n zhaoying818 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/10/2019-10-28-introducing-new-folder-authorization-plugin/", "title": "介绍新的文件夹授权插件", "type": "wechat", "date": "2019-10-28 00:00:00 +0000 UTC", "tags": ["外挂程式 安全 性能 gsoc gsoc2019"], "description": "介绍新的文件夹授权插件", "content": " 在我的 Google Summer of Code Project 期间,我创建了全新的 Folder Auth 插件,可轻松管理 Folders plugin 对文件夹中组织的项目的权限。这个新插件旨在通过易于管理的角色进行快速权限检查。该插件的 1.0 版本刚刚发布,可以从您的 Jenkins 更新中心下载。\n该插件的灵感来自角色策略插件,可改善性能并简化角色管理。开发该插件是为了解决 Role Strategy Plugin 在许多角色上的性能限制。同时,该插件通过文件夹解决了 Jenkins 中组织项目最受欢迎的方式之一。该插件还具有一个新的 UI ,将来会有更多改进。\n该插件支持三种类型的角色,分别适用于 Jenkins 中的不同位置。 * 全局角色:适用于 Jenkins 的所有地方 * 代理角色:限制连接到您的实例的多个代理的权限 * 文件夹角色:适用于文件夹内组织的多个作业\n角色策略插件的性能改进 与角色策略插件不同,此插件不使用正则表达式来查找匹配的项目和代理,从而改善了我们的性能并简化了管理员的工作。为了减少需要管理的角色数量,通过文件夹角色授予文件夹的权限将继承其所有子项。这对于通过单个角色访问多个项目很有用。同样,一个代理角色可以应用于多个代理,并分配给多个用户。\n此插件的设计目的是在权限检查方面优于角色策略插件。这些改进是使用我在 GSOC 项目的第一阶段创建的micro-benchmark framework来衡量的。两个插件相同配置的基准测试表明,与角色策略 2.13 中的全局角色相比, 500 个全局角色的权限检查速度提高了 934 倍,角色策略 2.13 本身包含一些性能改进。将文件夹角色与角色策略的项目角色进行比较,对于 250 个组织在 150 个用户的实例上的两级深层文件夹中的项目,对作业的访问权限检查几乎快了 15 倍。您可以在 此处 看到基准和结果比较。\nJenkins 配置作为代码支持 该插件支持 Jenkins 的“代码即配置”功能,因此您无需通过 Web UI 即可配置权限。YAML 配置如下所示:\njenkins: authorizationStrategy: folderBased: globalRoles: - name: \u0026quot;admin\u0026quot; permissions: - id: \u0026quot;hudson.model.Hudson.Administer\u0026quot; # ... sids: - \u0026quot;admin\u0026quot; - name: \u0026quot;read\u0026quot; permissions: - id: \u0026quot;hudson.model.Hudson.Read\u0026quot; sids: - \u0026quot;user1\u0026quot; folderRoles: - folders: - \u0026quot;root\u0026quot; name: \u0026quot;viewRoot\u0026quot; permissions: - id: \u0026quot;hudson.model.Item.Read\u0026quot; sids: - \u0026quot;user1\u0026quot; agentRoles: - agents: - \u0026quot;agent1\u0026quot; name: \u0026quot;agentRole1\u0026quot; permissions: - id: \u0026quot;hudson.model.Computer.Configure\u0026quot; - id: \u0026quot;hudson.model.Computer.Disconnect\u0026quot; sids: - \u0026quot;user1\u0026quot; 带有 Swagger 支持的 REST API 该插件提供 REST API ,用于通过 Swagger.json 管理具有 OpenAPI 规范的角色。您可以在 SwaggerHub 上查看 Swagger API 。SwaggerHub 提供了多种语言的存根,可以下载并用于与插件进行交互。您还可以使用 curl 从命令行查看一些示例请求。\n接下来做什么 在不久的将来,我想改进用户界面,使插件更容易使用。我还希望改进 API 、文档和更多的优化来提高插件的性能。\n链接和反馈 我很想听听你的意见和建议。请随时通过 Role Strategy Plugin Gitter chat 或通过 Jenkins Developer Mailing list 与我联系。\n Presentation slides for second phase evaluations Documentation for the Folder Auth Plugin Demo of the Folder Authorization plugin ", "auhtor": "Abhyudaya Sharma", "translator": "wenjunzhangp", "original": "https://jenkins.io/blog/2019/08/16/folder-auth-plugin/", "poster": "“./2019-10-28-introducing-new-folder-authorization-plugin/cover.jpg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/10/2019-10-25-plugin-management-tool-alpha-release/", "title": "Alpha 版本的插件管理库和 CLI 工具", "type": "wechat", "date": "2019-10-25 00:00:00 +0000 UTC", "tags": ["plugins", "pluginmanagement", "platform-sig", "cli", "gsoc", "gsoc2019"], "description": "Alpha 版本的插件管理库和 CLI 工具", "content": " \u0026ldquo;人人都在重复造轮子,部分像实现插件管理的\u0026rdquo;细节\u0026rdquo;(签名元数据,制品校验和,从核心独立出来的插件\u0026hellip;)。 很明显, Jenkins 应该为实时 Jenkins 实例之外的插件安装提供充足的工具。\u0026rdquo; JENKINS-53767\n我的 Google Summer of Code project 项目试图解决这个问题,方法是创建一个库,该库将在 Jenkins 的不同实现中统一插件管理逻辑,并提供一个可以使用户轻松下载插件并在 Jenkins 启动之前查看插件信息的 CLI 工具。 我很高兴分享我们刚刚发布的 Alpha 版本,您可以在此处查看!\nGSoC 阶段 1 更新 当我考虑将插件管理器从 Jenkins 核心中移出时,由于依赖项的复杂性和数量,这最终成为了最具挑战性的第一步。相反,我们决定首先将 Jenkins Docker 中的 install-plugins.sh bash 脚本转换为 Java。 install-plugins.sh 脚本存在多个问题,即它是 bash 脚本并且扩展性有限,此外,它不会检索所有最新的更新中心的元数据。\nAlpha 版本详情 模仿官方 Jenkins Docker 镜像中 install-plugins.sh 脚本中的操作,新的插件管理库接收插件列表、它们的版本和(或) URL,从中可以下载插件,并下载所需的插件及其依赖。插件从更新中心下载到指定目录,然后可以加载到 Jenkins 中。当前,可以通过 plugins.txt 文件和(或) -plugins 的 cli 选项指定要下载的插件,我们计划进一步扩展可以接收的输入格式。 还支持用于不同更新中心的自定义版本说明符。\n该库将首先检查当前是否在用户指定的下载位置或用户指定的 Jenkins war 文件中安装了任何请求的插件。如果要求更高版本或更高版本作为依赖项,则将忽略或升级已安装的插件。确定插件下载 URL 后,库将下载插件并解析和下载其依赖。\n这仅仅是个开始:插件管理器库和 cli 工具仍在开发中。 有关 CLI 选项以及如何运行该工具的最新信息,请参见存储库 README.md 。 即将提供更强大的输入解析,对安全警告和可用更新的支持,Docker集成以及其他功能!\n链接和反馈 欢迎通过插件安装管理器 CLI 工具 Gitter 聊天室或 Jenkins 开发者邮件列表与我们联系。我希望收到您的问题,评论和反馈!我们在世界标准时间下午6点(星期二和星期四)开会。\n Phase 1 Presentation Slides Phase 1 Recorded Demo Jira Issue Search Repository ", "auhtor": "stopalopa", "translator": "zhaoying818", "original": "https://jenkins.io/blog/2019/07/02/plugin-management-tool-alpha-release/", "poster": "devopsworld.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/10/2019-10-20-online-activity/", "title": "Jenkins 线上技术交流", "type": "wechat", "date": "2019-10-20 00:00:00 +0000 UTC", "tags": [], "description": "各种技术群里交流不过瘾?线上技术交流期待你的参与!", "content": "在 Jenkins 中文社区微信技术交流群里,看到有人提出各种各样的问题,有一些问题快速得到了解答, 有一些则可能由于各种原因没有收到回答。大家都能看出来,在各种群里交流有很多的弊端,例如:\n 某个时段大家在忙工作上的事情 文字性的问题描述不够清晰 难以记录交流成果 其他 为了能让更多 Jenkins 的用户有一个集中交流的地方,掌握正确的学习以及使用方法,了解常见问题如何排查。 我们会定期组织线上交流会,时间为两周一次,时长一个小时。参与者需要提前准备好 zoom 软件。如果希望 提问的话,则一定要提前找一个周围没有噪音的地方,否则主持人会禁掉你的麦克风。\n那么,分享的内容是什么呢?具体的活动流程是什么样的?\n值得您注意的是,任何人都可以在下次活动发布之前,申请作为分享人。您可以通过如下的几种方式进行申请:\n Jenkins 公众号后台留言 在社区活动微信群中留言 发送邮件到 admin@jenkins-zh.cn 您需要说明要分享的主题,时间控制在半个小时以内;如果内容较多的话,可以以系列的形式来分享。我们希望尽可能 给其他参与者多留一些提问时间。作为分享人,需要至少提前十分钟进入会议。\n因此,活动流程非常简单。首先是技术分享,然后参与者提问互动。活动中会有视频录制,并在结束后上传到 Jenkins 中文社区的哔哩哔哩账号下。\n而本次的线上分享活动,由 Jenkins 中文微信技术群的群主来分享有关 Jenkins 多分支流水线的内容。 大致内容包括:\n 流水线概要 多分支流水线的使用场景 多分支流水线的应用 多分支流水线的优缺点 活动时间:每个单周周三21:00~22:00 参与方式:请访问 https://jenkins-zh.github.io/event/\n注意\n每次活动时间开始后,五分钟内没有人加入的话,活动取消。 具体活动的动态,我们会在微信*活动群*中给出通知。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "eagle.jpeg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/10/2019-10-17-jcli-v0.0.21/", "title": "Jenkins CLI 命令行", "type": "wechat", "date": "2019-10-17 00:00:00 +0000 UTC", "tags": [], "description": "jcli-v0.0.21 发布", "content": " Jenkins CLI 可以帮忙你轻松地管理 Jenkins。不管你是一名插件开发者、管理员或者只是一个普通的 Jenkins 用户,它都是为你而生的!\n项目地址:https://github.com/jenkins-zh/jenkins-cli\n本次发布的更新 本次发布,主要增加了下载归档文件以及命令行补全的功能。\n🚀 功能 增加为 jcli 生成完整文档的子命令 (#174) @LinuxSuRen 支持流水线 input 的输入 (#164) @LinuxSuRen 增加下载归档文件的子命令 (#185) @LinuxSuRen 🐛 缺陷修复 为每个请求增加权限信息 (#187) @yJunS 修复了首次安装后无法打印版本信息的问题 (#186) @zirmax 📝 文档完善 增加中、英文项目自述文件的链接 (#194) @LinuxSuRen 👻 维护 移除无用的代码行 (#178) @LinuxSuRen 为 job 客户端增加测试代码 (#190) @LinuxSuRen 为idea 增加 git 提交时忽略的文件配置 (#199) @LinuxSuRen 增加 jcli completion 的命令描述 (#188) @LinuxSuRen 绑定代码质量和构建状态 (#184) @LinuxSuRen 为 user client 增加测试代码 (#180) @LinuxSuRen 增加代码仓库自动备份的流水线 (#173) @LinuxSuRen 增加下载数量以及代码仓库大小的徽标 (#168) @LinuxSuRen ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“great-wall.jpeg”" }, { "uri": "https://jenkins-zh.cn/meeting/2019-10-16/", "title": "", "type": "meeting", "date": "2019-10-16 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 例会时间 双周,指的是以年为单位的,第一周为单周,第二周为双周,以此类推 论坛 http://discourse.surenpi.com/ 邮箱服务器,不支持腾讯企业邮箱(可以自己搭建一个) 管理员 捐助 充值到阿里云账号 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/09/2019-09-27-jenkins-in-hacktoberfest/", "title": "Jenkins 喊你参加 Hacktoberfest", "type": "wechat", "date": "2019-09-27 00:00:00 +0000 UTC", "tags": [], "description": "第六届黑客十月庆典", "content": " Hacktoberfest 是一场为期一个月的开源软件庆祝活动,该活动由 DigitalOcean 和 DEV 共同组织。\n Hacktoberfest 面向全球社区的每一位贡献者 至少须要向公开的 GitHub 仓库提交四个正式的 Pull Request 你可以在十月一日到三十日之前的任意时间注册 如何开始? 在 https://hacktoberfest.digitalocean.com/ 注册账号,并提交 PR 到 GitHub 的公共仓库。推荐提交高质量的 PR。\n而作为 Jenkins 的用户,我们的首选当然是 Jenkins 社区的相关代码仓库了。\n我们非常地欢迎各位认可、热爱开源的朋友们,共同完善 Jenkins 简体中文插件、Jenkins 中文网站等本地化的内容。\n除了上一届活动的项目以外,今年社区还推荐了一个由 Golang 编写的 Jenkins CLI 项目。下面是 jcli 这个命令行工具的功能特点:\n 管理多个 Jenkins 服务器 支持搜索、安装、卸载、升级以及下载 Jenkins 插件 支持搜索、编辑、触发流水线任务,查看构建历史 支持查看、移除队列中的任务 支持命令行补全 支持代理设置 如果你用的是 MacOS 的话,可以通过 brew 很方便地安装该工具,命令如下:\nbrew tap jenkins-zh/jcli brew install jcli 对于其他操作系统的用户,也可以在项目首页 https://github.com/jenkins-zh/jenkins-cli/ 上找到对应的安装帮助信息。\n如果还希望了解更多的社区项目,请访问 https://jenkins.io/events/hacktoberfest/\n如何获取奖品 在你完成指定的 PR 后,请关注你的邮箱,官方会发送邮件让你来填写T恤尺码以及收件地址等。奖品除了T恤以外还有官方的贴纸。如果在11月初还没有收到邮件的话,请及时联系官方人员。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "hacktoberfest_19_logo.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/09/2019-09-23-devops-world-jenkins-world/", "title": "2019 DEVOPS WORLD和JENKINS WORLD 获奖者公布", "type": "wechat", "date": "2019-09-23 00:00:00 +0000 UTC", "tags": ["DEVOPS JENKINS"], "description": "2019 DEVOPS WORLD和JENKINS WORLD 获奖者公布", "content": " 15个组织和个人荣获DevOps杰出成就,开源贡献和渠道合作伙伴绩效\n DEVOPS WORLD | JENKINS WORLD,2019年8月15日在旧金山,由CloudBees,企业DevOps领导者推动经济持续发展,今天宣布了2019 DevOps world 和 Jenkins world 获奖者。该奖项表彰3个类别的成就:Jenkins 社区奖,表彰对 Jenkins 项目做出重大贡献的人;CloudBees 创新奖,表彰在 DevOps 转型中取得优秀成果的组织;和CloudBees 渠道合作奖,重点介绍在创收和帮助组织实现DevOps转型方向表现出色的合作伙伴。\nCloudBees创新将的获得者包括各种规模的组织,从风险投资的小型创业公司到全球技术巨头。Jenkins 社区将授予了4个人,他们为 Jenkins 社区做出了贡献。最后5个渠道合作伙伴因在勤奋卓越获得认可。\nJENKINS 社区奖 Jenkins 社区奖由 Jenkins 创始人兼 CloudBees 首席科学家 Kohsuke Kawaguchi 和 Jenkins 大使组成的小组选出。Jenkins 大使每年都会被提名,他们都是有影响力的 Jenkins 爱好者,热衷于与他人分享 Jenkins 的技术专长。\n“2019 Jenkins社区奖表彰了社区成员的努力,他们在几个关键领域为推进 Jenkins 做出了重大贡献“,Kawaguchi 表示,”今年的提交的质量比以往任何时候都要好。”\n2019 Jenkins 社区奖得主: 2019最有价值的 Jenkins 贡献者 - Oliver Gondža 2019Jenkins 安全 MVP - Victor Gazdag 2019最有价值的 Jenkins 倡导者 – 赵晓杰 2019最有创新的 Jenkins X 实现 - Vincent Behar *CloudBees创新奖** CloudBees 创新奖由一个评委团选出,评委团成员包括 CloudBees 首席执行管兼联合创始人 Sacha Labourey,DevOps.com 主编兼创始人 Alan Shimel,Google Cloud 产品管理总监 Aparna Sinha。\n“我们很高兴有机会庆祝 CloudBees 客户定期展示的杰出成就”,CloudBees 首席执行管兼联合创始人 Sacha Labourey 表示,“2019 DEVOPS WORLD | JENKINS WORLD奖获奖者是DevOps行业杰出领导力的5个例子”。\n2019 CloudBees 创新奖得主: DevOps 可扩展性成就 – AIG DevOps 可扩展性成就 – Accenture DevOps 优秀自动化 – American Express Global Business Travel DevOps 优秀自动化 – Broadridge Financial Solutions DevOps 新星(荣誉奖)- Pinger CloudBees 渠道合作伙伴奖 CloudBees 渠道合作伙伴奖由 CloudBees 渠道团队选出。奖项颁发给5个合作伙伴类别中的渠道合作伙伴。获奖者在 DevOps 中展示了经过验证的专业知识,同时在合作领域也表现出色。\n2019渠道合作伙伴奖得主: 2019年度美洲合作伙伴 – Zivra 2019年度最佳新秀合作伙伴 – ThunderCat 2019年度渠道营销合作伙伴 – Fierce Software 2019年度公共部门合作伙伴 - Fierce Software 2019年度亚太地区合作伙伴 – TechMatrix ", "auhtor": "Deborah Schalm", "translator": "h5ang", "original": "https://devops.com/2019-devops-world-jenkins-world-award-winners-announced/", "poster": "jenkins-world.jpeg" }, { "uri": "https://jenkins-zh.cn/meeting/2019-09-22/", "title": "", "type": "meeting", "date": "2019-09-22 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "今天主要讨论社区对于接收外部资金捐助的事情\n 有捐助意向的企业是:测吧(北京)科技有限公司 金额 我的理解是至少能给到2500(是基于在阿里云上购买一年的服务器的费用) 本次希望能得到2500~10000元的捐助 捐助方的权益 在官网首页以及合作伙伴中加logo以及链接 是否专款专用?\n 公开社区基金的用途\n 基础设施(域名、服务器) 技术类活动组织(茶歇、礼品、场地) 成员激励:季度、年度 社区基金问题\n 没有对公账户 缺少了解财务的人才 考虑从在校学生里的相关专业来招募 需要在一个地方明确地列出来资金的使用情况(进账、出账) 对资金的(进账、出账)做分类 需要确定一个流程\n 确定意向 确定捐助细节 捐助类型(资金、实物、虚拟物品等) 接收款项的账户 资金用途 时间 双方的联系人 公开捐助记录(历次) https://jenkins-zh.cn/about/sponsors-list/(增加类型以及明细) 撰写并发布感谢捐助方的文章 论坛\n 选型(开源) https://github.com/discourse/discourse https://github.com/satellity/satellity https://github.com/search?q=forum https://github.com/b3log/symphony 管理员(征集?严格的挑选) 考虑分短期和长期的管理员 调试完成后再使用基金 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/09/2019-09-19-introduce-react-plugin-template/", "title": "React Plugin Template,让你可以使用 React 来编写 Jenkins 插件", "type": "wechat", "date": "2019-09-19 00:00:00 +0000 UTC", "tags": ["react", "plugin", "template", "gsoc", "gsoc2019"], "description": "React Plugin Template,让你可以使用 React 来编写 Jenkins 插件", "content": " 模板地址\nReact Plugin Template https://github.com/jenkinsci/react-plugin-template\n起因 这个模板是笔者在今年的 Google Summer of Code 中的项目 Working Hours - UI Improvement 中产出的。由于我们想使用 React 的一些组件来优化用户体验,例如在 Working Hours 里面我们想用 ReactDatepicker 来帮助用户选择日期,于是整个 Working Hours 插件的前端部分都试图用 React 来编写,而由于 Jenkins 的传统插件编写主要还是用的 Jelly ,一套类似 JSP 的后端渲染引擎,因此笔者在一开始也踩了不少坑。以至于想到,可以抽象出一套插件的脚手架来帮助有相似需求的同学。\n链接:\nGSoC:Working Hours UI Improvement https://summerofcode.withgoogle.com/projects/#6112735123734528\nGithub:Working Hours 插件 https://github.com/jenkinsci/working-hours-plugin\n概述 在以往,我们可以使用 Jelly 来开发 Jenkins 插件的前端部分,同时一些请求可以绑定到对应的类,但是当我们想要更高程度地去自定义插件界面的时候,Jelly 就显得捉襟见肘了。这就是这个模板的目的,帮助开发者使用 React 来开发一个插件。\n同时,有了 React ,我们就可以使用很多基于 React 的库,webpack 也可以帮助我们更安全更高效地使用 js 库。\n特点 | 集成 React | 开发者可以使用 React 充分控制 UI | 使用了 Iframe | Iframe 隔离了之前 Jenkins 添加的一些 js 库会造成的影响,例如 Prototype.js。 | 使用 maven 的生命周期 | 使用了 Frontend Maven Plugin https://github.com/eirslett/frontend-maven-plugin, npm 脚本可以在 maven 的生命周期中被同步执行。 | 使用 Webpack | Webpack 可以减少最终包的体积,同时避免 js 库对全部命名空间的影响 | 为每个请求附加 Jenkins Crumb| Jenkins Crumb 是 Jenkins 的一套 token 系统,在本模板中已经自动附加到 axios 实例上 | 使用了 Express 的 devserver | 可以单独打开一个支持热更新的 devserver 来编写前端界面\n截图 插件 UI\n示例入口\n入门 克隆仓库:\ngit clone https://github.com/jenkinsci/react-plugin-template.git cd react-plugin-template 安装 maven 依赖和 npm 包\nmvn install -DskipTests 运行支持热更新的网页\nnpm run start 运行插件\nmvn hpi:run -Dskip.npm -f pom.xml 发送HTTP请求 由于 Jenkins Crumb 策略默认是开启的,每个请求都被要求包含一个 Jenkins Crumb, 所以请使用已经设置好了 Jenkins Crumb 的 axiosInstance,可以在 src/main/react/app/api.js 中找到。\nexport const apiGetData = () =\u0026gt; { return axiosInstance.post(\u0026quot;/data\u0026quot;); }; 或者你想使用你自己的 http client,你只需将 Jenkins Crumb 添加到你每个请求的 header中,这个 header 的 key 和 content 都可以使用 src/main/react/app/utils/urlConfig.js,具体操作如下\nconst headers = {}; const crumbHeaderName = UrlConfig.getCrumbHeaderName(); if (crumbHeaderName) { headers[crumbHeaderName] = UrlConfig.getCrumbToken(); } 编写后端的请求处理器 当你可以自定义你的请求后,你同时也需要一个在后端的 Handler。\nJenkins 使用了一个叫做 Stapler的框架来处理请求。你可以使用一个继承了 Action 的类来创建一个子 url ,同时可以使用一个 StaplerProxy 来转发或者直接处理请求。\n链接\nStapler Reference http://stapler.kohsuke.org/reference.html.\n示例 handler 如下,ManagementLink(已经继承 Action )会首先拿到这个请求然后转交个 PluginUI 来处理。\n@Extension public class PluginManagementLink extends ManagementLink implements StaplerProxy { PluginUI webapp; public Object getTarget() { return webapp; } public String getUrlName() { return \u0026quot;react-plugin-template\u0026quot;; } } 随后, stapler 会在 PluginUI 中寻找适合的处理函数,如下, doDynamic 便是一个处理函数, 然后便是我摸自定义的,根据 url 来判断需要调用的函数, getTodos 或者 setTodos, 在这里 PluginUI 可能更像一个 url router。\npublic class PluginUI{ public HttpResponse doDynamic(StaplerRequest request) { ... List\u0026lt;String\u0026gt; params = getRequestParams(request); switch (params.get(0)) { case \u0026quot;get-todos\u0026quot;: return getTodos(); case \u0026quot;set-todos\u0026quot;: return setTodos(request); } ... } } 保存数据 你可以使用一个 Descriptor 来保存你的数据\n@Extension public class PluginConfig extends Descriptor\u0026lt;PluginConfig\u0026gt; implements Describable\u0026lt;PluginConfig\u0026gt; 当你每次修改数据, 调用 save() 来保存他们。Jenkins 是使用基于 xml 的序列化方法来保持数据的。\npublic void setTodos( @CheckForNull List\u0026lt;Todo\u0026gt; value) { this.todos = value; save(); } 而在你的 handler 中,你可以调用如下代码来找到你的这个存储数据的对象。\nconfig = ExtensionList.lookup(PluginConfig.class).get(0); 自定义你的插件 把所有 react-template 修改为你的插件名 在 org/jenkinsci/plugins/reactplugintemplate/PluginUI/index.jelly , 修改 iframe 的 id 和 source url. 在 src/main/react/server/config.js , 修改 devserver 的代理路径 在 src/main/react/package.json , 修修 start 命令中的 BASE_URL 在 pom.xml , 修改 artifactId 在 org/jenkinsci/plugins/reactplugintemplate/PluginManagementLink.java , 修改 names。 为你的插件自定义一个页面 比较推荐使用 Management Link, 这会让你的插件有一个独立的页面, 并且可以在系统管理界面 /manage 放置一个入口。\n原理 本模板仅仅是将一个 webpack 的 project 放到了 Maven project 中,同时将 webpack 的 build 结果复制到插件的 webapp 目录,随后便可以在 iframe 中通过 url 访问到,最后被 Jelly 渲染到网页。\n为什么使用Iframe? 因为到现在,Jenkins 的网页已经添加了很多的 js 库了(似乎是添加到全局的),因此可能会和较新的库产生一些冲突。因此也行一个 Iframe 可以使我们的插件运行在一个相对“干净”的环境里面。\n链接 Github: React Plugin Template https://github.com/jenkinsci/react-plugin-template\nGithub: Working Hours Plugin https://github.com/jenkinsci/working-hours-plugin\n", "auhtor": "jackshen", "translator": "", "original": "", "poster": "plugin-ui.jpg" }, { "uri": "https://jenkins-zh.cn/meeting/2019-09-18/", "title": "", "type": "meeting", "date": "2019-09-18 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 线上活动 hacktoberfest 定期的线上活动,由于 zoom 出了问题,暂时没有推进 线下活动 上海 10月20日,人民广场 https://github.com/jenkins-zh/jenkins-zh/pull/95 人数(120),门票50 议题 Testerhome 接口测试(与 Jenkins 无关) UWA 自动化测试(与 Jenkins 无关) daocloud(待定) 社区合作 开源年会\n 给社区贡献的同学一张免费的门票(早鸟票99),以及其他的权益 没有在当地活跃的成员,无法开展我们社区的展台 工作坊(暂时无人组织) 开源基础设施\n 工作坊(暂时无人组织) 社区管理 是否容易获取到社区的动态 微信群 难以做到用户增长 其他问题 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/09/2019-09-16-jenkins-world-contributor-summit-and-ask-the-experts-booth/", "title": "Jenkins World 贡献者峰会及专家答疑展位", "type": "wechat", "date": "2019-09-15 00:00:00 +0000 UTC", "tags": ["jenkinsworld", "devopsworld2019", "gsoc2019", "community", "opensource", "events", "contributorsummit", "asktheexperts"], "description": "本文为 Jenkins World 贡献者峰会活动期间的记录", "content": " Jenkins 15周岁啦!Jenkins World 将 DevOps 思想领袖、IT 主管、持续交付实践者以及 Jenkins 社区和生态系统齐聚这场全球活动,让与会者有机会学习、探索以及面对面交流,帮助塑造 Jenkins 的下一次发展以及针对 DevOps 的解决方案。\n此外,Jenkins 贡献者峰会也于旧金山举行。Jenkins 贡献者峰会是现有贡献者以及未来贡献者围绕 Jenkins 项目,以最新思考和最大努力来共同探讨、学习和协作的地方。上午峰会安排是由核心贡献者进行一系列展示介绍。这些介绍突出了每项工作的内容,以及社区成员可以提供哪些帮助。下午分组讨论会上,与同好小组进行了深入讨论,并同子项目贡献者进行合作。\n我非常荣幸能成为其中一员。 第一天 第一天以贡献者峰会开场。这让大家有机会聚在一起讨论对社区的贡献,把脑海中熟悉的名字和本人对上号。大多数人我只通过视频聊天和在 gitter 上见过,所以当时我特别激动。我们聚在一起了解 Jenkins 开源画卷的起点。\n接下来是同好讨论/非正式会议。我主导这些讨论会,个人认为进展十分顺利。成员组织管理员 Martin d’Anjou 和 Jeff Pearce 为我们带来一场有关 Google 编程夏令营(Google Summer of Code,以下简称 GSoC)项目的演讲。\nGSoC 学生 Natasha Stopa 介绍了她的项目——Plugin Installation Manager Library/CLI Tool。这是一个超酷的项目,在社区受到广泛欢迎。\n讨论会结尾是博思艾伦咨询公司(Booz Allen Hamilton)的 Steven Terrana 的展示和精彩的 Jenkins 模板引擎。如果你还没有试过这个,请一定不要错过https://github.com/boozallen/jenkins-templating-engine。\n主展厅 从第二天起,我和其他几位 Jenkins 组织管理者将在 Jenkins 社区的专家答疑(Ask the Expert)展位。\n这真的是一场非常有意思的体验,让我有机会了解社区正在做什么,帮助他们解决面对的问题。问题涉及的范围很广,从 Jenkins X 到我负责维护的种种插件,如 Jenkins Prometheus 和 Sysdig Secure Scanning 插件。也有很多关于 Kubernetes 的问题。有很多关于 Kubernetes 使用情况提高的市场营销方面的数据,但对 Kubernetes 上 Jenkins 的超高兴趣度真的让我大吃一惊。当然,也有机会拍点儿自拍。\n午餐时段的 demo 开始,我们的流程很紧凑。第一个上台的是超棒的 Mark Waite,他来谈谈 Git 插件。很多人在 Jenkins 上用 git。非常感谢 Mark 的分享。\n下一位是 Jenkins 组织管理者 Martin d’Anjou,他介绍了 GSoC。让人难以相信的是,GSoC 也和 Jenkins 一样成立15周年了!\nNatasha Stopa 是参与 GSoC 的学生,她介绍了自己的项目 Plugin Installation Manager Library/CLI Tool。Natasha 真的在这个插件上做了很多努力,能在她的展示中看到结果和支持真的是太棒了。\n最后压轴的就是我了。我展示了正在维护的 Sysdig Secure Scanning 的 Jenkins 插件。感谢每一位当场的朋友。\n就在午餐 demo 之后,我顺道去看了下 Jenkins 开放区。这对社区而言,是讨论议题、自主活动的机会。我真的非常享受这次讨论会,觉得该形式在与会人员中的接受程度很好。\n我们以 Jenkins 组织管理员与 GSoC 学生的合照作为当天活动的结尾。未参与合照的组织管理员为 Lloyd Chang 和 Oleg Nenashev。\n结语 这是一场无与伦比的非凡体验。非常感谢 CloudBees、Jenkins 社区、GSoC、Tracy Miranda、Alyssa Tong 和我的公司 Sysdig。\n想到 Jenkins 成立15周年,真是太了不起了!我们完成了那么多事情,未来也格外灿烂。非常感谢让我有幸为社区服务,成为社区的一部分。未来还有更多个15年!\n如果你有兴趣加入 Jenkins 的任何特别兴趣小组(SIG),请查看以下链接。我们需要您的帮助:(https://jenkins.io/sigs/)\n如果你有兴趣参加编程夏令营,请看此处:(https://jenkins.io/projects/gsoc/) 如果你想和大家聊天讨论,可以在这找到我们:(https://jenkins.io/chat/) 如果你想给我们发邮件,请发送至:(https://jenkins.io/mailing-lists/)\n现场照片 关于作者 Marky Jackson (https://jenkins.io/blog/authors/markyjackson-taulia/)\n该作者没有设置个人简介,请参阅下方社交媒体链接。 GitHub(https://github.com/markyjackson-taulia)\n", "auhtor": "Marky Jackson", "translator": "shunw19", "original": "https://jenkins.io/blog/2019/08/25/jenkinsworld-contrib-summit-ask-the-expert-booth/", "poster": "./2019-09-15-jenkins-world-contributor-summit/cover.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/09/2019-09-11-introducing-gitlab-branch-source-plugin/", "title": "介绍新的 GitLab 分支源插件", "type": "wechat", "date": "2019-09-11 00:00:00 +0000 UTC", "tags": ["gitlab", "plugins", "pipeline", "multibranch", "gsoc", "gsoc2019"], "description": "新的 GitLab 分支源插件,允许您基于 GitLab `用户` 或 `组` 或 `子组` 项目创建任务", "content": " GitLab 分支源插件已经走出 beta 阶段,并已发布到 Jenkins 更新中心。 它允许您基于 GitLab 用户 或 组 或 子组 项目创建任务。 您可以:\n 从 GitLab 用户/组/子组导入单个项目的分支作为任务(多分支流水线任务) 从 GitLab 用户/组/子组导入所有或部分项目的分支作为任务(GitLab 组任务或 GitLab 文件夹组织) GitLab 组项目对项目进行扫描, 根据设置的规则导入流水线任务。 导入项目之后, Jenkins 立即基于 Jenkinsfile 流水线脚本运行任务并且将状态通知到 GitLab 流水线状态。 这个插件与其他分支源插件不同,它提供了 GitLab 服务器配置,可以在系统配置中配置。 Jenkins 配置即代码 (JCasC) 也可以用于配置服务器。 要想了解更多关于服务器配置的信息,请参考我之前的博客。\n要求 Jenkins - 2.176.2 (LTS)\n GitLab - v11.0+\n 创建任务 要创建多分支流水线任务(使用 GitLab 分支源)或 GitLab 组任务,您必须将 GitLab 个人访问令牌添加到服务端配置。 凭据用于获取项目的元数据,并在 GitLab 服务器上设置 hook。 如果令牌具有管理访问权限,您还可以设置 系统 Hook,而 Web Hook 可以从任何用户令牌设置。\n创建多分支流水线任务 转到 Jenkins \u0026gt; 新建任务 \u0026gt; 多分支流水线 \u0026gt; 添加源 \u0026gt; GitLab 项目\n Server - 从下拉菜单中选择所需的 GitLab 服务器,需要在创建此任务之前进行配置。\n Checkout Credentials - 如果插件要构建任何私有项目,添加 SSHPrivateKey 或 用户名/密码 类型的凭据。如果所有的项目都是公开的则不需要检出凭据。检出凭据与 GitLab 服务器配置中的凭据(GitLab 个人访问令牌 类型)不同。\n Owner - 可以是 用户、组 或 子组。 根据这一点填充 Projects 字段。\n Projects - 从下拉菜单中选择要构建的项目。\n Behaviours - 这些特性是非常强大的工具,用于配置构建逻辑和构建后逻辑。我们定义了新的特性。您可以在仓库文档中看到所有信息。\n 保存并等待分支索引。您可以从这里自由导航,任务进度显示在左侧。\n索引完成后,导入的项目将所有分支、合并请求和标签列示为任务。\n查看每个任务,您会发现左侧有一些操作项:\n 您可以通过选择 立即构建 手动触发任务。 您可以通过选择相应的按钮访问 GitLab 服务器上的特定分支/合并请求/标签。 创建 GitLab 组类型任务 转到 Jenkins \u0026gt; 新建任务 \u0026gt; GitLab Group\n您可以注意到,配置非常类似于多分支流水线任务,只是缺少 Projects 字段。 您可以添加在您的 Owner(用户/组/子组)中所有项目。 表单验证将与 GitLab 服务器检查 owner 是否有效。 您可以添加 Discover subgroup project 的特性,该特性允许您发现组或子组中所有子组的子项目,但此特性不适用于用户。 在索引时,web hook 在每个项目中创建。 GitLab Api 不支持创建组 web hook,所以这个插件不支持只有 GitLab EE 才支持的特性。\n现在可以查看导入的项目,如果需要,可以在每个文件夹上配置不同的设置。\nGitLab 流水线状态通知 GitLab 从任务排队的角度得到关于构建状态的通知。\n 成功 - 任务成功了 失败 - 任务失败了并且合并请求还没准备好合并 出错 - 发生了意外;例如:Jenkins 任务被终止了 等待 - 任务正在构建队列中等待 关于 GitLab 流水线状态,有指向相应 Jenkins 任务构建的超链接。 要查看流水线阶段和控制台输出,需要访问 Jenkins 服务器。 我们也计划通知管道阶段到 GitLab,但它有一些缺点,目前这已得到解决,有未来的计划添加它作为特性。\n您还可以通过从特性列表中选择 Skip pipeline status notifications 来跳过关于流水线状态的 GitLab 通知。\n合并请求 实现对项目合并请求的支持具有挑战性。 第一,MR 有两种类型,即原始分支和 Fork 的项目分支,因此每个 head 必须有不同的实现。 第二,来自 fork 的 MR 可能来自不可信的源,所以实现了一种新的策略 Trust Members,它允许 CI 仅从具有 Developer/Maintainer/Owner 访问级别的可信用户构建 MR。\n第三,来自 fork 的 MR 由于 GitLab 的问题不支持流水线状态通知,请参考这里。 您可以添加一个特性 Log Build Status as Comment on GitLab ,它允许那您添加一个 sudo 用户(如果你希望 owner 用户为空)以在 commit/tag/mr 上对构建结果进行评论。 要添加 sudo 用户,令牌必须具有管理访问权限。 默认情况下,只有失败/出错以评论的形式被记录,但是您也可以通过勾选复选框来启用成功构建的日志记录。\n有时候,合并请求因为外部错误而失败,因此因此您希望通过评论 jenkins rebuild 来触发 mr 的重新构建。 要启用该触发器,添加特性 Trigger build on merge request comment。 评论内容可以在特性中修改。 出于安全原因,评论者需要有该项目的 Developer/Maintainer/Owner 访问权限。\nHook 如果在服务器配置中配置了 web hook,则在项目上自动创建 web hook。 请确保 web hook 通过 CSRF 过滤器。 Jenkins 监听 /gitlab-webhook/post 路径上的 web hook 。 GitLab 上 web hook 在以下事件上被触发:\n Push Event - 当提交或分支被推送时\n Tag Event - 当新标签被创建时\n Merge Request Event - 当合并请求被创建/更新\n Note Event - 当对合并请求进行评论时\n 如果令牌具有管理访问权限,还可以在 GitLab 服务器上设置系统 Hook。 在创建新项目时触发系统 hook,Jenkins 根据配置触发新项目的重新扫描,并在其上设置 web hook。 Jenkins 监听 /gitlab-systemhook/post 路径上你的系统 hook。 GitLab 上系统 hook 在 Repository Update Events 上被触发:\n你也可以使用 Override Hook Management mode 特性来覆盖默认你的 hook 管理以及选择是否要使用不同的上下文(比如 Item)或完全禁用它。\nJob DSL 以及 JCasC 你可以使用 Job DSL 来创建任务。 下面有一个 Job DSL 脚本的示例:\norganizationFolder('GitLab Organization Folder') { description(\u0026quot;GitLab org folder created with Job DSL\u0026quot;) displayName('My Project') // \u0026quot;Projects\u0026quot; organizations { gitLabSCMNavigator { projectOwner(\u0026quot;baymac\u0026quot;) credentialsId(\u0026quot;i\u0026lt;3GitLab\u0026quot;) serverName(\u0026quot;gitlab-3214\u0026quot;) // \u0026quot;Traits\u0026quot; (\u0026quot;Behaviours\u0026quot; in the GUI) that are \u0026quot;declarative-compatible\u0026quot; traits { subGroupProjectDiscoveryTrait() // discover projects inside subgroups gitLabBranchDiscovery { strategyId(3) // discover all branches } originMergeRequestDiscoveryTrait { strategyId(1) // discover MRs and merge them with target branch } gitLabTagDiscovery() // discover tags } } } // \u0026quot;Traits\u0026quot; (\u0026quot;Behaviours\u0026quot; in the GUI) that are NOT \u0026quot;declarative-compatible\u0026quot; // For some 'traits, we need to configure this stuff by hand until JobDSL handles it // https://issues.jenkins.io/browse/JENKINS-45504 configure { def traits = it / navigators / 'io.jenkins.plugins.gitlabbranchsource.GitLabSCMNavigator' / traits traits \u0026lt;\u0026lt; 'io.jenkins.plugins.gitlabbranchsource.ForkMergeRequestDiscoveryTrait' { strategyId(2) trust(class: 'io.jenkins.plugins.gitlabbranchsource.ForkMergeRequestDiscoveryTrait$TrustPermission') } } // \u0026quot;Project Recognizers\u0026quot; projectFactories { workflowMultiBranchProjectFactory { scriptPath 'Jenkinsfile' } } // \u0026quot;Orphaned Item Strategy\u0026quot; orphanedItemStrategy { discardOldItems { daysToKeep(10) numToKeep(5) } } // \u0026quot;Scan Organization Folder Triggers\u0026quot; : 1 day // We need to configure this stuff by hand because JobDSL only allow 'periodic(int min)' for now triggers { periodicFolderTrigger { interval('1d') } } } 你也可以使用 JCasC 从 Job DSL 脚本直接创建任务。示例请查看该插件仓库。\n如何与我们讨论 bug 或新特性? 这个项目使用 Jenkins JIRA 来跟踪问题。 你可以查看 gitlab-branch-source-plugin 组件下面的问题。\n 在开发者邮件列表中发送你的邮件。\n 加入我们的 Gitter channel。\n 未来的工作 积极维护 GitLab 分支源插件 并从用户那里获取反馈以改进插件的用户体验。 扩展在 BlueOcean 中对 GitLab 流水线的支持。 资源 GitLab API 插件 GitLab API 插件 Wiki GitLab 分支源插件 项目概要 GitHub 分支源插件发布 感谢 Jenkins 以及 Google 编程夏令营 :)\n", "auhtor": "baymac", "translator": "donhui", "original": "", "poster": "./2019-09-11-introducing-gitlab-branch-source-plugin/gitlab_and_jenkins.png" }, { "uri": "https://jenkins-zh.cn/meeting/2019-09-05/", "title": "", "type": "meeting", "date": "2019-09-05 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 社区治理 公众号数据分享 线下活动 上海 地点:人民广场 费用:35 时间:需要进一步确定 日程:十月底 线上活动 形式:定期 时长:一小时 时间:周日晚上七点:grhahaha、yJunS 工作日(八点、九点):donhui、linan607、linuxsuren 费用:1~2 回顾:不作为标配,但有人愿意做的话,可以有 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/09/2019-09-05-award/", "title": "Jenkins 中文社区第二届明星贡献者名单", "type": "wechat", "date": "2019-09-05 00:00:00 +0000 UTC", "tags": ["贡献激励"], "description": "社区贡献激励", "content": " 有这样一群人,他们是一群富有热情的英雄,他们本着内心的使命感,从四面八方汇聚到开源社区,并且为社区贡献自己的一份力量。他们就是“Jenkins 中文社区贡献者”\nJenkins 中文社区贡献激励活动是一个旨在长期为社区贡献者谋福利的活动。在社区伙伴们的积极参与下,第二届社区激励活动结果新鲜出炉了!\n让我们用热烈的掌声恭喜五位明星贡献——donghui、李楠、yJunS、李煜东、书生。他们在社区运营、活动组织、技术交流等方面有着卓越的贡献,并得到社区伙伴们的广泛认可。\n为了表示对五位明星贡献者的感谢和认可,社区将给予五位奖励。奖品是由赞助方——人民邮电出版社提供的精美书籍一本(由贡献者自行挑选),同时明星贡献者名单将在 Jenkins 中文社区官网进行展示。\n奖品展示 成员 奖品 donghui 《人生护城河 如何建立自己真正的优势》 李楠 《持续交付 2.0 业务引领的 DevOps 精要》 yJunS 《精通 jQuery(第二版)》 李煜东 《算法 第四版》 书生 《极简主义——风靡欧美的工作与生活理念》 通过此次活动,让我们再次感觉到了伙伴们参与社区活动的热情! 社区也更加充满动力,会持续举办明星贡献者激励活动!\n为对 Jenkins 中文社区做出卓越贡献的伙伴们谋取更多福利! 第三届激励活动已经在路上,敬请期待。。。\n欢迎广而告之,让更多有着同样理想的伙伴们加入我们的社区! 让更多人一起共建开放、包容、活跃的 Jenkins 社区!\n相关说明: 感谢 Jenkins 中文社区赞助商—人民邮电出版社提供的奖品赞助,感谢积极参与投票的各位社区伙伴。如果有好的意见或者建议欢迎随时联系我们!!\n历次的激励名单请查看 https://jenkins-zh.cn/about/star-plan/\n", "auhtor": "shuimujiazi", "translator": "", "original": "", "poster": "eagle.jpeg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-30-open-source-meeting/", "title": "庆祝开源人线下见面会圆满结束", "type": "wechat", "date": "2019-08-30 00:00:00 +0000 UTC", "tags": ["open source"], "description": "让我们衷心庆祝开源人线下见面会圆满结束", "content": " 什么是开源精神、为什么以及如何参与开源、开源与个人以及企业之间的关系、开源社区存在的重要意义、996是否与开源背道而驰。\n 活动介绍 于2019年8月24日(周六)下午2点举办的开源人线下见面会圆满结束啦。本次活动是由Jenkins 中文社区与开源社首次联合主办的一次以社区、开源为主题的活动。\n活动主要分为几个部分: * 签到 * 嘉宾演讲 * Panel * 活动复盘\n嘉宾介绍 赵晓杰 Jenkins 中文社区发起人\n热衷于传播开源理念、开源技术。多年研发经验,目前关注于 DevOps 领域,尤其是持续交付方面。\n刘天栋 Ted 开源社理事长暨联合创始人、Apache 软件基金会正式会员\n开源社理事长暨联合创始人, Apache 软件基金会正式会员,ASF孵化器项目委员会成员/导师,ASF 筹款委员会成员/赞助伙伴大使,中国信息通信研究院。云计算开源产业联盟.特聘开源治理个人顾问。于2014年10月联合创始开源社。于2018年当选 ASF 正式成员,随后加入 ASF 筹款委员会并成为赞助伙伴大使,2019年成为 ASF 孵化器项目委员会成员,并担任孵化项目(ECharts)导师。 曾历任微软中国战略业务总监、微软开放技术公司及微软亚太研发集团负责开源技术布道及开源社区发展工作;甲骨文(中国)渠道及联盟总监、甲骨文(中国) Linux 战略总监、甲骨文大中华区中间件事业部总经理;Turbolinux 亚太区副总裁等。\n慕睿涛 北京卓晟互联网络技术有限公司 CTO\n毕业于北京工业大学,2003年加入 Sun Microsystems,负责嵌入式 Java 虚拟机的研发。曾于2008年创建了 PSP 上的JavaME 模拟器项目——PSPKVM,在 PSP 自制软件社区有很高的普及度。目前在北京卓晟互联网络技术有限公司任 CTO ,创建并主持了 JOSH 开源项目,致力于为微小型物联网终端设备提供 Java 应用开发与运行环境。\n曹勇华 Chatopera 软件工程师\n从事3年软件开发工作,掌握全栈开发技能,熟悉JavaScript、Java和Node.js等。目前在Chatopera从事春松客服,聊天机器人平台。春松客服是帮助中小型企业快速而低成本的获得好用的智能客服系统。\n演讲环节 赵晓杰分别从扁平~等级、自由~局限、多样~单一、社区精神等几个层面为我们讲解了他对于开源以及开源社区的理解,很客观地从这几个方面把开源的意义进行了剖析。 刘天栋 Ted为我们讲解了Apache 之道:从孵化器到顶级项目之路,生动地讲解了 Apache 之道20年如一日的态度持续为公众提供软件以及软件项目社区提供服务和支持。并且讲解了 Apache 如何从一个孵化器逐步成长为全球最大的开源基金会,令在场的听众听的可谓是如痴如醉。 慕睿涛为我们讲解了他在 Sun 公司的一些经历,以及跟开源开始结缘的一些事宜。从自由软件运动回顾、自由的代价、开放标准与开源代码、Android 与 Java 的纷争、Android 与 Linux 社区的分歧几个方面回顾与分析了开源与开放的本质区别。 panel 环节 此环节的主题为开源社区的发展和维护,由赵晓杰、刘天栋、慕睿涛、曹勇华等4位嘉宾进行了小组讨论。大家就社区而言比较了国内社区与国外社区环境的差别、从公司与社区等不同角度进行了分析,大家分别发表了自己的一些见解和看法。并且对于国内996的环境因素纷纷发表了自己对一些看法。 活动复盘环节 在复盘环节,现场观众纷纷发表了大家对一些看法,以及对于本次活动对一些态度。据现场观众描述,活动举办还是比较成功的,纷纷表示均有不少收获。 以下是现场观众对本次活动的一些建议: * 活动话题\u0026ndash;因为是 Jenkins 中文社区举办,所以大家在潜意识中认为可能会跟 Jenkins 相关,希望可以在活动介绍中把活动主题注明 * 活动议题\u0026ndash;在未参加活动前,大家对活动的议题不太了解,希望可以提前获知,并且可以提前将自己的问题准备好,提高效率 * 分享内容不完整\u0026ndash;因为时间关系,有些演讲嘉宾的内容没有全部分享完,令现场观众心中会有遗憾 * 互动比较少\u0026ndash;在活动中,嘉宾与现场观众的互动较少,提问环节时间较短 * 提前发通知\u0026ndash;希望可以在活动开始前几天提前通知。我们是通过邮件通知的,如果能在活动前加到微信群里的话,效果会好一些 * 设置专场\u0026ndash;希望可以设置不同专场,大家根据不同的专场参加\n结束语 在此,非常感谢京东云、平安云 GitHub、翊翎资本提供对Jenkins 中文社区的大力赞助,同时也感谢开源社与我们一起举办此次活动。\n最后,衷心庆祝本次开源人线下见面会圆满结束。\n", "auhtor": "yJunS", "translator": "", "original": "", "poster": "551566921548_.pic_hd.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-23-cloud-native-jenkins-on-aws/", "title": "AWS 上的云原生 Jenkins", "type": "wechat", "date": "2019-08-23 00:00:00 +0000 UTC", "tags": ["AWS"], "description": "我们如何运用 Terraform、Packer、Docker、Vault、ELB、ASG、ALB 或 EFS 等 AWS 服务实现 Jenkins Cloud-native,以及我们一路走来的收获", "content": " 我们使用 Jenkins 搭建持续交付流水线,和其他很多团队一样,这些年我们围绕 Jenkins 创建了很多工作流程和自动化。Jenkins 是我们团队取得成功的关键,让我们能够在上一季度顺利进入生产677次,搭建及部署时长平均为12分钟。\n我们的大部分应用和基础设施可以看作云原生,但当时 Jenkins 服务并不完全适合这个分类:服务在单个服务器上运行,同时很多任务直接在 master 上运行,其部分手动配置包括 secret、插件、定时任务和 startup hacking 的普通膨胀,该膨胀是自2014年首次搭建起不断累积而成。\nJenkins 不仅变成了单体服务和单点故障,而且拆除及重建 Jenkins 对企业也是很大的风险。\n我们决定必须做出改变。这篇博客说明了我们如何运用 Terraform、Packer、Docker、Vault、和 ELB、ASG、ALB 或 EFS 等 AWS 服务实现 Jenkins Cloud-native,以及我们一路走来的收获。\nJenkins 状态 当时不得不面对的关键问题是:如果我们将 Jenkins 服务置于一个容器/自动缩放实例中,我们需要恢复何种状态?\n问题的答案并不简单,值得一提的是,有个 Jenkins 特别兴趣小组(SIG)已经识别出所有导致这一 Jenkins 状态的存储组件。这是一个很棒的起点,因为我们至少得确保那篇文章列出的所有存储类型都考虑在内。\n捷径 这不是新问题。很多团队使用 Docker 容器运行 Jenkins,官方 Jenkins Docker 镜像也得到良好维护。如《Jenkins Dokcer 镜像》文档中解释的:\ndocker run -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts 这会把 workspace 存在 /var/jenkins_home。所有的 Jenkins 数据(包括插件和配置)都存在上述目录里。创建一个明确的 volume 可以方便管理和附加到另一个容器进行升级。\n上述示例装载主机上的 jenkins_home,其中包括所有 Jenkins 状态。然后该目录可以存在一个外部磁盘上,比如 Kubernetes 持久化存储卷。或者,如果 Jenkins 在 EC2 上运行,该目录可存在一个外部 EBS 或 EFS 卷上。\n这是一种有效的方法,但我们认为这个方法不能达到我们的标准,因为 jenkins_home 不仅包括状态,还包括配置。Block storage 拥有大量用户案例,但一个小小的配置修改就必须进行 snapshot 恢复操作,这似乎并不算是好的解决方案。此外,我们并不是想转移问题:外部存储无法免去手动配置、凭据储存在文件系统等问题。\nSCM 救援 过去,我们用了 Jenkins 备份插件,该插件基本上把配置修改备份在源码控制里,允许配置恢复。这个插件的设计想法很棒,但我们决定不使用它,因为我们无法轻松控制哪些数据实现备份,而且该插件自2011年就没有任何更新了。\n这样的话,如果我们把 jenkins_home 创建成个人 Git repo,并自动提交对 Jenkins 所做的修改呢?此处的关键是排除单独储存的任何二进制文件、secrets 或大型文件(稍后详细介绍)。我们的 .gitignore 文件如下所示:\n/.bash_history /.java/ /.kube/ /.ssh/ /.viminfo /identity.key.enc /jobs/ /logs/ /caches/ # Track static worker and exclude ephemeral ones /nodes/** !nodes/static-node/config.xml /org.jenkinsci.plugins.github_branch_source.GitHubSCMProbe.cache/ /plugins/ /saml-idp-metadata.xml /saml-jenkins-keystore.jks /saml-jenkins-keystore.xml /saml-sp-metadata.xml /scm-sync-configuration/ /scm-sync-configuration.success.log /secret.key /secret.key.not-so-secret /secrets/ /updates/ /workspaces/ 几乎所有的纯文本配置都正在 Git 实现持久化。为了给 Jenkins 提供这一配置,我们要做的就是检查 startup 上的 repo;事情渐渐成形。\nSecrets Jenkins 要访问很多地方,也就是说我们需要一个安全的 secret 存储空间。因为我们是 HashiCorpVault 的重度用户,所以自然而然就选了这个工具,不过遗憾的是,Vault 无法涵盖所有场景。比如,scm-branch-source 流水线插件需要 SCM 的认证凭据,并默认为 Jenkins 凭据插件。每次从 Vault 动态检索这些,我们都需要同步一个仓库,这可能导致错误,也会需要额外的精力去维护。\n这就是为什么我们采用 Vault 与 Jenkins 凭据混合的方法: 1. 在 startup 实例中,Jenkins 进行认证,VAult采用 IAM 认证方法。 2. 一个引导脚本检索 Jenkins master.key 和凭据插件所用的其他加密密钥。更多详情请参阅这篇文章。 3. 储存在 jenkins_home/credentials.xml 上的凭据现在可由 Jenkins 解密和访问。\n用 Vault 完全取代凭据插件是我们未来可能探索的问题,不过我们很开心这个方法满足了安全性要求, 同时能轻松与 Jenkins 的其余功能实现集成。\n任务和 workspace 数据 问题从这一步开始变得棘手:jenkins_home/jobs and jenkins_home/workspaces 都含有介于非结构化数据、创建制品和纯文本之间的混合体。这个信息很有价值,可以帮助我们审计、理解之前的流水线 build。这些 build 尺寸很大,而且不太适合 SCM 同步,因此这两个目录都排除在 .gitignore 之外了。\n那我们把这些储存在哪儿呢?我们认为 block storage 最适合存储这种数据。作为 AWS 的重度用户,使用 EFS 完全说得通,因为 EFS 的文件存储可扩展、可用性高并可以通过网络访问,非常易于使用。我们使用 Terraform 整合了 AWS EFS资源,并用 AWS 备份服务制定了一份定期备份计划。\n在 startup,我们将 EFS 卷 、符号链接 jenkins_home/jobs 和 jenkins_home/workspaces 装载到 EFS 目录上,然后启动 Jenkins 服务。\n接下来,Jenkins 服务是唯一可以读写任务 /workspace 数据的界面。值得一提的是,我们有一个 Jenkins 任务定期删除几周前的任务和 workspace 数据,这样数据不会一直增加。\nPacker 和 Terraform 实现编码化 Jenkins 你可能想知道这些是如何凑在一起的?我甚至没说过在哪里运行 Jenkins!我们广泛使用 Kubernetes,花了一些时间思考将 Jenkins 作为容器来运行,可我们决定使用 Packer 和 EC2 来运行 Jenkins master,用短暂 EC2 实例运行这些任务。\n尽管将 master 和 worker 双双作为容器运行的想法很有用,但我们在当前 Kubernetes 集群里没有找到存储 Jenkins 的地方。而且只是为了 Jenkins 就新建一个集群似乎有点儿“杀鸡用牛刀”。此外,我们想保留从其余服务中解耦的基础设施的关键部分。这样的话,如果 Kubernetes 升级对我们的 app 有影响,我们希望至少可以运用 Jenkins 进行回滚。 运行“Docker in Docker”还有另一个问题,这个问题有解,不过还是需要说明一下,因为我们的 build 经常用到 Docker 命令。\n其体系架构如下: 能使用 EC2 实例让过渡更顺畅:我们当时通过 Jenkins EC2 插件用临时 worker node 运行流水线工作,并在声明式流水线代码上调用了这一逻辑,所以不必重构就能用 Dokcer 代理节点是一个加分项。其余工作就是 Packer 和 Terraform 代码,这是我们已经很熟悉的部分了。\n插件 因为插件也是状态!我们在这个项目里想要解决的问题之一就是更好地审计、管理插件。在手动场景中,插件管理可能不受控制,很难了解安装插件的时间和原因。\n大多数 Jenkins 级别的插件配置可以在常规 Jenkins 配置 xml 文档中找到,但安装插件也导致 jar 制品、元数据、图片和其他文件存在 jenkins_home/plugin 目录。\n一种方法是在 EFS 中存储插件,不过我们想将 EFS 使用率保持在最低水平,这无法解决问题,只是转移问题。这就是为什么我们选择对插件安装进行“Packer 化”。\n基本上,在我们的 AMI 定义中,有一个插件文件罗列了插件和版本,大致如下:\n# Datadog Plugin required to send build metrics to Datadog datadog:0.7.1# Slack Plugin required to send build notifications to Slack slack:2.27 然后,我们的 AMI provision 脚本解析该文件,用 Jenkins CLI 安装插件和所选版本:\n# Wrapper function for jenkins_cli jenkins_cli() { java -jar \u0026quot;$JENKINS_CLI_JAR\u0026quot; -http -auth \u0026quot;${user}:${pw}\u0026quot; \u0026quot;$@\u0026quot; }for plugin in \u0026quot;${plugins[@]}\u0026quot;; do echo \u0026quot;Installing $plugin\u0026quot; jenkins_cli install-plugin \u0026quot;$plugin\u0026quot; -deploy done 然后,任何需要安装的新插件或升级到当前安装版本的版本升级都需要 GitHub Pull Request,这会触发搭建新 AMI。完美!\n安装其他软件 根据定义,Jenkins 要安装很多软件才能创建、测试和部署。首先,我们不想让 master node 运行任何任务,所以我们避免安装任何与任务相关的软件。Master 的主要任务是在其他短暂 worker node 上提供界面、编排 builds。\n这意味着我们可以在 worker node 上安装所需工具,但我们决定尽可能多地使用 docker run。这是因为我们是使用 Scala、Java、Node、Golang、Python等其他编程语言的多语言组织。为所有这些软件栈维护不同 build 工具可能让 worker node 设置变得有点儿复杂。\n以 JavaScript 为例,我们想让 Jenkins 针对 install 和 test 等 app 运行 yarn 命令。简单将加载检查过的 repo 目录作为一个 volume 安装到 Docker 容器里,从该容器中运行任何命令。以下为运用 Groovy 工作流代码的例子:\ndef node(command, image) { def nodeCmd = [ 'docker run -i --rm', '-u 1000', // Run as non-root user '-v ~/.npmrc:/home/node/.npmrc:ro', '-v ~/.yarn:/home/node/.yarn', '-e YARN_CACHE_FOLDER=/home/node/.yarn/cache', \u0026quot;-v ${env.WORKSPACE}:/app\u0026quot;, '--workdir /app', \u0026quot;${image}\u0026quot; ].join(' ') sh \u0026quot;${nodeCmd} ${command}\u0026quot; } 然后,我们检查仓库后可以调用这个功能:\ncheckout scm node('yarn install --frozen-lockfile', 'node:12.6.0-alpine') 漂亮收尾!因为除了 Docker 后台程序或 kubectl,我们不必在 worker machine 上安装、维护所用工具的多个版本。我们也相信 build 命令在本地和 CI 环境之间是一致的,因为用的是同一个 Docker 镜像。\n运用临时 node 创建时要记得缓存依赖。比如,一个 worker node 重建后,我们丢失了 sbt 缓存,由于缓存必须重建,这导致创建时间变慢。如果外部依赖不可用,这甚至会导致失败。我们决定将相关依赖缓存在另一个外部 EFS 上,以求获得更快、更可靠的 build。\n结语 Jenkins 是一个很棒的工具,但在管理外部状态上略有不足,因此以 cloud native 的方式创建 Jenkins 较有难度。我们的方法并不完美,但我们相信这个方法结合了两者的精华,而且确保安全性、操作简单、有弹性。令人高兴的是,我们完成这个项目,并把所有的生产 build 迁移到新的 Jenkins 服务之后,可以终止 master server,让自动缩放在几分钟内完成重建,而不会影响以前储存的状态。\n", "auhtor": "Alberto Alvarez", "translator": "shunw", "original": "https://medium.com/bench-engineering/cloud-native-jenkins-on-aws-b5c957c4fe18", "poster": "butler-in-action.png" }, { "uri": "https://jenkins-zh.cn/meeting/2019-08-21/", "title": "", "type": "meeting", "date": "2019-08-21 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 社区治理 对于微信群里设置一个投诉机制,对于符合一定条件的,把被投诉的人移出 @linuxsuren 在公众号后台或者邮件(admin at jenkins-zh.cn)发送投诉,写明被投诉人和理由 @linuxsuren 可以先和被投诉人进行私下沟通,如果不改正的话,就执行移除 @Shunw19 在公众号里发起一个投票,调研大家对公众号文章类型,质量的看法以及建议 @linuxsuren 文章类型:技术类、志愿者等活动类 考虑定期发起志愿者招募,例如在寒暑假之前 @linuxsuren 需要的人数 @Shunw19 分布在多个城市 如何组织 @linuxsuren 尽量明确任务 区分社区志愿、活动志愿者 @baobeizuoshoubuli 把完成志愿任务的人,在官网展示出来 @linuxsuren 给公众号加个目录分类,检索 @Shunw19 可以通过关键字检索 贡献者采访 @linuxsuren 口语比较好的来协作采访国外的贡献者 需要出一些稿子(中文、英文) 线下活动 北京 黑客松\n 活动报名已经启动 需要把活动宣传工作做好 开源人线下见面会 8月24日\n 教程 https://jenkins-zh.cn/tutorial/\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-19-hackathon-signup/", "title": "开源持续交付黑客松,5000大奖等你来拿", "type": "wechat", "date": "2019-08-19 00:00:00 +0000 UTC", "tags": [], "description": "黑客松编程比赛开启报名,巅峰对决,等你来战!", "content": " 你是否希望与顶尖编程高手同场较量,是否想体验创意与技术的碰撞?黑客松编程比赛释放你的激情,满足冠军梦想。\n黑客松编程比赛报名正式拉开帷幕。本次赛事以 DevOps 为主题集结研发、测试、运维、产品、文档、HR等各路人马,秉承开源开放的方式,旨在为各个行业面临的 IT 挑战提出解决方案,鼓励人人参与开源社区,展现开源之魅力。\n本次比赛为期两天,由 Jenkins 中文社区联手 CloudBees、京东云、阿里云、码云、开源社和微软组织承办。选手要在48小时内根据所选议题设计解决方案,在有限的时间内激发无限创意想法。\n比赛规则 活动中创建的新代码仓库均在码云上的 Jenkins 中文社区进行托管,任何人都可以根据对应开源协议进行修改、分发等操作。 所有代码工作(包括文档、设计等)必须当场完成。若提前准备或抄袭,一经发现,将取消当年及次年的比赛资格。 所有项目必须可以做到持续构建,持续交付和灰度发布则为加分项。 推荐与不同技能的小伙伴组建3人左右的团队,一起完成项目。 评选标准 团队协作、完整性、创新程度、难易程度、大众评分\n报名方式 本次比赛通过第三方平台“活动行”进行线上报名。组团报名满3人可享9折优惠,欢迎公司组团报名。 请点击开源持续交付黑客松或扫描下列二维码报名参赛。\n报名说明 选手须年满十八周岁且熟练使用码云。需要注意的是,报名者选定项目提议后,在报名时必须提供与所选项目相关且于活动发布后合并了的 PR 链接,我们将根据该链接决定是否通过报名。\n报名成功后,选手需给出明确项目提议,即有待完成的具体功能列表和需要修复的缺陷列表等。请注意,只有审核通过的项目提议可以在最后的线下活动继续比赛。\n上述流程必须在报名截止日期9月30日之前完成。后续通知可通过关注 Jenkins公众号获得。如果你对 Jenkins 技术交流感兴趣,可以在公众号后台回复“社区活动”来加入我们的微信群。\n奖项设置 冠军项目,5000元 亚军项目,2000元 入围项目,500*2元 项目提议 Kubernetes 插件优化 所需技能:Kubernetes、Java Jenkins 中文社区网站改版 所需技能:Hugo、Markdown、JavaScript、CSS Jenkins 命令行工具 jcli 所需技能:Golang、Jenkins API Jenkins 微信公众号后端服务 所需技能:Golang、微信公众号 API Jenkins Java 语言客户端 所需技能:Java、Jenkins API 微信机器人 所需技能:JavaScript ", "auhtor": "shunw", "translator": "", "original": "", "poster": "hackathon-poster.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-17-award/", "title": "提名 Jenkins 中文社区激励候选人", "type": "wechat", "date": "2019-08-17 00:00:00 +0000 UTC", "tags": [], "description": "Jenkins 中文社区贡献激励活动", "content": " Jenkins 中文社区是由 Jenkins 国内的爱好者、贡献者组成,共同推广以及完善 CI/CD 技术的学习试用和落地。我们非常欢迎每一位同学为社区贡献自己的一份力量,相应的我们会给予杰出贡献者奖励以表示认可和感谢,同时也欢迎更多对社区活动感兴趣的同学加入! 社区贡献激励是一个旨在长期为社区贡献者谋福利的活动,因此社区每三个月就会举办一次激励活动,惊不惊喜,激不激动! 第一期激励活动已经圆满落下帷幕,让我们再次恭喜三位明星贡献者——donhui,zacker330,yJunS,感谢三位对社区做出的杰出贡献,此处应该有掌声!!\nHold on!! 没有赶上第一期活动的同学们,请往这里看——第二期激励投票活动马上开始了,在这个炎热的夏天,让我们一起行动起来吧!\n评选规则: 社区秉承公平、公正、公开的原则,希望每位社区贡献者都有机会参与评选,本次活动将采取邮件征集投票的方式,选出本期社区突出贡献者\n参评标准: 翻译 Jenkins 相关文章 Jenkins 中文本地化 发表 Jenkins 原创文章 Review PR 在 Jenkins 中文社区有开源贡献(eg: 提交新的特性代码,提交补丁优化代码,撰写和改进项目的文档 etc.) 积极参与 Issue 的讨论,如答疑解惑、提供想法或报告无法解决的错误 组织社区活动 Meet up 其他重大贡献 投票规则: 请各位同学请选出心目中最佳贡献者,发送邮件至 admin@jenkins-zh.cn 可以推荐一位或者多位候选人 请在邮件正文中标注推荐的候选人信息: GitHub ID 微信号 推荐理由(理由要切实与本社区相关的哟,不要因为小哥哥小姐姐太好看就给投票哈) 邮件投票截止时间2019年8月28日23点59分——我们会在社区的例会上对从邮件中征集的候选人进行公开投票,最终选出五位最佳贡献者给予奖励(从直接参与社区贡献的人中挑选四位,从社区技术群积极帮助他人的人中挑选一位) 贡献激励: 加入 Jenkins 社区贡献者名单,并展现在 Jenkins 中文社区官网——获得由与社区合作的人民邮电出版社提供的技术书籍 有机会成为线下技术沙龙特邀嘉宾 相关说明: 评选结果将在 “Jenkins 官方微信公众号”进行公布——合作的出版社将直接邮寄奖品。\n激励让社区活动更加有趣,让我们一起构建伟大,无所不能。还不快快行动,让更多的人因为你的贡献打开通往新世界的大门!\n", "auhtor": "shuimujiazi", "translator": "", "original": "", "poster": "eagle.jpeg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-16-tutor-recruitment/", "title": "持续交付黑客松--导师招募", "type": "wechat", "date": "2019-08-16 00:00:00 +0000 UTC", "tags": ["黑客松", "导师", "招募"], "description": "持续交付黑客松导师招募", "content": " Jenkins 中文社区计划于2019年10月25日发起一场以 DevOps 为主题的黑客松编程比赛,我们将以开源、开放的方式策划、组织本次活动。开源\u0026ndash;黑客松上产生的所有代码、文档甚至想法都是开源的,都会托管在国内最大的代码托管网站\u0026ndash;码云上。开放\u0026ndash;任何岗位、背景的人都可以参与我们的活动,不仅仅只有研发、测试、运维等岗位的同学,我们非常欢迎文档工程师、产品经理、敏捷教练的加入,甚至 HR、PR 的同学也可以来参与。\n 集结这么多具有不同技能的同学后,我们希望能解决什么问题呢?我们希望让大家切实地体会到,参与开源并没有你想的那么困难、无趣,也绝不仅仅只有键盘侠的 Coding 独秀,人人都可以参与开源社区。通过开源社区可以集中解决很多通用性的问题,通过开源的黑客松活动,更是可以集中地解决我们在使用开源的持续交付方案中遇到的诸多通点。\n主办方 Jenkins 中文社区 合作方 CloudBees 码云 京东云 开源社 微软 导师招募 如果你在 - Java、JavaScript、Golang、css、Hugo - K8S 、Jenkins、Jenkins API - CI/CD、敏捷等 DevOps\n等相关领域有丰富的经验、独到的见解,包括且不限于以上领域,欢迎踊跃报名成为黑客松活动的导师。我们会认真、仔细地筛选符合条件的报名者。\n我们热切期盼你的到来,指导参赛队取得好成绩!\n 要求导师在某个领域工作至少5年以上\n 报名方式 发送邮件到event@jenkins-zh.cn,内容如下,请如实填写(注: GitHub ID 示例:https://github.com/githubId):\n活动名称: 姓名: 公司名称: 所在地: 部门: 职务: 联系电话: 微信号: GitHub ID: T 恤尺码: 个人简介(若您被选中导师,以下信息将发布在网站及海报上,请仔细填写):如工作经验、是否带过团队等信息 技术指导方向:参考项目提议选择指导方向 是否指导过黑客松比赛: 导师相关义务 积极配合议题的评审工作,以确保解决方案的高质量 比赛期间(10.25晚-10.27晚),请与指导团队准时到达比赛现场 协助活动组织者在微信等宣传渠道宣传本次活动 比赛结束后分享比赛心得及经验 你将获得 收获业内同行间最有价值的碰撞结果 K8S、Jenkins、Docker 等先进工具最佳实践案例 DevOps 、敏捷等方法的实际落地法 建立同行业人脉关系 树立个人行业影响力 为您的团队招揽精英 ", "auhtor": "linan607", "translator": "", "original": "", "poster": "./2019-08-16-tutor-recruitment/tutor.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-15-jenkins-pipeline-stage-result-visualization-improvements/", "title": "Jenkins 可视化阶段视图的改进", "type": "wechat", "date": "2019-08-15 00:00:00 +0000 UTC", "tags": ["pipeline", "blueocean"], "description": "流水线除了成功或失败以外,还有一种介于两者之间的状态", "content": " 最近发布了的一些变更给了流水线编辑者新的工具以改善在 Blue Ocean 中的流水线可视化,有一个备受瞩目关注的工单JENKINS-39203,这会导致当流水线的构建结果为不稳定时所有的阶段都被设置为不稳定的。这个缺陷导致无法快速地识别为什么构建是不稳定的,使得用户必须查看完整的日志和 Jenkinsfile 才能弄明白究竟发生了什么。\n为了修复这个问题,我们引入了一个新的流水线 API 用于为单个流水线步骤添加额外的结果信息。像 Blue Ocean 这样的可视化工具在决定阶段如何显示时会使用到这新的 API。像 junit 这样的步骤只能设置整个构建结果,现在可以通过新的 API 设置步骤级别的结果信息。我们创建了新的步骤 unstable 和 warnError,这样流水线编辑者在更复杂的场景下仍然可以利用这个新的 API。\n该问题涉及到的重要的修复包含在如下的插件中,它们都需要 Jenkins 2.138.4 以及更新的版本:\n Pipeline: API 2.34 Pipeline: Basic Steps 2.18 (需要同步更新到 Pipeline: Groovy 2.70) Pipeline: Graph Analysis 1.10 Pipeline: Declarative 1.3.9 Blue Ocean 1.17.0 这里是一条使用了 unstable 步骤的流水线在 Blue Ocean 中的截图,只会把失败的阶段标识为不稳定的:\n例子 这里给出一些如何在你的流水线中使用该特性的示例:\n 使用新的步骤 warnError 用于捕获错误,并把构建和阶段标记为不稳定的。 warnError 只需要一个 字符串 的参数,用于当捕获到错误时以日志的形式输出。当 warnError 捕获到一个错误时,它会记录该消息以及错误,并设置构建和阶段的结果为不稳定的。效果如下: warnError('Script failed!') { sh('false') } 使用新的步骤 unstable 设置构建和阶段结果为不稳定的。可以使用该步骤直接替换 currentBuild.result = 'UNSTABLE',在 warnError 不够灵活时这会比较有用。步骤 unstable 只需要一个 字符串 参数,当该步骤运行时会作为消息。使用的方法如下: try { sh('false') } catch (ex) { unstable('Script failed!') } JUnit Plugin: 更新到 1.28 或者更高的版本,使得步骤 junit 可以直接把该阶段设置为不稳定的。 Warnings Next Generation Plugin: 更新到 5.2.0 或者更高的版本,使得步骤 publishIssues 和 recordIssues 可以直接把该阶段设置为不稳定的。 其他插件: 如果你的流水线被其他插件中的步骤标记为不稳定的,请(在检查没有重复项后)给该组件提交一个新的 issue,清晰地描述哪个步骤是有问题的,以及发生问题的环境,并添加链接到该文章的开发者区域,以便维护者了解如何才能解决该问题。 局限 如果你不迁移到 unstable 或 warnError 步骤,或不升级插件到集成来新 API 的情况下设置构建状态,那么即使构建是不稳定的,Blue Ocean 也不会把任何阶段显示为不稳定的。 即使在这些变化后,currentBuild.result 继续只会覆盖构建状态。不幸的是,由于 currentBuild 是作为全局变量而实现的,因此,无法让它设置步骤或者阶段级别的结果,这意味这它没有任何步骤级别的上下文可以使用到新的 API。 Pipeline Stage View Plugin 尚未升级到使用这个新的 API,因此,这些变更不会在它提供的可视化中得到体现。 历史 Jenkins 流水线步骤可以以两种方式完成:成功并返回一个结果(可能为 null),或者是失败的,并抛出一个异常。当步骤失败并抛出异常时,该异常会贯穿整个流水线,直到有其他的步骤或者 Groovy 代码捕获,或者它到达流水线的顶层并导致流水线失败。基于抛出的异常的不同类型,流水线最终的结果可能不是失败(例如:某些情况下是被终止的)。基于异常传播的方式,像 Blue Ocean 这样的工具可以轻松地识别哪些步骤(以及阶段)是失败的。\n为了能够让流水线能够与相应的 Jenkins API 交互,对于流水线构建来说,可以在构建期间修改构建结果也是有必要的。对于其他的,这使得流水线可以使用构建步骤以及原先出自于自由风格的任务中的项目。\n在一些情况下,一个流水线步骤需要能够成功地完成,以便流水线可以继续正常执行,但对此而言能够标记有某种错误发生,因此,在可视化时能够识别到发生错误的步骤,即使没有彻底失败。比较好的一个例子就是 junit 步骤。该步骤关注特定的测试结果,如果有任何错误,会把整个构建结果标记为不稳定的。这种行为对类似 BlueOcean 的可视化工具而言是有问题的,因为该步骤是成功的,而且无法通过编程的方式覆盖于该步骤相关的最终结果。\n再次查看下 JENKINS-39203,我们看到关于可视化有两项基本的选项。因为有的步骤导致构建变成不稳定的,设置总体的构建结果是不稳定的,或者所有的步骤都成功完成来也展示为不稳定的;或者由于我们没有办法把特定步骤相关的构建结果作设置,它们可能显示为成功的。最后,选择了第一个选项。\n为了解决该问题,部分用户尝试通过抛出异常并在阶段中增加 try/catch 这样的代码块用于处理异常,这样 Blue Ocean 能够借助这些异常来标记步骤和阶段的结果为期望的状态,而且,捕获异常后,流水线可以继续正常执行。这种方式不容易理解,脆弱,而且无法在申明式的流水线中使用。\n开发者 如果你是一个插件的开发者,并在集成流水线时使用了步骤,想要利用这个新的 API 的话,你的步骤就可以给出一个非成功的结果,而不是抛出异常。请查看 Jenkins 开发者邮件列表中的这个帖子,如果你遇到任何问题了,可以在那里提问。\n", "auhtor": "dwnusbaum", "translator": "linuxsuren", "original": "https://jenkins.io/blog/2019/07/05/jenkins-pipeline-stage-result-visualization-improvements/", "poster": "./superhero.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-14-continuous-testing-what-why-and-how/", "title": "持续测试的那些事", "type": "wechat", "date": "2019-08-14 00:00:00 +0000 UTC", "tags": ["测试", "持续测试", "持续交付", "软件生命周期", "DevOps"], "description": "持续测试究竟是什么?你又如何实现它呢?", "content": " 敏捷,DevOps 和持续交付已然存在于现今每个技术人员的词汇当中。我们都想要像硅谷里的巨头和初创公司一样,敏捷开发,快速发布软件,做出创新的产品。 向敏捷转型在多方面都已有总结,并且到了能被顺利实践的程度。然而,测试仍然是一个有思想困惑和实践挑战的领域。 当软件发布周期从以年、月缩短到以周、天为单位,或者更短时; 我们该如何重塑测试实践,以保证当软件发布到生产环境时能令用户满意, 而不是掉链子?\n鉴于大多数 DevOps 实践仍然把测试视为软件生产中最令人头疼的瓶颈,显然,这是一个常见的挑战。\n持续测试就是答案,但持续测试究竟是什么?你又如何实现它呢? 维基百科定义持续测试为「在软件交付流水线中执行自动化测试的过程,目的是为了获得关于预发布软件业务风险的即时反馈」。 但是这个定义缺少了本质,缺少了持续测试所示意的转变的量纲。 除了自动化是一个重要的部分以外,持续测试从根本上转变了测试, 它把线性过程中的时间点事件嵌入到整个过程当中去,作为基础贯穿于整个软件交付周期的所有活动中。\n敏捷环境里持续测试的目标应该是「迭代内测试(in-sprint testing)」。 不管你的迭代是两周还是四周,目标都应该是完成迭代内所有类型的测试,这样每个迭代都可以得到一个测试完备的,准备交付的软件。 事实上很多持续交付的最佳实践都会告诉你,你不能简单的在没有持续测试的情况下去做持续交付。 如果你认为你的迭代时间不允许你去做一个综合的测试,很有可能是你对它的理解有误。\n七个步骤实现持续测试 1. 尽早规划测试,甚至早于写代码 描述不清的要求或者有不正确的理解,都可能导致返工甚至延期。 使用像行为驱动开发(BDD), 验收测试驱动开发(ATDD)和 基于模型的测试这类技术所使用的工具,如 cucumber/gherkin 和 CA Agile Requirements Designer (ARD), 可以确保业务主管,产品经理,开发人员和测试人员充分沟通并记录需求,定义清晰的测试用例,提早编写测试脚本,以达到一个流畅的测试过程。\n2. 优化测试覆盖率 一些组织默认「每次运行所有的测试」来保证代码覆盖率。这不但浪费资源还延长了测试周期,而且没有真正的保证代码覆盖率。 测试那些需要测试的部分,以节省时间、金钱和资源。可视化模型可以让各种路径被探索优化,以便只用少量的测试用例就能提供最大化的覆盖率。 可以借助 Rally, Jira, HP ALM, JIRA 等此类工具导入测试用例、移除重复用例、分发优化过的用例。\n3. 测试左移 为了实现「迭代内(in-sprint)」测试,将测试前置——这样测试可以在开发周期的早期运行。开发人员自己测自己的;卓越中心提供专家,定制系统和服务。 自动化测试覆盖 UI, 功能,性能和安全。各个团队一起工作,一起以要交付给客户的业务价值为专注点。这需要对开发者友好的工具以及文化转变。\n4. 提供完整的测试环境 提供测试环境的能力对实现持续测试是至关重要的。 通过友好型(例如编码、CI/CD 集成、被开源支持的软件)开发工具按照需求提供的完整的测试环境来消除障碍和减少等待时间。 这些环境应该包括:\n 虚拟服务——给那些不可达,不可访问的,还在开发中的服务提供鲁棒的模拟。开发和测试可以根据虚拟服务模拟实际服务返回的结果持续并行工作。 按照需求测试数据——帮助并保证各个团队可以使用与生产环境类似的数据来运行综合的测试。 预发环境——准备上线的需求,使用后退役。 5. 获取正确的测试数据 在很多应用发布周期,获取鲁棒性测试数据能力的缺乏会造成严重延期。为了准确的测试新功能,测试数据应该尽可能的跟生产环境时所应用遇到的数据相近。 如果测试数据缺乏特定真实世界的特征(例如具体字段、数据定义、负面场景等),测试就很难找到许多潜在问题和应用的弱点。 理解数据模型并提取出正确的数据是一种特殊的技巧。尽管使用生产环境数据测试是最接近真实的,但数据隐私条例通常都会限制使用生产数据。 下面,我们来看看 CA Test Data Manager 是如何复制生产数据,抹掉敏感信息的同时保持了测试所希望的生产数据特征(接近现实,并且多行指征完整)的。 生产数据不可用时,测试数据也可以使用 TDM 工具根据模版生成。\n6. 别忘了测试右移 测试向右移动,使用开发周期和生产中的数据来优化测试周期、调整测试用例,以建立最佳回归套装。右移技术包括真实用户监控、金丝雀部署、A/B 测试、混沌工程等。 例如,通过测试右移,你可以确定哪些功能被用于生产,保证回归测试覆盖能够这些功能。 同样的方法,你可以开放新功能给一小部分人(内部或外部),了解新功能可能给生产造成的影响,按需调整。 许多敏捷公司例如 Facebook 和 Netflix 都严重依赖测试右移。 Gartner(美国一家从事信息技术研究和顾问的公司)最近发布了一份测试右移的报告, 声称测试右移对 DevOps 实践来说是「必需」的。\n7. 使用数据矩阵持续优化 建立跨团队协作,根据可行性分析和反馈机制不断优化。持续交付和持续测试就像旅行。确保你的所有团队都有 KPI, 查阅那些能够提供附加优化的数据。 不要只是收集数据,那很容易办到,收集并且总结数据能够帮助你提出持续优化的确切建议。探索应用发布流程以实施建议,并作为所有团队应用交付周期的「单一事实来源」。\n要了解更多关于持续测试的挑战和实践,点击这里 CT Academy Video Series.\n", "auhtor": "Sushil Kumar", "translator": "tomatofrommars", "original": "https://dzone.com/articles/continuous-testing-what-why-and-how", "poster": "./2019-08-14-continuous-testing-what-why-and-how/test_automation.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-09-volunteer-recruitment/", "title": "持续交付黑客松--志愿者招募", "type": "wechat", "date": "2019-08-09 00:00:00 +0000 UTC", "tags": ["黑客松", "志愿者", "招募"], "description": "持续交付黑客松志愿者招募", "content": " Jenkins 中文社区计划于2019年10月25日发起一场以 DevOps 为主题的黑客松编程比赛,我们将会以开源、开放的方式策划、组织本次活动。开源——黑客松上产生的所有代码、文档甚至想法都会是开源的,都会托管在国内最大的代码托管网站——码云上。开放——任何岗位、背景的人都可以参与我们的活动,不仅仅只有研发、测试、运维等岗位的同学,我们非常欢迎文档工程师、产品经理、敏捷教练的加入,甚至 HR、PR 的同学也可以来参与。\n 集结这么多具有不同技能的同学后,我们希望能解决什么问题呢?我们希望让大家切实地体会到,参与开源并没有你想的那么困难、无趣,也绝不仅仅是只有键盘侠的 Coding 独秀,人人都可以参与开源社区。并且,通过开源社区可以集中地解决很多通用性的问题,通过开源的黑客松活动,更是可以集中地解决我们在使用开源的持续交付方案时遇到的诸多痛点。\n主办方 Jenkins 中文社区 合作方 CloudBees 码云 开源社 微软 志愿者招募 如有意愿参与黑客松活动,欢迎踊跃报名。我们会认真、仔细地筛选符合条件的报名者。\n报名方式 发送邮件到event@jenkins-zh.cn,内容如下,请如实填写(注: GitHub ID 示例:https://github.com/githubId):\n活动名称: 姓名: 公司名称(选填): 所在地: 职业: 联系电话: 微信号: GitHub ID: T 恤尺码: 个人擅长: 参加志愿者的初衷: 志愿者职责划分 文案、宣传 拍照/摄像 签到、场地布置 场地秩序维护、活动事项解答、物品库存管理等 志愿者职责说明 依据不同志愿者的职责分工,志愿者需提前对自己对职责做一个大概对计划表,提前与社区活动相关负责人员相互沟通,尽量减少在活动中遇到突发事件对情况以及对可能遇到突发事件的情况做好应对方案。\n志愿者福利 我们会根据志愿者的实际参与情况,给予志愿者相应福利: * 免费参加自本活动启动时一年内的所有活动 * 活动纪念品 * 赠送与本社区有合作关系的其他公司或者社区组织的活动门票\n", "auhtor": "yJunS", "translator": "", "original": "", "poster": "./2019-08-09-volunteer-recruitment/needyou.jpeg" }, { "uri": "https://jenkins-zh.cn/meeting/2019-08-08/", "title": "", "type": "meeting", "date": "2019-08-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 线下活动 上海 开源基础设施峰会2019 11月4-6日 https://www.openstack.cn/ 开源年会 11月2-3日 https://www.bagevent.com/event/5518928?bag_track=bagevent meetup 9月21/22日 场地(赵晓杰) 讲师,三名(需要征集一名) 活动宣传稿(高嵘) 礼品(空缺) 北京 黑客松 门票价格,早鸟票,标准票,晚鸟票 100,120,150 志愿者(彦军) 设备,摄像等 视频剪辑(王顺) vs-code 服务器的配置要求? 开源人线下见面会 8月24日 成员招募 明天拉个群\n教程 https://jenkins-zh.cn/tutorial/\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-08-jenkins-x-new-logo/", "title": "Jenkins X 新 logo", "type": "wechat", "date": "2019-08-08 00:00:00 +0000 UTC", "tags": ["jenkins x"], "description": "Jenkins X 推出新 logo", "content": " 早在2018年3月,Jenkins X 项目作为 Kubernetes 自动化 CI/CD 的 Jenkins 对应项目突然出现。作为这次发行的一部分,它的 logo 是 Jenkins logo 的一个变种,一个叼着烟斗的船长,他的帽子上有 Kubernetes logo。\n在软件中,我们喜欢说命名是困难的——因为确实如此。另一件同样困难的事情是试图在 logo 中捕捉项目的本质。Logo 在一个小空间里有很多意义。Icon ,例如 Jenkins logo,与许多开发人员建立强烈的情感联系。因此,考虑到这一点,我们总是密切听取有关新 logo 的反馈,以及人们如何看待这个项目。\n为什么我们要改变 logo 在听取各种不同来源的各种反馈时,我们听到了许多积极的事情,但也强调了一些问题和困惑。\n 并不是每个人都喜欢这个 logo,我们听到了不少关于人们不喜欢它的方面的反馈意见,其中“叼着烟斗”这个反馈意见排在最前面。 与 Jenkins 项目的混淆——我们也看到这个 logo 与 Jenkins 的其他吉祥物更加一致,这导致了关于 Jenkins X 是什么类型的项目的混淆——一些人认为这是生态系统中的另一个插件。 我们还听说,使用 Kubernetes logo 令人困惑,或可能并非完全在 Kubernetes logo 指南的范围内。 从实用的角度来看,我们也听说这个 logo 太详细了,因此不能很好地作为一个 icon,尤其是一个 favicon。它被看作是吉祥物而不是 logo。 随着持续交付基金会的成立,Jenkins X 是基金会创始项目之一,区别于 Jenkins,我们觉得是时候处理这个反馈了。所以我们真的回到了画板上,思考什么样的 logo 可以更好地代表 Jenkins X 作为一个项目。我们考虑了我们希望人们与项目相关联的内容:开源、持续交付、速度、自动化、稳定性、团队等等。我们也想要一个 logo,可以提高代表性,所以我们想要避免一个基于人的 logo,它可能会无意间编码性别、年龄和其他因素。此外,“X” 已经成为项目 logo 的一个独特部分,所以我们想在新 logo 中真正强调它。\n设计新 logo 和社区反馈 最终,我们专注于尝试可视化速度和自动化,这导致了机器人的想法。但是,我们仍然希望以某种方式向 logo 中的原始 Jenkins 项目表示致敬。我们明确决定不坚持传统上与 Kubernetes 和相关项目相关的航海主题。我们经历了几次迭代,精炼并减少细节。设计工作与 Linux 基金会创意总监 Craig Ross 及其团队密切合作,他们还制作了持续交付基金会,CNCF,Network Service Mesh 和 Tekton 品牌。\n在核心 Jenkins X 团队确定他们满意的设计之后,我们将其带到社区以获得反馈并解决一些细节问题。我们有很多反馈,包括它让人们想起的所有事情(一个颠倒的考拉,Bill Nye,Reddit logo,Flash Gordon,Tekton logo 等)。最初的设计有一个始终如一的主题,那就是它没有反映出社区的友好性。Kyounger 特别帮助分析了这一反馈,并加倍努力提出解决方案。我们同意并喜欢这个建议,并将其反馈到 logo 的最终版本中。非常感谢 Kenny 和开源 FTW!\nJenkins 和 Jenkins X Jenkins X 最初是 Jenkins 子项目,现在是持续交付基金会(CDF)的一个独立项目。新 logo 中的领结时刻提醒着人们它的出处。尽管我们的 logo 和品牌可能会发生变化,但在 CDF 的庇护下,我们将继续与 Jenkins 项目紧密合作,为开发人员的 CI/CD 和生产力需求共享相同的服务精神。\n推出新 logo 我们现在已经开始切换到新的 logo,并期待看到一些新的 swag 很快可用。我们现在将把旧的 logo 作为 Jenkins X 项目的吉祥物。如果您希望更新使用的 logo,新的艺术品在这里。\n这对项目来说是一个很大的改变,但最终我们投入这么多时间和精力的原因是,这对我们来说很重要,我们在做的每件事中都代表着 Jenkins X 的精神。所以当你使用 Jenkins X 的时候,当你看到新 logo 的时候,我们想让你感觉到开放友好的社区的一部分,我们想让你的团队专注于你真正想要关注的事情:以任何速度和规模交付高质量的软件。\n", "auhtor": "tracymiranda", "translator": "donhui", "original": "https://jenkins-x.io/news/new-logo-jenkins-x/", "poster": "./2019-08-08-jenkins-x-new-logo/jenkinsx-stacked-color.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-07-hackathon-startup/", "title": "开源持续交付黑客松--号角声起", "type": "wechat", "date": "2019-08-07 00:00:00 +0000 UTC", "tags": ["黑客松"], "description": "给你48小时,可以持续交付多少创意呢?", "content": " Jenkins 中文社区计划于2019年10月25日发起一场以 DevOps 为主题的开源黑客松编程比赛,该活动旨在为当下金融、能源、政务、交通等场景面临的 IT 挑战提出解决方案,我们希望本次赛事期间您也能够收获业内同行间最有价值的碰撞成果。\n 本次活动由 Jenkins 中文社区主办,并由受到 Cloudbees、码云、京东云以及开源社等合作伙伴的大力支持。我们非常欢迎关心和关注开源以及持续交付的企业以及社区加入或者支持我们。有意与我们合作,可以在 Jenkins 公众号后台回复,或者发送电子邮件到 admin@jenkins-zh.cn。\n比赛规则 活动中创建的新代码仓库,都会托管在 Jenkins 中文社区托管在码云上的组织下 。因此,任何人都可以根据对应的开源协议进行修改、分发等。\n 所有的代码(或文档、设计等)工作,必须在现场完成,如有发现提前准备或者抄袭者,将会被取消当年以及次年的比赛资格 所有项目必须可以做到持续构建,能做到持续交付、灰度发布的项目可以加分 推荐与不同技能的小伙伴组成3人左右的团队,一起完成项目 评选标准:团队协作、完整性、创新、难度、大众评分\n报名说明 年满十八周即可报名参加,鉴于我们的所有项目都会托管在码云上,因此,参赛者必须能够熟练地使用码云。而为了能够证明你能够完成本次活动中的项目,当你从下面的项目提议中选定一个后,在报名时必须提供一个与你所选项目相关的、自本活动发布后的、已经合并了的 PR 链接,我们会根据该 PR 链接来决定你的报名是否可以通过。\n报名成功后,需要给出明确的项目提议——要做的具体功能列表、修复的缺陷列表等。请注意,只有审核通过的项目提议才可以在最后的线下活动中继续参加比赛。\n上述过程必须在“报名截止”之前完成。具体报名方式,请关注 Jenkins 公众号后续的通知,或者在 Jenkins 公众号后台回复“社区活动”后加入我们的微信群。\n项目提议 Kubernetes 插件优化 所需技能:Kubernetes、Java Jenkins 中文社区网站改版 所需技能:Hugo、Markdown、JavaScript、CSS Jenkins 命令行工具 jcli 所需技能:Golang、Jenkins API Jenkins 微信公众号后端服务 所需技能:Golang、微信公众号 API Jenkins Java 语言客户端 所需技能:Java、Jenkins API 微信机器人 所需技能:JavaScript 奖项设置 悬赏项目(1~2个) 冠军项目(1个) 亚军项目(2个) 入围项目(若干) 活动安排 8月1日~8月31日 议题征集 9月30日 报名截止 10月25日~10月27日 比赛时间(以下为比赛日的时间) 10月25日(周五)晚上七点~八点 签到 10月25日(周五)晚上八点~九点 比赛动员宣讲 10月25日(周五)晚上九点~10月27日(周日)下午四点 持续创作 10月27日(周日)下午四点~晚上七点 作品评选 10月27日(周日)晚上七点~晚上八点 颁奖仪式 ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "hackthon.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/08/2019-08-05-jenkins-multi-branch-pipeline/", "title": "在大型企业里维护多分支流水线", "type": "wechat", "date": "2019-08-05 00:00:00 +0000 UTC", "tags": ["Jenkins", "multi-branch", "Pipeline", "remote-file"], "description": "如果没有适当的解决方案,在大型企业可能难以创建和维护多分支流水线", "content": " Jenkins 是 DevOps 领域里非常好的 CI/CD 工具,它凭借其独特的功能,几乎可以满足你一切的的业务要求。其中一个独特的功能是多分支流水线(Multi-branch 流水线),可以动态配置流水线。但是,随着公司的发展,单独的多分支流水线并不能完全满足你的所有需求,特别是在涉及大型企业时,你需要考虑流水线的集中管理,治理,稳定性,限制和安全性等其他事项。因此对于具有 Jenkins 流水线的大规模 CI/CD 环境,你需要添加之前没有想到的更多功能。\n动态配置流水线 当一个开发人员创建一个新分支并将其推送到远程代码仓库时,Jenkins 会为这个新分支动态创建流水线。根据代码仓库,甚至也可以作为动态创建 Pull Request 流水线。这个动态功能在使用 Feature 分支或其他类似功能的团队中非常有用,由于本文的主题不是多分支流水线,你可以在端到端多分支流水线项目创建中找到详细信息和一些示例。\n流水线即代码 在多分支流水线中,脚本存储在项目代码仓库中,这就是“流水线即代码”的概念。此外,当你拥有小型开发人员团队或项目没有大量分支时,它非常有用。这样,开发人员可以根据需要更改流水线,将更改推送到分支,并立即看到更改生效,但对于拥有数百或数千名拥有大量项目的开发人员的大型企业而言,这种方案就完成不可行了。\n集中式库 当你的团队或项目增加时,是时候考虑一种方法,比如通过共享的的方式应该在所有项目中。从长远来看,这种“集中式库”变得非常关键,因为随着规模的扩大,流水线中出现了新的要求或变化,在这种情况下,手动更改每个流水线或脚本对管理员来说将是一场噩梦。因此,如果你在一个地方进行更改并且每个流水线都得到更新,那么拥有该集中式库将更加实用。这是 Jenkins 共享库概念的用武之地。有关详细信息,你可以访问该站点。\n即使你只有一个流水线,仍然可以使用集中式库。\n治理与稳定 如果你的团队有对 CI/CD 一定了解的开发人员,并且你确信他们不会做出重大更改或编写脚本错误导致影响环境的稳定性,那么将流水线脚本放在代码中是很好的。但是,你真的确定吗?\n有人很可能会意外删除流水线文件或者可能出现小错误,这些小错误都会影响 CI/CD 的稳定性。如果你在早期发现这些错误时很容易解决这些错误,如果没有,这些微小的变化或错误将可能比你想象的更严重的影响 CI/CD,它将被传播到不同项目中的所有分支或 tag,这会变得很难解决。\n你需要将正确的流水线脚本推送到所有分支和/或代码仓库,或是要求每个开发人员提取最新的脚本,这种类型的问题集中式库这种更高级的方式来解决,除此之外,你的环境会因为有人可能会删除 Jenkins 文件或输入一些拼写错误带来风险。\n远程文件插件 为了消除不必要的更改的风险并降低使用的库的复杂性,我们需要以某种方式将流水线脚本与项目/代码代码仓库分开,同时仍继续使用多分支流水线功能。为此,我们有远程文件插件。\n这个插件使多分支流水线能够从其他代码仓库运行/加载流水线脚本,而不是将它们放在项目/代码代码仓库中,通过这个功能,你可以拥有一个单独的代码仓库,你可以在其中放置所有流水线脚本,并且只能为你自己提供访问权限。这样,你将拥有与集中式库相同的集中式流水线脚本代码仓库。此外,你可以将流水线脚本存储在集中式库本身中。\n这个功能的好处是除了有访问权限的人之外,没有人能够在流水线脚本中进行更改。你在集中流水线脚本中所做的任何更改都将影响使用该脚本文件的所有多分支流水线。这样,你无需等待所有开发人员获取更新版本或将脚本推送到所有代码仓库上的所有分支。\n另一个好处是,如果你将集中式流水线脚本放入 BitBucket 或 GitHub 等代码仓库中,你还将拥有代码审查功能。这样,你可以与其他人共享代码仓库,同时仍可限制或查看其他人所做的更改。\n结论 在大型企业中创建 CI/CD 流水线并不容易,你需要考虑治理,限制,稳定性和安全性等概念。在此上下文中,借助 Jenkins 的其他功能,Remote File Plugin 提供了一个独特的功能,用于集中,维护和共享流水线脚本。\n有关插件的详细信息,你可以访问插件的 Wiki 页面。\n", "auhtor": "Aytunc BEKEN", "translator": "shenxianpeng", "original": "https://dzone.com/articles/maintaining-multi-branch-pipelines-in-large-scale", "poster": "./2019-08-05-jenkins-multi-branch-pipeline/cover.jpeg" }, { "uri": "https://jenkins-zh.cn/about/volunteer-part-in/", "title": "活动志愿者报名", "type": "about", "date": "2019-08-05 00:00:00 +0000 UTC", "tags": [], "description": "社区活动志愿者报名", "content": " Jenkins 中文社区将不定期举行一些活动,志愿者的参与是不可或缺的。希望有更多的小伙伴可以通过志愿者的身份参与进来\n 如何报名 以邮件的形式发送到志愿者申请 內容如下(注: Github ID 示例:https://github.com/githubId):\n活动名称: 姓名: 公司名称(选填): 所在地: 职业: 联系电话: 微信号: Github ID: 个人擅长: 参加志愿者的初衷: 志愿者福利: 免费参加自本活动启动时一年内的所有活动 活动纪念品(小型活动没有纪念品) 赠送与本社区有合作关系的其他公司或者社区组织的活动门票 申明 欢迎小伙伴们报名志愿者,并且为志愿者准备了一些社区福利。但为了避免有人浑水摸鱼的事情发生,我们会根据实际参与情况以及参与活动的态度积极性来评判是否拥有志愿者福利的待遇。 ", "auhtor": "yJunS", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-31-pipeline-config-history-plugin/", "title": "Jenkins 流水线配置历史插件介绍", "type": "wechat", "date": "2019-07-31 00:00:00 +0000 UTC", "tags": ["pipeline", "plugins", "jenkins"], "description": "Jenkins 流水线配置历史插件,让流水线变更可追溯", "content": " 流水线是在 Jenkins 中创建任务的有效的和现代的方式。 为了快速、简单地识别流水线变更,我们开发了流水线配置历史插件。 这个插件检测流水线的变更,并为用户提供一个选项,以明显地、可追溯地查看流水线配置两次构建(差异)之间的变更。\n一切是如何开始的 这一切开始于十年之前 —— 经典的任务类型 (例如:自由风格、Maven 等等)。 每隔一段时间,用户就会联系我们,因为他们的任务无法在一夜之间完成。 为什么这个任务失败了呢? 这次失败和任务配置变更有关系吗? 用户典型的回答是:\u0026rdquo;我们没有改任何东西\u0026rdquo;,但这是真的吗? 我们思考了这个问题,并决定开发一个插件来帮助我们解决这个问题。 这就是plugin:jobConfigHistory[任务配置历史]的想法和开始。\n现在可以查看任务配置的变更(例如其他分支、JDK版本等),而且更常见的情况是,破坏构建的原因是任务配置的变更。\n多年来,该插件得到了开发,目前仍在开发中。 添加了新的功能,不仅可以查看任务配置,还可以查看全局和代理配置的变更。 还可以恢复旧的配置版本。 如今,这个插件已经有超过30,000次安装量。 多年来,JobConfigHistory 减轻了我们的日常工作 —— 我们有超过3000个 Jenkins 任务! 然后出现了一种新的任务类型:流水线。\n流水线 —— 需要一些新的东西 流水线任务和经典的任务类型有根本地区别。 经典的任务类型是通过 Jenkins GUI 配置的,而流水线任务是配置即代码。 实际上,每个流水线任务都是通过 Jenkins GUI 创建的,然而这并不一定是流水线配置的位置。 流水线可以被配置:\n 直接在 Jenkins 任务中作为脚本。 代码将直接插入任务配置页面。 作为源代码管理系统(SCM)中的 Jenkinsfile:流水线配置在 SCM 中的文本文件(Jenkinsfile)中定义。 在任务本身中,只配置了 Jenkinsfile 存储库的路径。 在构建过程中,Jenkinsfile 从 SCM 中被检出并被处理。 作为共享库:流水线配置的一部分被移动到单独文件中,它可以由多个任务使用。 这些文件也保存在 SCM 中。 即使这样仍然需要 Jenkinsfile(或者任务中的流水线脚本)。 对于任务配置的每次保存操作,如果发生了变更,JobConfigHistory 将创建实际任务配置的副本。 只有当流水线配置作为脚本插入到任务配置页面时,该方法才适用于流水线任务。 JobConfigHistory 未检测到 Jenkinsfile 或共享库中的变更。 您必须使用 SCM 系统查看 Jenkinsfile 或共享库的变更。 在构建时间和对 Jenkinsfile 或共享库的变更之间找到相关性是复杂且耗时的。\n这个新问题不仅仅是 JobConfigHistory。 需要一个新的解决方案来检测流水线变更并显示 Jenkins 中的这些变更。 所以我们开发了流水线配置历史插件。\n在每个流水线运行期间,Jenkinsfile 和相关的共享库都保存在任务的构建目录中。 流水线配置历史插件将最近运行和前一次运行之间流水线文件的变更保存为历史事件。 因此,当流水线任务以成功的构建结束时,您可以检查任何使用的流水线文件是否发生了变更。 您还可以看到发生变更的构建。\n因为流水线配置可以由可能发生变更的多个文件组成,所以 diff 中只显示两个构建版本之间发生变更的文件。 这使得整个过程更加紧凑和有效:\n但有时您可能想要显示的不仅仅是流水线文件之间的差异。 您可能希望查看哪些流水线文件正在使用,或者这些文件在使用时的内容。 因此可以查看所有文件及其内容。 如果需要,您也可以下载:\n结论 我们在生产中成功地使用了流水线配置历史插件。 它从第一天起就帮助我们解决了由于流水线配置变更而出现的问题。 流水线配置历史插件不会替换任务配置历史插件。 插件有不同的用例。 很多时候,任务或流水线配置上的小变更也会产生很大的影响。 由于任务或流水线配置的变更与不同的构建行为之间的时间相关性,现在可以大大减少分析构建失败的时间和精力。 任务配置历史和流水线配置历史插件允许我们在咨询和解决问题方面为用户提供帮助。通过访问任务的配置历史,我们可以更快地解决问题。这些插件对我们的日常工作是必不可少的。\n", "auhtor": "pch-maintainers", "translator": "donhui", "original": "https://jenkins.io/blog/2019/07/15/pipeline-config-history-plugin/", "poster": "./2019-07-31-pipeline-config-history-plugin/sunset.jpg" }, { "uri": "https://jenkins-zh.cn/about/about-event-planning/", "title": "活动策划", "type": "about", "date": "2019-07-31 00:00:00 +0000 UTC", "tags": [], "description": "社区组织活动策划", "content": " 本文讨论社区组织 meetup 、workshop 等活动策划的参考指引,方便社区其他地区组织者及志愿者借鉴使用。\n活动策划分为以下几步骤: - 活动地区及组织者确定 - 招募志愿者 - 活动任务分工认领 - 活动宣传\n1、活动地区及组织者确定 组织者需向 Jenkins 中文社区申请活动组织者得到许可后,才可以进行后续步骤。 - 确定活动地区 - 确定活动主题 - 确定大概活动日期\n2、招募志愿者 组织者可根据需要在公众号进行发布志愿者招募信息 - 活动策划志愿者 - UI 志愿者 - 现场活动志愿者\n志愿者采取主动报名的方式,报名方式可分为2种: - 社区内部报名 - 公众号发布招募信息,根据招募信息中的报名方式报名\n3、活动任务分工认领 活动主题确定后,如果有志愿者参与可根据下表进行任务分工认领:\n 任务分类 具体事项 完成情况 负责人 确认 场地 租赁与赞助、环境确认 赞助与礼品 赞助清单、礼品采购 讲师 讲师日期及演讲时长确认、ppt 收集 活动宣传 活动稿撰写、活动行及海报制作 活动议程 活动流程安排、日期提醒 场地布置 桌椅摆放、投影、白板 茶歇准备 茶歇采购、摆放 活动签到 参与者签到、礼品发放 活动拍摄 图片、视频拍摄及收集 抽奖活动 抽奖软件、抽奖环节安排 订餐安排 讲师与志愿者订餐 4、活动宣传 至少在活动举行前一个月完成活动宣传稿、活动行以及海报制作 - 首先在社区公众号发布活动通知 - 合作社区一并进行宣传 - 活动海报可在邻近活动日期进行发布 - 如果有精力可制作倒计时海报\n", "auhtor": "linan607", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-30-jenkins-meetup/", "title": "开源人线下见面会", "type": "wechat", "date": "2019-07-30 00:00:00 +0000 UTC", "tags": ["开源"], "description": "我们将从开源人精神、如何参与开源、开源与企业关系、开源社区存在的意义、996与开源关系等几个部分进行分享讨论。社区重于代码,你同意吗?", "content": " 本次活动是由 Jenkins 中文社区与“开源社”联合主办的一次关于如何参与开源的见会。\n大家共同探讨什么是开源精神、为什么以及如何参与开源、开源与个人以及企业之间的关系、开源社区存在的重要意义、996是否与开源背道而驰。\n我们的观点是:社区重于代码。是否与你的想法一致?欢迎来辩!\n分享嘉宾 赵晓杰 Jenkins 中文社区发起人\n热衷于传播开源理念、开源技术。多年研发经验,目前关注于 DevOps 领域,尤其是持续交付方面。\n刘天栋 Ted 开源社理事长暨联合创始人、Apache 软件基金会正式会员\n开源社理事长暨联合创始人, Apache 软件基金会正式会员,ASF孵化器项目委员会成员/导师,ASF 筹款委员会成员/赞助伙伴大使,中国信息通信研究院。云计算开源产业联盟.特聘开源治理个人顾问。于2014年10月联合创始开源社。于2018年当选 ASF 正式成员,随后加入 ASF 筹款委员会并成为赞助伙伴大使,2019年成为 ASF 孵化器项目委员会成员,并担任孵化项目(ECharts)导师。 曾历任微软中国战略业务总监、微软开放技术公司及微软亚太研发集团负责开源技术布道及开源社区发展工作;甲骨文(中国)渠道及联盟总监、甲骨文(中国) Linux 战略总监、甲骨文大中华区中间件事业部总经理;Turbolinux 亚太区副总裁等。\n慕睿涛 北京卓晟互联网络技术有限公司 CTO\n毕业于北京工业大学,2003年加入 Sun Microsystems,负责嵌入式 Java 虚拟机的研发。曾于2008年创建了 PSP 上的JavaME 模拟器项目——PSPKVM,在 PSP 自制软件社区有很高的普及度。目前在北京卓晟互联网络技术有限公司任 CTO ,创建并主持了 JOSH 开源项目,致力于为微小型物联网终端设备提供 Java 应用开发与运行环境。\n彭志雄 平安云 GitHub 产品专家\n13年IT行业工作经验,领域包括系统集成、售前支持和咨询、云计算和 DevOps 等业务。\n时间地点 日期 2019.8.24 地点 北京市朝阳区东直门外斜街56号 A座302 活动流程 时间 流程 13:00-13:30 签到 13:30-14:00 Jenkins 社区在国内的发展——赵晓杰 14:00-14:30 Apache 之道:从孵化器到顶级项目之路——刘天栋 Ted 14:30-14:45 茶歇 14:45-15:45 Panel 开源社区的发展和维护 15:45-16:00 茶歇 15:45-16:00 开源等于开放吗?——关于开源与开放之关系的思考——慕睿涛 16:00-16:30 用平安云 GitHub 转变企业软件开发模式——彭志雄 16:30-17:00 活动复盘 现场更有好礼相送 平安云赞助的保温杯 Jenkins 中文社区定制的笔、本以及贴纸 主办方 赞助企业 想更多地了解本次活动,请在 Jenkins 公众号后台回复“社区活动”,让我们社区的小伙伴把你拉进微信群。\n想报名的同学,请点击阅读原文。\n", "auhtor": "linan607", "translator": "", "original": "", "poster": "./2019-07-30-jenkins-meetup/shou.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-29-leveraging-jenkins-on-kubernetes/", "title": "在 Kubernetes 上使用 Jenkins ", "type": "wechat", "date": "2019-07-29 00:00:00 +0000 UTC", "tags": ["plugins", "pipeline", "Kubernetes", "ci", "cd"], "description": "Jenkins 是一个功能强大的自动化和 CI/CD 工具,可以成为 Kubernetes 流水线的重要组成部分", "content": " ​有几种方法可以在 DevOps 环境中管理您的云基础架构。 DevOps 是一种鼓励快速流动的应用程序开发以及促进 IT 团队开发、测试、发布过程无缝无缝衔接的方法。\nJenkins 通过自动化将持续集成(CI)和持续交付(CD)无缝集成到开发流程中来优化工作流程。\n可以使用 Kubernetes 中的 Jenkins pod 部署这些技术, Jenkins pod 可以根据团队的具体需求进行扩展。\nCI/CD 流水线 Jenkins 是 CI/CD 的同义词,它是自动化开发、部署应用程序和微服务的完美工具,目前是市场上最流行的自动化工具。 Jenkins 拥有1000多个插件,可以轻松地与其他系统(包括 Kubernetes )集成。插件不仅提供多系统集成,而且显著增强了 Jenkins 的能力,使 Jenkins 能够帮助您构建和部署几乎任何类型的项目。我们在另一篇文章中介绍了生活中最需要的20个 Jenkins 插件。\n​由于 Jenkins 和 Kubernetes 的原生兼容性,设置自己的 CI/CD 流水线非常容易。与基于 VM 的部署相比,在 Kubernetes 上部署 Jenkins 优势更明显。例如,获得按需拥有特定于 Jenkins slaves (代理)项目的能力,而不是让一个 vm 池空闲等待任务。它将使用 master-agent 体系结构来完全自动化微服务的创建和部署以及测试和部署所需的环境。\n​可以使用 Helm、kubectl 或 GUIs 部署 Jenkins ,以便将新的 pods 部署到集群中。安装后,下一步是为 K8s 配置 Jenkins 插件。我们需要配置系统设置,例如,代理在哪里找到 Jenkins master ,代理将使用的 Docker 镜像等。当然,将 Jenkins 配置为与 CI/CD 工作流一起工作也是至关重要的,包括设置测试和部署参数以及要如何设置 Jenkins 控制的集群。一旦 Jenkins 启动并运行,就可以实现一个完全自动化的连续交付环境。\n在 Jenkins 中设置一个流水线 ​让 Jenkins 启动只是一个开始,下一步是在 Jenkins 内配置 CI/CD 流水线。 你可以先运行 minikube service Jenkins ,然后使用其 Web UI 访问 Jenkins。\n​然后,您可以选择安装必要的插件。 根据您要创建的流水线,您可能需要下载并安装合适的插件,以实现流水线自动化以及更好的管理。必须使用 Kubernetes 插件。\n​另一个值得讨论的插件是 Kubernetes Continuous Deploy 插件,它专门为处理流水线的持续交付设计的。 该插件将处理为测试创建新的 pods 以及测试和部署之间的转换。\n​配置完所有插件后,重新启动 Jenkins。 Jenkins 提供的一个很好的功能能够自动执行这些手动更改,因此下次您配置 CI/CD 系统(例如,在基础结构迁移的情况下)时,不必再次通过手动更改。 您只需接收一个具有与以前相同配置和插件的实例。嵌入到 Jenkins Docker 镜像和 Jenkins 配置文件 config.xml 中的脚本 install_plugins.sh 实现了这一功能。\n​现在,您可以继续创建您的第一个流水线,为它分配凭据,并开始在流水线内部进行开发。记住, Jenkins 并不总是从本地存储中提取代码;您需要在第一次配置时手动发出推送请求。\n​创建第一个流水线,然后您可以通过优化 minikube 立即运行新应用程序。在大多数 CI/CD 工作流中,手动推送请求实际上很方便,因为现在您可以通过流水线更好地控制想要推送的代码。\n在不同的情况下推动变化 ​当您打开应用程序代码并对其进行更改时, Jenkins 不会立即更新部署包。相反,您必须提交更改并等待 Jenkins 提取这些更改(取决于代码签出的配置方式),然后才能执行其他操作。\n​在 Jenkins 用户界面上,有一个 Build now 命令用于运行新的构建。构建完成后,下次使用 Minikube 运行应用程序时,您将看到所做的更改。 Jenkins 流水线的配置方式使该工具非常有用。\n​例如,您可以使用 Jenkins 来支持多团队开发。 Jenkins 流水线作为代码运行,这意味着具有正确凭据的任何用户都可以提交更改并执行流水线中内置的流程。\n​它也非常通用。 如果服务器突然崩溃,流水线及其中的进程将自动恢复。 Jenkins 永远不会失去对它管理的集群的控制权,因此您可以使用 Jenkins完全消除对 CI / CD 环境的手动配置的需要。\n​我个人最喜欢的是 Jenkins 管理多个流水线的方式,管理员可以清楚地查看系统中的所有流水线。再加上暂停和恢复流水线的能力,管理微服务和大型项目的开发使用 Jenkins 非常有帮助。\n​另外的伟大的插件是流水线和多分支流水线,它帮助我们可视化 CI/CD 流。它允许在 repo 中定义一个 jenkins 文件,包括我们希望 jenkins 执行的所有步骤。不需要从 GUI 进行手动配置(可能只保留给管理员),并且允许开发人员灵活地控制给定项目/分支的流程。由于它在 Github 中,因此它也可以与任何其他应用程序库一起进行版本控制。\nJenkins 和 Kubernetes ​让我们回到我们的主要观点:在 Kubernetes 上使用 Jenkins 。从 Jenkins 工具的工作方式来看,很容易看出这种自动化度量如何完美地补充了 Kubernetes 。一旦配置了插件,每次触发新的构建/任务, Jenkins 都会在 K8s 中创建一个 Pod (通过设计用于执行该工作的按需代理)。一旦完成, Pod 将被销毁,从而避免了有固定的代理池等待任务执行的需要。如您所见, Kubernetes 为每个开发团队提供了强大的 CI/CD 基础架构,而 Jenkins 则大大简化了对该环境的管理。\n​这种组合能够在不同的情况下改进 CI/CD 工作流,包括在更大的开发项目中。如果你考虑到大量 Jenkins 插件的可用性,包括 Kubernetes 流水线、凭据以及目前已经可用的更多插件,您就会知道您有一个强大的 CI/CD 工具可以使用。甚至有能力将流水线中的非安装工作和材料工作分开;没道理不爱它?\n这篇文章最初发表在这里。\n", "auhtor": "Juan Ignacio Giro", "translator": "baobeizuoshoubuli", "original": "https://dzone.com/articles/leveraging-jenkins-on-kubernetes", "poster": "./2019-07-29-leveraging-jenkins-on-kubernetes/sea.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-18-jenkins-weekly-release/", "title": "Jenkins 每周版更新", "type": "wechat", "date": "2019-07-18 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "本次更新的版本包括:2.180~2.184", "content": " 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.29 到 3.33。 (issue 57959, issue 50095, issue 57713, 完整变更日志) 2.181 (2019-06-16) 插件管理界面中,允许对有可选依赖的插件禁用。 (issue 33843) 用于等待外部进程结束的线程池可能导致类加载溢出。 (issue 57725) 稳健性:当调度队列中的任务时有异常抛出可能会导致无法调度其他任务。 (issue 57805) 替换节点通道相关的部分异常栈为简单的消息。 (issue 57993) 更新 JNA 4.5.2 到 5.3.1,修复了在 AIX 上使用 OpenJDK 加载共享库的问题。 (issue 57515) 开发者:更新依赖 ant 1.9.2 到 1.9.14。 (pull 4053) 内部:使用 SpotBugs 代替 FindBugs 用于静态分析。 (pull 4062) 内部:为 hudson.model.UpdateSite#isDue 添加 synchronized 标记。 (issue 57466) 2.180 (2019-06-09) 由于 JNLP 节点在特定情况下无法连接云节点,Remoting 回退到 3.29(在版本 2.176 中退化) (issue 57759, issue 57713) 改善配置即代码对 ListView 的兼容性。 (issue 57121) ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“./2019-07-09-jenkins-release/great-wall.jpeg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-15-let-s-celebrate-java-11-support/", "title": "让我们庆祝 Jenkins 对 Java 11的支持", "type": "wechat", "date": "2019-07-15 00:00:00 +0000 UTC", "tags": ["core", "developer", "java11", "community", "platform-sig"], "description": "本文是为了庆祝 Jenkins 对 Java 11的支持", "content": " NOTE:这是由 Java 11支持团队准备的联合博客文章:Adrien Lecharpentier、Ashton Treadway、Baptiste Mathus、Jenn Briden、Kevin Earls、MaríaIsabelVilacides、Mark Waite、RamónLeón 和 Oleg Nenashev。\n 我们为此努力工作,现在就在这里。我们非常激动地宣布,从 Jenkins 2.164(2019年2月10日发布)和 LTS 2.164.1(ETA:3月14日)开始,在 Jenkins 中全面支持 Java 11。这意味着您现在可以使用 Java 11 JVM 运行 Jenkins master 和代理程序。\n从2018年6月开始,组织了许多活动来改进 Jenkins 代码库并添加 Java 11支持。除了这些事件之外,Core/Plugins 维护者和许多其他贡献者都在努力工作,确保他们发现并解决与 Java 11支持相关的尽可能多的问题。\n支持 Java 11的努力导致在 Jenkins 中创建了 JEP-211: Java 10+ support in Jenkins。它还促使平台特别兴趣小组的成立,以协调 Java 11工作和其他平台支持工作。\n庆祝活动 我们想花点时间感谢参与这些任务的每个人:代码贡献者、问题记者、测试人员、活动策划者和与会者以及社区中所有慷慨地为这项工作提供时间和支持的人。谢谢你们!\n以下是一些帮助完成此任务的贡献者(按字母顺序排列):\nAlex Earl, Alyssa Tong, Ashton Treadway, Baptiste Mathus, Carlos Sanchez, Daniel Beck, David Aldrich, Denis Digtyar, Devin Nusbaum, Emeric Vernat, Evaristo Gutierrez, Gavin Mogan, Gianpaolo Macario, Isabel Vilacides, James Howe, Jeff Pearce, Jeff Thompson, Jenn Briden, Jesse Glick, Jonah Graham, Kevin Earls, Ksenia Nenasheva, Kohsuke Kawaguchi, Liam Newman, Mandy Chung, Mark Waite, Nicolas De Loof, Oleg Nenashev, Oliver Gondža, Olivier Lamy, Olivier Vernin, Parker Ennis, Paul Sandoz, Ramón León, Sam Van Oort, Tobias Getrost, Tracy Miranda, Ulli Hafner, Vincent Latombe, Wadeck Follonier\n(如果我们错过了此列表中的任何人,我们深感抱歉。)\n指南 为了简单起见,以下是使用 Docker 镜像在 Java 11上启动 Jenkins 的方法。您可以通过为镜像的标签添加后缀来选择基于 Java 11的镜像-jdk11。如果要升级现有实例,请在升级之前阅读 Jenkins Java 版本升级从8到11。\n所以你可以在 Java 11上运行 Jenkins:\ndocker run -p 50000:50000 -p 8080:8080 jenkins/jenkins:2.164-jdk11 但是,和往常一样,您仍然可以使用其他方法启动 Jenkins。请参阅 Java 11上运行 Jenkins 的更详细文档。\n开发者指南 对于参与 Jenkins 开发的开发人员,您可以在 Java 11开发人员指南中找到有关开发和测试 Jenkins 以在 Java 11上运行的详细信息。\n此资源重新组合可能需要执行的修改,以验证 Java 11插件的兼容性。\n下一步是什么 尽管这是一项重大成就,但我们仍有工作要做。\n我们的首要任务是为 JenkinsFile Runner 项目添加 Java 11支持。从那里开始,我们将继续为 Jenkins X 项目和 Evergreen 项目提供 Java 11支持。\n所以,即使这对我们来说是个大问题,这也不是故事的结局。这是使Jenkins社区的用户,开发人员和成员受益的重要一步。\n参考链接 Running Jenkins on Java 11 https://wiki.jenkins.io/display/JENKINS/Known+Java+11+Compatibility+issues https://wiki.jenkins.io/display/JENKINS/Java+11+Developer+Guidelines JEP-211:Java 11 support in Jenkins ", "auhtor": "alecharp", "translator": "yJunS", "original": "https://jenkins.io/blog/2019/03/11/let-s-celebrate-java-11-support/", "poster": "./2019-07-15-let-s-celebrate-java-11-support/c3bd32a48c96b4f10dad51a10f644233.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-14-jenkins-pipeline-workshop/", "title": "持续交付落地实践工作坊", "type": "wechat", "date": "2019-07-14 00:00:00 +0000 UTC", "tags": ["jenkins", "pipeline"], "description": "Jenkins 中文社区2019第二场工作坊", "content": "Jenkins 中文社区第二次线下持续交付落地实践工作坊在召唤每一位希望学习并掌握持续交付技术的同学,就在 2019年7月27日(周六)。\nKubernetes 已经成为容器技术中必不可少的平台,甚至会作为未来的“操作系统”。相信每一次 IT 从业人员都有理由把 Kubernetes 掌握,本次活动首先由 Linux 基金会与 CNCF 基金会官方认证 Kubernetes CKA 培训讲师(LFAI)的孟凡浩为我们分享 Kubernetes 的入门介绍。\n之后,分享如何基于 Kubernetes 强大的平台下实践持续交付。\n在上次的工作坊实践中,我们首先完整地介绍了 Jenkins 的流水线功能,然后大家一起通过四个练习项目加强并巩固了 Jenkins 流水线 Jenkinsfile 文件的编写。\n上次练习的项目包括:\n 构建 Maven 项目 制品归档 构建 Docker 镜像 参数化构建,指定 Docker 镜像 Tag 过程中录制的视频,可以从我们的优酷地址上找到 https://i.youku.com/jenkinszh\n而对于参加本次工作坊实践活动的同学,可以根据自身的情况选择练习上面的题目或者下面进阶的题目:\n 构建 Maven 项目并发布到 Nexus 使用私有 Nexus 中的依赖进行构建 构建 Docker 镜像并推送到 Harbor 构建 Heml Charts 并推送到 Chartmuseum 我们期望每一位参加的同学都可以从中学习并掌握基于 Jenkins 的持续交付技术,助力你所在团队的 DevOps 实践。更多的实训项目请参考 https://jenkins-zh.cn/about/course/#17\n最后,让我们一起感谢京东云为我们本次活动提供的 Kubernetes 云计算资源。因此,每一位参加练习的同学,只需要带上自己的笔记本,以及 SSH 客户端即可。\n想更多地了解本次活动,请在 Jenkins 公众号后台回复“社区活动”,让我们社区的小伙伴把你拉进微信群。\n想报名的同学,请点击阅读原文。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "pipeline-example.png" }, { "uri": "https://jenkins-zh.cn/about/branching-strategy/", "title": "分支策略", "type": "about", "date": "2019-07-09 19:56:04 +0800 +0800", "tags": [], "description": "推荐使用的分支策略", "content": " 本文讨论分支策略主要是提供执行并行任务时的参考指引,方便社区贡献者借鉴使用。\n需要理解和注意以下几点: - 三个代码仓库 - 每个任务一个分支 - 分支策略\n三个 repo git 是一个分布式版本管理系统。以提交文章到 jenkins-infra/wechat 为例,在这个过程中,我们会涉及到三个代码仓库:\n jenkins-infra/wechat repo,也就是 upstream repo,你需要 git remote add upstream 将其配置为 upstream repo fork/wechat repo,如果你从这里 clone 的话,也就是对应的 origin repo local repo,所有的分支管理都是从这里发起的 每个任务一个分支 每个任务一个分支的目的是,保证在 PR review/merge 的时候不会发生冲突。 换言之,PR review/merge 不存在先后关系,可以独立进行。 对于原创文章或翻译文章,每篇文章(包括资源文件)是一个独立的任务,每个任务对应一个分支。\n分支策略 假设已经完成 PR 提交操作(jenkins-infra/wechat:master \u0026lt;- fork/wechat:dev-01),下面是可能存在的相关分支。\njenkins-infra/wechat: master fork/wechat: master dev-01 local: master dev-01 这里的故事可以分为以下几步:\n 在 Github UI 上完成 fork 操作,所以,jenkins-infra/wechat:master 对应到 fork/wechat:master git clone 到本地,所以 fork/wechat:master 对应到 local:master 在本地创建 dev-01 分支 提交 commit,并 push 到 fork/wechat:dev-01 GitHub UI 发起 PR (jenkins-infra/wechat:master \u0026lt;- fork/wechat:dev-01) 这里需要注意的是,jenkins-infra/wechat:master 和 fork/wechat:master 经常会 不一致(jenkins-infra/wechat:master 是 source of truth ,会有很多 merge 来的 commits), 这并没有什么大的影响。\n有了上面的认识,下面就是一步一步的命令行,假设上面的 dev-01 已经被合并,需要新建 dev-02 分支执行新的任务:\n git checkout master git pull upstream master --rebase git checkout -b dev-02 (do something) git add . \u0026amp;\u0026amp; git commit -m 'do something' git push origin dev-02 # origin is your fork via Github UI (jenkins-infra/wechat:master \u0026lt;- fork/wechat:dev-02) ", "auhtor": "donhui", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-09-jenkins-release/", "title": "Jenkins 长期支持版更新", "type": "wechat", "date": "2019-07-09 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "本次更新的版本包括:2.164.2、2.164.3、2.176.1", "content": " 2.176.1 (2019-06-10) 自 2.176 以来的变更:\n 恢复安装向导中用到的中文本地化资源。 (issue 57412) Robustness: 当 ComputerListener#onOnline() 发生运行时异常后不把节点设置为离线状态。 (issue 57111) CLI 中通过参数 (-remoting option) 对远程模式的支持已经被移除。 (pull 3838, 博客发布)\n 移除符号 nonStoredPasswordParam 对密码参数定义的误导,因为,它会存储加密后的数据。 (issue 56776)\n 移除对 CCtray (cc.xml) 文件的默认支持。 要使用该功能,需要按照插件 CCtray XML Plugin。 (issue 40750)\n 增加 CLI 命令 stop-job 终止构建。 (issue 11888)\n 在日志配置中支持关闭一项日志记录器。 (issue 56200)\n 为 REST API 的响应增加运行参数过滤器。 (issue 56554)\n 构建结束后更新状态图标。 (issue 16750)\n 在 Jenkins 节点的界面上移除对 Java Web Start and JNLP 的误导性引用。 (pull 3998)\n 当涉及到以虚拟 SYSTEM 用户运行构建时,通知管理员潜在的不安全设置。 (issue 24513)\n 当运行在虚拟的 SYSTEM 认证下时,在构建日志中增加一条日志消息。 (pull 3908)\n 迁移所有中文本地化资源文件到 简体中文插件。 (pull 4008)\n 调整流刷新行为,使得运行在远程的节点上时有更好的性能。这可能会导致部分插件在节点机器上打印构建日志却不刷新输出时丢失消息。 通过 -Dhudson.util.StreamTaskListener.AUTO_FLUSH=true 可以让自由风格的构建回到之前的行为。 注意,流水线的构建总是期待远程刷新。 (pull 3961)\n Winstone 的版本从 5.1 更新到 5.2,使得 HTTPS cipher 为可配置的。 (issue 56659, issue 56591, 完整变更日志)\n 从核心中移除邮件相关的本地化字符串。确保你使用 Mailer Plugin 1.23。 (issue 55292)\n 如果工作空间已经被一个跨节点运行的流水线重连时使用了,那么,它将不会再给新的构建分配租期。 (issue 50504)\n 开发者:为了支持从任意插件中加载本地化资源,Stapler 的版本从 1.256 更新到 1.257。 增加接口 jenkins.PluginLocaleDrivenResourceProvider 用于让其他插件可以定制本地化资源的查找过程。 (JEP-216, 完整变更日志)\n 开发者:本地化库的版本从 1.24 更新到 1.26,使用插件可以覆盖查找本地化资源文件的逻辑。 (pull 3896, JEP-216, 完整变更日志)\n 开发者:为类似于单行 f:password 的多行文本凭据添加 Jelly UI 组件 f:secretTextarea。 (pull 3967, 在 Jenkins 中存储凭据)\n 开发者:SystemProperties 现在可以用于节点端的代码。参考 SystemProperties#allowOnAgent。 (pull 3961)\n 2.164.3 (2019-05-09) 有问题的 console notes 会使得 ConsoleNote#readFrom 抛出一个无意义的 NegativeArraySizeException 异常,并导致构建日志无法正常显示。 (issue 45661) 安装向导没有正确地对密码进行转义,导致遇到特殊字符后会有错误。 (issue 56856) 使得 Jenkins 经典界面中的表单提交按钮与 Firefox 即将发布的缺陷修复兼容。 (issue 53462, Firefox bug 1370630) 正确地刷新 Maven console annotator 的输出。 (issue 56995) 使得 Debian/Ubuntu 的启动脚本与 Java 11 兼容。 (issue 57096) 复用 Stapler 请求分发 telemetry。 (issue 57167) 2.164.2 (2019-04-10) 安全修复。 (安全公告) 运行在 Microsoft Docker 下的 Windows Server 2016 时,工作空间以及归档文件无法工作。(由 2.150.2 引入的缺陷回归) (issue 56114) 当丢弃不可读的指纹数据时避免 NullPointerException 。 (issue 43218) ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“./2019-07-09-jenkins-release/great-wall.jpeg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-08-wechat-answer-1/", "title": "Jenkins 中文社区技术交流微信群问题集之一", "type": "wechat", "date": "2019-07-08 00:00:00 +0000 UTC", "tags": ["pipeline"], "description": "群里讨论过的问题(使用方法、缺陷)太多,无法全部包含在一篇文章中", "content": " 申明:下文中的问题是群友发起的,回答则是由笔者收集整理的。\n1. 同一流水线,如何做某个阶段定时执行代码扫描 这个需求的意思是存在一条流水线,流水线中的阶段为:构建阶段 \u0026ndash;\u0026gt; 代码扫描阶段 \u0026ndash;\u0026gt; 发布测试环境阶段 \u0026ndash;\u0026gt; \u0026hellip; 而提问者希望当有代码提交时,就执行整条流水线。当到某个时间点时,就只执行扫描阶段。\n回答一 当代码没有变化,我们为什么要重复执行扫描呢?\n回答二 换成两个流水线,一个提交触发,一个定时触发\n回答三 一条流水线加个开关设置是否跳过扫描。\n2. 有人做过增量包构建么? 有人做过增量包构建么?问下要用哪些插件,怎么做? 经确认,提问人的需求是有一个代码仓库 x,然后 x 里有 a,b,c 三个模块,开发提交了 a 模块的代码,这时,只打包 a 模块的制品。\n 回答一 要做的是在流水线里判断提交代码中修改了哪个模块,然后执行你的 ant 命令指定构建某个模块就好了。代码 demo 如下:\npipeline{ agent any stages{ stage('build a'){ when{ changeset \u0026quot;a/**\u0026quot; } steps{ echo \u0026quot;build a\u0026quot; } } stage('build b'){ when{ changeset \u0026quot;b/**\u0026quot; } steps{ echo \u0026quot;build b\u0026quot; } } } } 回答二 增量包,四五年前我有过相关实践,构建工具也是 ant。记得当初是根据修改的文件路径,解析出 ant target 列表,然后根据事先声明好的依赖关系对它排序,然后执行 ant 构建命令,最后将生成的二进制包挑出来生成增量包,大致这么个思路。\n3. post 里如何指定 agent 请教一下,jenkinsfile中 post里面可以指定agent吗?\n 回答 post { always { node('master') { cleanWs() } } } 笔者注:node('\u0026lt;node\u0026gt;') 中的 \u0026lt;node\u0026gt; 可以是 agent 节点名称,也可以是 agent 的标签。\n4. windows 上 无法使用 curl 有些步骤是跑在 Windows 节点上,在 Windows 上又希望能发 http 请求。\n 回答 这时,应该使用 HTTPRequest 插件,它是平台无关的。\n4. 怎么把 slave 的内容 copy 到 master 机器上? 因为比如我用有一个 windows 节点,然后我代码拉取后,需要进行一些测试,测试完成后生成数据和 HTML 报告,这部分测试全都在节点上完成,我想把测试完成后到数据发到 master 上,然后由 master 生成 html 报告\n 回答 不确定,我是否理解正确。可以考虑这样做,把你现在的事情分成两个阶段,阶段一在 windows 上测试,然后将数据和 html 报告上传到某个地方,阶段二,将数据和报告下载回来,比如下载到 master 上。接着,想干嘛就干嘛了。\n5. httpRequest 如何发 POST 请求 httprequest这个插件 请求body这块一行一个参数? 回答 httpRequest authentication: credentialName, contentType: 'APPLICATION_JSON_UTF8', httpMode: 'POST', requestBody: \u0026quot;\u0026quot;\u0026quot;{\u0026quot;reportJson\u0026quot;: \u0026quot;111\u0026quot;,\u0026quot;id\u0026quot;: \u0026quot;111\u0026quot;,\u0026quot;executeNum\u0026quot;: 111}\u0026quot;\u0026quot;\u0026quot;, responseHandle: 'LEAVE_OPEN', url: \u0026quot;http://127.0.0.1/echo\u0026quot; 6. 我仓库特多,怎么设计流水线 我的仓库一共有4个 分别存放 代码 战斗脚本 资源 协议。4个代码仓库各有3个分支 名字都是对应的,比如1号仓库分支 master develop production. 2号仓库 也是这几个分支 以此类推 我拉取代码进行打包的时候 会拉取 4个仓库名字都叫 master 的分支 或者名字都叫 develop 的分支进行打包 现在问题就出在 我拉取4分仓库都叫 master 的分支的时候 拉取完代码后 最后一个仓库的代码会把前个仓库的代码覆盖掉,后来有老哥给了建议 用 dir 分别存到 workspace 下的好几个目录 现在遇到的问题是 我多分支流水线第一次启动时,会把1号仓库的代码直接拉到 workspace 下 我的问题就是可以不可在多分支流水线第一次启动时,不要拉取代码\n 回答 建立一条流水线,接受 gitlab 触发,然后根据触发请求中的数据,决定拉取哪个代码仓库。参考 Generic Webhook Trigger 插件。\n7. 流水线中如何指定工作目录 pipeline 中怎么指定这个流水线的工作目录,我在开头定义 WORKSPACE 但是没用\n 回答 8. 如何在 pipeline 中使用第三方 jar 包 请教下 pipeline 需要引用第三方 jar 包时,要放在哪里才能被 import 进来啊,我放到 classpath 下还是不行,总是提示找不到包。在本地执行 groovy,impor t进来没有问题\n 回答 把 jar 包放到 tomcat 安装 jenkins 的目录下的 lib 里貌似能解决。\n后记 如果读者朋友在使用 Jenkins 过程中也遇到各种问题,可关注Jenkins微信公众号。后台回复“微信群”入群。群里会有热心朋友回复。\n", "auhtor": "zacker330", "translator": "", "original": "", "poster": "./2019-07-08-wechat-answer-1/wechat.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-04-performance-testing-jenkins/", "title": "Jenkins 插件的微基准测试框架", "type": "wechat", "date": "2019-07-04 00:00:00 +0000 UTC", "tags": ["jmh", "plugins", "benchmark", "performance", "developer", "gsoc", "gsoc2019"], "description": "本文介绍了 Jenkins 插件的微基准测试框架以及如何在插件中运行基准测试", "content": " Jenkins 插件的微基准测试框架 作为我 Google 编程夏令营的一部分,我一直致力于改进角色策略插件(Role Strategy Plugin)的性能。 由于没有现有的方法来度量性能以及在 Jenkins 插件上做基准测试, 我在项目第一阶段的工作是创建一个框架在一个 Jenkins 实例中运行 Jenkins 插件中的基准测试。 为了让我们的工作更容易些,我们选择了 Java微基准测试工具来运行这些基准。 这使我们能够可靠地度量对时间要求严格的功能的性能,将有助于让 Jenkins 为每个人更快的运转。\n最近在 Jenkins 单元测试工具2.50中发布了微基准测试框架。 下面的博客文章展示了如何在插件中运行基准测试。\n介绍 该框架通过为 JMH 基准的每个 fork 启动一个临时的 Jenkins 实例来运行, 就像 Jenkins 测试工具中的 JenkinsRule。 基准测试是直接从 JUnit 测试运行的,它允许在运行过程中失败构建,并且很容易从 IDE 中运行基准测试,就像单元测试一样。 你可以很容易地通过使用 Java 方法或使用 Jenkins plugin:configuration-as-code:[配置即代码插件]来配置基准并将路径传递到 YAML 文件。\n要从您的插件运行基准测试,您需要做以下工作:\n 将所需的最低 Jenkins 版本升级到2.60.3或更高版本 将 Plugin-POM 升级到 ≥ 3.46 的版本或手动更新 Jenkins 测试工具到 ≥ 2.51 的版本 现在,要运行基准测试,您需要有一个包含 @Test 的基准测试运行程序,以便它可以像 JUnit 测试一样运行。 从测试方法内部,可以使用 JMH 提供的 OptionsBuilder 来配置基准。 例如:\npublic class BenchmarkRunner { @Test public void runJmhBenchmarks() throws Exception { ChainedOptionsBuilder options = new OptionsBuilder() .mode(Mode.AverageTime) .forks(2) .result(\u0026quot;jmh-report.json\u0026quot;); // Automatically detect benchmark classes annotated with @JmhBenchmark new BenchmarkFinder(getClass()).findBenchmarks(options); new Runner(options.build()).run(); } } 示例基准 现在,你可以编写第一个基准:\n无需任何特别的设置 @JmhBenchmark public class JmhStateBenchmark { public static class MyState extends JmhBenchmarkState { } @Benchmark public void benchmark(MyState state) { // benchmark code goes here state.getJenkins().setSystemMessage(\u0026quot;Hello world\u0026quot;); } } 使用配置即代码 要使用配置即代码,除了上面的依赖外,还需要在你的 pom.xml 添加如下内容:\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.jenkins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;configuration-as-code\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.21\u0026lt;/version\u0026gt; \u0026lt;optional\u0026gt;true\u0026lt;/optional\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;io.jenkins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;configuration-as-code\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.21\u0026lt;/version\u0026gt; \u0026lt;classifier\u0026gt;tests\u0026lt;/classifier\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; 现在配置一个基准很简单,只需提供 YAML 文件的路径并指定包含基准状态的类。\n@JmhBenchmark public class SampleBenchmark { public static class MyState extends CascJmhBenchmarkState { @Nonnull @Override protected String getResourcePath() { return \u0026quot;config.yml\u0026quot;; } @Nonnull @Override protected Class\u0026lt;?\u0026gt; getEnclosingClass() { return SampleBenchmark.class; } } @Benchmark public void benchmark(MyState state) { Jenkins jenkins = state.getJenkins(); // jenkins is configured and ready to be benchmarked. // your benchmark code goes here... } } 更多示例 作为这个项目的一部分,在角色策略插件(Role Strategy Plugin)中创建了一些基准测试,它们展示了为各种情况配置实例。 你可以在这里找到它们。\n运行基准测试 从 Maven 运行基准测试 为了方便从 Maven 运行基准测试,创建了一个 Maven 配置文件来运行基准测试,并且可以从 Plugin-POM 3.45 版本开始使用。 然后你可以使用 mvn test -Dbenchmark 从命令行运行基准测试。\n在 ci.jenkins.io 运行基准测试 如果您的插件托管在 ci.jenkins.io 上,那么可以直接从 Jenkinsfile 轻松地运行基准测试。 通过在 Jenkinsfile 中的 buildPlugin() 步骤后使用 runBenchmarks() 方法,该步骤现在在 Jenkins 流水线库。 此函数还接受生成的 JMH 基准报告的路径作为可选的参数并存档基准结果。 在 pull request 构建中运行基准测试允许您不断地进行测试监视给定更改的性能影响。 例如,来自角色策略插件(Role Strategy Plugin)的 Jenkinsfile :\nbuildPlugin() runBenchmarks('jmh-report.json') 可视化基准测试结果 可以使用 plugin:jmh-report[JMH 报告插件]或将基准测试报告传递给 JMH 可视化工具 web 服务来可视化生成的基准报告(JSON格式)。 举个例子,这里有一些来自角色策略插件(Role Strategy Plugin)中基准测试的可视化报告:\n上面所看到的这些改进是通过对插件的一个小的 pull request 获得的,并展示了即使是看起来很小的更改也可以带来很大的性能改进。 微基准测试有助于找到这些热点,并估计更改的影响。\n一些提示与技巧 由于上面示例中的 BenchmarkRunner 类名不符合 Maven Surefire 插件的测试条件命名约定,基准测试不会干扰 JUnit 测试。 基准测试方法需要用 @Benchmark 进行注解,以便 JMH 检测它们。 当注解为 @JmhBenchmark 时,包含基准的类由 BenchmarkFinder 自动找到。 对 Jenkins 实例的引用可以通过 JmhBenchmarkState#getJenkins() 或通过 Jenkins.getInstance() 获得,就像您在其他情况下会做的那样。 JmhBenchmarkState 提供了 setup() 和 tearDown() 方法,根据您的基准测试的需求,可以重写这些方法来配置 Jenkins 实例。 由于 highmem 节点的可用性有限,基于 ci.jenkins.io 的基准测试目前被限流。 基准框架在 Jenkins 测试工具2.50中提供,建议使用2.51版本,因为它包含一些错误修复。 链接及反馈 如果您有任何反馈、评论或问题, 请通过角色策略插件(Role Strategy Plugin) Gitter 聊天室 或通过 Jenkins 开发者邮件列表随时与我联系。\n 演示幻灯片 在平台 SIG 会议中的示例 微基准测试框架的文档: 编写基准测试 (Jenkins 测试工具) 使用 JCasC 预配置基准 使用 Plugin POM profile 运行基准测试 在 ci.jenkins.io 上运行基准测试的构建步骤 ", "auhtor": "abhyudayasharma", "translator": "donhui", "original": "https://jenkins.io/blog/2019/06/21/performance-testing-jenkins/", "poster": "./2019-07-04-performance-testing-jenkins/reflection.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-10-phase-1-multibranch-pipeline-support-for-gitlab/", "title": "多分支流水线任务对 GitLab SCM 的支持", "type": "wechat", "date": "2019-07-04 00:00:00 +0000 UTC", "tags": ["gitlab", "plugins", "pipeline", "credentials", "developer", "gsoc", "gsoc2019"], "description": "本文介绍了多分支流水线任务对 GitLab SCM 的支持", "content": " 这是在 GSoC 2019中的一个 Jenkins 项目。 我们正致力于增加多分支流水线任务和文件夹组织对 GitLab 的支持。 这个计划是创建以下插件: * GitLab API 插件 - 包装 GitLab Java APIs。 * GitLab 分支源插件 - 包括两个包: * io.jenkins.plugins.gitlabserverconfig - 管理服务器配置和 Web hooks 管理。理想情况下应该在另一个名为 GitLab Plugin 的插件中。 未来,这个包应该移动到新的插件中。 * io.jenkins.plugins.gitlabbranchsource - 为多分支流水线任务(包括 Merge Requests )和文件夹组织添加 GitLab 分支源。\n现状 完全支持自由风格的任务和流水线(单分支)任务。 部分支持多分支流水线任务(没有 MRS 检测)。 不支持 Gitlab 文件夹组织。 这个项目的目标 实现一个依赖于 Gitlab API 插件的轻量级 Gitlab 插件。 遵循3个独立插件的约定,即 GitLab 插件,GitLab API 插件,GitLab 分支源插件。 实现 Gitlab 分支源插件,支持多分支管道作业。 支持新的 Jenkins 特性,例如 Jenkins 代码即配置 (JCasC), 增量式工具。 清晰高效的设计。 支持新的 SCM 特性 APIs。 支持 Java 8 及更高版本。 构建插件 这个插件还没有二进制文件可用,因为这个插件还处于非常早期的 alpha 阶段,还没有为公众准备好。 如果您想尽早介入,可以尝试自己从源代码构建它。\n安装: 将源代码签出到您的本地机器上:\ngit clone https://github.com/baymac/gitlab-branch-source-plugin.git cd gitlab-branch-source-plugin 安装插件:\nmvn clean install mvn clean install -DskipTests # to skip tests 运行插件:\nmvn hpi:run # runs a Jenkins instance at localhost:8080 mvn hpi:run -Djetty.port=\u0026lt;port\u0026gt; # to run on your desired port number 如果您想用 Jenkins 服务器测试它,mvn clean install 之后在你的 Jenkins 实例中遵循以下步骤: 1. 选择 系统管理 2. 选择 插件管理 3. 选择 高级 选项卡 4. 在 上传插件 部分,选择 选择文件 5. 选择 $\u0026lt;root_dir\u0026gt;/target/gitlab-branch-source.hpi 6. 选择 上传 7. 选择 安装(无需重启)\n使用 假设插件安装已经完成。\n在 Jenkins 上设置 Gitlab 服务器配置 在 jenkins 上,选择 系统管理 选择 系统设置 向下滚动找到 GitLab 部分 4. 选择 Add GitLab Server | 选择 GitLab Server 5. 现在您将看到 GitLab 服务器配置选项。\n![gitlab-server](gitlab-server.png) 需要配置的字段有4个: * `Name` - 插件自动为您生成唯一的服务器名称。用户可能希望配置此字段以满足其需要,但应确保它足够唯一。我们建议保持原样。 * `Server URL` - 包含指向 Gitlab 服务器的 URL 。默认设置为 \u0026quot;https://gitlab.com\u0026quot; 。用户可以修改它以输入其 Gitlab 服务器 URL ,例如 https://gitlab.gnome.org/、http://gitlab.example.com:7990 等等。 * `Credentials` - 包含类型为 GitLab Personal Access Token 的凭据条目列表。当没有添加凭证时,它显示 \u0026quot;-none-\u0026quot; 。用户可以通过单击 \u0026quot;Add\u0026quot; 按钮添加凭证。 * `Web Hook` - 此字段是一个复选框。如果希望插件在与 Gitlab 项目相关的任务上设置 Webhook ,请选中此框。该插件监听相关 Gitlab 项目的 URL ,当 Gitlab 服务器中发生事件时,服务器将向设置 Web Hook 的 URL 发送事件触发器。如果您希望在 Gitlab 项目上持续集成(或持续交付),那么您可能希望自动设置它。 添加一个 Personal Access Token 凭据(自动生成 Personal Access Token 请参考下一个部分):\n 用户需要添加一个 GitLab Personal Access Token 类型凭证条目用来安全地将 token 保存在 Jenkins 内部。\n 在你的 GitLab 服务器生成一个 Personal Access Token 从右上角选择配置文件下拉菜单 选择 Settings 从左侧菜单选择 Access Token 输入一个名称 | 将 Scope 设置为 api,read_user,read_repository 选择 Create Personal Access Token 复制生成的 token 返回 Jenkins | 在凭据字段中选择 Add | 选择 Jenkins 设置 Kind 为 GitLab Personal Access Token 输入 Token 在 ID 处输入唯一的 id 输入人类可读的描述 选择 Add\n 测试连接:\n 在 Credentials 下拉列表选择你需要的 token 选择 Test Connection 它应该会返回 Credentials verified for user \u0026lt;username\u0026gt; 选择 Apply(在底部)\n GitLab 服务器现在在 Jenkins 设置好了\n 在 Jenkins 内创建个人访问令牌 或者,用户可以在 Jenkins 内部生成 Gitlab 个人访问令牌,并自动添加 Gitlab 个人访问令牌凭据到 Jenkins 服务器凭据。 1. 在 GitLab 部分的底部选择 Advanced 2. 选择 Manage Additional GitLab Actions 3. 选择 Convert login and password to token 4. 设置 GitLab Server URL 5. 有两个选项来生成令牌: * From credentials - 要选择已在的持久存储的用户名密码凭据,或添加用户名密码凭据来持久存储它。 * From login and password - 如果这是一次性的,那么您可以直接在文本框中输入凭据,并且用户名/密码凭据不会持久化。\n 设置完你的用户名密码凭据后,选择 Create token credentials. token 创建器将在 GitLab 服务器中为具有所需范围的给定用户创建个人访问令牌,并为 Jenkins 服务器中的相同用户创建凭据。 您可以返回 GitLab 服务器配置来选择生成的新凭证(首先选择 \u0026ldquo;-none-\u0026rdquo; ,然后将出现新的凭证)。出于安全原因,此令牌不显示为纯文本,而是返回一个 id 。 它是一个128位长的 UUID-4字符串(36个字符)。\n 配置即代码 没有必要在UI中浪费时间。 Jenkins 配置即代码 (JCasC) 或者简单地 配置即代码 插件允许你通过一个 yaml 文件配置 Jenkins。 如果你是新用户,你可以在这里了解更多关于 JCasC 的信息.\n添加配置 YAML: 这里有多种方式配置 JCasC yaml 文件来配置 Jenkins: * JCasC 默认情况下在 $JENKINS_ROOT 搜索一个名为 jenkins.yaml 的文件。 * JCasC 寻找一个环境变量 CASC_JENKINS_CONFIG ,其中包含配置 yaml 文件的路径。 * 一个包含一组配置文件的文件夹的路径,例如: /var/jenkins_home/casc_configs。 * 单个文件的完整路径,例如: /var/jenkins_home/casc_configs/jenkins.yaml。 * 一个指向 web 上提供的文件的 URL ,例如: https://\u0026lt;your-domain\u0026gt;/jenkins.yaml。 * 您还可以在 UI 中设置配置的 yaml 路径。转到 \u0026lt;your-jenkins-domain\u0026gt;/configuration-as-code。 输入 jenkins.yaml 的路径或 URL 并选择 Apply New Configuration。\n一个通过 jenkins.yaml 配置 GitLab 服务器的例子:\ncredentials: system: domainCredentials: - credentials: - gitlabPersonalAccessToken: scope: SYSTEM id: \u0026quot;i\u0026lt;3GitLab\u0026quot; token: \u0026quot;XfsqZvVtAx5YCph5bq3r\u0026quot; # gitlab personal access token unclassified: gitLabServers: servers: - credentialsId: \u0026quot;i\u0026lt;3GitLab\u0026quot; manageHooks: true name: \u0026quot;gitlab.com\u0026quot; serverUrl: \u0026quot;https://gitlab.com\u0026quot; 要获得更好的安全性,请参阅 JCasC 文档中的处理 secrets 部分。\n未来工作范围 GSoC 的第二阶段将用于开发 Gitlab 分支源插件。新功能正在开发中,但代码库不稳定,需要大量的错误修复。 一些功能(如多分支流水线任务)工作正常。在第二阶段结束时会有更多关于它的信息。\n问题跟踪 这个项目使用 Jenkins JIRA 来跟踪问题。你可以在 gitlab-branch-source-plugin 模块提交问题。\n致谢 这个插件是由 Google 编程夏令营 (GSoC)团队为 GitLab 支持多分支流水线而构建和维护的。 很多灵感来自于 GitLab 插件,Gitea 插件 及 GitHub 插件。\n我们的团队成员:baymac,LinuxSuRen, Marky,Joseph, Justin,Jeff。\n来自其他人的支持:Oleg,Greg,Owen。\n也感谢整个 Jenkins 社区提供的专业技术和灵感。\n链接 第一阶段示例 演示幻灯片 GitLab API 插件 GitLab 分支源插件 GitLab API 插件 Wiki 第一阶段的问题跟踪 博客 ", "auhtor": "baymac", "translator": "donhui", "original": "https://jenkins.io/blog/2019/06/29/phase-1-multibranch-pipeline-support-for-gitlab/", "poster": "./2019-07-10-phase-1-multibranch-pipeline-support-for-gitlab/tea.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/07/2019-07-01-introducing-the-jenkins-templating-engine/", "title": "介绍 Jenkins 模板引擎", "type": "wechat", "date": "2019-07-01 00:00:00 +0000 UTC", "tags": ["JTE", "pipeline", "plugin", "pipeline-authoring"], "description": "这是 StevenTerrana 的客座帖子,他是 Booz Allen Hamilton 的首席技术专家,也是模板引擎插件的首席工程师。他参加了流水线设计特别兴趣小组", "content": " 在企业范围内实施 DevSecOps 实践具有挑战性。由于组织内的不同应用程序正在使用多种编程语言、自动化测试框架和安全遵从性安全合规工具,因此每个团队构建和维护流水线变得很难。\n无论应用程序使用哪个特定的技术栈,大多数流水线都将遵循相同的通用工作流。模板引擎插件(简写为 JTE ,用于 Jenkins 模板引擎)允许您通过创建不依赖于工具的模板化工作流来获取效率,每个团队都可以重用这些工作流。\n作为公共部门和私营部门客户的技术顾问,我们在 Booz Allen 发现,每个新项目都要从头开始建造 DevSecOps 流水线。通过开发 Jenkins 模板引擎,我们已经看到流水线开发从几个月减少到几天,现在我们可以重用工具集成,同时为 Jenkins 流水线带来新的治理级别。\n流水线模板 组织受益于让应用程序开发人员专注于他们最擅长的工作:构建应用程序。支持这个,意味着建立一个集中式的 DevOps 团队,负责维护平台基础设施,并创建开发团队使用的 CI/CD 流水线。\n随着基于微服务的体系结构的兴起,一个集中的 DevOps 团队可以同时支持许多不同的开发团队;所有这些团队都可能利用不同的编程语言和自动化测试工具。\n虽然开发团队之间的工具可能不同,但工作流通常是相同的:单元测试、静态代码分析、构建和发布制品、部署它,然后针对部署的应用程序执行不同类型的测试。\n 模板引擎插件允许您从每个被团队定义可继承通用工作流的存储库中删除 Jenkinsfile 。作为替代每个存储库需定义整个流水线,团队提供一个使用工作流的工具配置文件。\n JTE 实战 让我们通过一个简单的示例来演示模板的可重用性: 流水线模板例子: unit_test() build() static_code_analysis() 模板利用库提供的步骤概述工作流团队必须实现的步骤。虽然模板的执行方式与任何其他 Jenkinsfile 都一样(这意味着支持标准的脚本化和声明性语法),但模板的目标应该是以纯英语的方式阅读,并避免任何技术实现。\n 通过这种方式利用模板,您可以将流水线的业务逻辑(应该在什么时候发生)与技术实现(实际将要发生什么)分开。其结果是一个 CI/CD 管道,当同时支持多个团队时,该流水线被证明非常容易管理。\n 此模板( unit_test 、 build 和 static_code_analysis )概述的步骤是专门命名的。通过这种方式,团队可以使用的不同库共享同一流水线。\n实现模板 使用模板引擎实现可共享流水线需要几个关键组件: 1. 流水线模板:概述要执行的工作流 2. 库:提供工作流步骤的技术实现 3. 配置文件:指定要使用的库及其配置\n步骤1、创建流水线配置存储库 流水线配置存储库用于存储团队继承的常见配置和流水线模板。\n这个示例流水线配置存储库稍后将被配置为治理层的一部分:JTE 的机制中允许您构建表示组织的层次结构配置。\n治理层包含三个方面: 1. 流水线模板 2. 库资源清单 3. 层的配置文件( pipeline_config.groovy )\n 治理层的流水线模板和配置文件存储在流水线配置存储库中。\n 在 Jenkins 中配置治理层时,您将为包含上述组件的存储库以及可以找到这些制品的基本目录提供源代码管理位置。\n步骤2、创建流水线模板 接下来,我们将为治理层创建一个 Jenkinsfile 。在 JTE 中, Jenkinsfile 是执行将使用的默认流水线模板。\nJenkinsfile unit_test() build() static_code_analysis() 步骤3、 创建库 模板引擎插件实现了一个版本的 Jenkins 共享库,以增强库的可重用性。库是源代码存储库中的根目录,并且该存储库已在治理层上配置为库源。\n在我们的示例中,流水线模板需要执行单元测试、打包制品和运行静态代码分析。\n假设我们有一些团队使用 Gradle ,一些团队使用 Maven 来构建和测试他们的应用程序,但是他们都将使用 SonarQube 来执行静态代码分析。\n在这个场景中,我们应该创建 gradle 、 maven 和 sonarqube 库。\n|- gradle/ \\-- build.groovy \\-- unit_test.groovy |- maven/ \\-- build.groovy \\-- unit_test.groovy |- sonarqube/ \\-- static_code_analysis.groovy 步骤4、实施步骤 实现库步骤与将常规全局变量作为默认 Jenkins 共享库的一部分写入完全相同。\n为了这个演示的目的,我们将让每个步骤打印出步骤名称和贡献库。\ngradle/build.groovy void call(){ println \u0026quot;gradle: build()\u0026quot; } 读更多关于 JTE 开发库。\n 步骤5、创建配置文件 JTE 的配置文件名为 pipeline_config.groovy 。\n在治理层,我们将建立一个配置文件,具体说明应用程序之间的共同配置。在此情况下,两种应用都是使用 sonarqube 库。\npipeline_config.groovy libraries{ merge = true // allow individual apps to contribute additional libraries sonarqube } 接下来,我们将创建另外两个表示 Maven 和 Gradle 应用程序的存储库。在这些存储库中,我们只需要一个特定的 pipeline_config.groovy 文件。\n这些存储库都包含应用程序 pipeline_config.groovy 配置文件。\nmaven app: pipeline_config.groovy libraries{ maven } gradle app: pipeline_config.groovy libraries{ gradle } 步骤6、在 Jenkins 中配置治理层 既然我们有了流水线配置存储库和库源存储库,那么就可以在 Jenkins 中配置治理层:\n 上图中显示的配置可以在以下找到 Manage Jenkins \u0026gt;\u0026gt; Configure System 。\n通过模板引擎,您可以通过 Jenkins 中的文件夹表示此结构,从而创建与组织分类相匹配的流水线治理层次结构。\n 步骤7、为两个应用程序创建多分支流水线 当为每个应用程序创建多分支流水线项目时,模板引擎插件提供一个名为 Jenkins 模板引擎的新 Project Recognizer 。项目设置为在存储库中的所有分支使用模板引擎框架。。\n 您还可以为 GitHub 组织项目设置 Jenkins 模板引擎项目识别器,使您能够轻松地在整个 GitHub 组织中共享相同的流水线!\n 步骤8、运行流水线 就这样!现在,这两个应用程序将利用完全相同的流水线模板,同时具有选择工作流每个阶段应使用哪些工具的灵活性。\n下面是两个应用程序运行流水线的控制台日志的示例输出:\nGradle: [JTE] Obtained Template Configuration File pipeline_config.groovy from git https://github.com/steven-terrana/example-jte-configuration [JTE] Obtained Template Configuration File pipeline_config.groovy from git https://github.com/steven-terrana/example-jte-app-gradle.git [JTE] Loading Library sonarqube from git https://github.com/steven-terrana/example-jte-libraries.git [JTE] Loading Library gradle from git https://github.com/steven-terrana/example-jte-libraries.git ... [JTE] Obtained Template Jenkinsfile from git https://github.com/steven-terrana/example-jte-configuration [JTE][Step - gradle/unit_test] [Pipeline] echo gradle: unit_test() [JTE][Step - gradle/build] [Pipeline] echo gradle: build() [JTE][Step - sonarqube/static_code_analysis] [Pipeline] echo sonarqube: static_code_analysis() [Pipeline] End of Pipeline Maven: [JTE] Obtained Template Configuration File pipeline_config.groovy from git https://github.com/steven-terrana/example-jte-configuration [JTE] Obtained Template Configuration File pipeline_config.groovy from git https://github.com/steven-terrana/example-jte-app-maven.git [JTE] Loading Library sonarqube from git https://github.com/steven-terrana/example-jte-libraries.git [JTE] Loading Library maven from git https://github.com/steven-terrana/example-jte-libraries.git ... [JTE] Obtained Template Jenkinsfile from git https://github.com/steven-terrana/example-jte-configuration [JTE][Step - maven/unit_test] [Pipeline] echo maven: unit_test() [JTE][Step - maven/build] [Pipeline] echo maven: build() [JTE][Step - sonarqube/static_code_analysis] [Pipeline] echo sonarqube: static_code_analysis() [Pipeline] End of Pipeline 模板引擎的好处 应用组织治理 利用模板引擎插件,您可以定义企业级的、经过批准的工作流,无论使用什么工具,团队都可以使用这些工作流。这种自上而下的方法使得在组织中扩展和执行 DevSecOps 原则变得非常容易。\n优化代码重用 实际上,组织中的每个团队都不需要反复思考如何做相同的事情。在 Booz Allen ,我们已经看到流水线开发时间从几个月减少到几天,因为我们不断地重复使用和扩展模板引擎库组合,作为解决方案交付平台的一部分。\n简化流水线可维护性 通常,DevOps 工程师会发现自己同时为多个开发团队构建和支持流水线。通过将工作流与技术实现分离,并将流水线定义合并到一个集中的位置,模板引擎插件允许 DevOps 工程师更快地扩展。\n参与进来! 模板引擎插件是开源的,并在 Jenkins 更新中心提供。\n我们总是感谢反馈和贡献!如果你有一个有趣的用例或者想问一些问题,可以试试 Gitter 上的模板引擎插件。\n高级功能 配置文件条件继承 外部化库配置 面向方面的生命周期钩子 多个流水线模板 默认步骤实现 配置文件 DSL 沙盒 更多资源 对于这个演示 Pipeline 配置存储库 示例库 Maven 存储库示例 Gradle 存储库示例 其他资源 模板引擎文档 源代码 Booz Allen 的 SDP 流水线库 博思艾伦咨询公司 ", "auhtor": "Steven Terrana", "translator": "linan607", "original": "https://jenkins.io/blog/2019/05/09/templating-engine/", "poster": "./2019-07-01-introducing-the-jenkins-templating-engine/JTE.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-26-using-active-choices-plugin-merge-jobs/", "title": "使用Active-Choices-Plugin插件将十个Job合成一个", "type": "wechat", "date": "2019-06-26 00:00:00 +0000 UTC", "tags": ["Jenkins", "plugin"], "description": "使用Active-Choices-Plugin插件将十个Job合成一个", "content": " 现在Spring Cloud越来越火爆,许多公司也都在如火如荼投入使用中,而微服务最大的一个特点,就是多,同一大项目之下,可能会被拆分成十几二十几个子服务,对于运维而言,可能也需要一个对应一个地在Jenkins中创建十几二十几个Job。\n刚刚还在一个博主的自我介绍里看到这样一句话:喜欢一切优雅的运维方式···\n于是,我一直在想着,通过一些合理的参数变幻,从而将刚刚提到的十几二十几个服务,汇集到一个Job当中就能完成。\n1,环境说明 主机:CentOS-7.5 Jdk:jdk1.8.0_192 Tomcat:8 Jenkins:2.177 如上环境的准备工作本文就不赘述了。\n2,安装插件。 官方地址:https://wiki.jenkins.io/display/JENKINS/Active+Choices+Plugin 安装方式:在Jenkins插件当中直接搜索即可安装。 功能说明:根据所选参数,自动调出对应参数所依赖的后续参数。 3,使用前介绍。 插件安装之后,可以在项目配置中的参数化配置中看到一些新增了的选项。\n 1,Active Choices Parameter(主动选择参数) Active Choices参数使用Groovy脚本或Scriptler目录中的脚本动态生成构建参数的值选项列表。 2,Active Choices Reactive Parameter(主动选择反应参数) 根据主动选择参数的选项而提供不同的对应值或者列表选项。 3,Active Choices Reactive Reference Parameter(主动选择反应参考参数) 根据主动选择参数的选项而展示对应参数的一些说明,与第二项的区别在于本参数只作为说明信息,而不能够作为变量往下传递。 可能刚刚这些说明都比较抽象,接下来容我通过项目实战,来对其进行一一解析。\n4,配置前分析。 优秀的插件,它的优秀之处,往往是需要我们结合生产实际,开动聪明的大脑,打破常规使用套路来成就的。\n因此,如何才能更好地应用插件的优秀功能,需要我们先对项目进行分析,从全局的眼光,判断项目前后该配置什么样的参数来进行联动。\n这里我说明一下我准备的实验项目情况,为了简便测试,我这里仅使用两个项目来进行举例,聪明的你也一定能够通过案例进行举一反三,将二合一推广为十合一的。\n两个项目的情况如下:\n1,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 从刚刚这些配置里边可以看出,有不少共同点,也有不少不同点,我们只需把眼光放在不同点上,通过一些统一的变量控制,就能达到二合一的目的。\n另外说明一点,这个项目已经部署在k8s环境当中,因此我的脚本内容也就展示成了k8s项目部署的流程了。\n5,创建项目。 首先创建一个自由风格的Jenkins项目,然后配置一下项目构建保存历史。\n6,字符参数。 添加一个名为branch的字符参数以用于控制代码分支的变量。\n7,选项参数。 添加一个名为mode的选项参数以用于控制部署或者回滚的变量。\n8,选择参数。 1,主动选择参数 首先添加一个主动选择参数,用于控制项目名称这个变量。\n Name:project Groovy Script: return[ \u0026quot;eureka\u0026quot;, \u0026quot;user\u0026quot; ] Description:选择对应的应用名称部署对应的应用。 Choice Type:Radio Buttons 2,主动选择反应参数 接着添加一个主动选择反应参数,用于控制项目类型这个变量。\nName:type - Groovy Script:\nA=[\u0026quot;server\u0026quot;] B=[\u0026quot;service\u0026quot;] if(project.equals(\u0026quot;eureka\u0026quot;)){ return A } else if(project.equals(\u0026quot;user\u0026quot;)){ return B } Description:跟随项目的选择自动弹出对应类型 Choice Type:Single Select Referenced parameters:project 3,主动选择反应参数 然后再添加一个主动选择反应参数,用于控制项目端口这个变量。\n Name:port Groovy Script: if(project.equals(\u0026quot;eureka\u0026quot;)){ return [\u0026quot;8761\u0026quot;] } else if (project.equals(\u0026quot;user\u0026quot;)){ return [\u0026quot;6666\u0026quot;] } Description:跟随跟随项目的选择自动弹出对应端口 Choice Type:Single Select Referenced parameters:project 这样,对应的参数都创建完毕了,大概有以下几个小的注意点需要注意:\n 1,参数的名称将是整个构建流程使用的一个变量,因此起名的时候需要注意。 2,创建了一个主动选择参数,和两个主动选择反应参数,是因为我们的实际需求需要两个真实有效的参数,如果最后的port项选择了主动选择反应参考参数,那么到后边是无法显式使用的。 3,注意后两个跟随参数中的Referenced parameters,都需要填写主动参数的名称,才能够前后贯通,实现联动。 9,Git地址配置。 接着就该添加Git地址了,同样,这个地方也应该合理利用项目标准化的优势,合理应用变量来进行配置。\n具体如下图所示:\n10,执行脚本。 接下来就该通过脚本来完成构建的主要流程了。\n#!/bin/bash source /etc/profile # ##set color## echoRed() { echo $'\\e[0;31m'\u0026quot;$1\u0026quot;$'\\e[0m'; } echoGreen() { echo $'\\e[0;32m'\u0026quot;$1\u0026quot;$'\\e[0m'; } echoYellow() { echo $'\\e[0;33m'\u0026quot;$1\u0026quot;$'\\e[0m'; } ##set color## # version=`date +%Y%m%d%H%M%S` echo ------------------------------------- # 克隆项目并编译 echoGreen \u0026quot;开始进行mvn编译!\u0026quot; cd $WORKSPACE \u0026amp;\u0026amp; mvn clean install -DskipTests=true [ $? != 0 ] \u0026amp;\u0026amp; echoRed \u0026quot;请注意,在执行mvn编译时出错,故而退出构建,需开发同学自检代码!\u0026quot; \u0026amp;\u0026amp; exit 1 cd $WORKSPACE/target/ \u0026amp;\u0026amp; mv ishangjie-$project-$type-1.0.0.jar app.jar # 创建docker镜像 cat \u0026gt; run.sh \u0026lt;\u0026lt; EOF #!/bin/bash source /etc/profile java -jar /opt/app.jar --spring.profiles.active=test1 EOF chmod +x run.sh cat \u0026gt;Dockerfile \u0026lt;\u0026lt; EOF FROM 192.168.10.1/public/jdk:1.8 MAINTAINER eryajf \u0026lt;liqilong@edspay.com\u0026gt; ENV LANG en_US.UTF-8 ADD app.jar /opt/app.jar ADD run.sh / EXPOSE $port ENTRYPOINT [ \u0026quot;sh\u0026quot;, \u0026quot;-c\u0026quot;, \u0026quot;/run.sh\u0026quot; ] EOF # 构建镜像 echoGreen \u0026quot;开始构建当次镜像!\u0026quot; docker build -t 192.168.10.1/isj/$project:$version . [ $? != 0 ] \u0026amp;\u0026amp; echoRed \u0026quot;请注意,在执行镜像构建时出错,故而退出构建,请联系运维同学处理!\u0026quot; \u0026amp;\u0026amp; exit 1 # 上传到docker私服 echoGreen \u0026quot;开始将镜像push到私服!\u0026quot; docker push 192.168.10.1/isj/$project:$version [ $? != 0 ] \u0026amp;\u0026amp; echoRed \u0026quot;请注意,在执行镜像上传时出错,故而退出构建,请联系运维同学处理!\u0026quot; \u0026amp;\u0026amp; exit 1 docker rmi 192.168.10.1/isj/$project:$version #更新镜像 echoGreen \u0026quot;开始将最新镜像部署到远端!\u0026quot; rancher kubectl set image deployment/isj-$project isj-$project=192.168.10.1/isj/$project:$version -n isj-wfw [ $? != 0 ] \u0026amp;\u0026amp; echoRed \u0026quot;请注意,在执行镜像更新时出错,故而退出构建,请联系运维同学处理!\u0026quot; \u0026amp;\u0026amp; exit 1 echoGreen \u0026quot;部署完成!\u0026quot; 针对这个脚本有几点简单说明:\n 1,因为应用到了颜色输出,因此记得在构建环境当中开启color颜色输出。 2,尽量在关键地方添加一下判断,然后输出明了的内容以提高生产效率,比如编译有问题,直接退出构建,输出开发自检,如果是后边构建问题,同样退出构建,输出联系运维解决。 3,巧用cat的EOF特性,从而也可以将不同的变量控制进来。 4,尽量将所有构建过程的内容都写到Jenkins这里来,以便于后期问题排查与分析。 5,因为这是实验,因此没有添加回滚功能,如果添加的话,就针对mode参数做一个判断即可。 11,构建后操作。 因为是多个项目在同一个WORKSPACE下工作,因此,为了避免出现不可预知问题,这里添加了构建后清空WORKSPACE的选项。\n12,效果展示。 一切配置完成之后,就可以尝试一下点击构建了。\n好了,这就是本期的分享,当然,关于这个插件,这里也只是介绍了其中一种一个思路,可能还有很多种其他的方案,期待各位发挥思维发掘更多妙用。\n", "auhtor": "eryajf", "translator": "", "original": "", "poster": "./2019-06-26-使用Active-Choices-Plugin插件将十个Job合成一个/the_one.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-17-10-courses-to-learn-devops-engineering-in-depth/", "title": "10节课带你深入学习 DevOps 工程", "type": "wechat", "date": "2019-06-17 00:00:00 +0000 UTC", "tags": ["devops", "docker", "git", "AWS"], "description": "对那些想要涉足 DevOps 领域的工程师来说,这些多样的课程提供了一个很好的开始", "content": " DevOps 现在真的很热门,对于杰出的工程师和 DevOps 专业人员来说有许多工作机会。 如果你想成为一名 DevOps 工程师,那么你来对地方了。在本文中,我将分享一下最好的在线培训课程, 让你成为 DevOps 专业人员。\nDevops 最重要的优势,它可以帮助你更好地发布软件并且利用现代自动化工具对环境和软件开发过程中提供更多控制。这就是 DevOps 专业人员需求呈指数增长的原因。除了 Data Science 和 Machine Learning 外,它也是薪酬最高的 IT 工作之一。\n根据 Glassdoor 的数据,DevOps 的工程师每年的收入从105000美元到146000美元不等。这意味着,如果你正在寻找加薪或想在美好年纪从事一些令人兴奋的工作赚更多的钱,学习 DevOps 可能是一个不错的选择。\n学习像 Jenkins 这样的持续集成工具和像 Docker 这样的容器以及一般的 DevOps 技能,在技术领域获得了巨大的动力。这与几年前的移动应用程序开发类似。\n公司希望新的开发人员能够管理 Web 应用程序的整个生命周期。这意味着开发和部署应用程序。\n为了成为一名有效的 DevOps 工程师,您必须扩展对软件开发中使用的不同工具的知识,包括构建工具(如 Maven、 Ant 和 Gradle )、单元测试工具(如 Junit 和 Selenium )、部署工具(如 Docker )、监控工具(如 New Relic )、基础设施自动化工具(如 Chef 和 Puppet )、源代码控制工具,如 Git 和 Github,以及持续集成工具,如 Jenkins 和 TeamCity。这些课程为基本的 DevOps 工具提供了很好的介绍。\n十节面向经验丰富的开发人员 DevOps 课程 在不浪费更多时间的情况下,这里列出了一些学习 DevOps 的最佳课程以及在软件开发和部署过程中实现自动化所需的基本工具。\n1.学习路径:现代 DevOps DevOps 以一种全新的方式看待软件开发。您可以实现自动化,构建基础结构服务器的配置,然后解决自动化、连续部署、容器和监控方面的问题。\nGit、Docker 和 Puppet 是现代 DevOps 世界中最重要的工具,本课程将向您介绍这三种工具。\n简而言之,这是一门很好的入门课程,适用于系统管理员、开发人员和 IT 专业人员等 DevOps 领域的新手,还提供了对基本 DevOps 工具的良好概述。\n2.面向 DevOps 和开发者的 Docker 技术 Docker 是 DevOps 最重要的技术之一。它允许您将组件捆绑在一起,并将它们部署在任何平台(如 Linux 或 Windows )上的容器上。\n本课程涵盖了 Docker 软件的所有基础知识,并向您传授了开发和部署 Docker 现代应用程序所需的一切知识。\n3.Jenkins,从小白到专家:成为一名 DevOps JenKins 大师 Jenkins 可能是 DevOps 工程师进行持续集成工作的最重要工具。\n对于 DevOps 专业人员,具备持续检查、持续集成、持续部署的知识,且知道它们之间的区别是十分必要的。\n本课程涵盖了有关 Jenkins 的所有基础知识,并向您传授建立 Jenkins 构建管道所需的所有知识,从持续检查(构建、测试和静态分析)开始,一直到持续部署(待部署和生产)。\n4.学习 DevOps:完整的 Kubernetes 课程 当谷歌十年前开始运行容器时,没有人能够达到这种基础设施的灵活性和效率。利用这些知识,谷歌发布了 Kubernetes 作为一个免费的开源项目。\n如今,Kubernetes 被那些希望获得跟谷歌一样效率和速度的小公司和大企业使用。本课程将教您如何在 Kubernetes 上运行、部署、管理和维护容器化的 Docker 应用程序。\n5.学习 DevOps:持续发布更好的软件 这是关于 Udemy 的 DevOps 的最完整的课程之一,它将教授您 DevOps 工程师使用的大多数基本工具和技术。\n本课程面向这样的软件工程师和系统管理员:他们希望提供更好的软件,并帮助您在交付和部署过程中更好地使用 Git、Vagrant、Chef、Ansible、Jenkins、Docker 和 Kubernetes 这些工具。\n6.DevOps 课程的 Docker:从开发到生产 本课程向您展示了通过 Docker,您可以构建什么以及如何进行构建。除此之外,你还将学习 Docker 的基本知识!我们将一起讨论开发和部署多服务 Flask 和 Ruby on Rails 应用程序。\n7.学习 DevOps:使用 TerraForm 实现基础设施自动化 基础设施自动化是 DevOps 的一个重要组成部分。像 Ansible、Chef、Puppet 等工具都很有用,但 TerraForm 最近更受欢迎,如果您正在或即将成为一个 Ops/DevOps,您需要掌握这些工具,这就是本在线课程将帮助您的地方。\nTerraform 开始于相同的规则、基础设施即代码,但更专注于基础结构本身的自动化。您的整个云基础设施(实例、卷、网络、IP)在 TerraForm 中被描述。\n在本课程中,您将学习如何通过 TerraForm 以及 AWS、Packer、Docker、ECR、ECS 和 Jenkins 来实现自动化基础设施。\n8.使用 AWS codepipeline、Jenkins 和 AWS codedeploy 的 DevOps 如果您对什么是持续集成(CI)或持续交付/持续部署(CD)感到困惑,以及如何使用 Amazon Web 服务(如 AWS 和Jenkins)进行 DevOps,那么这是适合您的课程。\n在本课程中,您将学习必要的DevOps技能,以及在AWS云中的持续集成和持续交付。\n9.DevOps:用 Jenkins pipelines, Maven, Gradle 进行 CI/CD 本在线 DevOps 课程将教您如何使用 Jenkins 及它的一些插件(尤其是流水线插件),来构建复杂的持续集成和持续交付流水线。\n本课程旨在向您传授 Jenkins 的经验,并建立 DevOps 流水线,即使您几乎没有经验,也可以帮助您实现这些 DevOps 实践,从而简化您的开发过程。\n总之,用 Java、Gradle、Maven、AtdiPrand 和 Sqitch 构建的持续集成、持续交付和 DevOps 流水线是一个伟大的过程。\n10.用 Docker, Jenkins, GIT, Vagrant, 和 Maven 完成 DevOps 如果您正在寻找一个实践 DevOps 课程,它不仅可以向您解释 DevOps 工程师的角色,而且可以提供关于基本 DevOps 工具的实践经验,那么这是您的课程。\n它提供了一个关于 DevOps 基本技术的完整教程。您将通过实践指导学习 Docker Mastery、Jenkins、Git、Vagrant 和 Maven。\n正如我所说,对优秀的 DevOps 工程师和软件开发人员的需求呈指数级增长,市场上没有足够的 DevOps 专业人员来支持这一需求。\n这意味着这是一个学习 DevOps 并进入这个更负责任、高薪和令人兴奋的领域的绝佳机会。如果你打算在2019年成为一名 DevOps 工程师,那么这些课程是一个很好的起点。\n如果你喜欢这些 DevOps 课程,请与你的朋友和同事分享。如果您有任何问题或反馈,请留言。\n", "auhtor": "Javin Paul", "translator": "linan607", "original": "https://dzone.com/articles/10-courses-to-learn-devops-in-2019", "poster": "./2019-06-17-10-courses-to-learn-devops-engineering-in-depth/devops.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-14-setup-jenkins-ci-in-30-minutes/", "title": "30分钟搞定 Jenkins CI", "type": "wechat", "date": "2019-06-14 00:00:00 +0000 UTC", "tags": ["jenkins", "ci"], "description": "设置新的 Jenkins CI,以便可以开始测试新的 Jenkins 插件", "content": " 你想在本地设置中使用 Jenkins CI 进行实验吗?在本文中,我们将设置一个本地 Jenkins CI 服务,为一个简单的 Spring Boot Maven 项目创建一个构建工作,并将创建的 Docker 镜像推送到 DockerHub。这将是一个本地实验的设置,但如果你想尝试一个 Jenkins 插件,它会非常方便。\n1.先决条件 开始之前,我们需要以下先决条件:\n 我们使用了 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 服务。完整的文档可以在这里找到。用以下命令启动容器:\n$ docker run -p 8080:8080 --name myjenkins -v jenkins_home:/var/jenkins_home -v jenkins_downloads:/var/jenkins_home/downloads jenkins/jenkins:lts 让我们来仔细看看我们正在做什么:\n -p 8080:8080:我们将内部 Jenkins 端口(冒号后)映射到外部端口,该端口可从我们的 Docker 主机访问; \u0026ndash;name myjenkins:我们为容器提供一个名称;否则,Docker将为你生成一个名称。最好给它起个名字;这样,你可以轻松地启动和停止容器; -v jenkins_home:/var/jenkins_home:我们希望将内部 Jenkins 主目录(冒号之后)映射到 Docker 主机上的一个目录。通过这种方式,Jenkins 数据将被保存在我们的主机上,这让我们有机会备份数据; -v jenkins_downloads:/var/jenkins_home/downloads:我们需要在Jenkins中安装额外的工具; 因此,我们创建一个目录来复制 *.tar.gz 文件。在这篇文章的后面,我们将清楚地知道我们将使用目录做什么; jenkins/jenkins:lts:要使用的 Docker 镜像。我们将使用 LTS 版本,但如果你愿意,也可以使用不太稳定的版本。在撰写本文时,v2.150.1 是 LTS 版本。 在此之后,你可以通过其名称停止和启动容器: $ docker stop myjenkins $ docker start myjenkins 3.配置 Jenkins 以供首次使用 一旦容器启动后,我们就可以访问 Jenkins Web 控制台了。当然,我们需要知道 Jenkins 实例的 IP 地址。因此,请执行以下命令:\n$ docker inspect myjenkins 这将显示一些 JSON 输出。转到该 Networks 部分,参数 IPAddress 显示我们的 Jenkins IP 地址(在我们的例子中为172.17.0.3):\n\u0026quot;Networks\u0026quot;: { \u0026quot;bridge\u0026quot;: { \u0026quot;IPAMConfig\u0026quot;: null, ... \u0026quot;IPAddress\u0026quot;: \u0026quot;172.17.0.3\u0026quot;, ... \u0026quot;DriverOpts\u0026quot;: null } } Jenkins Web 控制台可通过浏览器访问 http://172.17.0.3:8080/。\n这将向我们显示以下页面:\n我们使用临时密码,启动容器后在控制台输出中显示:\n************************************************************* ************************************************************* ************************************************************* Jenkins initial setup is required. An admin user has been created and a password generated. Please use the following password to proceed to installation: f586346583e04fa78e2cc8edbf7566e1 This may also be found at: /var/jenkins_home/secrets/initialAdminPassword ************************************************************* ************************************************************* ************************************************************* 输入临时密码后,将显示一个页面,在这里我们可以选择要安装的默认插件集或自定义插件集。我们将选择默认设置。\n现在,坐等插件安装好:\n接下来,创建第一个管理员用户:\n最后,配置 Jenkins 实例:\n太棒了!Jenkins 现在已经准备好可以使用了:\n4.安装所需的工具 我们的构建需要在 Jenkins 中提供一些工具。我们需要 JDK11,Maven 和 Docker。在下一节中,我们将展示如何在容器中使用这些属性。\n在启动容器期间,我们在容器中创建了 /var/jenkins_home/downloads 的挂载卷。首先,我们将验证是否可以从容器中访问此路径。执行以下命令:\n$ docker exec -it myjenkins ls -l /var/jenkins_home/downloads total 0 如上所述返回0个结果时,那么我们就可以继续了。否则,你必须检查在启动容器期间是否输入正确。\n4.1 安装 JDK 11 我们将使用 Adopt OpenJDK 11,可在此处下载。我们必须将下载的 *.tar.gz 文件复制到已安装在主机上的卷 jenkins_home/downloads 中。为了检索我们机器上的路径,我们再次执行 docker inspect 命令,就像以前检索Jenkins IP地址一样。这一次,转到分段 Mounts:\n\u0026quot;Mounts\u0026quot;: [ ... { \u0026quot;Type\u0026quot;: \u0026quot;volume\u0026quot;, \u0026quot;Name\u0026quot;: \u0026quot;jenkins_downloads\u0026quot;, \u0026quot;Source\u0026quot;: \u0026quot;/var/lib/docker/volumes/jenkins_downloads/_data\u0026quot;, \u0026quot;Destination\u0026quot;: \u0026quot;/var/jenkins_home/downloads\u0026quot;, ... } ], 在我们的示例中,卷位于 /var/lib/docker/volumes/jenkins_downloads/_data 上。将 *.tar.gz 文件复制到此位置。\n跳转到 Manage Jenkins – Global Tool Configuration 和 *JDK 安装部分*。单击 Add JDK 按钮。默认情况下,java.sun.com 会添加安装程序。我们不会使用这个,所以删除它并添加一个 Extract *.zip/*.tar.gzinstaller。根据下面的屏幕截图填写字段。二进制存档的路径是 file:/var/jenkins_home/downloads/OpenJDK11U-jdk_x64_linux_hotspot_11.0.1_13.tar.gz。Label 留空是很重要的;否则,JDK的安装将失败。\n跳转到 *Manage Jenkins – Configure System*,到 Global properties 部分并启用 *环境变量*。为其添加环境变量 JAVA_HOME 并填充路径 /var/jenkins_home/tools/hudson.model.JDK/JDK11/jdk-11.0.1+13。\n4.2 安装 Maven 我们将使用 Maven 3.6.0,可以在这里下载。安装过程与 JDK 安装相同:下载 *.tar.gz 文件并将其复制到 jenkins_home/downloads。\n转到 Manage Jenkins – Global Tool Configuration 和 Maven 安装部分。单击 Add Maven 按钮。默认情况下,Apache 会添加安装程序。我们不会使用这个,所以删除它并添加一个 Extract *.zip/*.tar.gzinstaller。根据下面的屏幕截图填写字段。二进制存档的路径是 file:/var/jenkins_home/downloads/apache-maven-3.6.0-bin.tar.gz。Label 留空是很重要的;否则,Maven 的安装将失败。将子目录设置为 apache-maven-3.6.0 也很重要;否则,Maven 主目录没有正确设置,mvn 可执行文件将无法找到。\n4.3 配置 Docker 在 Docker 内部安装 Docker 不是一个好主意,请参阅本文。因此,我们将使用宿主机的 Docker 安装,并将宿主机的 Docker 套接字挂载到容器。实际上,这也不是一个好主意,但是对于我们的 Jenkins 实验环境来说,这是可以的,但是出于安全原因,永远不要以这种方式暴露 Docker 套接字。\n我们删除现有的容器(这不是有害的,因为我们的所有数据都保存在我们的主机上,我们不会丢失任何数据),然后使用 -v /var/run/docker.sock:/var/run/docker.sock 重新启动容器。\n$ docker rm myjenkins $ docker run -p 8080:8080 --name myjenkins -v /var/run/docker.sock:/var/run/docker.sock -v jenkins_home:/var/jenkins_home -v jenkins_downloads:/var/jenkins_home/downloads jenkins/jenkins:lts 为了使其工作,我们还必须设置 docker.sock 的权限给 jenkins 用户。默认情况下,它被挂载为 root,因此,由于 Permission Denied 错误,我们的构建将失败。\n以 root 身份登录 Docker 容器:\n$ docker exec -it -u root myjenkins 检查权限 docker.sock,这表明它拥有者 root:\n$ ls -l /var/run/docker.sock srw-rw---- 1 root 999 0 Jan 6 11:45 /var/run/docker.sock 让 jenkins 成为新所有者,并再次列出权限:\n$ chown jenkins: /var/run/docker.sock $ ls -l /var/run/docker.sock srw-rw---- 1 jenkins jenkins 0 Jan 6 11:45 /var/run/docker.sock 现在,jenkins 是所有者,我们不会再得到 Permission Denied 的错误。\n为了将 Docker 镜像推入 Docker registry,我们需要通过 settings.xml 将凭据提供给 Maven。我们可以通过配置文件提供程序插件轻松地提供 settings.xml。去 Manage Jenkins – Manage plugins 并安装插件(不重启安装)。\n转到 *Manage Jenkins – Managed files*,然后单击 *Add a new Config*。创建 Global Maven settings.xml 并使用 DockerHub 帐户凭据添加以下部分:\n\u0026lt;servers\u0026gt; \u0026lt;server\u0026gt; \u0026lt;id\u0026gt;docker.io\u0026lt;/id\u0026gt; \u0026lt;username\u0026gt;docker_username\u0026lt;/username\u0026gt; \u0026lt;password\u0026gt;docker_password\u0026lt;/password\u0026gt; \u0026lt;/server\u0026gt; \u0026lt;/servers\u0026gt; 5.创建构建工作 最后要做的是创建我们的构建工作。转到 Jenkins CI 主页,然后单击 *New Item*。我们将把构建工作命名为 *MyKubernetesPlanet*,并选择一个 *Freestyle Project*。\n在构建工作的配置部分,我们转到 Source Code Management 部分,并填写 Git URL https://github.com/mydeveloperplanet/mykubernetesplanet.git 和 branch */feature/jenkinsci。\n在 Build 部分,我们添加了一个 Invoke top-level Maven targets 的构建步骤。我们将调用以下 Maven 目标来构建我们的应用程序并将 Docker 镜像推送到 Docker registry:\n$ clean install dockerfile:push 我们还需要设置之前创建的 Maven版本 和 *全局配置文件*。\n手动为我们的工作启动构建,这将创建 jar 文件,创建我们的 Docker 镜像,并将其推送到 Docker registry。\n6.结论 在本文中,我们提供了一种让 Jenkins 实例运行的快速方法,包括执行 Maven 构建、创建 Docker 镜像并将其推入 Docker registry 的构建作业。请注意,这不是一种安全的方法,但是对于实验用例来说,它并没有太大的危害。现在我们已经有了一个完全运行的 Jenkins 实例,我们可以使用它来测试新的 Jenkins 插件。\n", "auhtor": "Gunter Rotsaert", "translator": "yJunS", "original": "https://dzone.com/articles/setup-jenkins-ci-in-30-minutes", "poster": "./2019-06-15-setup-jenkins-ci-in-30-minutes/788b731c3a30bba88e622c162ec0ea54.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-10-jenkins-pipeline-workshop/", "title": "还在苦恼不会写 Jenkins 流水线?来场工作坊!", "type": "wechat", "date": "2019-06-10 00:00:00 +0000 UTC", "tags": ["jenkins", "pipeline"], "description": "Jenkins 中文社区2019第一场工作坊", "content": "前段时间,Jenkins 中文社区建了一个“Jenkins 中文社区技术交流”的微信群。\n群里不温不火,不时有人抛出几个关于 Jenkins 流水线的问题。比如以下聊天记录:\n而这些问题都共同说明另一个问题:Jenkins 的流水线的普及度还很低。大家都苦恼着不知道如何写 Jenkins 流水线呢。\n所以,Jenkins 中文社区决定6月22日组织一场工作坊,手把手教大家如何写 Jenkins pipeline。工作坊内容包括: * 流水线基础讲解及其练习。 * 流水线高级部分讲解及其练习。 * 案例实战(注意啦,可是有案例的。不是虚的。)\n问题来了?谁是这次工作坊的教练呢?\n赵晓杰:jenkinsci Contributor,Jenkins 中文社区发起人。\n想参加的同学,请点击阅读原文报名参加。\n如果无法现场参加的同学可以发邮件至 events@mail.jenkins-zh.cn 申请 ZOOM 网络会议接入。另,我们鼓励由一人申请,并组织好其他人一起参与。这样多人一起进行工作坊,效果更佳。申请邮件中写明:申请人所在公司、地点、参与人数。\n对了想入伙加群?很简单,Jenkins 公众号后台回复“微信群”,扫码入群。趁现在群没满,你懂的!~\n", "auhtor": "jenkins-zh-robot", "translator": "", "original": "", "poster": "pipeline-example.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-09-github-share/", "title": "在线分享 - 作为一名开源贡献者是如何使用 GitHub 的?", "type": "wechat", "date": "2019-06-09 00:00:00 +0000 UTC", "tags": ["在线分享"], "description": "这是一场开源事业有缘人的在线分享、交流会", "content": " 本次在线分享活动,是由 Jenkins 中文社区与开源社共同发起,旨在向每一位有意了解、参与开源社区活动的朋友们普及 GitHub 的使用。\nGitHub 作为全球最大、最为专业的开源社交平台,不仅仅是研发或者技术相关岗位人员的专利,文案、市场相关同学同样可以利用这个 有着无限潜力的开源平台来为开源事业贡献自己的一份绵薄之力。\n社区重于代码,这是很多资深开源人士的共同观点。除了可以在 GitHub 上托管我们的源代码之外,到底还可以让 GitHub 为大家所在的 开源社区、项目提供哪些便利的服务呢?除了如何使用 GitHub 以外,这也是我希望与大家分享、共同探讨的。\n分享人 瑞克,Jenkins 中文社区发起人,热衷于传播开源理念、开源技术。多年研发经验, 目前关注于 DevOps 领域,尤其是持续交付方面。\n分享概要 GitHub 基本介绍 常用功能 开源礼仪 非技术类使用概要 熟悉一个项目 了解如何做贡献 常规的贡献流程 更高效的实践经验 Git 基本介绍 客户端利器 hub 的几种模式 互动环节 合作企业 平安云 GitHub\n报名 感兴趣的同学,请及时点击“阅读原文“进行报名,名额有限。我们会在活动前通过邮件的方式告知参与链接。\n活动时间为:2019年6月14日 19:00~20:00\n注意事项 为了能够让大家能够共同完成一次高效的在线分享活动,请各位准备参加的同学仔细阅读下面的事项:\n 提前安排好时间,找一个安静的环境 检查网络是否通畅 准备好你的问题或者疑问 安装好客户端 https://github.com/github/hub 有任何技术细节、疑问,请关注 Jenkins 公众号,回复:微信群 ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "./github.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-05-devops-challenges-in-2019-how-to-overcome-them/", "title": "2019年 DevOps 面临的挑战以及如何战胜它们", "type": "wechat", "date": "2019-06-05 00:00:00 +0000 UTC", "tags": ["devops"], "description": "新的 DevOps 采用者应该意识到他们在使用 DevOps 时会面临的一些挑战", "content": " 随着 DevOps 逐渐成为主流,许多团队都在问自己应该从哪里开始采用 DevOps , 他们将在此过程中面临哪些挑战,以及如何解决那些挑战。 每年都有越来越多的公司希望从传统的瀑布式方法转向 DevOps 。\n许多软件开发公司将 DevOps 看作是一个公司在效率方面所能达到的顶峰,并且这有点难。 应对挑战可能大大降低你的生产力,同时适应 DevOps 方法会导致各种自动化工具和开发过程之间缺乏协调。\n在本文中,我们将讨论 DevOps 在2019年面临的一些重大挑战,以及可以采取哪些措施来战胜它们。\n关注遗留的应用程序和系统 DevOps 团队面临的第一个和主要挑战涉及到遗留应用程序的构建, 这些应用程序是在没有考虑 DevOps 的情况下构建的。 这似乎看起来有益无害,但这对于转变来说是相当棘手的。 即使你关注使用 DevOps 的新应用程序和系统,你也需要维护这些遗留系统。\n对于遗留应用程序的转变这里还有其他原因。 一开始,你需要努力逐步将淘汰它们,或者逐渐将客户转移到使用 DevOps 系统维护的新版本。 否则,你可以尝试创建一个新的系统来维护遗留的应用程序,它不会干扰你的 DevOps 系统。 你也可以使用 Scala 性能度量工具,比如 AppOptics ,它有助于逐步淘汰非 DevOps 系统。\n选择适合的项目 对于一个新的 DevOps 团队来说,为每个新项目选择 DevOps 似乎很明智,但事实并非总是如此。 DevOps 不是强制性的,因为如果没有正确地实现 DevOps ,有时会降低整个生产过程的速度。 因此,在选择要使用 DevOps 的项目时,你应该非常勤奋。 在考虑 DevOps 是否必要时,最好记住 DevOps 是一种运营策略,并不总是适合的。\n如果你正在努力快速规模化的软件,并从其敏捷性中获得更快的速度,那么 DevOps 是一个明智的选择。 同样地,DevOps 并不是一直起作用,所以不应该把它当作解决所有问题的首选解决方案。 例如,如果你正在使用一个较旧的系统,那么最好坚持使用旧的方法和流程,因为不可能总是为这些方法和流程找到自动化的系统。\n除此之外,规划和设计工作被认为不适合 DevOps ,因为进行设计和 UX 是处理流程的更成功的方法,而不是不断改进。\n性能测试 有一点没有改变,那就是随着用户期望的提高,对广泛测试的需求也在增加。 多亏了 DevOps ,现在可以更快地创建和发布产品了,但是你不应该在发布之前对足够的产品测试作出牺牲。\nDevOps 擅长多种事情,但是就 bug 而言,它也有一些限制。 幸运的是,有大量的工具,例如 Tricentis 和 Zephyr ,可以帮助你确保发布的产品的最高性能。\n难以捉摸的人的问题 通过对 DevOps 的各种研究,许多团队还在与一个叫做\u0026rdquo;人的问题\u0026rdquo;的挑战作斗争,这真是一个奇迹。 当开发人员创建一个 DevOps 无法启动的环境时,问题就会在开发人员和管理人员之间出现。 这种问题始于缺乏经验,因为许多团队只是因为新奇事物综合症而采用 DevOps ,最终会经历灾难。\n另一个障碍可能是缺乏糟糕的领导,因为 DevOps 团队需要有足够的自由来为项目做出战略决策。 在强大领导的支持下,你可以通过培训整个开发和运营团队来进行 DevOps 工作。\n2019年DevOps的前景如何? DevOps 有望在2019年占据开发者心目中的最高位置,原因显而易见。 DevOps 方法为自动化和不断改进找到了空间,这在现代技术世界中是至关重要的。\n正如我们上面所讨论的,在接下来的一年里,仍然有许多挑战威胁着许多团队 DevOps 的成功。 如果你正在考虑 DevOps 或寻找更好的方法来改进策略并接受上述挑战, 那么你可以通过适当的耐心和承诺更好地解决这些问题。不断学习!\n", "auhtor": "Herman Morgan", "translator": "donhui", "original": "https://dzone.com/articles/devops-challenges-in-2019-how-to-overcome-them", "poster": "./2019-06-05-devops-challenges-in-2019-how-to-overcome-them/xian.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-29-jenkins-release/", "title": "Jenkins 2.176~2.178版本更新", "type": "wechat", "date": "2019-05-29 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "Jenkins 每周更新版2.176~2.178更新内容", "content": " 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.4.18变更日志, Jetty 9.4.17变更日志, Jetty 9.4.16变更日志) 恢复安装向导使用的中文本地化资源。(在2.176中回归)。 (issue 57412) 健壮性:对于 ComputerListener#onOnline() 中的运行时异常,不要将代理脱机。 (issue 57111) 由于排除筛选,不要为存档制品中不包含的文件记录指纹。 (issue 41696) 开发者:使 UserSeedProperty 对插件开发人员可用。 (pull 4018) 开发者:添加对 titleClassMethod 的支持(从流水线中的 symbol-hetero-list )到 f:hetero-list. (issue 56379) 2.176 (2019-05-05) 在 2.175 中有些插件可能会失败,并会有一个与序列化 FilePath 有关的错误。 现在,这已被降级为警告。 插件更新仍然应该被用来修正潜在的错误。 (issue 57244) 添加 stop-job CLI命令,该命令允许中止构建。 (issue 11888) 将 Remoting 从3.29更新到3.30,以修复一些较小的问题。 (issue 51004, issue 57107, issue 46515, 完整的变更日志) 将所有中文本地化资源迁移到本地化:中文(简体)插件。 (pull 4008) 当 Jenkins#addNode 或 Nodes#addNode 实际替换现有节点时,NodeListener#onCreated 被调用。 (issue 57273) 开发者:在 classpath 中包含 CLI 模块生成的源文件。 (pull 4006) ", "auhtor": "donhui", "translator": "", "original": "", "poster": "“./2019-05-29-jenkins-release/qingshanlake.jpg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-28-jenkins-pipeline-shared-lib-unit-test/", "title": "如何对 Jenkins 共享库进行单元测试", "type": "wechat", "date": "2019-05-28 00:00:00 +0000 UTC", "tags": ["jenkins"], "description": "包括该单元测试框架的原理介绍", "content": " Jenkins 共享库是除了 Jenkins 插件外,另一种扩展 Jenkins 流水线的技术。通过它,可以轻松地自定义步骤,还可以对现有的流水线逻辑进行一定程度的抽象与封装。至于如何写及如何使用它,读者朋友可以移步附录中的官方文档。\n对共享库进行单元测试的原因 但是如何对它进行单元测试呢?共享库越来越大时,你不得不考虑这个问题。因为如果你不在早期就开始单元测试,共享库后期可能就会发展成如下图所示的“艺术品”——能工作,但是脆弱到没有人敢动。\n[图片来自网络,侵权必删]\n这就是代码越写越慢的原因之一。后人要不断地填前人有意无意挖的坑。\n共享库单元测试搭建 共享库官方文档介绍的代码仓库结构 (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.foo.Bar 以上是共享库官方文档介绍的代码仓库结构。整个代码库可以分成两部分:src 目录部分和 vars 目录部分。它们的测试脚手架的搭建方式是不一样的。\nsrc 目录中的代码与普通的 Java 类代码本质上没有太大的区别。只不过换成了 Groovy 类。\n但是 vars 目录中代码本身是严重依赖于 Jenkins 运行时环境的脚本。\n接下来,分别介绍如何搭建它们的测试脚手架。\n测试 src 目录中的 Groovy 代码 在对 src 目录中的 Groovy 代码进行单元测试前,我们需要回答一个问题:使用何种构建工具进行构建?\n我们有两种常规选择:Maven 和 Gradle。本文选择的是前者。\n接下来的第二个问题是,共享库源代码结构并不是 Maven 官方标准结构。下例为标准结构:\n├── pom.xml └── src ├── main │ ├── java │ └── resources └── test ├── java └── resources 因为共享库使用的 Groovy 写的,所以,还必须使 Maven 能对 Groovy 代码进行编译。\n可以通过 Maven 插件:GMavenPlus 解决以上问题,插件的关键配置如下:\n\u0026lt;configuration\u0026gt; \u0026lt;sources\u0026gt; \u0026lt;source\u0026gt; \u0026lt;!-- 指定Groovy类源码所在的目录 --\u0026gt; \u0026lt;directory\u0026gt;${project.basedir}/src\u0026lt;/directory\u0026gt; \u0026lt;includes\u0026gt; \u0026lt;include\u0026gt;**/*.groovy\u0026lt;/include\u0026gt; \u0026lt;/includes\u0026gt; \u0026lt;/source\u0026gt; \u0026lt;/sources\u0026gt; \u0026lt;testSources\u0026gt; \u0026lt;testSource\u0026gt; \u0026lt;!-- 指定单元测试所在的目录 --\u0026gt; \u0026lt;directory\u0026gt;${project.basedir}/test/groovy\u0026lt;/directory\u0026gt; \u0026lt;includes\u0026gt; \u0026lt;include\u0026gt;**/*.groovy\u0026lt;/include\u0026gt; \u0026lt;/includes\u0026gt; \u0026lt;/testSource\u0026gt; \u0026lt;/testSources\u0026gt; \u0026lt;/configuration\u0026gt; 同时,我们还必须加入 Groovy 语言的依赖:\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.codehaus.groovy\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;groovy-all\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${groovy-all.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; 最终目录结构如下图所示: 然后我们就可以愉快地对 src 目录中的代码进行单元测试了。\n测试 vars 目录中 Groovy 代码 对 vars 目录中的脚本的测试难点在于它强依赖于 Jenkins 的运行时环境。换句话说,你必须启动一个 Jenkins 才能正常运行它。但是这样就变成集成测试了。那么怎么实现单元测试呢?\n经 Google 发现,前人已经写了一个 Jenkins 共享库单元测试的框架。我们拿来用就好。所谓,前人载树,后人乘凉。\n这个框架叫:Jenkins Pipeline Unit testing framework。后文简称“框架”。它的使用方法如下:\n 在 pom.xml 中加入依赖: xml \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;com.lesfurets\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;jenkins-pipeline-unit\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;1.1\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; 写单元测试\n// test/groovy/codes/showme/pipeline/lib/SayHelloTest.groovy // 必须继承 BasePipelineTest 类 class SayHelloTest extends BasePipelineTest { @Override @Before public void setUp() throws Exception { // 告诉框架,共享库脚本所在的目录 scriptRoots = [\u0026quot;vars\u0026quot;] // 初始化框架 super.setUp() } @Test void call() { // 加载脚本 def script = loadScript(\u0026quot;sayHello.groovy\u0026quot;) // 运行脚本 script.call() // 断言脚本中运行了 echo 方法 // 同时参数为\u0026quot;hello pipeline\u0026quot; assertThat( helper.callStack .findAll { c -\u0026gt; c.methodName == 'echo' } .any { c -\u0026gt; c.argsToString().contains('hello pipeline') } ).isTrue() // 框架提供的方法,后面会介绍。 printCallStack() } } 创建单元测试时,注意选择 Groovy 语言,同时类名要以 Test 结尾。\n 改进 以上代码是为了让读者对共享库脚本的单元测试有更直观的理解。实际工作中会做一些调整。我们会将 extends BasePipelineTest 和 setUp 方法抽到一个父类中,所有其它测试类继承于它。 此时,我们最简单的共享库的单元测试脚手架就搭建好了。\n但是,实际工作中遇到场景并不会这么简单。面对更复杂的场景,必须了解 Jenkins Pipeline Unit testing framework 的原理。由此可见,写单元测试也是需要成本的。至于收益,仁者见仁,智者见智了。\nJenkins Pipeline Unit testing framework 原理 上文中的单元测试实际上做了三件事情: 1. 加载目标脚本,loadScript 方法由框架提供。 2. 运行脚本,loadScript 方法返回加载好的脚本。 3. 断言脚本中的方法是否有按预期执行,helper 是 BasePipelineTest 的一个字段。\n从第三步的 helper.callStack 中,我们可以猜到第二步中的script.call() 并不是真正的执行,而是将脚本中方法调用被写到 helper 的 callStack 字段中。从 helper 的源码可以确认这一点:\n/** * Stack of method calls of scripts loaded by this helper */ List\u0026lt;MethodCall\u0026gt; callStack = [] 那么,script.call() 内部是如何做到将方法调用写入到 callStack 中的呢?\n一定是在 loadScript 运行过程做了什么事情,否则,script 怎么会多出这些行为。我们来看看它的底层源码:\n/** * Load the script with given binding context without running, returning the Script * @param scriptName * @param binding * @return Script object */ Script loadScript(String scriptName, Binding binding) { Objects.requireNonNull(binding, \u0026quot;Binding cannot be null.\u0026quot;) Objects.requireNonNull(gse, \u0026quot;GroovyScriptEngine is not initialized: Initialize the helper by calling init().\u0026quot;) Class scriptClass = gse.loadScriptByName(scriptName) setGlobalVars(binding) Script script = InvokerHelper.createScript(scriptClass, binding) script.metaClass.invokeMethod = getMethodInterceptor() script.metaClass.static.invokeMethod = getMethodInterceptor() script.metaClass.methodMissing = getMethodMissingInterceptor() return script } gse 是 Groovy 脚本执行引擎 GroovyScriptEngine。它在这里的作用是拿到脚本的 Class 类型,然后使用 Groovy 语言的 InvokerHelper 静态帮助类创建一个脚本对象。\n接下来做的就是核心了:\nscript.metaClass.invokeMethod = getMethodInterceptor() script.metaClass.static.invokeMethod = getMethodInterceptor() script.metaClass.methodMissing = getMethodMissingInterceptor() 它将脚本对象实例的方法调用都委托给了拦截器 methodInterceptor。Groovy 对元编程非常友好。可以直接对方法进行拦截。拦截器源码如下:\n/** * Method interceptor for any method called in executing script. * Calls are logged on the call stack. */ public methodInterceptor = { String name, Object[] args -\u0026gt; // register method call to stack int depth = Thread.currentThread().stackTrace.findAll { it.className == delegate.class.name }.size() this.registerMethodCall(delegate, depth, name, args) // check if it is to be intercepted def intercepted = this.getAllowedMethodEntry(name, args) if (intercepted != null \u0026amp;\u0026amp; intercepted.value) { intercepted.value.delegate = delegate return callClosure(intercepted.value, args) } // if not search for the method declaration MetaMethod m = delegate.metaClass.getMetaMethod(name, args) // ...and call it. If we cannot find it, delegate call to methodMissing def result = (m ? this.callMethod(m, delegate, args) : delegate.metaClass.invokeMissingMethod(delegate, name, args)) return result } 它做了三件事情: 1. 将调用方法名和参数写入到 callStack 中 2. 如果被调用方法名是被注册了的方法,则执行该方法对象的 mock。下文会详细介绍。 3. 如果被调用方法没有被注册,则真正执行它。\n需要解释一个第二点。并不是所有的共享库中的方法都是需要拦截的。我们只需要对我们感兴趣的方法进行拦截,并实现 mock 的效果。\n写到这里,有些读者朋友可能头晕了。笔者在这里进行小结一下。\n 因为我们不希望共享库脚本中的依赖于 Jenkins 运行时的方法(比如拉代码的步骤)真正运行。所以,我们需要对这些方法进行 mock。在 Groovy 中,我们可以通过方法级别的拦截来实现 mock 的效果。 但是我们又不应该对共享库中所有的方法进行拦截,所以就需要我们在执行单元测试前将自己需要 mock 的方法进行注册到 helper 的 allowedMethodCallbacks 字段中。methodInterceptor拦截器会根据它来进行拦截。\n 在 BasePipelineTest 的 setUp 方法中,框架注册了一些默认方法,不至于我们要手工注册太多方法。以下是部分源码:\nhelper.registerAllowedMethod(\u0026quot;sh\u0026quot;, [Map.class], null) helper.registerAllowedMethod(\u0026quot;checkout\u0026quot;, [Map.class], null) helper.registerAllowedMethod(\u0026quot;echo\u0026quot;, [String.class], null) registerAllowedMethod 各参数的作用: * 第一个参数:要注册的方法。 * 第二参数:该方法的参数列表。 * 第三参数:一个闭包。当该访问被调用时会执行此闭包。\n以上就是框架的基本原理了。接下来,再介绍几种场景。\n几种应用场景 环境变量 当你的共享库脚本使用了 env 变量,可以这样测试:\nbinding.setVariable('env', new HashMap()) def script = loadScript('setEnvStep.groovy') script.invokeMethod(\u0026quot;call\u0026quot;, [k: '123', v: \u0026quot;456\u0026quot;]) assertEquals(\u0026quot;123\u0026quot;, ((HashMap) binding.getVariable(\u0026quot;env\u0026quot;)).get(\u0026quot;k\u0026quot;)) binding 由 BasePipelineTest 的一个字段,用于绑定变量。binding 会被设置到 gse 中。\n调用其它共享库脚本 比如脚本 a 中调用到了 setEnvStep。这时可以在 a 执行前注册 setEnvStep 方法。\nhelper.registerAllowedMethod(\u0026quot;setEnvStep\u0026quot;, [LinkedHashMap.class], null) 希望被 mock 的方法能有返回值 helper.registerAllowedMethod(\u0026quot;getDevOpsMetadata\u0026quot;, [String.class, String.class], { return \u0026quot;data from cloud\u0026quot; }) 后记 不得不说 Jenkins Pipeline Unit testing framework 框架的作者非常聪明。另外,此类技术不仅可以用于单元测试。理论上还可以用于 Jenkins pipeline 的零侵入拦截,以实现一些平台级特殊的需求。\n附录 共享库官方文档:https://jenkins.io/zh/doc/book/pipeline/shared-libraries/ 本文示例代码:https://github.com/zacker330/jenkins-pipeline-shared-lib-unittest-demo JenkinsPipelineUnit:https://github.com/jenkinsci/JenkinsPipelineUnit ", "auhtor": "zacker330", "translator": "", "original": "", "poster": "poster.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-27-docs-sig-announcement/", "title": "Jenkins 文档特别兴趣小组", "type": "wechat", "date": "2019-05-27 00:00:00 +0000 UTC", "tags": ["documentation", "docs", "community"], "description": "Jenkins 宣布成立文档特别兴趣小组", "content": " 我们很高兴地宣布 Jenkins 文档特别兴趣小组的成立。 文档特别兴趣小组鼓励贡献者和外部社区创建和 review Jenkins 文档。\n更多详情和计划,请参见:文档特别兴趣小组简介。\n我能帮什么忙呢? Jenkins 文档特别兴趣小组希望从以下方面得到您的帮助:\n review 及修复 打开的 bug 报告 review Jenkins 文档 pull requests review Jenkins X 文档 pull requests 我该如何修复文档 bug? 关于如何为 Jenkins 文档做贡献的说明,请参见站点仓库中的 CONTRIBUTING 文件。 按照说明文件,提交 pull requests 以供 review 。\n关于如何为 Jenkins X 文档做贡献的说明,请参见站点仓库中的 Jenkins X 文档站点。 按照说明文件,提交 pull requests 以供 review 。\n我该如何评估 pull request? Jenkins 项目的 pull requests 会在 Jenkins 文档仓库进行 review 。 使用您的凭据登录到 GitHub,向 pull requests 中添加评论。\nJenkins X 项目的 pull requests 会在 Jenkins X 档仓库进行 review 。 使用您的凭据登录到 GitHub,向 pull requests 中添加评论。\n", "auhtor": "markewaite", "translator": "donhui", "original": "https://jenkins.io/blog/2019/05/11/docs-sig-announcement/", "poster": "./2019-05-27-docs-sig-announcement/Jenkins_Needs_You-02.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-24-achieve-cicd-with-jenkins-x-kubernetes-and-spring/", "title": "使用 Jenkins X、Kubernetes 和 Spring Boot 实现 CI/CD", "type": "wechat", "date": "2019-05-24 00:00:00 +0000 UTC", "tags": ["jenkins-x", "k8s", "kubernetes", "ci", "cd", "spring boot"], "description": "通过使用 Jenkins X 和 Kubernetes 来改进 Spring Boot 应用程序,使 Jenkins X 成为 CI/CD 过程的关键部分。", "content": " 过去五年中的变化,如迁移到公有云以及从虚拟机向容器的转变,已经彻底改变了构建和部署软件的意义。\n以 Kubernetes 为例。Google 于2014年开源,现在所有主流的公有云供应商都支持它\u0026mdash;它为开发人员提供了一种很好的方式,可以将应用程序打包到 Docker 容器中,并部署到任意 Kubernetes 集群中。\n使用 CI/CD、Kubernetes 和 Jenkins X 进行高性能开发 在技术上,高性能团队几乎总是成功的必要条件,而持续集成、持续部署(CI/CD)、小迭代以及快速反馈是构建模块。为你的云原生应用程序设置 CI/CD 可能比较困难。通过自动化所有内容,开发人员可以花费宝贵的时间来交付实际的业务。\n如何使用容器、持续交付和 Kubernetes 成为高效团队?这就是 Jenkins X 的切入点。\n“Jenkins X 的理念是为所有开发人员提供他们自己的海军航海管家,可以帮助你航行持续交付的海洋。” - James Strachan\nJenkins X 帮助你自动化你在 Kubernetes 中的 CI/CD - 你甚至不需要学习 Docker 或 Kubernetes!\nJenkins X 能做什么? Jenkins X 在 Kubernetes 上自动安装,配置和升级 Jenkins 和其他应用程序(Helm,Skaffold,Nexus 等)。它使用 Docker 镜像、Helm 图表和流水线来自动化应用程序的 CI/CD。它使用 GitOps 来管理环境之间的升级,并通过在拉取请求和生产时对其进行评论来提供大量反馈。\nJenkins X 入门 要安装 Jenkins X,首先需要在你的机器或云供应商上安装 jx 二进制文件。从 Google Cloud 可以获得300美元的积分,所以我决定从那里开始。\n在 Google Cloud 上安装 Jenkins X 并创建群集 浏览到cloud.google.com并登录。如果你还没有帐户,请注册免费试用。转到控制台(右上角有一个链接)并激活 Google Cloud shell。将以下命令复制并粘贴到 shell 中。\ncurl -L https://github.com/jenkins-x/jx/releases/download/v1.3.79/jx-linux-amd64.tar.gz | tar xzv sudo mv jx /usr/local/bin 注意:Google Cloud Shell 将在一小时后终止在你的主目录之外所做的任何更改,因此你可能必须重新运行这些命令。好消息是它们将在你的历史中,所以你只需要向上箭头并进入。你也可以删除上面的 sudo mv 命令,并将以下内容添加到 .bashrc 中。\nexport PATH=$PATH:. 使用以下命令在 GKE(Google Kubernetes Engine)上创建集群。你可能必须为你的帐户启用 GKE。\njx create cluster gke --skip-login 如果系统提示你下载 helm,请确认你要安装。系统将提示你选择 Google Cloud Zone。我建议选择一个靠近你的位置。我选择 us-west1-a,因为我住在 Denver, Colorado 附近。对于 Google Cloud Machine 类型,我选择了 n1-standard-2 并使用了 min(3)和 max(5)个节点数的默认值。\n对于 GitHub 名称,键入你自己的(例如 mraible)和你在 GitHub 上注册的电子邮件(例如 matt.raible@okta.com)。我试图使用 oktadeveloper(一个 GitHub 组织),但我无法使其工作。\n注意:如果你的帐户启用了两步认证,则 GitHub 集成将失败。如果你希望成功完成该过程,则需要在 GitHub 上禁用它。\n当提示安装 ingress controller 时,按 Enter 键 确定。再次按 Enter 键选择默认 domain。\n系统将提示你创建 GitHub API Token。单击 提供的 URL 并将其命名为 “Jenkins X”。将 token 值复制并粘贴回控制台。\n在安装完成后喝杯咖啡、饮料或做一些俯卧撑。可能需要几分钟。\n下一步是将 API token 从 Jenkins 复制到你的控制台。按照控制台中提供的说明进行操作。\n完成后,运行 jx console 并单击链接以登录到 Jenkins 实例。单击 Administration 并升级 Jenkins 及其所有插件(插件管理器 \u0026gt; 滚动到底部并选择全部)。如果未能执行此步骤,将无法从 GitHub pull request 到 Jenkins X CI 进程。\n创建一个 Spring Boot 应用程序 当我第一次开始使用 Jenkins X 时,我尝试导入现有项目。即使我的应用程序使用了 Spring Boot,但是根目录中没有 pom.xml,所以 Jenkins X 认为它是一个 Node.js 应用程序。出于这个原因,我建议首先创建一个空白的 Spring Boot 应用程序,以保证 Jenkins X 正确创建。\n从 Cloud Shell 创建一个简单的 Spring Boot 应用程序:\njx create spring -d web -d actuator 此命令使用 Spring Initializr,因此系统会提示你进行一些选择。以下是我的选择:\n QUESTION ANSWER Language java Group com.okta.developer Artifact okta-spring-jx-example 提示:为你的 artifact name 选取一个简洁的名称将减轻你的痛苦。Jenkins X 对于版本名称有53个字符的限制,oktadeveloper/okta-spring-boot-jenkinsx-example 将会使它超过两个字符。\n为 git 用户名、初始化 git 和提交消息都选择默认值。如果你不想使用个人帐户,可以选择要使用的组织。运行以下命令以查看应用程序的 CI/CD 流水线。\njx get activity -f okta-spring-jx-example -w 运行 jx console,单击生成的链接,然后导航到你的项目(如果你想要一个更富视觉效果的视图)。\n此过程将执行一些任务:\n 为你的项目创建一个版本。 为演示环境项目创建 pull request。 将其自动部署到演示环境,以便你可以查看它的运行情况。 Merge status checks all passed so the promotion worked! Application is available at: http://okta-spring-jx-example.jx-staging.35.230.106.169.nip.io 注意:由于 Spring Boot 默认情况下不提供欢迎页面,所以打开上面的 URL 时将返回404。\n使用 Jenkins X 将 Spring Boot 应用程序部署到生产环境中 默认情况下,Jenkins X 只会自动部署到演示环境。你可以手动改进从演示到生产使用:\njx promote okta-spring-jx-example --version 0.0.1 --env production 你可以使用 jx edit environment 更改生产环境,以使用自动部署。\n既然你已经知道如何使用 Jenkins X 和一个简单的 Spring Boot 应用程序,让我们来看看如何通过一个更实际的示例使其工作。\n保护你的 Spring Boot 应用程序并添加 Angular PWA 在过去的几个月里,我写了一系列有关使用 Ionic/Angular 和 Spring Boot 构建 PWA(渐进式 Web 应用程序)的博文。\n 使用 Okta 保护你的加密货币财富跟踪 PWA 使用 Okta(而不是本地存储)安全地存储用户的数据 使用 WireMock、Jest、Protractor 和 Travis CI 测试 Spring Boot API 和 Angular 组件的 Hitchhiker 指南 将你的 Spring Boot + Angular PWA 部署为一个 Artifact 这是该系列的最后一篇博客文章。我相信这是一个真实应用程序的很好的例子,因为它有许多单元和集成测试,包括与 Protractor 的端到端测试。让我们看看如何使用 Jenkins X 和 Kubernetes 自动化生产路径! 克隆刚刚从GitHub创建的Spring Boot项目(确保在URL中更改{yourUsername}):\ngit clone https://github.com/{yourUsername}/okta-spring-jx-example.git okta-jenkinsx 在邻近目录中,将创建的具有 Spring Boot + Angular 的项目克隆为一个 artifact:\ngit clone https://github.com/oktadeveloper/okta-spring-boot-angular-auth-code-flow-example.git spring-boot-angular 在终端中,导航到 okta-jenkinsx 并删除不再需要的文件:\ncd okta-jenkinsx rm -rf .mvn src mvnw* pom.xml 结果应该是包含以下文件的目录结构:\n$ tree . . ├── charts │ ├── okta-spring-jx-example │ │ ├── Chart.yaml │ │ ├── Makefile │ │ ├── README.md │ │ ├── templates │ │ │ ├── deployment.yaml │ │ │ ├── _helpers.tpl │ │ │ ├── NOTES.txt │ │ │ └── service.yaml │ │ └── values.yaml │ └── preview │ ├── Chart.yaml │ ├── Makefile │ ├── requirements.yaml │ └── values.yaml ├── Dockerfile ├── Jenkinsfile └── skaffold.yaml 4 directories, 15 files 将 spring-boot-angular 所有文件复制到 okta-jenkinsx。\ncp -r ../spring-boot-angular/* . 使用 Travis CI 测试此应用程序时,我运行了 npm install 作为该过程的一部分。使用 Jenkins X,使用一个容器(例如 maven 或者 nodejs)保存所有内容更简单,因此在 frontend-maven-plugin(在 holdings-api/pom.xml)中添加执行以运行 npm install (提示:你将需要执行 id==’npm install' 添加到现有的pom.xml中)。\n现在是 okta-jenkinsx 在 IntelliJ IDEA、Eclipse、Netbeans 或 VS Code 等 IDE 中作为项目打开目录的好时机!\n\u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;com.github.eirslett\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;frontend-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${frontend-maven-plugin.version}\u0026lt;/version\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;workingDirectory\u0026gt;../crypto-pwa\u0026lt;/workingDirectory\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;executions\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;install node and npm\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;install-node-and-npm\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;nodeVersion\u0026gt;${node.version}\u0026lt;/nodeVersion\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;npm install\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;npm\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;phase\u0026gt;generate-resources\u0026lt;/phase\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;arguments\u0026gt;install --unsafe-perm\u0026lt;/arguments\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/execution\u0026gt; ... \u0026lt;/executions\u0026gt; \u0026lt;/plugin\u0026gt; 注意:--unsafe-perm 标志是必要的,因为 Jenkins X 以 root 用户身份运行构建。我从 node-sass 的故障排除说明中找到了这个解决方案。\n增加 Actuator 并关闭 HTTPS Jenkins X 依靠 Spring Boot 的 Actuator 进行健康检查。这意味着如果你不将其包含在你的项目中(或有 /actuator/health 防护),Jenkins X 会报告你的应用程序启动失败。\n将 Actuator starter 作为依赖项添加到 holdings-api/pom.xml 中:\n\u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-starter-actuator\u0026lt;/artifactId\u0026gt; \u0026lt;/dependency\u0026gt; 你还需要允许访问其运行健康检查。Jenkins X 将部署你的应用程序在一个 NGINX 服务器中,因此你也需要强制关闭 HTTPS,否则你将无法访问你的应用程序。修改 holdings-api/src/main/java/.../SecurityConfiguration.java 以允许 holdings-api/src/main/java/.../SecurityConfiguration.java 和删除 requiresSecure()。\npublic class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers(\u0026quot;/**/*.{js,html,css}\u0026quot;); } @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .and() .authorizeRequests() .antMatchers(\u0026quot;/\u0026quot;, \u0026quot;/home\u0026quot;, \u0026quot;/api/user\u0026quot;, \u0026quot;/actuator/health\u0026quot;).permitAll() .anyRequest().authenticated(); } } 调整 Dockerfile 和 Jenkinsfile 中的路径 由于此项目构建在子目录而不是根目录中,因此请更新 ./Dockerfile 以查找 holdings-api 文件。\nFROM openjdk:8-jdk-slim ENV PORT 8080 ENV CLASSPATH /opt/lib EXPOSE 8080 # copy pom.xml and wildcards to avoid this command failing if there's no target/lib directory COPY holdings-api/pom.xml holdings-api/target/lib* /opt/lib/ # NOTE we assume there's only 1 jar in the target dir # but at least this means we don't have to guess the name # we could do with a better way to know the name - or to always create an app.jar or something COPY holdings-api/target/*.jar /opt/app.jar WORKDIR /opt CMD [\u0026quot;java\u0026quot;, \u0026quot;-jar\u0026quot;, \u0026quot;app.jar\u0026quot;] 你还需要更新 Jenkinsfile,以便它可以运行 holdings-api 目录中的任何 mvn 命令。也添加 -Pprod 配置文件。例如:\n// in the 'CI Build and push snapshot' stage steps { container('maven') { dir ('./holdings-api') { sh \u0026quot;mvn versions:set -DnewVersion=$PREVIEW_VERSION\u0026quot; sh \u0026quot;mvn install -Pprod\u0026quot; } } ... } // in the 'Build Release' stage dir ('./holdings-api') { sh \u0026quot;mvn versions:set -DnewVersion=\\$(cat ../VERSION)\u0026quot; } ... dir ('./holdings-api') { sh \u0026quot;mvn clean deploy -Pprod\u0026quot; } 这应该足以让这个应用程序与 Jenkins X 一起使用。但是,除非你有一个 Okta 帐户并相应地配置它,否则你将无法登录它。\n为什么使用Okta? 简而言之,我们使标识管理比你可能习惯的更简洁、更安全、更具可扩展性。Okta 是一种云服务,允许开发人员创建、编辑和安全存储用户帐户和用户帐户数据,并将其与一个或多个应用程序相连接。我们的 API 使你能够:\n 对用户进行身份验证和授权 存储关于用户的数据 执行基于密码和社交登录 使用多重身份验证保护应用程序 了解更多!查看我们的产品文档 你心动了吗?注册一个永远免费的开发者帐户,当你完成后,请返回,以便我们可以通过 Spring Boot 和 Jenkins X 了解有关 CI/CD 的更多信息! 在 Okta 中为 Spring Boot 应用程序创建一个 Web 应用程序 完成设置过程后,登录到你的帐户并导航到 Applications \u0026gt; Add Application。单击 Web 和 下一步。在下一页中,输入以下值并单击 Done (必须单击 Done,然后编辑以修改注销重定向 URI)。\n 应用名称: Jenkins X 默认 URI: http://localhost:8080 登录重定向 URI: http://localhost:8080/login 注销重定向 URI: http://localhost:8080 打开 holdings-api/src/main/resources/application.yml 并将你 org/app 中的值粘贴到其中。 okta: client: orgUrl: https://okta.okta.com token: XXX security: oauth2: client: access-token-uri: https://okta.okta.com/oauth2/default/v1/token user-authorization-uri: https://okta.okta.com/oauth2/default/v1/authorize client-id: {clientId} client-secret: {clientSecret} resource: user-info-uri: https://okta.okta.com/oauth2/default/v1/userinfo 你将注意到 token 值是 xxx。这是因为我更喜欢从环境变量中读取它,而不是签入源代码控制。你可能也想为你的客户密钥执行此操作,但我只是为了简洁而做一个属性。要创建 API token:\n 导航到 API \u0026gt; Tokens ,然后单击 Create Token 为令牌命名(例如 “Jenkins X”),然后将其值设置为 OKTA_CLIENT_TOKEN 环境变量。 你需要在组织的用户配置文件中添加一个 holdings 属性,以便将你的加密货币存储在 Okta 中。导航到 Users \u0026gt; Profile Editor。点击 Profile 表格中的第一个配置文件。你可以通过其 Okta 标识来识别它。单击 Add Attribute 并使用以下值: 显示名称: Holdings 变量名: holdings 描述: Cryptocurrency Holdings 执行这些步骤后,你应该能够导航到 http://localhost:8080, 并在运行以下命令后登录: cd holdings-api ./mvnw -Pprod package java -jar target/*.jar 在 Jenkins X 中存储 Secrets 在本地存储环境变量非常简单。但是你如何在 Jenkins X 中做到这一点?看看它的凭证功能就知道了。下面是使用方法:\n 在 Google Cloud Shell 上运行 jx console,以获取 Jenkins X 网址 单击该链接,登录,然后单击顶部的 Administration 单击 Credentials \u0026gt; (global) \u0026gt; Add Credentials(在左侧) 从下拉列表中选择 Secret text,并为 ID 输入 OKTA_CLIENT_TOKEN 将 Okta API token 复制/粘贴到 Secret 字段中 当你在里面,添加 secrets:OKTA_APP_ID、E2E_USERNAME 和 E2E_PASSWORD。第一个是你创建的 Jenkins X OIDC 应用程序的 ID。您可以通过在 Okta 上导航到您的应用程序并从 URL 复制值来获得它的值。该 E2E-* 密钥应该是要用来运行终端到终端(Protractor)测试的凭证。你可能想为此创建一个新用户。 你可以通过将这些值添加到 environment 顶部附近的部分来访问 Jenkinsfile 中的这些值 。\nenvironment { ORG = 'mraible' APP_NAME = 'okta-spring-jx-example' CHARTMUSEUM_CREDS = credentials('jenkins-x-chartmuseum') OKTA_CLIENT_TOKEN = credentials('OKTA_CLIENT_TOKEN') OKTA_APP_ID = credentials('OKTA_APP_ID') E2E_USERNAME = credentials('E2E_USERNAME') E2E_PASSWORD = credentials('E2E_PASSWORD') } 将环境变量转移到 Docker 容器 要将 OKTA_CLIENT_TOKEN 环境变量转移到 Docker 容器,请查看:\nsh \u0026quot;make preview\u0026quot; 并将其更改为:\nsh \u0026quot;make OKTA_CLIENT_TOKEN=\\$OKTA_CLIENT_TOKEN preview\u0026quot; 此时,你可以创建分支,提交更改,并验证 Jenkins X 中的所有内容是否正常工作。\ncd .. git checkout -b add-secure-app git add . git commit -m \u0026quot;Add Bootiful PWA\u0026quot; git push origin add-secure-app 打开浏览器并导航到 GitHub 上的存储库并创建 pull request。创建后它应该如下所示。\n如果你的 pull request 测试通过,你应该能看到一些绿色标记和 Jenkins X 的评论,说明你的应用程序在预览环境中可用。\n如果你单击此处链接并尝试登录,则可能会从 Okta 得到一个错误,指出重定向 URI 尚未列入白名单。\n在 Okta 中自动添加重定向 URI 当你在 Okta 中创建应用程序并在本地运行它们时,很容易知道应用程序的重定向 URI 将是什么。对于这个特定的应用程序,它们将 http://localhost:8080/login 用于登录,http://localhost:8080 用于注销。当您进入生产环境时,URL通常也是众所周知的。但是,使用 Jenkins X,URL 是动态的,并根据你的 pull request 编号动态创建的。\n要使用 Okta 进行此操作,你可以创建一个 Java 类,该类与 Okta API 进行交互。创建 holdings-api/src/test/java/.../cli/AppRedirectUriManager.java 并使用以下代码完善它。\npackage com.okta.developer.cli; import com.okta.sdk.client.Client; import com.okta.sdk.lang.Collections; import com.okta.sdk.resource.application.OpenIdConnectApplication; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @SpringBootApplication public class AppRedirectUriManager implements ApplicationRunner { private static final Logger log = LoggerFactory.getLogger(AppRedirectUriManager.class); private final Client client; @Value(\u0026quot;${appId}\u0026quot;) private String appId; @Value(\u0026quot;${redirectUri}\u0026quot;) private String redirectUri; @Value(\u0026quot;${operation:add}\u0026quot;) private String operation; public AppRedirectUriManager(Client client) { this.client = client; } public static void main(String[] args) { SpringApplication.run(AppRedirectUriManager.class, args); } @Override public void run(ApplicationArguments args) { log.info(\u0026quot;Adjusting Okta settings: {appId: {}, redirectUri: {}, operation: {}}\u0026quot;, appId, redirectUri, operation); OpenIdConnectApplication app = (OpenIdConnectApplication) client.getApplication(appId); String loginRedirectUri = redirectUri + \u0026quot;/login\u0026quot;; // update redirect URIs List\u0026lt;String\u0026gt; redirectUris = app.getSettings().getOAuthClient().getRedirectUris(); // use a set so values are unique Set\u0026lt;String\u0026gt; updatedRedirectUris = new LinkedHashSet\u0026lt;\u0026gt;(redirectUris); if (operation.equalsIgnoreCase(\u0026quot;add\u0026quot;)) { updatedRedirectUris.add(loginRedirectUri); } else if (operation.equalsIgnoreCase(\u0026quot;remove\u0026quot;)) { updatedRedirectUris.remove(loginRedirectUri); } // todo: update logout redirect URIs with redirectUri (not currently available in Java SDK) app.getSettings().getOAuthClient().setRedirectUris(Collections.toList(updatedRedirectUris)); app.update(); System.exit(0); } } 该类使用 Spring Boot 的 CLI(命令行接口)支持,这使得可以使用 Exec Maven 插件调用它。要添加对 Maven 运行它的支持,请在 holdings-api/pom.xml 进行以下修改 。\n\u0026lt;properties\u0026gt; ... \u0026lt;exec-maven-plugin.version\u0026gt;1.6.0\u0026lt;/exec-maven-plugin.version\u0026gt; \u0026lt;appId\u0026gt;default\u0026lt;/appId\u0026gt; \u0026lt;redirectUri\u0026gt;override-me\u0026lt;/redirectUri\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;!-- dependencies --\u0026gt; \u0026lt;build\u0026gt; \u0026lt;defaultGoal\u0026gt;spring-boot:run\u0026lt;/defaultGoal\u0026gt; \u0026lt;finalName\u0026gt;holdings-app-${project.version}\u0026lt;/finalName\u0026gt; \u0026lt;plugins\u0026gt; \u0026lt;!-- existing plugins --\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.codehaus.mojo\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;exec-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${exec-maven-plugin.version}\u0026lt;/version\u0026gt; \u0026lt;executions\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;add-redirect\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;java\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;/executions\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;mainClass\u0026gt;com.okta.developer.cli.AppRedirectUriManager\u0026lt;/mainClass\u0026gt; \u0026lt;classpathScope\u0026gt;test\u0026lt;/classpathScope\u0026gt; \u0026lt;arguments\u0026gt; \u0026lt;argument\u0026gt;appId ${appId} redirectUri ${redirectUri}\u0026lt;/argument\u0026gt; \u0026lt;/arguments\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;/plugins\u0026gt; \u0026lt;/build\u0026gt; 然后更新 Jenkinsfile 以在构建镜像之后添加一段 mvn exec:java 供运行。\ndir ('./charts/preview') { container('maven') { sh \u0026quot;make preview\u0026quot; sh \u0026quot;make OKTA_CLIENT_TOKEN=\\$OKTA_CLIENT_TOKEN preview\u0026quot; sh \u0026quot;jx preview --app $APP_NAME --dir ../..\u0026quot; } } // Add redirect URI in Okta dir ('./holdings-api') { container('maven') { sh ''' yum install -y jq previewURL=$(jx get preview -o json|jq -r \u0026quot;.items[].spec | select (.previewGitInfo.name==\\\\\u0026quot;$CHANGE_ID\\\\\u0026quot;) | .previewGitInfo.applicationURL\u0026quot;) mvn exec:java@add-redirect -DappId=$OKTA_APP_ID -DredirectUri=$previewURL ''' } } 提交并推送你的更改,应用程序应该更新为 http://{yourPreviewURL}/login 的重定向 URI。你需要手动为 http://{yourPreviewURL} 添加一个注销重定向 URI, 因为 Okta 的 Java SDK 目前不支持此功能。\n要将你的 pull request 上传到演示环境,请将其合并,并将主分支推送到演示环境。不幸的是,你将无法登录。这是因为没有进程使用你的 Okta 应用程序注册登台站点的重定向 URI。如果手动添加 URI,一切都应该有效。\n在 Jenkins X 中运行 Protractor 测试 对我来说,弄清楚如何在 Jenkins X 中运行端到端测试是最难的。我首先添加了一个新的 Maven 配置文件,它允许我使用 Maven 而不是 npm 运行测试。\n注意:要使此配置文件起作用,你需要将 http://localhost:8000/login 登录重定向 URI 添加到你的应用程序,并将 http://localhost:8000 作为注销重定向URI。\n\u0026lt;profile\u0026gt; \u0026lt;id\u0026gt;e2e\u0026lt;/id\u0026gt; \u0026lt;properties\u0026gt; \u0026lt;!-- Hard-code port instead of using build-helper-maven-plugin. --\u0026gt; \u0026lt;!-- This way, you don't need to add a redirectUri to Okta app. --\u0026gt; \u0026lt;http.port\u0026gt;8000\u0026lt;/http.port\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;build\u0026gt; \u0026lt;plugins\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.springframework.boot\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;spring-boot-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;executions\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;pre-integration-test\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;start\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;arguments\u0026gt; \u0026lt;argument\u0026gt;--server.port=${http.port}\u0026lt;/argument\u0026gt; \u0026lt;/arguments\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;post-integration-test\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;stop\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;/executions\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;com.github.eirslett\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;frontend-maven-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${frontend-maven-plugin.version}\u0026lt;/version\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;workingDirectory\u0026gt;../crypto-pwa\u0026lt;/workingDirectory\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;executions\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;webdriver update\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;npm\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;phase\u0026gt;pre-integration-test\u0026lt;/phase\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;arguments\u0026gt;run e2e-update\u0026lt;/arguments\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;execution\u0026gt; \u0026lt;id\u0026gt;ionic e2e\u0026lt;/id\u0026gt; \u0026lt;goals\u0026gt; \u0026lt;goal\u0026gt;npm\u0026lt;/goal\u0026gt; \u0026lt;/goals\u0026gt; \u0026lt;phase\u0026gt;integration-test\u0026lt;/phase\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;environmentVariables\u0026gt; \u0026lt;PORT\u0026gt;${http.port}\u0026lt;/PORT\u0026gt; \u0026lt;CI\u0026gt;true\u0026lt;/CI\u0026gt; \u0026lt;/environmentVariables\u0026gt; \u0026lt;arguments\u0026gt;run e2e-test\u0026lt;/arguments\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/execution\u0026gt; \u0026lt;/executions\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;/plugins\u0026gt; \u0026lt;/build\u0026gt; \u0026lt;/profile\u0026gt; 提示:你可能会注意到,我必须为 e2e-update 和 e2e-test 分两次不同的执行。我发现运行 npm e2e 与 frontend-maven-plugin 不兼容,因为它只调用其他 npm run 命令。看来你需要在使用 frontend-maven-plugin 时直接调用二进制文件。\n这里使用的不是 TRAVIS 环境变量,而是 CI 变量。此更改需要更新 crypto-pwa/test/protractor.conf.js 来匹配。\nbaseUrl: (process.env.CI) ? 'http://localhost:' + process.env.PORT : 'http://localhost:8100', 进行这些更改,你应该能够运行 ./mvnw verify -Pprod,e2e 以在本地运行端到端测试。请注意,你需要将 E2E_USERNAME 和 E2E_PASSWORD 定义为环境变量。\n当我第一次在 Jenkins X 中尝试这个功能时,我发现 jenkins-maven 代理没有安装 Chrome。我发现很难安装并发现 jenkins-nodejs 预安装了 Chrome 和 Xvfb。当我第一次尝试它时,我遇到以下错误:\n[21:51:08] E/launcher - unknown error: DevToolsActivePort file doesn't exist 此错误是由 Chrome on Linux 问题引起的 。我发现解决办法是在 Protractor 的 chromeOptions 中指定 -disable-dev-shm-usage。我还添加了一些推荐的额外标志。我特别喜欢 --headless,在本地运行时,因此浏览器不会弹出并妨碍我。如果我想实时看到这个过程,我可以快速删除该选项。\n如果你希望在 Jenkins X 上看到项目的 Protractor 测试运行,则需要修改 crypto-pwa/test/protractor.conf.js 以指定以下内容 chromeOptions:\ncapabilities: { 'browserName': 'chrome', 'chromeOptions': { 'args': ['--headless', ''--disable-gpu', '--no-sandbox', '--disable-extensions', '--disable-dev-shm-usage'] } }, 然后向 Jenkinsfile 添加一个新的 Run e2e tests 阶段,该阶段位于 “CI 构建”和“构建发布”阶段之间。如果有帮助,你可以看到最终的 Jenkins 文件。\nstage('Run e2e tests') { agent { label \u0026quot;jenkins-nodejs\u0026quot; } steps { container('nodejs') { sh ''' yum install -y jq previewURL=$(jx get preview -o json|jq -r \u0026quot;.items[].spec | select (.previewGitInfo.name==\\\\\u0026quot;$CHANGE_ID\\\\\u0026quot;) | .previewGitInfo.applicationURL\u0026quot;) cd crypto-pwa \u0026amp;\u0026amp; npm install --unsafe-perm \u0026amp;\u0026amp; npm run e2e-update Xvfb :99 \u0026amp; sleep 60s DISPLAY=:99 npm run e2e-test -- --baseUrl=$previewURL ''' } } } 完成所有这些更改后,创建一个新分支,签入你的更改,并在 GitHub 上创建一个 pull request。\ngit checkout -b enable-e2e-tests git add . git commit -m \u0026quot;Add stage for end-to-end tests\u0026quot; git push origin enable-e2e-tests 我确实需要做一些额外的调整才能通过所有的 Protractor 测试:\n 在 crypto-pwa/e2e/spec/login.e2e-spec.ts 中,我无法通过 should show a login button 测试,所以我忽略了它,将 it(…) 改为 xit(…)。 在同一个文件中,我将2000 ms 超时更改为5000 ms,将5000 ms 超时更改为30000 ms。 在 crypto-pwa/test/protractor.conf.js 中,我将 defaultTimeoutInterval 更改为 600000。 第一次运行时测试可能会失败,因为未为新预览环境配置注销重定向URI。更新 Okta 应用程序的注销重定向 URI 以匹配你的 PR 的预览环境 URI,重新 pull request 测试,一切都应该通过! 你可以在 GitHub 上的此示例中找到已完成应用程序的源代码 。\n了解有关 Jenkins X、Kubernetes 和 Spring Boot 的更多信息 要了解有关 Spring Boot、Jenkins X 和 Kubernetes 的更多信息,请查看以下资源:\n Deploy Your Secure Spring Boot + Angular PWA as a Single Artifact Build a Basic CRUD App with Angular 5.0 and Spring Boot 2.0 Introducing Jenkins X: a CI/CD solution for modern cloud applications on Kubernetes Kubernetes The Hard Way by Kelsey Hightower 如果你在 Kubernetes 上运行生产应用程序,我建议你研究 Jenkins X.它提供了一种在相同环境中进行 CI/CD 的方法,快速迭代并为你的客户更快地交付业务价值。 Jenkins X 还包括一个 DevPods 功能,可以在笔记本电脑上进行开发时,可以自动部署保存。我不确定 DevPods 是否适用于需要具有生产转换步骤的 JavaScript 应用程序。我宁愿让 webpack 和 Browsersync 在几秒钟内刷新我的本地浏览器,而不是等待几分钟创建并部署 Docker 镜像到 Kubernetes。\n要获得 Jenkins X 的精彩概述和演示,请观看 James Strachan 在2018年6月的 Virtual JUG 会议上为 Kubernetes 发布的 Jenkins X: Continuous Delivery。\n如果你有任何疑问,请在下面添加评论,在 Twitter 上发帖,或在我们的开发者论坛 上发帖提问。要获得有关未来博客文章和开发人员智慧的通知,你可以在Twitter上关注我的整个团队。\n使用 Jenkins X 和 Kubernetes 将 CI/CD 添加到 Spring Boot 应用程序中,最初于2018年7月11日发布到 Okta 开发人员博客。\n", "auhtor": "Matt Raible", "translator": "yJunS", "original": "https://dzone.com/articles/achieve-cicd-with-jenkins-x-kubernetes-and-spring", "poster": "../05/2019-05-24-achieve-cicd-with-jenkins-x-kubernetes-and-spring/cicd.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-23-chinese-localization/", "title": "Jenkins 中文本地化的重大进展", "type": "wechat", "date": "2019-05-23 00:00:00 +0000 UTC", "tags": [], "description": "Jenkins 中文社区大事件", "content": " 我从2017年开始,参与 Jenkins 社区贡献。作为一名新成员,翻译可能是帮助社区项目最简单的方法。 本地化的优化通常是较小的改动,你无需了解项目完整的上下文, 甚至都不需要在任务跟踪系统中添加任务。 但很快,就遇到了一些问题,那就是并没有以中文为母语的人帮助 review 我的 PR。因此,有时候, 我提交的 PR 过很久才能够被合并到 master 中。\n后来,有贡献者告诉我,可以在邮件列表中发一份邮件来描述当前遇到的问题,然后大家来讨论如何解决。 后来,我才了解到,在邮件列表中公开地讨论社区里的事情, 正是开源社区的做事风格。任何人都可以发表自己的观点, 我们并不受某个公司的限制,大家共同作出一致的决定。下面,我想与各位分享一下我们讨论后得出的一些成果。\nJEP-216 JEP 是 Jenkins Enhancement Proposoals 的缩写,也就是 Jenkins 增强提议。所有针对 Jenkins 社区的增强或者改进的想法都可以通过这样的一种 提议机制来推动,特别兴趣小组(SIG)就是其中的一项提议。JEP-216 是关于 改进本地化的一项提议。\n在之前,所有语言的本地化资源文件都是集中保存在 Jenkins Core 以及各个插件中的。而在 该提议中,每个语言都可以有一个单独的本地化插件,例如:简体中文插件。 终于,经过半年多的时间, 本地化支持插件和 简体中文插件已经可以支持各种类型的本地化资源文件(包括: Messages、属性以及帮助文件等)。从 插件网站上, 你可以看到 简体中文插件已经有超过1.3万的安装量,而且还在持续增长中。到目前为止,我们已经把 Jenkins Core 里所有简体中文的资源文件 迁移到了简体中文插件中,具体可以查看 PR-4008。\n我相信,这对于每一位 Jenkins 的中文用户都是一件意义重大的事情,Jenkins 中文社区也会努力带给大家带来更好的使用体验。当然, 我们欢迎并期待任何一位有志参与开源社区的朋友!\n在享受成果的同时,请与我一起感谢社区里为此作出重要贡献的朋友们。在 Daniel Beck 的帮助下,完成了“本地化支持插件”的发布; 在 Liam Newman 的帮助下完成了 JEP-216, 当然还包括社区中很多参与到中文本地化工作的贡献者。\n中文本地化特别兴趣小组 我们相信,这个特别兴趣小组能够给 Jenkins 的中文用户带来更好的使用体验,并聚集更多来自中国的贡献者。这里的贡献者,并不只是开发者的专利和特权, 实际上开源社区需要很多有不同技能的人加入,包括当不仅限于:测试、运维、文档工程师 甚至是设计师、市场运营等等。不管你是尚未毕业的在校学生, 还是懵懂初入职场,或者已经是具有多年丰富的从业经历,在这里 都是平等、公开的。\n该组会负责维护 Jenkins 官方中文站点,通过微信公众号在国内宣传和推广 Jenkins 社区及其技术。 我们会发布官方博客文章、实际案例、原创文章、Jenkins 版本发布,还有 Jenkins Meetup 或者其他的线上线下活动。 我们的官方公众号自半年前开通以来,已经有超过一千八百多位 Jenkins 的用户关注,并可以从这里及时获取最新的官方咨讯信息。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“great-wall.jpeg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-22-jacoco-coverage-for-functional-test/", "title": "基于 Jenkins + JaCoCo 实现功能测试代码覆盖率统计", "type": "wechat", "date": "2019-05-22 00:00:00 +0000 UTC", "tags": ["jenkins", "jacoco", "ci", "coverage"], "description": "本文对 JaCoCo 进行简要介绍,并借助 Jenkins 实现功能测试代码覆盖率统计", "content": " 使用 JaCoCo 统计功能测试代码覆盖率? 对于 JaCoCo,有所了解但又不是很熟悉。 \u0026ldquo;有所了解\u0026rdquo;指的是在 CI 实践中已经使用 JaCoCo 对单元测试代码覆盖率统计: 当代码 push 到代码仓库后,用 JaCoCo 进行单元测试代码覆盖率统计,并将相应数据推送到 SonarQube。 \u0026ldquo;不是很熟\u0026rdquo;指的是应用场景也仅限于此,并未进行过多研究与实践。\n前不久,有测试同事提出,想要在实际测试时,用 JaCoCo 统计功能测试代码覆盖率。 其主要目的是在经过功能测试后,通过查看代码覆盖率统计的相关指标,增强对软件质量的信心。 经查阅资料,证明这是可行的。\n由于对 JaCoCo 不甚了解,于是查阅官网资料对 JaCoCo 进一步了解。\n进一步了解 JaCoCo JaCoCo,即 Java Code Coverage,是一款开源的 Java 代码覆盖率统计工具。 它由 EclEmma 团队根据多年来使用和集成现有库的经验教训而创建。\nJaCoCo 愿景 JaCoCo 应该为基于 Java VM 的环境中的代码覆盖率分析提供标准技术。 重点是提供一个轻量级的、灵活的、文档良好的库,以便与各种构建和开发工具集成。\nJaCoCo 产品功能 指令(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 等其它工具的集成方式。\n抛开理论,开始实践 JaCoCo 不仅支持统计本地服务的代码覆盖率,也支持统计远程服务的代码覆盖率。 单元测试覆盖率统计就是统计本地服务的代码覆盖率,代码和运行的服务在一台机器上,笔者这里通过使用 JaCoCo Maven 插件完成的。 而功能测试代码覆盖率统计则是统计远程服务的代码覆盖率,代码和运行的服务一般不在一台机器上,这里需要借助 JaCoCo Java agent 实现。 \u0026gt; 备注:实际上,JaCoCo Maven 插件也使用了 JaCoCo Java agent,不过用户不需要直接关系 Java agent 及其选项,Maven 插件都透明地处理了。\n1、下载 JaCoCo 分发包 可以从 JaCoCo 官网下载分发包,也可以从 Maven 仓库(中央仓库或私服)下载。 分发包的 lib 目录下,包括以下库:\n2、Java 应用启动脚本添加 jacocoagent 相关 JVM 参数 需要将 jacocoagent.jar 推送到部署应用的服务器上,笔者这里用 Ansible 进行了批量推送。 Java 应用启动脚本需要加入类似下面的 JVM 参数:\nJAVA_OPTS=\u0026quot;$JAVA_OPTS -javaagent:/path/jacocoagent.jar=includes=*,output=tcpserver,append=false,address=$IP,port=$JACOCO_PORT\u0026quot; 这样在应用成功启动后,会暴露一个 TCP 服务,客户端可以连接到这个服务并获取执行数据文件。\n相关属性说明如下: - append:其中 append=false 表示 dump 每次会生成一个新的执行数据文件,如果 append=true,dump 时则会将数据追加到已存在的执行数据文件。 其中 output=tcpserver 表示 agent 监听来自被 adrress 和 port 属性指定的TCP 端口的连接,执行数据被写到这个连接; - output:如果 output=tcpclient 则表示在启动时,agent 连接到被 adrress 和 port 属性指定的TCP 端口,执行数据被写到这个连接; 如果 output=file 则表示在 JVM 终止时,执行数据被写到被 destfile 属性指定的文件。output 默认值为 file 。 - address:当 output 为 tcpserver 时绑定到的 IP 地址或主机名,或者当 output 为 tcpclient 时连接到的 IP 地址或主机名。 在 tcpserver 模式下,值为“*”导致代理只接受本机地址上的连接。address 默认值为 127.0.0.1 。 - port:当 output 方式为 tcpserver 时绑定到该端口,或者当 output 方式为 tcpclient 时连接到该端口。 在 tcpserver 模式下,端口必须可用,这意味着如果多个 JaCoCo agent 在同一台机器上运行,则必须指定不同的端口。port 默认值为 6300 。\n3、创建及配置 Jenkins Pipeline 任务 Jenkins 任务大致有几个步骤:拉取代码,构建,dump 应用执行数据( jacoco.exec ),解析 JaCoCo 产生的 jacoco.exec 文件,然后生成覆盖率报告(HTML 格式)。 拉取代码这里无需多说,配置下从代码仓库(SVN/Git)和分支地址就可以了,比较简单。 构建这里用了 Jenkins Pipeline Maven Integration Plugin ,笔者这里所用的 Maven 命令是 mvn clean package -Dmaven.test.skip=true 。 dump 应用执行数据这里有多种方式:Ant、CLI、Maven,因为Java 应用是用 Maven 构建的,这里选择了 Maven Jacoco Plugin。 解析 JaCoCo 产生的 jacoco.exec 文件,然后生成覆盖率报告(HTML 格式)笔者这里使用了 Jenkins Jacoco Plugin。\nJenkins Pipeline 案例如下:\npipeline { agent any tools { jdk 'JDK1.8' } stages { stage('Checkout'){ steps{ git branch: '${GIT_BRANCH}', credentialsId: 'xxx-xxx-xx-xx-xxx', url: '${GIT_URL}' } } stage('Build') { steps{ withMaven(maven: 'maven'){ sh \u0026quot;mvn clean package -Dmaven.test.skip=true\u0026quot; } } } stage('DumpFromServer'){ steps { withMaven(maven: 'maven'){ sh 'mvn org.jacoco:jacoco-maven-plugin:0.8.4:dump -Djacoco.address=${SERVER_IP} -Djacoco.port=${JACOCO_PORT}' } } } stage('JacocoPublisher') { steps { jacoco() } } } } JaCoCo 覆盖率报告,部分截图如下:\n总结 笔者所实现的方式并未覆盖任何场景,但是大同小异,相关工具的使用详情可以查看官网文档,因为它是最全面的。 笔者希望这个实践能给有类似诉求的同行一些参考,当然笔者也希望能够和大家互相交流。 同时笔者的 JaCoCo 实践之路并未结束,可能在使用的过程中会有一些问题需要解决, 后续也将考虑使用 Jenkins API 为需要统计功能测试代码覆盖率的 Java 应用实例自动生成一个对应的 Jenkins 任务, 并在 Java 应用实例销毁后,对相应的 Jenkins 任务进行清理等其它功能。\n参考 https://www.eclemma.org/jacoco/index.html https://www.jacoco.org/jacoco/trunk/doc/integrations.html https://www.jacoco.org/jacoco/trunk/doc/agent.html https://www.jacoco.org/jacoco/trunk/doc/counters.html https://www.eclemma.org/jacoco/trunk/doc/mission.html ", "auhtor": "donhui", "translator": "", "original": "", "poster": "“./2019-05-22-jacoco-coverage-for-functional-test/hangzhou.jpg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-20-jenkins-ansible-springboot/", "title": "使用 Jenkins + Ansible 实现 Spring Boot 自动化部署101", "type": "wechat", "date": "2019-05-20 00:00:00 +0000 UTC", "tags": ["jenkins", "ansible", "springboot"], "description": "实现 Spring Boot 最基本的流水线", "content": " 本文要点: 1. 设计一条 Spring Boot 最基本的流水线:包括构建、制品上传、部署。 1. 使用 Docker 容器运行构建逻辑。 1. 自动化整个实验环境:包括 Jenkins 的配置,Jenkins agent 的配置等。\n1. 代码仓库安排 本次实验涉及以下多个代码仓库:\n% tree -L 1 ├── 1-cd-platform # 实验环境相关代码 ├── 1-env-conf # 环境配置代码-实现配置独立 └── 1-springboot # Spring Boot 应用的代码及其部署代码 1-springboot 的目录结构如下:\n% cd 1-springboot % tree -L 1 ├── Jenkinsfile # 流水线代码 ├── README.md ├── deploy # 部署代码 ├── pom.xml └── src # 业务代码 所有代码,均放在 GitHub:https://github.com/cd-in-practice\n2. 实验环境准备 笔者使用 Docker Compose + Vagrant 进行实验。环境包括以下几个系统: * Jenkins * 1 Jenkins master,全自动安装插件、默认用户名密码:admin/admin。 * Jenkins agent * 2 Jenkins agent 运行在 Docker 容器中,共启动两个。 * Artifactory * 1 一个商业版的制品库。笔者申请了一个 30 天的商业版。\n使用 Vagrant 是为了启动虚拟机,用于部署 Spring Boot 应用。如果你的开发机器无法使用 Vagrant,使用 VirtualBox 也可以达到同样的效果。但是有一点需要注意,那就是网络。如果在虚拟机中要访问 Docker 容器内提供的服务,需要在 DNS 上或者 hosts 上做相应的调整。所有的虚拟机的镜像使用 Centos7。\n另,接下来笔者的所有教程都将使用 Artifactory 作为制品库。在此申明,笔者没有收 JFrog——研发 Artifactory 产品的公司——任何广告费。 笔者只是想试用商业产品,以便了解商业产品是如何应对制品管理问题的。\n启动 Artifactory 后,需要添加 “Virtual Repository” 及 “Local Repository”。具体请查看 Artifactory 的官方文档。如果你当前使用的是 Nexus,参考本教程,做一些调整,问题也不大。\n如果想使用已有制品库,可以修改 1-cd-platform 仓库中的 settings-docker.xml 文件,指向自己的制品库。\n实验环境近期的总体结构图如下:\n之所以说是“近期的”,是因为上图与本篇介绍的结构有小差异。本篇文章还没有介绍 Nginx 与 Springboot 配置共用,但是总体不影响读者理解。\n3. Springboot 应用流水线介绍 Springboot 流水线有两个阶段: 1. 构建并上传制品 2. 部署应用\n流水线的所有逻辑都写在 Jenkinsfile 文件。接下来,分别介绍这两个阶段。\n3.1 构建并上传制品 此阶段核心代码:\ndocker.image('jenkins-docker-maven:3.6.1-jdk8') .inside(\u0026quot;--network 1-cd-platform_cd-in-practice -v $HOME/.m2:/root/.m2\u0026quot;) { sh \u0026quot;\u0026quot;\u0026quot; mvn versions:set -DnewVersion=${APP_VERSION} mvn clean test package mvn deploy \u0026quot;\u0026quot;\u0026quot; } 它首先启动一个装有 Maven 的容器,然后在容器内执行编译、单元测试、发布制品的操作。\n而 mvn versions:set -DnewVersion=${APP_VERSION} 的作用是更改 pom.xml 文件中的版本。这样就可以实现每次提交对应一个版本的效果。\n3.2 部署应用 注意: 这部分需要一些 Ansible 的知识。\n 首先看部署脚本的入口 1-springboot/deploy/playbook.yaml:\n--- - hosts: \u0026quot;springboot\u0026quot; become: yes roles: - {\u0026quot;role\u0026quot;: \u0026quot;ansible-role-java\u0026quot;, \u0026quot;java_home\u0026quot;: \u0026quot;{{JAVA_HOME}}\u0026quot;} - springboot 先安装 JDK,再安装 Spring Boot。JDK 的安装,使用了现成 Ansible role: https://github.com/geerlingguy/ansible-role-java。\n重点在 Spring Boot 部署的核心逻辑。它主要包含以下几部分:\n 创建应用目录。 从制品库下载指定版本的制品。 生成 Systemd service 文件(实现服务化)。 启动服务。 以上步骤实现在 1-springboot/deploy/roles/springboot 中。\n流水线的部署阶段的核心代码如下:\ndocker.image('williamyeh/ansible:centos7').inside(\u0026quot;--network 1-cd-platform_cd-in-practice\u0026quot;) { checkout([$class: 'GitSCM', branches: [[name: \u0026quot;master\u0026quot;]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: \u0026quot;env-conf\u0026quot;]], submoduleCfg: [], userRemoteConfigs: [[url: \u0026quot;https://github.com/cd-in-practice/1-env-conf.git\u0026quot;]]]) sh \u0026quot;ls -al\u0026quot; sh \u0026quot;\u0026quot;\u0026quot; ansible-playbook --syntax-check deploy/playbook.yaml -i env-conf/dev ansible-playbook deploy/playbook.yaml -i env-conf/dev --extra-vars '{\u0026quot;app_version\u0026quot;: \u0026quot;${APP_VERSION}\u0026quot;}' \u0026quot;\u0026quot;\u0026quot; } 它首先将配置变量仓库的代码 clone 下来,然后对 playbook 进行语法上的检查,最后执行 ansible-playbook 命令进行部署。--extra-vars 参数的 app_version 用于指定将要部署的应用的版本。\n3.3 实现简易指定版本部署 在 1-springboot/Jenkinsfile 中实现了简易的指定版本部署。核心代码如下: 1. 流水线接受参数\nparameters { string(name: 'SPECIFIC_APP_VERSION', defaultValue: '', description: '') } 如果指定了版本,则跳过构建阶段,直接执行部署阶段 groovy stage(\u0026quot;build and upload\u0026quot;){ // 如果不指定部署版本,则执行构建 when { expression{ return params.SPECIFIC_APP_VERSION == \u0026quot;\u0026quot; } } // 构建并上传制品的逻辑 steps{...} } 之所以说是“简易”,是因为部署时只指定了制品的版本,并没有指定的部署逻辑和配置的版本。这三者的版本要同步,部署才真正做到准确。 4. 配置管理 所有的配置项都放在 1-env-conf 仓库中。Ansible 执行部署时会读取此仓库的配置。\n将配置放在 Git 仓库中有两个好处: 1. 配置版本化。 2. 任何配置的更改都可以被审查。\n有好处并不代表没有成本。那就是开发人员必须开始关心软件的配置(笔者发现不少开发者忽视配置项管理的重要性。)。\n本文重点不在配置管理,后面会有文章重点介绍。\n5. 实验环境详细介绍 事实上,整个实验,工作量大的地方有两处:一是 Spring Boot 流水线本身的设计;二是整个实验环境的自动化。读者朋友之所以能一两条简单的命令就能启动整个实验环境,是因为笔者做了很多自动化的工作。笔者认为有必要在本篇介绍这些工作。接下来的文章将不再详细介绍。\n5.1 解决流水线中启动的 Docker 容器无法访问 http://artifactory 流水线中,我们需要将制品上传到 artifactory(settings.xml 配置的仓库地址是 http://artifactory:8081),但是发现无法解析 host。这是因为流水线中的 Docker 容器所在网络与 Docker compose 创建的网络不同。所以,解决办法就是让流水线中的 Docker 容器加入到 Docker compose 的网络。\n具体解决办法就是在启动容器时,加入参数:--network 1-cd-platform_cd-in-practice\n5.2 Jenkins 初次启动初始化 在没有做任何设置的情况启动 Jenkins,会出现一个配置向导。这个过程必须是手工的。笔者希望这一步也是自动化的。Jenkins 启动时会执行 init.groovy.d/目录下的 Groovy 脚本。\n5.3 虚拟机中如何能访问到 http://artifactory ? http://artifactory 部署在 Docker 容器中。Spring Boot 应用的制品要部署到虚拟机中,需要从 http://artifactory 中拉取制品,也就是要在虚拟机里访问容器里提供的服务。虚拟机与容器之间的网络是不通的。那怎么办呢?笔者的解决方案是使用宿主机的 IP 做中转。具体做法就是在虚拟机中加一条 host 记录:\nmachine.vm.provision \u0026quot;shell\u0026quot; do |s| s.inline = \u0026quot;echo '192.168.52.1 artifactory' \u0026gt;\u0026gt; /etc/hosts\u0026quot; end 以上是使用了 Vagrant 的 provision 技术,在执行命令 vagrant up 启动虚拟机时,就自动执行那段内联 shell。192.168.52.1 是虚拟宿主机的 IP。所以,虚拟机里访问 http://artifactory:8081 时,实际上访问的是 http://192.168.52.1:8081。\n网络结构可以总结为下图:\n后记 目前遗留问题: 1. 部署时制品版本、配置版本、部署代码版本没有同步。 2. Springboot 的配置是写死在制品中的,没有实现制品与配置项的分离。\n这些遗留问题在后期会逐个解决。就像现实一样,经常需要面对各种遗留项目的遗留问题。\n附录 使用 Jenkins + Ansible 实现自动化部署 Nginx:https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-25-jenkins-ansible-nginx/ 简单易懂 Ansible 系列 —— 解决了什么:https://showme.codes/2017-06-12/ansible-introduce/ ", "auhtor": "zacker330", "translator": "", "original": "", "poster": "./2019-05-20-jenkins-ansible-springboot/poster.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-20-translation-norms/", "title": "转载规范及声明", "type": "wechat", "date": "2019-05-20 00:00:00 +0000 UTC", "tags": ["spec"], "description": "为了保护本站文章的原创性,请规范转载,违者必究", "content": " 转载声明 首先感谢大家对 Jenkins 中文社区内容的认可。传播有道,我们希望每一篇文章的发声不仅能被看见,也都能得到尊重。因此,若需转载本社区的文章,请先获取本社区授权,未经授权禁止转载。如未经许可私自转载,我们会有专人负责沟通进行整改,对于不听劝解的将会被添加到社区官网的黑名单中以作公示。\n如需转载,请仔细阅读并遵守以下转载须知: 1. 本站发文均于Jenkins 中文社区首发,然后由微信公众号、CSDN、简书、开源中国、掘金等渠道发出 2. 不论通过何种渠道获得本站文章,若想要转载,均可在文章下方留言,获得授权后方可进行在转载 3. 文章转载首行,需添加本文转自 [Jenkins 中文社区],Jenkins 中文社区需加入链接 http://jenkins-zh.cn 4. 转载文章标题不得进行修改 5. 转载文章内容不得做任何修改,如有文章内容问题,请与本社区相关联系人沟通后,再进行下一步处理 6. 为了保护作者权益,作者署名必须保留 7. 如是微信公众号转载,请在获得授权的情况下,使用微信的转载功能进行转载 8. 文章在推送三天后方可进行转载\n", "auhtor": "yJunS", "translator": "", "original": "", "poster": "./2019-05-20-translation-norms/banquan.jpg" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-17-from-jenkins-to-jenkins-x/", "title": "从 Jenkins 到 Jenkins X", "type": "wechat", "date": "2019-05-17 00:00:00 +0000 UTC", "tags": ["jenkins", "jenkins x", "kubernetes", "devops", "ci", "cd"], "description": "这是一个关于 dailymotion 从 Jenkins 到 Jenkins X 的旅程,我们遇到的问题,以及我们是如何解决它们的故事", "content": " 这是一个关于 dailymotion 从 Jenkins 到 Jenkins X 的旅程,我们遇到的问题,以及我们是如何解决它们的故事。\n我们的上下文 在 dailymotion ,我们坚信 devops 最佳实践,并且在 Kubernetes 投入了大量投资。 我们的部分产品已经部署在 Kubernetes 上,但并不是全部。 因此,当迁移我们的广告技术平台的时候,我们想要完全采用“ Kubernetes 式”——或者云原生,以追随技术趋势! 这意味着要重新定义整个 CI/CD 流水线,从静态/永久环境迁移,转向动态按需分配环境。 我们的目标是授权给我们的开发人员,缩短我们的上线时间以及降低我们的运营成本。\n对于新的 CI/CD 平台我们的初始需求是: - 尽可能避免从零开始:我们的开发人员已经习惯使用 Jenkins 和声明式流水线,并且它们可以很好地满足我们当前的需求。 - 以公有云基础设施为目标——Google 云平台和 Kubernetes 集群 - 与 gitops 方法论兼容——因为我们喜欢版本控制、同行评审和自动化\n在 CI/CD 生态系统中有相当多的参与者,但是只有一个符合我们的需求,Jenkins X ,它基于 Jenkins 和 Kubernetes ,原生支持预览环境和 gitops\nKubernetes 之上的 Jenkins Jenkins X 的设置相当简单,并且在他们的官方网站上已经有很好的文档(译注:译者曾对 Jenkins X 文档中文本地化做了一些贡献,同时也期待更多的人参与以完善中文文档)。 由于我们已经使用了 Google Kubernetes Engine (GKE),所以 jx 命令行工具自己创建了所有东西,包括 Kubernetes 集群。 这里有一个小小的*哇哦效果*,在几分钟内获得一个完整的工作系统是非常令人印象深刻的。\nJenkins X 提供了很多快速入门和模板来增加*哇哦效果*, 然而,在 dailymotion ,我们已经有了带有 Jenkins 流水线的仓库,我们想要重用它们。 我们决定以\u0026rdquo;艰难的方式\u0026rdquo;做事情,并重构我们的声明式流水线,使它们与 Jenkins X 兼容。\n实际上,这一部分并不针对 Jenkins X ,而是基于 Kubernetes 插件在 Kubernetes 上运行 Jenkins 。 如果您习惯使用“经典的” Jenkins ,即在裸金属或虚拟机上运行静态代理,那么这里的主要更改是,每次构建都将在自己的短暂的 pod 上执行。 流水线的每个步骤都可以指定应该在 pod 的哪个容器上执行。 在插件的源代码中有一些流水线的例子。 在这里,我们的\u0026rdquo;挑战\u0026rdquo;是定义容器的粒度,以及它们将包含哪些工具:需要足够的容器,以便我们可以在不同流水线之间重用它们的镜像,但也不能太多,以控制维护量——我们不想花时间重新构建容器镜像。\n以前,我们通常在 Docker 容器中运行大多数流水线步骤,当我们需要自定义步骤时,我们在运行中的流水线中构建它,就在运行它之前。 虽然它比较慢,但是易于维护,因为所有内容都是在源代码中定义的。 例如,升级 Go 运行时的版本可以在一个 pull-request 中完成。 因此,要预先构建容器镜像听起来像是给现有设置增加了更多的复杂性。 它还有几个优点:仓库之间的重复更少,构建速度更快,并且不会因为某些第三方托管平台宕机而出现更多构建错误。\n在 Kubernetes 上构建镜像 这些天将给我们带来一个有趣的话题:在 Kubernetes 集群中构建容器镜像。\nJenkins X 附带了一组\u0026rdquo;构建打包\u0026rdquo;,使用 \u0026ldquo;Docker in Docker\u0026rdquo; 从容器内部构建镜像。 但是随着新的容器运行时的到来,Kubernetes 推出了它的容器运行时接口( CRI ),我们想要探索其他的选择。 Kaniko 是最成熟的解决方案,符合我们的需求/技术栈。 我们很兴奋……\n……直到我们遇到两个问题: - 第一个问题对我们来说是一个阻塞问题:多阶段构建不起作用。 多亏了谷歌,我们很快发现我们不是唯一受到影响的人,而且目前还没有解决办法。 然而,Kaniko 是用 Go 开发的,而我们是 Go 开发人员,所以……为什么不看看源代码呢? 事实证明,一旦我们理解了问题的根本原因,修复就很容易了。 Kaniko 维护者是很愿意帮忙的,并且快速地合并了修复,所以一天之后一个被修复的 Kaniko 镜像就已经可用了。 - 第二个问题是,我们不能使用同一个 Kaniko 容器构建两个不同的镜像。 这是因为 Jenkins 并没有按照预期的方式使用 Kaniko ——因为我们需要先启动容器,然后再运行构建。 这一次,我们找到了一个针对谷歌的解决方案:声明我们所需要的尽可能多的 Kaniko 容器来构建镜像,但是我们不喜欢它。 所以回到源代码,再一次,一旦我们理解了根本原因,修复就很容易了。\n我们测试了一些解决方案来为 CI 流水线构建定制的\u0026rdquo;工具\u0026rdquo;镜像, 最后,我们选择使用一个单个仓库,每个分支对应一个 Dockerfile 和镜像。 因为我们将源代码托管在 Github 上,并且使用 Jenkins Github 插件来构建我们的仓库, 所以它可以构建我们所有的分支,并为 webhook 事件上的新分支创建新的任务,这使得管理起来很容易。 每个分支都有自己的 Jenkinsfile 声明式流水线,使用 Kaniko 构建镜像,并将其推入我们的容器注册中心。 这对于快速添加新镜像或编辑现有的镜像非常有用,因为我们知道 Jenkins 会处理好所有的事情。\n声明所需资源的重要性 我们在之前的 Jenkins 平台中遇到的一个主要问题来自静态的代理/执行器,在高峰时间有时构建队列很长。 Kubernetes 之上的 Jenkins 使这个问题很容易解决,主要是在 Kubernetes 集群上运行时,它能支持集群自动伸缩。 集群将根据当前负载简单地添加或删除节点。 但这是基于所请求的资源,而不是基于所观察到的使用的资源。 这意味着,作为开发人员,我们的工作是在构建 pod 模板中定义所需的资源( CPU 和内存)。 然后 Kubernetes 调度程序将使用此信息找到一个匹配的节点来运行 pod ——或者它可能决定创建一个新的节点。 这真是太好了,因为我们不再有长构建队列。 但相反,我们需要谨慎地定义我们所需资源的恰当数量,并在更新流水线时更新它们。 由于资源是在容器级别定义的,而不是在 pod 级别定义的,所以处理起来有点复杂。 但是我们不关心限制,只关心请求。 pod 的请求只是所有容器请求的相加。 因此,我们只是将整个 pod 的资源请求写在第一个容器上——或者 jnlp 容器上——它是默认的容器。 下面是我们使用的一个 Jenkinsfile 的例子, 也是我们如何声明请求的资源的例子:\npipeline { agent { kubernetes { label 'xxx-builder' yaml \u0026quot;\u0026quot;\u0026quot; kind: Pod metadata: name: xxx-builder spec: containers: - name: jnlp Jenkins X 上的预览环境 现在我们已经拥有了所有的工具,并且能够为我们的应用程序构建一个镜像, 我们准备下一步:将它部署到\u0026rdquo;预览环境\u0026rdquo;!\nJenkins X 通过重用现有的工具——主要是 Helm ,使得部署预览环境变得很容易, 只要你遵循一些约定,例如用于镜像标签的值的名称。 最好是从\u0026rdquo;包\u0026rdquo;中提供的 Helm charts 复制/粘贴。 如果你不熟悉 Helm ,它基本上是一个 Kubernetes 应用程序包管理器。 每个应用程序都打包为一个 \u0026ldquo;chart\u0026rdquo; ,然后可以通过使用 helm 命令行工具作为一个 \u0026ldquo;release\u0026rdquo; 被部署。 预览环境是通过使用 jx 命令行工具进行部署的,该工具负责部署 Helm chart ,并以评论的形式,将所公开服务的 URL 添加到 Github pull-request 中。 这一切都非常好,而且对于我们第一个使用纯 http 的 POC 来说很有效。 但现在是2018年(译注:作者是在2018年写的这篇文章),没有人再使用 http 了。 让我们加密吧! 多亏了 cert-manager,当在 kubernetes 中创建 ingress 资源时,我们可以自动为我们的新域名获得一个 SSL 证书。 我们试图在我们的设置中启用 tls-acme 标志——与 cert-manager 进行绑定,但是它不起作用。 这给了我们一个机会来看看 Jenkins X 的源代码——它也是用 Go 开发的。 稍作修复之后都好了, 现在我们可以使用 let\u0026rsquo;s encrypt 提供的自动化证书来享受安全的预览环境。\n我们在预览环境中遇到的另一个问题与上述环境的清理有关。 每个打开一个 pull-request ,就创建一个预览环境,因此在 pull-request 被合并或关闭时应该删除预览环境。 这由 Jenkins X 设置的 Kubernetes 任务来处理,它删除了预览环境所使用的名称空间。 问题是这个任务不会删除 Helm release ——所以,比如如果您运行 helm list,您仍然会看到一个很大的旧的预览环境列表。 对于这个问题,我们决定改变使用 Helm 部署预览环境的方式。 Jenkins X 团队已经写过关于 Helm 和 Tiller ( Helm 的服务器端组件)的这些问题, 因此,我们决定使用 helmTemplate 特性标志,只使用 Helm 作为模板渲染引擎,并使用 kubectl 处理生成的资源。 这样,我们就不会用临时预览环境\u0026rdquo;污染\u0026rdquo; Helm releases 列表。\nGitops 应用到 Jenkins X 在初始化 POC 的某个阶段,我们对我们的设置和流水线感到满意,并希望将我们的 POC 平台转变为准生产的平台。 第一步是安装 SAML 插件以设置 OKTA 集成——以允许内部用户登录。 它运行得很好,几天后,我注意到我们的 OKTA 集成已经不再存在了。 我正忙着做其他事情,所以我只是问我的同事他是否做了一些改变,然后继续做其他事情。 但几天后再次发生时,我开始调查。 我注意到的第一件事是 Jenkins Pod 最近重新启动过。 但是我们有一个持久化的存储,我们的任务仍然在那里,所以是时候仔细看看了! 事实证明,用于安装 Jenkins 的 Helm chart 有一个启动脚本, 它从 Kubernetes configmap 重置了 Jenkins 配置。 当然,我们不能像在虚拟机上管理 Jenkins 那样管理在 Kubernetes 中运行的 Jenkins !\n因此,我们没有手动编辑 configmap ,而是后退一步,查看全局。 这个 configmap 本身由 jenkins-x-platform 管理, 因此升级平台将重置我们的自定义更改。 我们需要将我们的\u0026rdquo;定制\u0026rdquo;存储在安全的地方并跟踪我们的更改。 我们可以用 Jenkins X 的方式,用一个 umbrella chart 来安装/配置一切, 但是这种方法有一些缺点:它不支持 \u0026ldquo;secret\u0026rdquo; —— 我们将一些敏感的值存储在我们的 Git 仓库中—— 它\u0026rdquo;隐藏\u0026rdquo;了所有的 sub-charts 。 所以,如果我们列出所有已安装的 Helm releases ,我们将只看到一个。 但是还有其他基于 Helm 的工具,它们更对 Gitops 更友好。 Helmfile 就是其中之一,它通过 helm secrets 插件和 sops为 secrets 提供了原生支持。 我现在不会详细介绍我们的设置,但别担心,这将是我下一篇博客文章的主题!\n迁移 我们故事的另一个有趣的部分是从 Jenkins 到 Jenkins X 的实际迁移。 以及我们如何使用两个构建系统处理仓库。 首先,我们设置新的 Jenkins 来只构建 \u0026ldquo;jenkinsx\u0026rdquo; 分支, 并且更新了旧的 Jenkins 的配置来构建除 \u0026ldquo;jenkinsx\u0026rdquo; 分支之外的所有分支。 我们计划在 \u0026ldquo;jenkinsx\u0026rdquo; 分支中准备新的流水线,并将其合并以进行迁移。 对于我们的初始化 POC ,它工作得很好,但是当我们开始使用预览环境时, 我们必须创建新的 PR ,而这些 PR 不是基于新的 Jenkins 构建的,因为分支限制。 因此,我们选择在这两个 Jenkins 实例上构建一切, 但对于旧的 Jenkins 使用 Jenkinsfile 文件名,对于新的 Jenkins 使用 Jenkinsxfile 文件名。 迁移之后,我们将更新此配置并重命名文件,但这是值得的, 因为它使我们能够在两个系统之间进行平滑的转换,并且每个项目都可以自己迁移,而不会影响其他项目。\n我们的目的地 所以,Jenkins X 为大家准备好了吗?老实说,我不这么认为。 并非所有功能和所支持的平台—— Git 托管平台或 Kubernetes 托管平台——都足够稳定。 但是,如果您准备投入足够的时间来深入研究,并选择适合您的使用场景的稳定特性和平台, 那么您将能够使用 CI/CD 等所需的一切来改进您的流水线。 这将缩短您的上线时间,降低您的成本,如果您对测试也很认真,那么请对您的软件质量充满信心。\n一开始,我们说这是我们从 Jenkins 到 Jenkins X 的旅程。但我们的旅程并未结束,我们还在旅行中。 部分原因是我们的目标仍在移动:Jenkins X 仍处于大的发展阶段,而且它本身正在朝着 Serverless 的方向前进, 目前正在使用 Knative 构建 的路上。 它的目的地是云原生 Jenkins 。 它还没有准备好,但是您已经可以预览它的外观了。\n我们的旅程还将继续,因为我们不希望它结束。 我们现在的目的地并不是我们的最终目的地,而是我们不断进化的一个步骤。 这就是我们喜欢 Jenkins X 的原因:因为它遵循相同的模式。 那么,你在等待什么来开始你自己的旅程呢?\n 译注:译者曾对 Jenkins X 文档中文本地化做了一些贡献,同时也期待更多的人在 Jenkins X 旅程中, 能够参与到 Jenkins 中文社区以完善 Jenkins X 的中文文档。\n ", "auhtor": "Vincent Behar", "translator": "donhui", "original": "https://medium.com/dailymotion/from-jenkins-to-jenkins-x-604b6cde0ce3", "poster": "“./2019-05-20-from-jenkins-to-jenkins-x/journey.jpeg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-16-cloud-agnostic-automated-cicd-for-k8s/", "title": "与云无关的用于 Kubernetes 的自动化 CI/CD ", "type": "wechat", "date": "2019-05-16 00:00:00 +0000 UTC", "tags": ["cd", "ci", "kubernetes"], "description": "请看看您可能想要用来设置与云无关的生产和开发环境的一些工具和流程。", "content": " 在本文中,我想讨论一种在云环境中为 Kubernetes 工作负载实现自动化端到端 CI/CD 的方法。 这里可能有其它解决方案,而像 AWS、Microsoft Azure 和 GCP 这样的云提供商也提供了自己的一套框架,以实现与 Kubernetes 相同的目标。\n它的部署模型的核心是 Rancher,Rancher 负责为托管在不同云环境和裸机环境中的多个 Kubernetes 集群提供集中管理与运营的能力。 根据应用程序和业务需要,这里提到的工具可以替换为自己选择的工具。\n在详细介绍之前,这里有张部署模型的快照:\n持续集成组件 我们使用 JIRA、BitBucket、Bamboo 和 Nexus 作为自动化持续集成组件。 需求和用户故事来自 JIRA ; 开发人员将他们的代码放进 BitBucket ; 代码被代码评审工具和静态分析工具构建与集成,Bamboo 生成的 Docker 镜像被推送到 Nexus。 这些镜像会经过特定的容器安全检查。\n当你有许多微服务/应用程序需要构建时,那么处理 Kubernetes 集群工作负载的部署、升级和回滚可能会复杂。 版本控制是我们需要考虑的另一个挑战。 Helm 有助于克服这些大多数挑战,并使部署变得简单。\n如果你想知道你是否需要有一个 chart 将所有 deployments 包含在其中, 或者允许每个应用程序和微服务都有一个单独的 chart , 那么我们希望将这些 charts 放到特定的应用程序或微服务的仓库中, 这样我们就不需要有单独的仓库来维护 Helm 制品。 这就省去了为实际的代码和 Helm 模板维护两个独立仓库的工作。 开发人员可以对任何应用程序代码更改所需的模板更改有更多的控制权。\nNexus 作为 Docker 镜像和 Helm chart(使用的是 Helm Nexus 插件)的仓库。 每次成功构建应用程序后,镜像和 chart 都是可用的并被推送到 Nexus 。\n持续部署组件 为了实现与云无关的准备,我们选择了 Terraform ,因为它易于学习并易于部署。 我们发现对于准备后的配置管理/维护活动, Terraform 并不是非常有用,所以我们还放置了一些 Ansible 脚本。 我们也曾考虑 Ansible 用于准备,但是使用 Terraform 可以让我们更好地控制启动实例, 这些实例可以作为 Rancher Server/节点,并且可以被自动的添加到自动伸缩组中。 我们使用启动脚本功能实现了这一点。\n我们认为可以将为 AWS 编写的大多数 Terraform 脚本重用到 Azure 中,但事实并非如此。 我们必须做出相当大的改变。\n我们部署了一个运行在三个不同实例上的高可用的 Rancher Server ,前面有一个 NGINX Server 来为这三个实例做负载均衡。 部署是使用 Terraform 和启动脚本完成的。 脚本使用 RKE ( Rancher Kubenetes 引擎)和 Rancher API 调用来启动集群(高可用的 Rancher Server )。\nRancher 提供了各种选项来在不同的云提供商上添加 Kubernetes 集群。 您可以从选项中进行选择,使用托管的 Kubernetes 提供商,或者使用基础设施提供商的节点或自定义节点。 在这个场景中,我们选择使用 AWS 和 Azure 上的自定义节点,而不是托管的 Kubernetes 提供商。 这帮助我们向自动伸缩组添加一组工作节点,并使用集群自动伸缩器进行节点伸缩。\n所有这些都是通过启动脚本和 Rancher API 调用自动完成的,因此任何通过 ASG (和自动伸缩器)添加的新节点都会自动注册为一个 Rancher/Kubernetes 节点。 通过启动脚本自动执行的一些活动包括: - 安装和配置所需的 Docker 版本 - 在所有实例上安装和配置 Zabbix 代理(稍后将在监控中使用) - 安装所需的 GlusterFS 客户端组件 - 安装所需的 kubectl 客户端 - 后端数据库集群所需的任何其他自定义配置 - 自动挂载额外的 EBS 卷和 GlusterFS 卷 - 为 Rancher 代理/Kubernetes 节点运行 Docker 容器并附加特定的角色( etcd/controlplane/worker ) - 检查以确保 Rancher 代理可用、启动和运行。\nGlusterFS 被考虑可以处理 EBS 和 Azure 中不可用的 ReadWriteMany 磁盘卷类型。 这对于我们部署的许多应用程序都是必需的。\n一个 ELK stack ( ElasticSearch、Logstash 和 Kibana )使用 Helm charts 部署在 Kubernetes 上, 并被配置为通过 logstash 推送容器日志、审计和其他自定义日志。\nHAProxy 和 NGINX 被用于两个不同的目的。 NGINX 是在 Rancher Server HA 设置期间所提供的默认 ingress controller 。 这用于三个 Rancher Server 的负载均衡。 我们在 Kubernetes 集群上部署了一个 HAProxy Ingress Controller, 这样我们就可以通过这些特定的节点(其 IPs 映射到特定的 FQDNs)暴露应用程序的 end points 。 HAProxy ingress controller 被部署为 daemonset ,因此对于任何额外的负载,节点的数量会基于自动伸缩组和自动伸缩器自动增加。\n持续监控组件 我们部署了 Prometheus、Grafana 和 Alertmanager 套件,用于容量规划以及监控 Rancher/Kubernetes 集群的状态。 这再次通过 Rancher Helm Chart Provisioner 部署。 我们也可以通过常规的/稳定的 Helm charts 来部署它。 它确实有助于我们监控和收集开发环境中诸如 CPU、内存利用率和 IO 操作之类的指标,并据此为 staging 环境和生产环境进行容量规划。\n我们还在集群上部署了 Zabbix Server,它用于为部署的所有节点监控各种操作系统级别的和应用程序特定的指标和警告。 这包括任何后端数据库集群节点、Kubernetes 节点、Rancher servers、文件服务器或通过 Terraform 提供的任何其他服务器。 Zabbix Server 被配置为节点/代理自动注册,以便通过自动缩放组或自动缩放器添加到集群中的任何新节点都可用于监控。\n结论 这是我们为 Kubernetes 工作负载构建完整的 CI/CD 工具链所遵循的方法之一。 这个模型帮助我们自动化所有的三个环境的准备。 通过 Rancher ,我们能够提供一个开发环境,每个开发人员都可以使用这个项目概念。 每个开发人员都有一个节点和一个项目,它由 RBAC 控制,这样他们就可以部署和测试他们自己的更改。 没有人可以看到项目/节点的详细信息,也不会妨碍其他开发人员部署的 Kubernetes 工作负载。 由于节点自动注册到 Rancher Server,系统重新启动不会影响节点的可用性。 即使在最坏的情况下,如果节点丢失,也很容易在几分钟内打开一个新节点。 应用程序可以使用 Helm charts 进行部署,也可以使用 Rancher 提供的内置的 Helm charts 进行部署。\n这些是我们部署的来管理整个环境的一些高级组件。 我们考虑的其他方面是高可用性集群环境,用于 Rancher servers、Kubernetes 集群、Gluster 文件服务器集群或任何其他后端集群。 在提出此方法时,需要考虑生产级环境所需的更改和更新。 还考虑了其他方面,例如对集群实例的安全访问、升级、备份和恢复,以及根据行业标准提出的分层体系结构建议。\n希望本文为您提供一些参考,当您计划为多个云提供商提供生产级环境准备时,可以考虑这些参考。\n", "auhtor": "Ravi Sarma Kasibhatla", "translator": "donhui", "original": "https://dzone.com/articles/cloud-agnostic-automated-cicd-for-k8s", "poster": "../../../images/articles/2019/04/2019-05-16-cloud-agnostic-automated-cicd-for-k8s/blue.jpg" }, { "uri": "https://jenkins-zh.cn/about/plugins/", "title": "插件列表", "type": "about", "date": "2019-05-15 20:30:05 +0800 +0800", "tags": [], "description": "Jenkins 中文社区维护的插件", "content": "下面的列表是由 Jenkins 中文社区的成员维护的插件:\n 插件 GitHub 仓库 版本 安装量 主要维护者 Simplified Chinese Plugin jenkinsci/localization-zh-cn-plugin LinuxSuRen Hugo Plugin jenkinsci/hugo-plugin LinuxSuRen Maven SNAPSHOT Check Plugin jenkinsci/maven-snapshot-check-plugin donhui Code Coverage API Plugin jenkinsci/code-coverage-api-plugin cizezsy WeiBo Plugin jenkinsci/weibo-plugin LinuxSuRen Job priorty sorter for Multi-branch Job jenkinsci/multi-branch-priority-sorter-plugin LinuxSuRen 同时也期待有更多的贡献者增砖添瓦。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-15-gsoc-annoncement/", "title": "19年 GSoC 中 Jenkins 的七个项目", "type": "wechat", "date": "2019-05-15 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "Jenkins 社区在 Google Summer of Code 中的项目", "content": "Google Summer of Code (GSoC) 项目是一个年度性的全球化活动,该项目旨在鼓励高校学生在暑假期间参与到开源项目中来。\n通过审核的学生会收到由 Google 提供的带薪工作,参与到设计好的项目中以改进或提升 Jenkins 项目。作为回报,数名 Jenkins 社区成员会志愿作为学生“导师”来帮助他们融入开源社区并成功完成他们的夏令营项目。\nJenkins 社区从2009年开始以开源社区的身份参与到 GSoC 中,并分别在16年有5个项目、18年有3个项目被选中。 而今年的项目、导师的数量是最多的一年,相信在这个夏天里,Jenkins 社区可以给我们的用户带来很多不错的 成果,其中也许正有你或者你们团队所希望有的功能或者改进。\n2019年被选中的七个项目包括:\n 支持制品升级的流水线插件 基于云的外部工作空间管理器插件 多分支流水线对 Gitlab 的支持 插件安装管理器的 CLI 工具以及库 基于 Apache Kafka 以及 Kubernetes 的远程协议 基于角色策略的插件的改进 时间窗口插件——UI 改进 上面的每个项目都有一位学生主导进行,至少两位具有相关经验的导师加以指导,每周会有两次的同步会议来 保证方向与进度。当然,在开源社区里任何人都可以通过 PR 的形式对代码或者文档进行 Review。\n今年负责 GSoC 的管理员为:\n Martin d’Anjou Jeff Pearce Lloyd Chang Oleg Nenashev 我本人是“多分支流水线对 Gitlab 的支持”项目的领队导师,请大家与我一起期待这七位高校学生的精彩表现,后续社区也会及时发布上面项目的介绍以及进展。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“../../../images/gsoc/gsoc-big-logo.jpeg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-14-devops-jenkins-credential-manage/", "title": "基于 Jenkins 的 DevOps 平台应该如何设计凭证管理", "type": "wechat", "date": "2019-05-14 00:00:00 +0000 UTC", "tags": ["jenkins", "devops"], "description": "一种基于 Jenkins 的 DevOps 平台建设思路", "content": " 背景 了解到行业内有些团队是基于 Jenkins 开发 DevOps 平台。而基于 Jenkins 实现的 DevOps 平台,就不得不考虑凭证的管理问题。\n本文就此问题进行讨论,尝试找出相对合理的管理凭证的方案。\n一开始我们想到的方案可能是这样的:用户在 DevOps 平台增加凭证后,DevOps 再将凭证同步到 Jenkins 上。Jenkins 任务在使用凭证时,使用的是存储在 Jenkins 上的凭证,而不是 DevOps 平台上的。\n但是,仔细想想,这样做会存在以下问题: * Jenkins 与 DevOps 平台之间的凭证数据会存在不一致问题。 * 存在一定的安全隐患。通过 Jenkins 脚本命令行很容易就把所有密码的明文拿到。哪天 Jenkins 被注入了,所有的凭证一下子就被扒走。 * 无法实现 Jenkins 高可用,因为凭证存在 Jenkins master 机器上。\n那么,有没有更好的办法呢?\n期望实现的目标 先定我们觉得更合理的目标,然后讨论如何实现。以下是笔者觉得合理的目标: \u0026gt; 用户还是在 DevOps 管理自己的凭证。但是 DevOps 不需要将自己凭证同步到 Jenkins 上。Jenkins 任务在使用凭证时,从 DevOps 上取。\n实现方式 Jenkins 有一个 Credentials Binding Plugin 插件,在 Jenkins pipeline 中的用法如下:\nwithCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) { sh ''' curl -u \u0026quot;$USERPASS\u0026quot; https://private.server/ \u0026gt; output ''' } withCredentials 方法做的事情就是从 Jenkins 的凭证列表中取出 id 为 mylogin 的凭证,并将值赋到变量名为 USERPASS 的变量中。接下来,你就可以在闭包中使用该变量了。\n说到这里,不知道读者朋友是否已经有思路了?\n思路就是实现一个和 Credentials Binding Plugin 插件类似功能的方法,比如叫 zWithCredentials(后文还会提到)。与 withCredentials 不同的是,zWithCredentials 根据凭证 id 获取凭证时,不是从 Jenkins 上获取,而是从 DevOps 平台获取。\n会遇到的坑 需要适配只认 Jenkins 凭证的插件 withCredentials 方法是将凭证的内容存到变量中,这可以满足一大部分场景。但是有一种场景是无法满足的。就是某些 Jenkins 插件的步骤接收参数时,参数值必须是 Jenkins 凭证管理系统中的 id。比如 git 步骤中 credentialsId 参数:\ngit branch: 'master', credentialsId: '12345-1234-4696-af25-123455', url: 'ssh://git@bitbucket.org:company/repo.git' 这种情况,我们不可能修改现有的插件。因为那样做的成本太高了。\n那怎么办呢?\n笔者想到的办法是在 zWithCredentials 中做一些 hack 操作。也就是 zWithCredentials 除了从 DevOps 平台获取凭证,还在 Jenkins 中创建一个 Jenkins 凭证。在 Jenkins 任务执行完成后,再将这个临时凭证删除。这样就可以适配那些只认 Jenkins 凭证 id 的插件了。\n对凭证本身的加密 DevOps 平台在存储凭证、传输凭证给 Jenkins 时,都需要对凭证进行加密。至于使用何种加密方式,交给读者思考了。\n小结 以上解决方案对 Jenkins 本身的改造几乎没有,我们只通过一个插件就解耦了 Jenkins 的凭证管理和 DevOps 平台的凭证管理。\n思路已经有了。具体怎么实现,由于一些原因不能开源,虽然实现起来不算难。还请读者见谅。\n最后,希望能和遇到同样问题的同学进行交流。看看是否还可以有更好的设计思路。\n", "auhtor": "zacker330", "translator": "", "original": "", "poster": "./2019-05-14-devops-jenkins-credential-manage/devops-platform-lock-jenkins.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-13-jenkins-book-gift/", "title": "Jenkins 公众号送书福利", "type": "wechat", "date": "2019-05-13 00:00:00 +0000 UTC", "tags": ["jenkins"], "description": "赠送 5 本《Jenkins 2.x实践指南》", "content": " Jenkins 中文社区是一个开放、包容、活跃的社区,包含大量的 Jenkins 干货。\n当然,它也会为公众号的粉丝们发放福利。\n本次福利是《Jenkins 2.x实践指南》x 5,以下是介绍:\n本次活动书籍均由博文视点(Broadview)提供,特此感谢。\n参与方式: 关注本公众号,并在后台回复【抽奖】,根据二维码进入小程序抽奖。 开奖时间为:5月19日晚上7点自动开奖(记得填自己的手机号,地址以便中奖后邮寄发出)。 中奖的同学,不要忘记发朋友圈分享支持噢~\n等不急的同学,还可以扫二维码直接购买:\n", "auhtor": "zacker330", "translator": "", "original": "", "poster": "./2019-05-13-jenkins-book-gift/poster.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-13-cdf-call-for-papers/", "title": "持续交付峰会 Call For Papers", "type": "wechat", "date": "2019-05-13 00:00:00 +0000 UTC", "tags": ["cdf", "cfp"], "description": "持续交付基金会在上海 KubeCon 的同场活动", "content": " 持续交付峰会是一个为期一天的活动,将开源 CI/CD 社区汇集在一起。这一天将包括主题演讲,项目展示和终端用户的故事,以及 BoF 会议。与同行会面并推动未来持续交付的方向。\n重要日期 CFP 开始:4月29日,星期一 CFP 关闭:太平洋标准时间 5月17日,23:59,星期五 CFP 通知:5月29日,星期三 日程通知:5月30日,星期一 幻灯片截止:6月17日,星期四 活动时间:6月24日 建议的话题 CDF 的项目 Jenkins Jenkins X Tekton 和 Spinnaker 讲述你正在使用的这些项目的功能或者集成的功能,分享你为什么要使用以及如何利用这些项目解决了哪些问题 你们团队的持续交付 我们希望能听到真实项目中的使用,以及你们团队所推荐的持续交付实践 安全与合规性最佳实践 分享在持续交付中改善你们的软件供应链中的安全性的案例和技巧 帮助我们的同时也帮助自己 描绘你希望看到的 CI/CD 景象 点击这里提交你的演讲题目\n点击这里查看其他更多的同场活动。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“../../../images/logos/cdf-logo.png”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-09-jenkins-release/", "title": "Jenkins 版本发布", "type": "wechat", "date": "2019-05-09 00:00:00 +0000 UTC", "tags": ["jenkins", "release"], "description": "Jenkins 每周更新版发布", "content": " 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) ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "“../../../images/cow.jpg”" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-08-jenkins-plugin-develop-within-two-days-part02/", "title": "Jenkins 插件开发之旅:两天内从 idea 到发布(下篇)", "type": "wechat", "date": "2019-05-08 00:00:00 +0000 UTC", "tags": ["jenkins", "maven", "jira"], "description": "两天内,从产生 idea 到编写插件,最后发布到 Jenkins 插件更新中心", "content": " 本文分上下两篇,上篇介绍了从产生 idea 到插件开发完成的过程; 下篇将介绍将插件托管到 Jenkins 插件更新中心的一系列过程。\n托管插件 托管插件包括一系列流程步骤。 笔者完成了它所有步骤(包括非必须的步骤),其中主要有两个具有标志性的任务: - 插件代码被托管在 jenkinsci GitHub 组织的一个仓库,然后作者拥有它的管理权限。\n笔者插件的代码仓库为:jenkinsci/maven-snapshot-check-plugin 。 - 你可以将插件发布到 Jenkins 项目的 Maven 仓库,它是 Jenkins 项目所使用的更新站点的数据来源。\n准备工作 在请求插件托管之前,需要完成以下几个步骤。\n查找类似的插件 Jenkins 社区欢迎任何人的贡献,但为了让 Jenkins 用户受益, 它要求查找解决相同或类似问题的插件,看看是否可以与现有的维护人员联手。 可以在 https://plugins.jenkins.io 查看所有的插件, 以确认是否已有类似的插件实现了你计划实现的功能。 笔者在之前已进行过查找,并没有找到可以实现笔者计划实现的功能的类似插件。\n命名规约 Jenkins 制定了一些与插件相关的命名规约。 插件开发者要确保遵循这些命名规约。\nartifactId 插件的 artifactId 被用于文件基本名称,是 Jenkins 插件和更新站点的唯一标识。\n它需要遵循一些发布规约: - 使用小写 ID ,并根据需要使用连字符分隔术语。 - 除非名称有任何意义,否则不要在 ID 中包含 jenkins 或 plugin 。\n插件名称 插件的名称在 Jenkins UI 和其它地方(如:插件站点)展示给用户。\n如果可以,建议使用简短的描述性名称,如 Subversion 。\n笔者所写的插件的名称为:Maven SNAPSHOT Check 。\ngroupId 推荐使用 io.jenkins.plugins 或 org.jenkins-ci.plugins 作为 groupId 。 但是不禁止其他组织 ID ,除非它们是恶意的(例如引用与你没有关系的组织)。 笔者所写的插件使用的 groupId 为: org.jenkins-ci.plugins 。\nJava 源代码 Jenkins 项目一般遵循 Oracle Java 代码规约, 但是并没有很好的强制甚至在核心组件中。 个别的插件维护者有时会选择使用不同的风格指南作为插件。 笔者日常使用 IDEA 进行开发,之前安装了「阿里 Java 规约插件」, 因而使用它作为编码规约。\n提交消息 Git 提交消息应该从引用与之相关的 JIRA 问题开始(如果适用), 然后在第一行进行简短的总结,并在随后的行中提供更多详细信息。例如:\n[JENKINS-00000] Frobnicate the widget 如果给定的提交修复了指定的问题, 那么使用以下前缀中的任何一个将会自动化解决相关的 JIRA 问题。\n[FIX JENKINS-00000] Frobnicate the widget [FIXED JENKINS-00000] Frobnicate the widget [FIXES JENKINS-00000] Frobnicate the widget 由于还没过将插件托管,笔者并没有遵循该规约, 等插件发布后,笔者将考虑遵循该规约。\nLicense Jenkins 项目分发的所有插件都需要是免费的开源软件。 这适用于插件源代码及其所有依赖项。 要确保在 pom.xml 文件和仓库中的 LICENSE 文件指定协议。 官方建议使用 MIT license ,它用于 Jenkins 核心和大多数插件和库, 但是任何 OSI 批准的开源 license 都可以。 笔者这里使用了 MIT license 。\n要求注册的账号 通过 Jenkins 项目更新站点分发的插件需要托管在 jenkinsci GitHub 组织中, 因此需要在 GitHub 上有一个账号,并且需要有一个公共仓库来存放插件源代码。\n为了完整地发布你的插件,需要注册一个 Jenkins 社区帐号, 它可以让你访问 JIRA,wiki 和 Maven 仓库 。\n发起托管请求 注意:Jenkins 官方自动化流程使用更容易实现的 fork + 删除的方式(见下文),而不是转移仓库所有者。\n 登录到 JIRA 然后在 HOSTING 项目创建一个问题。 请确保按照描述填写所有字段。 Jenkins 项目成员将在几天内审查你的请求。 如果审查人员要求你更改,那么请按照要求进行更改。\n笔者提交的申请为:HOSTING-750, 比较幸运的是当天凌晨(北京时间)笔者的请求就被审查, 正巧那时笔者未眠,于是随后按要求进行了更改并在不久后该申请被审批通过。\n一旦满足了所有的需求,你的仓库将被 fork 到 jenkinsci 组织中, 并且你将被邀请加入该组织,并且将为你在 JENKINS 项目中创建 JIRA 组件。\n此时,将要求你删除 Jenkins 从中 fork 的仓库。 之后你可以通过再次从 jenkinsci 那里 fork 来重新创建它。 这将确保 jenkinsci 仓库是 Github 上网络图的根。 这意味着: - 不会混淆哪个仓库是权威仓库。 - 即使在 GitHub 上没有大量的关注者,源代码搜索也会成功。 - 其他人更可能在 jenkinsci 仓库中提交 pull request(这是协作的理想选择)。\n创建 wiki 页面 尽管这对发布插件来说这不是严格要求的,但最好为插件创建一个 wiki 页面来存储文档。关于如何执行此操作的详细信息,请参阅插件 wiki 页面指南。\n笔者所写的插件的 wiki 页面为:Maven SNAPSHOT Check Plugin 。 其间除了官方文档,笔者还参考了其它插件 wiki 页面的排版。\n开启 CI 构建 Jenkins 项目托管了一个 Jenkins 实例来执行插件的持续集成构建。 官方推荐通过在插件的 Github 仓库根目录创建一个 Jenkinsfile, 为在 Jenkinsci Github 组织中的插件设置 CI 构建。 典型的插件构建( Maven 或 Gradle )只需在 Jenkinsfile 中包含以下语句即可运行:\nbuildPlugin() 申请上传权限 在源代码被 fork 到 jenkinsci 组织后,需要提交一个上传权限请求。 按照 jenkins-infra/repository-permissions-updater/ 仓库的 README 文件中所说的来做就可以。\nJenkins 项目在 Artifactory 上托管 Maven 制品,例如核心和插件发布。 它的权限系统与 Github 是独立的, 限制了那些用户(由 Jenkins LDAP 帐户标识,与 wiki 和 JIRA 一样)可以上传。 这个仓库包含 YAML 格式的 Artifactory 上传权限定义, 以及将它们同步到 Artifactory 的工具。 \u0026gt; 先决条件:在申请权限之前,需要先用 Jenkins 社区帐号登录一次 Artifactory 。\n要请求对制品(通常是插件)的上传权限,需要提交一个 PR , 该 PR 需要创建与申请上传权限相关的 YAML 文件。 笔者所提交的 PR 为:Plugin: Permission for maven-snapshot-check-plugin 。\n通过查看它可以看出该 PR 增加了一个文件:permissions/plugin-maven-snapshot-check.yml ,其内容如下:\nname: \u0026quot;maven-snapshot-check\u0026quot; github: \u0026quot;jenkinsci/maven-snapshot-check-plugin\u0026quot; paths: - \u0026quot;org/jenkins-ci/plugins/maven-snapshot-check\u0026quot; developers: - \u0026quot;donhui\u0026quot; 在创建 PR 后,会有帮助说明以及 checklist 让提交人对该 PR 进行检查确认。\n等这个 PR 被审批后,插件开发者就会拥有该插件的发布权限。\n发布插件 前提 要先确认拥有发布该插件的权限。\nMaven 要使用的 Artifactory 凭据 需要告诉 Maven 访问 Artifactory 的凭据。 登录 Artifactory ,从用户 profile 中获取加密的密码。 在 ~/.m2/settings.xml 文件配置 server 认证信息,如下所示:\n\u0026lt;settings xmlns=\u0026quot;https://maven.apache.org/SETTINGS/1.0.0\u0026quot; xmlns:xsi=\u0026quot;http://www.w3.org/2001/XMLSchema-instance\u0026quot; xsi:schemaLocation=\u0026quot;https://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd\u0026quot;\u0026gt; \u0026lt;servers\u0026gt; \u0026lt;server\u0026gt; \u0026lt;id\u0026gt;maven.jenkins-ci.org\u0026lt;/id\u0026gt; \u0026lt;username\u0026gt;your_user_name_here\u0026lt;/username\u0026gt; \u0026lt;password\u0026gt;your_encrypted_password_here\u0026lt;/password\u0026gt; \u0026lt;/server\u0026gt; \u0026lt;/servers\u0026gt; \u0026lt;/settings\u0026gt; 配置 GitHub 以接受你的 SSH key 当执行 release 时,Maven Release Plugin 会自动往仓库推送代码, 所以需要配置 GitHub 以接受你的 SSH key 。\n更多信息可以参考:GitHub help on SSH 。\n执行发布 当 GitHub 和 Maven 凭据配置好后, 执行一次发布应该很简单,只需要运行下面的命令:\nmvn release:prepare release:perform 可能在执行发布时会遇到 \u0026ldquo;401 Unauthorized\u0026rdquo; 或 \u0026ldquo;403 Forbidden\u0026rdquo; 之类问题, 这一般是 settings.xml 配置问题或是没有上传权限。 一些公共的问题处理方案可以查看:HostingPlugins-Workingaroundcommonissues。\n插件发布后,8 小时内,将可以在插件更新中心看到它。\n笔者所写的 maven-snapshot-check 插件, 在插件列表页的地址为:https://plugins.jenkins.io/maven-snapshot-check 。\nJenkins 实例的插件管理页面的「可选插件」选项截图如下: 为插件分类 在 Jenkins 插件列表页面,可以对插件进行分类显示。\n要为插件添加一个分类,需要向 jenkins-infra/update-center2 仓库提交一个 PR 。 笔者所提交的 PR 为:add maven-snapshot-check category 。\n通过查看它可以看出该 PR 在 src/main/resources/label-definitions.properties 文件增加了一行,如下所示:\nmaven-snapshot-check=builder 总结 两天的 Jenkins 插件开发之旅(尤其是 04.24 晚上花了很多时间), 让笔者了解了插件开发的基本知识,并在托管插件的过程中学到一些知识。 然后在周末花了几个小时总结回顾,并将它写成文档。 同时也希望此文能给 Jenkins 插件开发者入门带来一点帮助!\n参考 Guide to Plugin Hosting Performing a Plugin Release ", "auhtor": "donhui", "translator": "", "original": "", "poster": "./2019-05-08-jenkins-plugin-develop-within-two-days-part02/sunset.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-07-jenkins-install-plugins-shell/", "title": "Jenkins 自动化安装插件", "type": "wechat", "date": "2019-05-07 00:00:00 +0000 UTC", "tags": ["jenkins"], "description": "Jenkins 批量安装指定版本插件", "content": " 手工安装 Jenkins 插件的方法 通常,我们有两种方法安装 Jenkins 插件。第一种方法是到 Jenkins 插件管理页面搜索插件,然后安装。第二种方法是上传 Jenkins 插件的 hpi 文件安装。这两种方法能满足大多数人的需求。\n第一种方法,如下图所示: 第二种方法,如下图所示: 但是对于需要保证 Jenkins 稳定或在 Jenkins 上进行二次开发的同学来说,以上方法是无法满足需求的。\n第一种方法是无法指定插件的版本。第二种方式必须自己找到该插件的依赖树,然后根据依赖关系一个个地安装。是的,手工上传插件的这种方法,Jenkins 是不会自动下载依赖的。\n还有,就是这两种方式都无法实现批量安装。\n自动安装插件的方法 那么,有什么方法能指定插件的版本,又能自动下载它的依赖,还能批量下载呢?\n幸运的是,Jenkins 的 Docker 镜像的代码仓库里的 install-plugins.sh 脚本已经实现。只不过需要我们拿过来小小修改才能使用。笔者修改后创建了相应的代码仓库:jenkins-install-plugins-shell 。链接在文章末尾。\n以下是 jenkins-install-plugins-shell 的使用方法: 1. 将代码 clone 到 JENKINS_HOME 目录中。\ncd $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 执行安装\n# Jenkins War 的路径,用于分析 export JENKINS_WAR_PATH=\u0026lt;Jenkins war文件的路径\u0026gt; chmod +x install-plugins.sh jenkins-support ./install-plugins.sh \u0026lt; plugins.txt 重启 Jenkins install-plugins 本质上做的事情就只是将插件从云端下载到 JENKINS_HOME 下的 plugins 目录中。要使安装的插件生效,还需要重启 Jenkins。\n 关于 Jenkins 插件的名称 Jenkins 插件有两个名称。一个叫 display name,一个叫 short name。比如 Ansible 插件的 disply name 为 Ansible plugin,short name 为 ansible。\n如何知道一个插件的 short name 呢?可以在 Jenkins 插件官网上找到,比如 Ansible 的:\n在 plugins.txt 中使用的是 short name。\n总结 笔者为什么一定要确定 Jenkins 插件的版本?是因为插件的版本会影响 Jenkins 流水线的可靠性。所以,笔者才会这么在意 Jenkins 插件的版本。\n附录 Jenkins 官方 Docker 镜像中的自动化插件安装脚本:https://github.com/jenkinsci/docker/blob/master/install-plugins.sh 笔者修改后的自动化插件安装脚本: https://github.com/zacker330/jenkins-install-plugins-shell ", "auhtor": "zacker330", "translator": "", "original": "", "poster": "./2019-05-07-jenkins-install-plugins-shell/poster.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/05/2019-05-06-jenkins-plugin-develop-within-two-days-part01/", "title": "Jenkins 插件开发之旅:两天内从 idea 到发布(上篇)", "type": "wechat", "date": "2019-05-06 00:00:00 +0000 UTC", "tags": ["jenkins", "maven", "jira"], "description": "两天内,从产生 idea 到编写插件,最后发布到 Jenkins 插件更新中心", "content": " 本文介绍了笔者首个 Jenkins 插件开发的旅程, 包括从产生 idea 开始,然后经过插件定制开发, 接着申请将代码托管到 jenkinsci GitHub 组织, 最后将插件发布到 Jenkins 插件更新中心的过程。\n鉴于文章篇幅过长,将分为上下两篇进行介绍。\n从一个 idea 说起 前几天和朋友聊天时,聊到了 Maven 版本管理领域的 SNAPSHOT 版本依赖问题, 这给他带来了一些困扰,消灭掉历史遗留应用的 SNAPSHOT 版本依赖并非易事。\n类似问题也曾经给笔者带来过困扰,在最初没能去规避问题, 等到再想去解决问题时却发现困难重重,牵一发而动全身, 导致这个问题一直被搁置,而这也给笔者留下深刻的印象。\n等到再次制定 Maven 规范时,从一开始就考虑 强制禁止 SNAPSHOT 版本依赖发到生产环境。\n这里是通过在 Jenkins 构建时做校验实现的。 因为没有找到提供类似功能的 Jenkins 插件, 目前这个校验通过 shell 脚本来实现的, 具体的做法是在 Jenkins 任务中 Maven 构建之前增加一个 Execute shell 的步骤, 来判断 pom.xml 中是否包含 SNAPSHOT 关键字,如果包含,该次构建状态将被标记为失败。 脚本内容如下:\n#!/bin/bash if [[ ` grep -R --include=\u0026quot;pom.xml\u0026quot; SNAPSHOT .` =~ \u0026quot;SNAPSHOT\u0026quot; ]]; then echo \u0026quot;SNAPSHOT check failed\u0026quot; \u0026amp;\u0026amp; grep -R --include=\u0026quot;pom.xml\u0026quot; SNAPSHOT . \u0026amp;\u0026amp; exit 1; else echo \u0026quot;SNAPSHOT check success\u0026quot;; fi 恰好前不久在看 Jenkins 插件开发文档, 那何不通过 Jenkins 插件的方式实现它呢?\n于是笔者开始了首个 Jenkins 插件开发之旅。\n插件开发过程 Jenkins 是由 Java 语言开发的最流行的 CI/CD 引擎。\n说起 Jenkins 强大的开源生态,自然就会说到 Jenkins 插件。 Jenkins 插件主要用来对 Jenkins 的功能进行扩展。 目前 Jenkins 社区有上千个插件, 用户可以根据自己的需求选择合适的插件来定制 Jenkins 。\n插件开发准备 插件开发需要首先安装 JDK 和 Maven,这里不做进一步说明。\n创建一个插件 Jenkins 为插件开发提供了 Maven 原型。 打开一个命令行终端,切换到你想存放 Jenins 插件源代码的目录,运行如下命令:\nmvn -U archetype:generate -Dfilter=io.jenkins.archetypes: 这个命令允许你使用其中一个与 Jenkins 相关的原型生成项目。\n$ mvn -U archetype:generate -Dfilter=io.jenkins.archetypes: ...... Choose archetype: 1: remote -\u0026gt; io.jenkins.archetypes:empty-plugin (Skeleton of a Jenkins plugin with a POM and an empty source tree.) 2: remote -\u0026gt; io.jenkins.archetypes:global-configuration-plugin (Skeleton of a Jenkins plugin with a POM and an example piece of global configuration.) 3: remote -\u0026gt; io.jenkins.archetypes:hello-world-plugin (Skeleton of a Jenkins plugin with a POM and an example build step.) Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 3 Choose io.jenkins.archetypes:hello-world-plugin version: 1: 1.1 2: 1.2 3: 1.3 4: 1.4 Choose a number: 4: 4 ...... [INFO] Using property: groupId = unused Define value for property 'artifactId': maven-snapshot-check Define value for property 'version' 1.0-SNAPSHOT: : [INFO] Using property: package = io.jenkins.plugins.sample Confirm properties configuration: groupId: unused artifactId: maven-snapshot-check version: 1.0-SNAPSHOT package: io.jenkins.plugins.sample Y: : Y 笔者选择了 hello-world-plugin 这个原型, 并在填写了一些参数,如artifactId、version 后生成了项目。\n可以使用 mvn verify 命令验证是否可以构建成功。\n构建及运行插件 Maven HPI Plugin 用于构建和打包 Jenkins 插件。 它提供了一种便利的方式来运行一个已经包含了当前插件的 Jenkins 实例:\nmvn hpi:run 这将安装一个 Jenkins 实例,可以通过 http://localhost:8080/jenkins/ 来访问。 等待控制台输出如下内容,然后打开 Web 浏览器并查看插件的功能。\nINFO: Jenkins is fully up and running 在 Jenkins 中创建一个自由风格的任务,然后给它取个名字。 然后添加 \u0026ldquo;Say hello world\u0026rdquo; 构建步骤,如下图所示:\n输入一个名字,如:Jenkins ,然后保存该任务, 点击构建,查看构建日志,输出如下所示:\nStarted by user anonymous Building in workspace /Users/mrjenkins/demo/work/workspace/testjob Hello, Jenkins! Finished: SUCCESS 定制开发插件 Jenkins 插件开发归功于有一系列扩展点。 开发人员可以对其进行扩展自定义实现一些功能。\n这里有几个重要的概念需要做下说明:\n扩展点( ExtensitonPoint ) 扩展点是 Jenkins 系统某个方面的接口或抽象类。 这些接口定义了需要实现的方法,而 Jenkins 插件需要实现这些方法。\n笔者所写的插件需要实现 Builder 这个扩展点。 代码片段如下:\npublic class MavenCheck extends Builder {} Descriptor 静态内部类 Descriptor 静态内部类是一个类的描述者,用于指明这是一个扩展点的实现, Jenkins 通过这个描述者才能知道我们写的插件。 每一个描述者静态类都需要被 @Extension 注解, Jenkins 内部会扫描 @Extenstion 注解来获取注册了哪些插件。\n代码片段如下:\n@Extension public static final class DescriptorImpl extends BuildStepDescriptor\u0026lt;Builder\u0026gt; { public DescriptorImpl() { load(); } @Override public boolean isApplicable(Class\u0026lt;? extends AbstractProject\u0026gt; aClass) { return true; } @Override public String getDisplayName() { return \u0026quot;Maven SNAPSHOT Check\u0026quot;; } } 在 DesciptorImpl 实现类中有两个方法需要我们必须要进行重写: isApplicable() 和 getDisplayName() 。 isApplicable() 这个方法的返回值代表这个 Builder 在 Jenkins Project 中是否可用, 我们可以将我们的逻辑写在其中,例如做一些参数校验, 最后返回 true 或 false 来决定这个 Builder 是否可用。\ngetDisplayName() 这个方法返回的是一个 String 类型的值, 这个名称被用来在 web 界面上显示。\n数据绑定 前端页面的数据要和后台服务端进行交互,需要进行数据绑定。 前端 config.jelly 页面代码片段如下:\n\u0026lt;?jelly escape-by-default='true'?\u0026gt; \u0026lt;j:jelly xmlns:j=\u0026quot;jelly:core\u0026quot; xmlns:st=\u0026quot;jelly:stapler\u0026quot; xmlns:d=\u0026quot;jelly:define\u0026quot; xmlns:l=\u0026quot;/lib/layout\u0026quot; xmlns:t=\u0026quot;/lib/hudson\u0026quot; xmlns:f=\u0026quot;/lib/form\u0026quot;\u0026gt; \u0026lt;f:entry title=\u0026quot;check\u0026quot; field=\u0026quot;check\u0026quot;\u0026gt; \u0026lt;f:checkbox /\u0026gt; \u0026lt;/f:entry\u0026gt; \u0026lt;/j:jelly\u0026gt; 如上所示,需要在 config.jelly 中包含需要传入的参数配置信息的选择框,field 为 check ,这样可以在 Jenkins 进行配置,然后通过 DataBoundConstructor 数据绑定的方式,将参数传递到 Java 代码中。 服务端 Java 代码片段如下:\n@DataBoundConstructor public MavenCheck(boolean check) { this.check = check; } 核心逻辑 笔者所写的插件的核心逻辑是检查 Maven pom.xml 文件是否包含 SNAPSHOT 版本依赖。\nJenkins 是 Master/Agent 架构, 这就需要读取 Agent 节点的 workspace 的文件, 这是笔者在写插件时遇到的一个难点。\nJenkins 强大之处在于它的生态,目前有上千个插件, 笔者参考了 Text-finder Plugin 的源码, 并在参考处添加了相关注释,最终实现了插件要实现的功能。\n详细代码可以查看 jenkinsci/maven-snapshot-check-plugin 代码仓库。\n分发插件 使用 mvn package 命令可以打包出后缀为 hpi 的二进制包, 这样就可以分发插件,将其安装到 Jenkins 实例。\n插件使用说明 以下是对插件的使用简要描述。\n如果勾选了下面截图中的选择框, Jenkins 任务在构建时将会检查 pom.xml 中是否包含 SNAPSHOT 。 如果检查到的话,则会将该次构建状态标记为失败。 总结 文章上篇主要介绍了从产生 idea 到插件开发完成的过程。\n那么插件在开发完成后是如何将它托管到 Jenkins 插件更新中心让所有用户都可以看到的呢?\n两天后的文章下篇将对这个过程进行介绍,敬请期待!\n参考 Plugin tutorial Preparing for Plugin Development Create a Plugin Build and Run the Plugin ", "auhtor": "donhui", "translator": "", "original": "", "poster": "./2019-05-06-jenkins-plugin-develop-within-two-days-part01/huashan.png" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-30-what-cicd-tool-should-i-use/", "title": "应该使用什么 CI/CD 工具?", "type": "wechat", "date": "2019-04-30 00:00:00 +0000 UTC", "tags": ["ci", "cd", "pipeline"], "description": "了解典型自动化 CI/CD 部署流水线的组件以及您需要的组件。", "content": " 在我们正在进行的 Kubernetes FAQ 系列中,我们回答了社区中一些常见的问题,本周我们将讨论在选择 CI/CD 工具时需要考虑什么。\n目前已经有大量的 CI/CD 工具可供选择-开源解决方案和商业解决方案。在这里,我们重点介绍在设置持续交付流水线时要考虑的一些最重要的注意事项。\n在这篇文章中你将学到: - 为什么需要自动化流水线 - 部署典型流水线的组件 - CD 流水线功能需要考虑 - 如何合并 GitOps\n为什么要创建自动化 CI/CD 流水线? 自动化 CI/CD 流水线有许多好处: - 将您的上线时间从数周或数月减少到数天或数小时。通过自动化流水线,开发团队可以提高发布的速度以及代码的质量。以小增量连续添加的新功能和修复可以使产品具有更少的缺陷。 - 一个强大的开发团队。由于交付流水线的所有阶段都可供团队中的任何人检查、改进和验证,因此可以创建对构建的所有权,从而鼓励整个组织的强大团队合作和协作能力。 - 降低软件开发的风险和成本。自动化鼓励开发人员在继续前进之前分阶段验证代码更改,从而减少了缺陷最终出现在生产中的机会。 - 减少进展中的工作量。CD 流水线提供从开发到客户的快速反馈循环。这个迭代周期不仅可以帮助您构建正确的产品,而且还允许开发人员更快地进行产品改进,从而减少正在进行的工作。 典型的部署流水线 CD 流水线由几个不同的阶段组成; 一个工具不能满足所有这些步骤。\n以下是构成大多数自动化流水线的步骤: 1. 在笔记本电脑上编写代码,将其推入源代码仓库(如 Git)。 2. 代码通过单元、集成和其他自动化测试。如果测试通过,将构建成新的 Docker 镜像。 3. 将镜像推送到镜像仓库。 4. 将新镜像推送到集群中。 思考 CD 流水线的特性 创建流水线的困难之一是成功地将您想要使用的工具粘合在一起。这些是为流水线选择工具时要考虑的主要功能: - 端到端的安全性 - 能够使用完全可重现的审计跟踪进行回滚 - 内置可观察性和警报功能 - 平均快速部署时间以及平均快速恢复时间 - 简单的开发人员经验和工作流程\n流水线端到端的安全性 在市场上的 CI/CD 工具中,有些工具将 CI 和 CD 部分合并为一个工具。或者更糟糕的是,那些负责创建 CI/CD 流水线的人将组装一系列手工锻造的脚本,这些脚本可以在一个方向上通过流水线推送代码,或执行被称为CIOP 流水线。\n出于多种原因,您不希望这样做。这是一种反模式,因为集群安全和其他凭据不在集群之外,这可能是不安全的。建议的方法是使用实​​现 Kubernetes Operator 的工具。\n部署到集群的 Kubernetes Operator 可以监视仓库中的新镜像。更进一步,如果您的整个集群状态(通过声明性清单)都保存在 Git 中,那么“diff alert”可以成为从仓库中“提取”新镜像并将其部署到集群的动力。这不仅是一种更安全的部署方法,而且还为开发人员提供了一种更简单的方法来应用和回滚生产环境的更改。\n具备完整审计跟踪回滚 跟踪差异历史记录,以及在团队中处理大型应用程序时管理新旧部署的回滚可能具有挑战性。您需要一个可以轻松处理此类方案的工具。如果您拥有一个完全可审计的路径,它可以帮助您了解何时何时执行了哪些操作,这也有助于 SOC 2合规性规定的增加。\n可观察性和警报 将可观察性纳入您的流水线意味着什么?\n为了提高你的速度,你的流水线需要结合可观察性来回答这些问题:\n如果自动发布更改,我怎么知道它是否有效? 在复杂的分布式系统中,我如何理解问题、诊断问题并管理事件 - 尤其是当您需要回滚时? 将持续交付与实时可观察性相结合,使您的开发团队能够在部署新功能之前做出更好的决策。\n新功能和补丁被推送到 Git 并触发部署流水线,当它们准备好发布时,理想情况下应该对正在运行的集群实时监控。这允许开发人员根据反馈做出决策。可以将它们返回到流水线的起点,或将更新后的镜像部署到生产集群中。 更快的平均部署和恢复时间 除了能够频繁可靠地部署之外,还需要考虑考虑一个重要场景,是在集群宕机时的恢复。这需要快速、平滑,并且可能由可能不是由 Kubernetes 专业的开发人员来执行。\n简单的开发人员经验和 Git 工作流程 为了在当今的云原生世界中快速发展,开发人员必须从端到端控制流水线。提交凭据等待人来回复的时期已经没有了。从开发人员一直使用的工具构建流水线是有意义的。像 Git 这样的工具。\n使用 GitOps,有三个基本原则:\n#1.所有可以描述的内容都必须存储在 Git 中 通过使用 Git 作为事实源,可以观察集群并将其与所需的状态进行比较。目标是描述所有内容:策略、代码、配置,甚至监控事件和版本控制。将所有内容保持在版本控制之下,可以增强收敛性,如果最初它们没有成功,则可以重新应用更改。\n#2.不要直接使用 kubectl 一般来说,使用命令行工具 kubectl 直接部署到集群不是一个好主意。许多人让他们的 CI 工具推动部署,但是这样做可能会对生产环境遭受更容易被攻击的风险。\n#3.使用遵循操作符模式的 Kubernetes Operator 使用遵循操作符模式的 Kubernetes Operator,您的集群始终通过其签入 Git 的配置文件与“事实源”保持同步。由于集群的所需状态保存在 Git 中,因此还可以观察到与正在运行的集群的差异。\n将 GitOps 工作流程应用于流水线 通过采用 GitOps,开发人员可以通过提取请求管理基础架构配置和软件部署以及回滚。当真实来源与集群中运行的不同时,集群会自动与 Git 中保存的内容同步。 Weave Cloud 的部署代理在集群内部运行。这意味着容器映像注册表和集群 API 的凭据永远不会离开集群的域。通过使用 Git 作为事实源,可以比较和警告所需的状态和当前状态。这不仅可以确保集群保持最新,而且还可以在集群崩溃时提供从灾难中快速恢复的方法。\n", "auhtor": "Anita Buehrle", "translator": "yJunS", "original": "https://dzone.com/articles/what-cicd-tool-should-i-use", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-29-progressive-delivery-with-jenkins-x-automatic-cana/", "title": "使用 Jenkins X 渐进式交付:自动化金丝雀部署", "type": "wechat", "date": "2019-04-29 00:00:00 +0000 UTC", "tags": ["jenkins"], "description": "为了避免渐进式交付可能带来的麻烦,学习使用 Jenkins X 为金丝雀发布自动部署。", "content": " 这是渐进式交付系列的第三篇文章,前两篇请参见: - Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署 - 使用 Jenkins X 渐进式交付\n渐进式交付被 Netflix, Facebook 以及其它公司使用用来减轻部署的风险。 但是现在你可以在使用Jenkins X时采用它。\n渐进式交付是持续交付的下一步,它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估,如果不匹配某些关键指标,则进行回滚。\n尤其是,我们聚焦金丝雀发布,并让它在你的 Jenkins X 应用中变得易于采用。 金丝雀发布包括向应用程序的新版本发送一小部分流量,并在向其他用户发布之前验证这里没有错误。 Facebook 就是这样做的,首先向内部员工提供新版本,然后是一小部分用户,然后是其他所有用户,但是你要采用它并不需要成为 Facebook !\n你可以在 Martin Fowler 的网站阅读更多与金丝雀发布相关信息。\nJenkins X 如果在 Jenkins X 中你已经有一个应用,那么你知道的你可以 通过 jx promote myapp --version 1.0 --env production 命令 promote 它到\u0026rdquo;生产\u0026rdquo;环境。 但是,在检查新版本是否失败的同时,它也可以自动并逐步地向一定比例的用户推出。 如果发生失败,应用程序将自动回滚。 整个过程中完全没有人为干预。\n注意:这个新功能是非常新的,在将来这些步骤将不再需要,因为它们也将由 Jenkins X 自动化了。\n作为第一步,三个 Jenkins X 插件需要被安装: - Istio : 一种服务网格容许我们管理我们服务的流量。 - Prometheus :Kubernetes 中最流行的监控系统。 - Flagger :一个使用 Istio 的项目,该项目使用 Prometheus 的指标自动化进行金丝雀发布和回滚。\n插件可以使用如下命令安装(使用一个最近版本的 jx CLI ): 1. jx create addon istio 2. jx create addon prometheus 3. jx create addon flagger\n这将在 jx-production 命名空间启动 Istio 来进行指标收集。\n现在获取 Istio ingress 的 IP ,并将一个通配符域名(如: *.example.com )指向它,以便我们可以使用它根据主机名路由多个服务。 Istio ingress 提供了金丝雀发布需要的路由能力(流量转移),传统的 Kubernetes ingress 对象不支持该功能。\n集群被配置后,是时候配置我们的应用了。 在 charts/myapp/templates 目录下向你的 helm chart 添加一个 canary.yaml。\n然后往 charts/myapp/values.yaml 追加如下内容,将 myapp.example.com 修改为你的主机名或域名:\n不久,当你从 Jenkins X 快速开始创建你的应用,将不再需要修改 canary.yaml 和 values.yaml 这两个文件,因为它们默认启用金丝雀部署。\n就这样!现在当使用 jx promote myapp --version 1.0 --env production 将你的应用 promote 到生产环境,它将执行一次金丝雀部署。 请注意,第一次被 promote 时,它不会执行金丝雀部署,因为它需要与以前的版本数据进行比较,但从第二次 promotion 开始,它将起作用。\n根据上面 values.yaml 文件中的配置,它看起来像: - 第 1 分钟:将 10% 的流量发送到新版本 - 第 2 分钟:将 20% 的流量发送到新版本 - 第 3 分钟:将 30% 的流量发送到新版本 - 第 4 分钟:将 40% 的流量发送到新版本 - 第 5 分钟:将 100% 的流量发送到新版本\n如果我们配置的指标(请求持续时间超过 500 毫秒或超过 1% 的响应返回 500 错误)失败,Flagger 将注意到失败,并且如果重复 5 次,它将回滚这次发布,将 100% 的流量发送到旧版本。\n获得金丝雀事件输出,执行如下命令: 1. $ kubectl -n jx-production get events \u0026ndash;watch\n2. \u0026ndash;field-selector involvedObject.kind=Canary 3. 23m \u0026hellip; New revision detected! Scaling up jx-production-myapp.jx-production 4. 22m \u0026hellip; Starting canary analysis forjx-production-myapp.jx-production 5. 22m \u0026hellip; Advance jx-production-myapp.jx-production canary weight 10 6. 21m \u0026hellip; Advance jx-production-myapp.jx-production canary weight 20 7. 20m \u0026hellip; Advance jx-production-myapp.jx-production canary weight 30 8. 19m \u0026hellip; Advance jx-production-myapp.jx-production canary weight 40 9. 18m \u0026hellip; Advance jx-production-myapp.jx-production canary weight 50 10. 18m \u0026hellip; Copying jx-production-myapp.jx-production template spec to jx-production-myapp-primary.jx-production 11. 17m \u0026hellip; Promotion completed! Scaling down jx-production-myapp.jx-production\n仪表盘 为了可视化的目的,Flagger 包含一个 Grafana 面板,尽管它在金丝雀发布中不需要。 可以在本地通过 Kubernetes 端口转发访问它。\n然后使用 admin/admin 访问 http://localhost:3000/,选择 canary-analysis 面板以及 - namespace 选择 jx-production - primary 选择 jx-production-myapp-primary - canary 选择 jx-production-myapp\n它将为我们提供当前版本和新版本的对比视图,视图中包含不同指标(CPU,内存,请求持续时间,响应错误……)。\n附加说明 请注意 Istio 默认地将阻止从你的 Pod 访问外部集群(一种预计将在 Istio 1.1 中发生变化的行为)。 学习如何控制 Istio ingress 流量。\n如果因为指标失败出现自动回滚,生产环境的 Jenkins X GitOps 仓库会过时,仍然使用新版本而不是旧版本。 这是计划在即将发布的版本中修复的内容。\n", "auhtor": "Carlos Sanchez", "translator": "donhui", "original": "https://dzone.com/articles/progressive-delivery-with-jenkins-x-automatic-cana", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-28-devsecops/", "title": "我们为什么需要 DevSecOps 和制品仓库?", "type": "wechat", "date": "2019-04-28 00:00:00 +0000 UTC", "tags": ["security", "devops"], "description": "Helen Beal 在 Nexus 用户大会上发表的关于构建 DevSecOps 的建议", "content": "Helen Beal 曾经在一次讨论什么是 DevSecOps 工程师的会议上发言。令她惊讶的是,在与会人员中,许多人都没有将安全机制引入 DevOps。在与人们讨论之后,她将大家的问题总结为三类:安全机制会制造额外的隔阂;组织中的人很难理解 DevOps,因此安全机制可能会造成更多困惑;可能没有为安全机制预留空间。\n当然,Helen 不同意这些观点。她在技术领域从业近20年,专注于软件开发生命周期,对于 DevOps 和DevSecOps 有一些自己的理解。她自称为 Ranger4 的 「DevOpsologist」,因为她帮助那里的组织实现 DevOps。她在世界各地分享知识,并且她将参加我们在 2018 年的 Nexus User Conference ,讨论工具仓库及其在 DevSecOps 工具链中的角色。\n从高层次来看,Helen 为 DevSecOps 提出了一些重要建议:\n 确保安全是每一个人的职责 认识到安全人员的匹配限制。平均而言,人员比例为 100 名开发人员 : 10 名运维人员 : 1名安全人员 尽早移交产品进行测试和验证。缺乏足够的安全人员会造成一定的约束,移交并自动执行任务可以减少瓶颈并提前解决问题。 积极主动地降低风险 培养安全文化 Helen 花了一些时间阐述如何培养安全文化,组织在维护系统和人员行为安全时可以采用的一些关键原则和行动。\n行为安全使个人和团队能够以安全的方式行事。为了培养行为安全,她建议:\n 让人们意识到,失败是一个学习机会 确保团队之间有共同的责任和目标 不要吝啬花时间做实验 使用可协作的平台来分享学习经验和最佳实践 对实验的过程进行回顾,并确保有后续 她提到了几个真实的例子,例如 Esty,LEGO 还有 P\u0026amp;G 的「失败奖励」以及 Spotify 用来展示和追踪失败的「失败墙」。\n系统安全能够保障你的基础设施安全,她关于培养系统安全的建议包括:\n 用持续集成进行构建 使用部署自动化来驱动一致性和可审计性,并允许即时重新部署上一个已知的可用版本 用 ChatOps 来归类问题和事件 使用应用程序性能管理以提早发现问题并警告 降低出现问题波及范围,例如使用功能开关,金丝雀测试,蓝/绿环境和微服务 将产品需求与服务台相结合 养成使用混沌工程来找到失败原因的习惯 在讲述 DevSecOps 案例并说明如何灌输安全文化后,她将话题转向如何使用制品仓库。 毕竟,这是一个 Nexus 会议,制品仓库是 Nexus 的特色。\n她引用了 Manfred Moser 的话:「开发软件中没有制品仓库和制造业中没有仓库是一样的。」你不会奢望在没有仓库的情况下开办工厂,软件开发也一样。制品仓库保存了你每次构建的结果,并且确保你拥有可用的构建。\n制品仓库位于 DevOps 工具链的集成阶段,尽管其在构思阶段可被用来表示你想使用的工具是可用状态。\n如果没有开源策略,你就不应该使用制品仓库。制品仓库会自动执行你的开源策略,这样就不会像 35% 的组织一样有开源策略但忽略它。\nHelen 利用 Nexus Lifecycle 来告诉开发人员如何更好地使用制品,降低风险,并协助运维和安全部门确保使用了正确的软件。\n最重要的是,如果你还没有用上 DevSecOps ,那你应该尽早启用。这是未来的趋势,它已经渡过了发展期成为了一个成熟的概念,也有成熟的工具来帮助你。这会花一些时间,但一定是值得的。\n如果对 Helen 的整篇演讲感兴趣,可以在 此处 免费观看。\n", "auhtor": "Derek Weeks", "translator": "p01son6415", "original": "https://dzone.com/articles/why-you-need-devsecops-and-artifact-repositories", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-26-progressive-delivery-with-jenkins-x/", "title": "使用 Jenkins X 渐进式交付", "type": "wechat", "date": "2019-04-26 00:00:00 +0000 UTC", "tags": ["progressive delivery", "kubernetes", "k8s", "jenkins", "jenkins x", "shipper", "istio", "flagger"], "description": "使用 Jenkins X 渐进式交付", "content": " 这是渐进式交付系列的第二篇文章,第一篇请看:Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署。\n我使用的我的 Croc Hunter 示例项目评估了 Jenkins X 中金丝雀部署和蓝绿色部署的三种渐进式交付方案。 - Shipper 为 Jenkins X 构建的 Helm 图表启用了蓝绿部署和多集群部署,但是对图表的内容有限制。 你可以在 staging 和生产环境之间做蓝绿部署。 - Istio 允许通过创建一个虚拟服务将一定比例的流量发送到 staging 或预览环境。 - Flagger 构建在 Istio 之上,并添加了金丝雀部署,可以根据指标自动进行滚动部署和回滚。 Jenkins X 可以通过创建一个 Canary 对象自动启用金丝雀功能,从而实现优雅的滚动部署,以升级到生产环境。\n这里可以查看 Shipper、Isito 和 Flager 的示例代码。\nShipper 由于 Shipper 对创建的 Helm 图表有多个限制,因此我必须对应用做一些更改。 而且 Jenkins X 只从 master 分支构建 Helm 包,所以我们不能做 PRs 的滚动部署,只能对 master 分支做滚动部署。\n应用标签不能包含发布名称,例如: app: {{ template “fullname” . }} 不起作用, 需要一些类似这样的标签: app: {{ .Values.appLabel }}。\n由 Jenkins X 生成的图表导致应用滚动失败,归因于生成的 templates/release.yaml 可能和 jenkins.io/releases CRD 冲突。\nChart croc-hunter-jenkinsx-0.0.58 failed to render: could not decode manifest: no kind \u0026quot;Release\u0026quot; is registered for version \u0026quot;jenkins.io/v1\u0026quot; 我们只需要将 jx step changelog 更改为 jx step changelog -generate-yaml =false ,这样就不会生成文件。\n在多集群环境,需要在 shipper 应用 yaml 中为 chartmuseum 和 docker registry 使用公开的 url,以便其他集群可以发现管理集群服务来下载图表。\nIstio 我们可以创建这个虚拟服务, 将所有进入 Ingress 网关的主机为 croc-hunter.istio.example.org 的请求的 1% 的流量发送到 Jenkins X 预览环境( PR 号为 35 )。\napiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: croc-hunter-jenkinsx namespace: jx-production spec: gateways: - public-gateway.istio-system.svc.cluster.local - mesh hosts: - croc-hunter.istio.example.com http: - route: - destination: host: croc-hunter-jenkinsx.jx-production.svc.cluster.local port: number: 80 weight: 99 - destination: host: croc-hunter-jenkinsx.jx-carlossg-croc-hunter-jenkinsx-serverless-pr-35.svc.cluster.local port: number: 80 Flagger 我们可以为 Jenkins X 在 jx-production 命名空间中部署的图表创建一个 Canary 对象, 所有新的 Jenkins X 对 jx-production 的 promotions 每次将自动滚动 10% , 如果出现任何失败,将自动回滚。\napiVersion: flagger.app/v1alpha2 kind: Canary metadata: # canary name must match deployment name name: jx-production-croc-hunter-jenkinsx namespace: jx-production spec: # deployment reference targetRef: apiVersion: apps/v1 kind: Deployment name: jx-production-croc-hunter-jenkinsx # HPA reference (optional) # autoscalerRef: # apiVersion: autoscaling/v2beta1 # kind: HorizontalPodAutoscaler # name: jx-production-croc-hunter-jenkinsx # the maximum time in seconds for the canary deployment # to make progress before it is rollback (default 600s) progressDeadlineSeconds: 60 service: # container port port: 8080 # Istio gateways (optional) gateways: - public-gateway.istio-system.svc.cluster.local # Istio virtual service host names (optional) hosts: - croc-hunter.istio.example.com canaryAnalysis: # schedule interval (default 60s) interval: 15s # max number of failed metric checks before rollback threshold: 5 # max traffic percentage routed to canary # percentage (0-100) maxWeight: 50 # canary increment step # percentage (0-100) stepWeight: 10 metrics: - name: istio_requests_total # minimum req success rate (non 5xx responses) # percentage (0-100) threshold: 99 interval: 1m - name: istio_request_duration_seconds_bucket # maximum req duration P99 # milliseconds threshold: 500 interval: 30s ", "auhtor": "Carlos Sanchez", "translator": "donhui", "original": "https://blog.csanchez.org/2019/01/24/progressive-delivery-with-jenkins-x/", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-25-jenkins-ansible-nginx/", "title": "使用 Jenkins + Ansible 实现自动化部署 Nginx", "type": "wechat", "date": "2019-04-25 00:00:00 +0000 UTC", "tags": ["jenkins", "ansible", "nginx"], "description": "使用 Jenkins + Ansible 实现自动化部署 Nginx", "content": " 本文介绍如何使用 Jenkins + Ansible 实现对 Nginx 的自动化部署。最终达到的效果有如下几点: 1. 只要你将 Nginx 的配置推送到 GitHub 中,Jenkins 就会自动执行部署,然后目标服务器的 Nginx 配置自动生效。这个过程是幂等(idempotent)的,只要代码不变,执行多少遍,最终效果不变。 2. 如果目标机器没有安装 Nginx,则会自动安装 Nginx。 3. 自动设置服务器防火墙规则。\n1. 实验环境介绍 本次实验使用 Docker Compose 搭建 Jenkins 及 Jenkins agent。使用 Vagrant 启动一台虚拟机,用于部署 Nginx。使用 Vagrant 是可选的,读者可以使用 VirtualBox 启动一个虚拟机。使用 Vagrant 完全是为了自动化搭建实验环境。\n以下是整个实验环境的架构图: 注意,图中的 5123 \u0026lt;-\u0026gt; 80 代表将宿主机的 5123 端口请求转发到虚拟机中的 80 端口。\n 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 agent bash docker-compose up -d 通过 http://localhost:8080 访问 Jenkins master,如果出现“解锁密码”页面,如下图,则执行命令 docker-compose logs jenkins 查看 Jenkins master 启动日志。将日志中的解锁密码输入到表单中。然后就一步步按提示安装即可。 安装 Jenkins 插件 本次实验需要安装以下插件: Pipeline 2.6:https://plugins.jenkins.io/workflow-aggregator Swarm 3.15:https://plugins.jenkins.io/swarm 用于 实现 Jenkins master 与 Jenkins agent 自动连接 Git 3.9.3:https://plugins.jenkins.io/git 配置 Jenkins master 不执行任务 进入页面:http://localhost:8080/computer/(master)/configure,如下图所示设置: 确认 Jenkins 安全配置有打开端口,以供 Jenkins agent 连接。 我们设置 Jenkins master 开放的端口,端口可以是固定的 50000 ,也可以设置为随机。设置链接:http://localhost:8080/configureSecurity/。 启动目标机器,用于部署 Nginx 在命令行中执行以下命令:\nvagrant up 注意,Vagrantfile 文件中的 config.vm.box 值必须改成你的 vagrant box 。\n 至此,实验环境已经搭建好了。接下来就可以新建 Jenkins 任务了。\n3. 在 Jenkins 上创建部署任务 新建流水线任务 配置流水线 配置 Jenkins 任务从远程仓库拉取 Jenkinsfile,如下图所示: 除此之外,不需要其它配置了,是不是很简单?\n4. 手工触发一次自动化构建 点击“立即构建”: 最终执行日志如下: 至此,部署已经完成。以后修改 Nginx 的配置,只需要修改代码,然后推送到远程仓库,就会自动化部署。不需要手工登录到目标机器手工修改了。\n最后,我们可以通过访问 http://localhost:5123,如果出现如下页面说明部署成功:\n5. 代码讲解 以上步骤并不能看出自动化部署真正做了什么。那是因为我们所有的逻辑都写在代码中。是的,可以说是 everything is code。\n接下来我们介绍代码仓库。\n% tree -L 2 ├── JenkinsSlaveAnsibleDockerfile # Jenkins agent 镜像 Dockerfile ├── Jenkinsfile # 流水线逻辑 ├── README.md ├── Vagrantfile # Vagrant 虚拟机定义文件 ├── docker-compose.yml # Jenkins 实现环境 ├── env-conf # 所有应用配置 │ └── dev # dev 环境的配置 ├── deploy # Ansible 部署脚本所在文件夹 │ ├── playbook.yaml │ └── roles └── swarm-client.sh # Jenkins swarm 插件的客户端 5.1流水线逻辑 Jenkinsfile 文件用于描述整条流水线的逻辑。代码如下:\npipeline{ // 任务执行在具有 ansible 标签的 agent 上 agent { label \u0026quot;ansible\u0026quot;} environment{ // 设置 Ansible 不检查 HOST_KEY ANSIBLE_HOST_KEY_CHECKING = false } triggers { pollSCM('H/1 * * * *') } stages{ stage(\u0026quot;deploy nginx\u0026quot;){ steps{ sh \u0026quot;ansible-playbook -i env-conf/dev deploy/playbook.yaml\u0026quot; } }}} environment 部分:用于定义流水线执行过程中的环境变量。 triggers 部分:用于定义流水线的触发机制。pollSCM 定义了每分钟判断一次代码是否有变化,如果有变化则自动执行流水线。 agent 部分:用于定义整条流水线的执行环境。 stages 部分:流水线的所有阶段,都被定义在这部分。 以上只是定义流水线是如何执行的,目前整条流水线只有一个 deploy nginx 阶段,并且只执行了一条 ansible-playbook 命令。但是它并没有告诉我们部署逻辑是怎么样的。\n5.2 部署逻辑 所有的部署逻辑,包括 Nginx 的安装启动、配置的更新以及加载,都放在 Ansible 脚本中。对 Ansible 不熟的同学,可以在本文末尾找到介绍 Ansible 的文章。\n整个部署逻辑的入口在 deploy/playbook.yaml,代码如下:\n--- - hosts: \u0026quot;nginx\u0026quot; become: true roles: # Nginx 的部署 - ansible-role-nginx # 对防火墙的设置 - ansible-role-firewall hosts:定义了 playbook 部署的目标主机分组名为 nginx。 roles:包含了两个执行具体部署动作的 role,至于 role 内部逻辑,不在本文讨论范围,有兴趣的同学阅读源码。 5.3 配置管理 谈到部署,就不得不谈配置管理。\n回顾前文中流水线中执行的 shell 命令:ansible-playbook -i env-conf/dev deploy/playbook.yaml 我们通过 -i 参数指定部署时所使用的环境配置。通过这种方式实现环境配置与执行脚本的分离。这样带来以下几个好处: 1. 新增环境时,只需要复制现有的环境,然后将里面的变量的值改成新环境的即可。比如,要对测试环境进行部署,只需要将 -i 参数值改成:env-conf/test。 2. 对配置版本化控制。\n本次实验中,各个环境的配置放在 env-conf 目录中,目前只有 dev 环境,以下是 env-conf/ 目录结构:\n% cd env-conf/ % tree └── dev ├── group_vars │ └── nginx.yaml ├── host_vars │ └── 192.168.52.10 └── hosts hosts文件:Ansible 中通过“分组”来实现对主机的管理。hosts 文件内容如下: [nginx] 192.168.52.10 host_vars 目录:用于存放主机级别的配置变量,本例中 192.168.52.10 是一个 YAML 格式文件。注意文件名是该主机的 IP。我们在文件中放主机相关的配置,比如 Ansible 连接主机时使用到的用户名和密码。 group_vars 目录:用于存放组级别的配置变量。比如 nginx.yaml 对应的就是 nginx 这个组的的配置变量。文件名与 hosts 中的组名对应。 总结 到此,我们完整的自动化部署已经讲解完成。但是还遗留下一些问题: 1. 本文只是安装了一个“空”的 Nginx,但是没有介绍 Nginx 真正配置。 2. 目前主机的连接信息(SSH 密码)是明文写在 host_vars/192.168.52.10 文件中的,存在安全风险。 3. 没有介绍如何当 Java 应用部署时,如何自动更新 Nginx 的配置。\n本文属于使用 Jenkins + Ansible 实现自动化部署的入门文章,笔者将根据读者的反馈决定是否写续集。\n如果觉得本文讲的 Jenkins 流水线逻辑部分不够过瘾,可以考虑入手一本最近才出版的《Jenkins 2.x实践指南》。长按下图进行扫码购买。\n附录 本次实验环境代码:https://github.com/zacker330/jenkins-ansible-nginx 简单易懂 Ansible 系列 —— 解决了什么:https://showme.codes/2017-06-12/ansible-introduce/ Puppet,Chef,Ansible 的共性:https://showme.codes/2016-01-02/the-nature-of-ansible-puppet-chef/ ", "auhtor": "zacker330", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-24-progressive-delivery-in-kubernetes-blue-green-and-canary-deployments/", "title": "Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署", "type": "wechat", "date": "2019-04-24 00:00:00 +0000 UTC", "tags": ["progressive delivery", "kubernetes", "k8s", "shipper", "istio", "flagger"], "description": "本文介绍 Kubernetes 中与渐进式交付相关的三个有趣的项目:Shipper、Istio 以及 Flagger ", "content": " 渐进式交付是持续交付的下一步, 它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估, 如果不匹配某些关键指标,则进行回滚。\n这里有一些有趣的项目,使得渐进式交付在 Kubernetes 中变得更简单。 我将使用一个 Jenkins X 示例项目 对它们之中的三个进行讨论:Shipper、Istio 以及 Flagger。\nShipper shipper 是来自 booking.com 的一个项目, 它对 Kubernetes 进行了扩展,添加了复杂的部署策略和多集群编排(文档)。 它支持从一个集群到多个集群的部署,允许多区域部署。\nShipper 通过一个 shipperctl 命令行进行安装。 它增加不同集群的配置文件来进行管理。 请注意这个与 GKE 上下文相关的问题。\nShipper 使用 Helm 包来部署,但是它们没有随着 Helm 一起安装,它们不会在 helm list 的输出显示。 同样地,deployments 的版本必须是 apps/v1 , 否则 shipper 将不能编辑 deployment 来添加正确的标签和副本数量。\n使用 shipper 部署都是与从旧版本(现有版本)过渡到新版本(竞争版本)相关。 这是通过创建一个新的应用对象实现的, 它定义了部署需要通过的多个阶段。例如下面 3 个步骤过程: 1. Staging:部署新版本到一个 pod ,没有流量 2. 50 / 50:部署新版本到 50% 的 pods,50% 的流量 3. Full on:部署新版本到全部的 pods,全部的流量\nstrategy: steps: - name: staging capacity: contender: 1 incumbent: 100 traffic: contender: 0 incumbent: 100 - name: 50/50 capacity: contender: 50 incumbent: 50 traffic: contender: 50 incumbent: 50 - name: full on capacity: contender: 100 incumbent: 0 traffic: contender: 100 incumbent: 0 如果发布的某个步骤没有将流量发送到 pods , 则可以使用 kubectl port-forward 访问它们,如:kubectl port-forward mypod 8080:8080, 这对于在用户看到新版本之前进行测试非常有用。\nShipper 支持多集群的概念,但是以相同的方式对待所有集群,仅使用区域并通过 capabilities (配置在集群对象中)进行筛选, 所有对一个应用对象来说,这里没有一个 dev, staging, prod 集群的选项。 但是我们可以有两个应用对象: - myapp-staging 部署到 \u0026ldquo;staging\u0026rdquo; 区域 - myapp 部署到其它区域\n在 GKE 中,你可以轻松地配置多集群 ingress , 该入口将公开在多个集群中运行的服务,并从离你所在位置最近的集群提供服务。\n局限性 Shipper 中的主要的局限性有: - Chart 限制:Chart 必须有一个部署对象。 Deployment 的名称必须使用 {{.Release.Name}} 模板化。 Deployment 对象应该有 apiVersion:apps/v1 。 - 基于 Pod 的流量切换:这里没有细粒度的流量路由,例如:发送 1% 的流量到新版本,它基于正在运行的 Pod 数量。 - 如果 Shipper 不工作了,新的 Pod 将获取不到流量。\nIstio Istio 不是一个部署工具,而是一个服务网格。 然而,它很令人感兴趣,因为它已经变得非常流行,并且允许流量管理,例如,将一定比例的流量发送到不同的服务和其他高级网络。\n在 GKE 中,只需在集群配置中选中复选框即可启用 Istio 。 在其它集群中,可以通过 Helm 手动安装。\n有了 Istio ,我们可以创建一个网关,通过 Ingress 网关处理所有外部流量,并创建虚拟服务来管理到我们服务的路由。 为此,只需找到 ingress 网关的 ip 地址并为其配置通配符 DNS 。 然后创建一个网关,通过 Ingress 网关路由所有外部流量。\napiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: public-gateway namespace: istio-system spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - \u0026quot;*\u0026quot; Isito 不管理应用的生命周期,只管理网络。 我们可以创建一个虚拟服务,为所有进入 ingress 网关的请求 向 pull request 或 master 分支中部署的服务发送 1% 的流量。\napiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: croc-hunter-jenkinsx namespace: jx-production spec: gateways: - public-gateway.istio-system.svc.cluster.local - mesh hosts: - croc-hunter.istio.example.org http: - route: - destination: host: croc-hunter-jenkinsx.jx-production.svc.cluster.local port: number: 80 weight: 99 - destination: host: croc-hunter-jenkinsx.jx-staging.svc.cluster.local port: number: 80 weight: 1 Flagger Flagger 是一个由 Weaveworks 赞助的使用了 Istio 的项目, 该项目使用 Prometheus 的指标进行自动化金丝雀发布和回滚。 它超越了 Isito 提供了基于指标的自动化渐进式发布和回滚。\nFlager 需要将 Istio与 Prometheus、Servicegraph 和某些系统的配置一起安装, 另外还要安装 Flager 控制器本身。 它也提供了一个 Grfana 面板来监控部署进度。\n部署 rollout 通过 Canary 对象定义, 它会生成主要的和金丝雀 Deployment 对象。 编辑 Deployment 时,例如要使用新的镜像版本, Flagger 控制器将负载从 0% 切换到 50% ,每分钟增加 10% ,然后它将切换到新的 deployment 或者如果响应错误和请求持续时间等指标失败则进行回滚。\n比较 此表总结了 Shipper 和 Flagger 在几个渐进式交付特性方面的优势和劣势。\n Shipper Flagger 流量路由 k8s 原生的按 Pods 的百分比进行均衡 基于 Istio 的高级流量路由(请求的百分比) 部署进度 UI 无 Grafana 面板 支持的 Deployments 具有较强限制的 Helm charts 任何 Deployment 多集群部署 是 否 在不同命名空间(如 jx-staging 和 jx-production )的金丝雀部署或蓝绿部署 否 否,但是要做到它可以手动编辑虚拟服务 在不同集群的金丝雀部署或蓝绿部署 是,但是有点极客,使用一个新应用并将它链接到新区域 也许可以使用 Istio 多集群? 自动部署 否,操作者必须手动完成这些步骤 是,每分钟增加 10% 的流量,可配置的 自动回滚 否,操作者必须发现错误并手动完成这些步骤 是,基于 Prometheus 指标 必需品 无 Istio,Prometheus 告警 Slack 综上所述,我看到了 Shipper 在多集群管理和简单性方面的价值,它不需要 Kubernetes 以外的任何东西,但是它有一些严重的局限性。\nFlager 确实在自动部署和回滚以及对流量进行细粒度控制的过程中付出了额外的努力,它以更高的复杂性成本提供了所需的所有额外服务( Isito、Prometheus )。\n这里可以查看 Shipper、Isito 和 Flager 的示例代码。\n", "auhtor": "Carlos Sanchez", "translator": "donhui", "original": "https://blog.csanchez.org/2019/01/22/progressive-delivery-in-kubernetes-blue-green-and-canary-deployments/", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-23-jenkins-master-shared-home/", "title": "关于 Jenkins master 共享 JENKINS_HOME 目录的实验", "type": "wechat", "date": "2019-04-23 00:00:00 +0000 UTC", "tags": ["jenkins"], "description": "你觉得能通过共享 JENKINS_HOME 目录实现 Jenkins master 的高可用吗?", "content": " 审校:王冬辉,linuxsuren\n Jenkins master 的高可用是个老大难的问题。和很多人一样,笔者也想过两个 Jenkins master 共享同一个 JENKINS_HOME 的方案。了解 Jenkins 原理的人,都会觉得这个方案不可行。但是真的不可行吗?\n由于工作原因,笔者需要亲自验证以上猜想。\nJENKINS_HOME 介绍 Jenkins 所有状态数据都存放文件系统的目录中,这个目录被称为 JENKINS_HOME 目录。\n实验环境介绍 笔者通过 Docker compose 启动两个独立的 Jenkins master,分别为 jenkins-a 和 jenkins-b。它们共用同一个 JENKINS_HOME 目录。相应的代码仓库的链接放在文章底部。\n将代码克隆到本地后,进入仓库,执行 docker-compose up -d 即可启动实验环境。启动完成,在浏览器中输入 http://localhost:7088 可访问 jenkins-a,jenkins-b 的地址是 http://localhost:7089 。但是你会发现它们启动后的界面显示是不一样的。\njenkins-b 的界面如下图所示:\n而 jenkins-a 的界面如下图所示:\n这时,将 jenkins-a 日志中的解锁密码(Unlock password)输入到 jenkins-b 的页面中,会得到报错信息:\nERROR: The password entered is incorrect, please check the file for the correct password 这时,再次 jenkins-b 日志中的解锁密码(Unlock password)输入到表单中即可进入下一步。接下来就是按照提示一步步完成了。在 jenkins-b 安装步骤的最后一步,我们设置了管理员的用户名密码:admin/admin。然后就算完成任务了。\n然后我们再在 jenkins-a 使用 admin/admin 进行登录,登录是报错的:用户密码不正确。\n接下来,执行 docker-compose restart jenkins-a 命令重启 jenkins-a。再次使用 admin/admin 就可以登录成功了。\n当两个 Jenkins 启动完成后,接下来开始做实验。\n实验1:创建任务 在 jenkins-a 创建任务 x,刷新 jenkins-b 的页面,jenkins-b 上会不会显示出任务 x ?\n结果:jenkins-b 不会出现任务 x。重启 jenkins-b 后,任务 x 出现在任务列表中。\n实验2:任务结果可见性 jenkins-a 上任务执行,jenkins-b 上能否看到任务执行结果?\njenkins-a 执行任务 x,并且执行成功。刷新 jenkins-b 看不到任何执行记录。重启 jenkins-b 后,可看到执行记录。\n实验3:两 master 同时执行同一任务 分别在两个 Jenkins master 上(几乎)开始同一个任务 x。其中一个任务的 build number 会更新,但是另一个不会。\n其中 jenkins-a 任务 x 的 build number 会升到 2,而 jenkins-b 保持的是 1。这时,单独执行 jenkins-b 的任务 x,日志会出现错误:\njenkins-b_1 | WARNING: A new build could not be created in job x jenkins-b_1 | java.lang.IllegalStateException: JENKINS-23152: /var/jenkins_home/jobs/x/builds/2 already existed; will not overwrite with x #2 实验4:编辑任务 jenkins-a 上设置任务 x 定时执行,刷新 jenkins-b 页面,任务 x 中并没有定时执行的设置。重启 jenkins-b 后,任务 x 更新。\n实验5:定时任务的结果是什么? 如果 jenkins-a 和 jenkins-b 两个任务均为定时任务,而且都生效了。它们运行结果是什么的呢?\n看到的现象是,两个任务都会按时执行,但是只有一个任务能将运行结果写入到磁盘中。界面如下图:\n另,从日志中,可以确认 jenkins-a 和 jenkins-b 确实按时执行了。如下图日志中,看出 jenkins-a 定时执行 #6 次构建时报错,因为 jenkins-b 已经执行过 #6 次构建了:\n小结 可以确认的是,当两个 Jenkins 进程共用同一个 JENKINS_HOME 目录时,其中一个 Jenkins 进程更新了 JENKINS_HOME 的内容,另一个是不会实时更新的。所以,同时启动两个 Jenkins master 共用同一个 JENKINS_HOME 的方案是不可行的。我们不能在 jenkins-a 挂了后,直接将流量切到 jenkins-b。因为 jenkins-b 必须重启。\n最后结论:多个 Jenkins master 共享同一个 JENKINS_HOME 的方案是无法使用 Jenkins master 的高可用。\n附录 Jenkins standby 实验环境:https://github.com/zacker330/jenkins-standby-experiment ", "auhtor": "zacker330", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-22-jenkins-weekly-2.173/", "title": "Jenkins 2.173 发布通知", "type": "wechat", "date": "2019-04-22 00:00:00 +0000 UTC", "tags": ["devops", "ai"], "description": "Jenkins 更新通知", "content": "本次更新移除了一些不太推荐的功能,请管理员及时关注,如果希望能恢复的旧的形态,可以按照下面的提示操作。\n另外,有一项重要的更新,使得我们可以把所有的中文本地化资源文件从 Jenkins 核心中移除。因此, 请关注 Jenkins 简体中文插件后续的动态,我们会及时完成所有的迁移。\n 移除对 CCtray 文件的内置支持。\n如果要继续使用该功能的话,请安装CCtray XML Plugin (issue 40750) 调整代码在远程计算节点上运行时的流刷新行为,使得具有更好的性能。\n这可能导致插件在节点集群上输出日志,但是没有刷新时,丢失消息。\n使用 -Dhudson.util.StreamTaskListener.AUTO_FLUSH=true 恢复自由风格构建之前的行为。注意,流水线的构建总是需要远程刷新。 (pull 3961) 增加用于将新创建的 API token 拷贝到粘贴板的按钮。 (issue 56733) 使得 Jenkins 经典界面上的表单提交按钮,对 Firefox 的 bug 修复是兼容的。 (issue 53462, Firefox bug 1370630) 如果一个工作空间已经被跨节点重连的流水线正在使用,那么,不会提供给新的构建。 (issue 50504) 从核心中移除 Mailer 相关的本地化字符串。确保你使用 Mailer Plugin 1.23。 (issue 55292) 从 Maven 控制台装饰器中适当地刷新输出。 (issue 56995) 开发者:更新 Stapler 1.256 到 1.257,增加对从任意插件中加载本地化 webapp 资源的支持。\n增加接口 jenkins.PluginLocaleDrivenResourceProvider 使得插件可以参与本地化资源的查找。 (JEP-216, 完整的变更日志) 开发者:SystemProperties 可以在计算节点中使用。 参考 SystemProperties#allowOnAgent。 (pull 3961) 开发者:增加 LineTransformationOutputStream#Delegating 使得更加方便。 (pull 3959) 开发者:hudson.util.ssh.SFTPClient 被移除。\n使用库 Trilead SSH 中的 com.trilead.ssh2.jenkins.SFTPClient 作为代替。 (issue 56166) 内部:更新 commons-beanutils 1.8.3 到 1.9.3。 (pull 3948) ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-19-the-business-value-of-cd/", "title": "持续交付的商业价值", "type": "wechat", "date": "2019-04-19 00:00:00 +0000 UTC", "tags": ["cd", "devops", "jenkins"], "description": "了解整体的持续交付如何帮助你的组织以更低的风险更快地交付和更新软件", "content": "持续交付使你能够以更低地风险、更快低交付新软件或是更新已有软件。\n降低风险很重要,但是,支持持续交付的流程将转化为对业务更重要的价值: - 加速价值时间。 一个小企业不需要一个 MBA 就可以认识到持续交付可以帮助他们完成工作。 一家大型企业已经规划了其价值流, 并且在整个大型组织中拥有复杂的投资和合约, 将发现持续交付有助于加速实现价值的时间。 - 数据驱动决策。 部署、度量和调整。 你仍然可以推动更大规模的发布,但你的流程将更适合于持续的数据收集。 这将缩短与客户的反馈循环。 它提高了你的反应能力,计划你的下一步行动,并保持领先的竞争力。 - 质量。 你持续发布的行为使你必须提高你的质量标准以及完全的自动化测试实践。 更好的质量意味着更快乐的客户、更低的成本、更少的消防演习和更少的计划外工作。 - 试验 = 创新。 开发人员和业务线可以自由地以较低的成本尝试新的想法, 从而释放出长期高投资发布周期背后的创新想法。 - 降低成本。 大的发布会有巨大的成本,如果出现错误会有严重的后果。 保持可交付成果处于可发布状态会降低交付成本。\n对企业来说,这些价值一起使持续交付成为真正的游戏变革者。 尽管可以在团队或项目级别开始采用和验证,但持续交付的本质是它以需要真正投资和自上而下承诺的方式跨越了组织边界。 选择与现有投资互补并共存的持续交付工具链是走向成功的关键一步, 特别是因为 CD 可以引导你的组织采用 DevOps 文化。\n持续交付为创建更好的软件开辟了全新的道路。 CD 是商业层面的热门话题,这有很多的原因: - 早期的采用者已经证明了它的价值。 主流采用者都观察到了它的优势,并感觉到竞争的刺痛,因为他们更灵活的竞争对手超过了他们。 - DevOps 作为一种运动获得了关注。 业务人员理解,在开发和运营之间有一个共同的理解,打破孤立的行为,并在整个组织内发展一种责任文化,是提高效率和上市时间的关键步骤。 在许多方面,持续交付等同于 DevOps 。 - 随着软件“吞噬世界”,商业领袖们越来越清楚 IT 必须被用作战略资产。 在正确处理安全性、可用性和合规性的同时,能够缩短交付时间、提高质量并快速适应变化是一项挑战。 持续交付,强调自动化和尽早的、直接的反馈,是实现这些目标的方法。 - 当你通过持续交付实现廉价的、低风险的试验时,你可以用更多的信息指导业务投资,并发现你可能完全错过的机会。\n持续交付正在改变企业使用其 IT 资产与客户和合作伙伴联系的方式。 CD 建立在多年来之不易的敏捷过程和持续集成经验的基础上, 将这些好处提升到业务级别,而不是简单地成为开发团队使用的技术, 并最终导致 DevOps 。 随着开发和运营人员学习如何协作和分担责任时,许多成功的关键都植根于组织和文化的变革。 无论是在组织范围内还是在本地,实现这种变革的技术工具链可能包括 Jenkins 。 CloudBees Jenkins 企业版,通过扩展开源 Jenkins 的使用范围, 提供了一个支持 Jenkins 混合模型(本地部署、云上部署或混合部署)的平台, 是组织在今天转向持续交付和在不久的将来实施 DevOps 的必要工具。\n更多内容请参见白皮书:持续交付的商业价值\n", "auhtor": "Brian Dawson", "translator": "donhui", "original": "https://dzone.com/articles/the-business-value-of-cd", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-17-aiops/", "title": "AIOps:DevOps 的未来", "type": "wechat", "date": "2019-04-17 00:00:00 +0000 UTC", "tags": ["devops", "ai"], "description": "DevOps 将结合人工智能变得更加强大", "content": " DevOps 和云技术正在逼近极限 范式转变往往会产生意想不到的后果,这些后果可能需要数年才能被完全消化。 云计算就是一个很好的例子。 云计算迎来了灵活的基础设施和低资本要求的时代,由于资源只是一个API调用,工程师们无需等待部署。 然而,这一切只是开始。\n敏捷的公司利用云来打破开发和运维之间的隔阂,并采用敏捷方法以缩短开发周期,从而创造战略优势。 他们将应用程序生命周期中的工程师团队分工从之前的开发和测试变为部署和运维, 并创建了需要一系列新技能的职位。这些公司使用 CI/CD 和 DevOps 进一步推动自动化流水线, 以实现更快的交付。\n这样有隐患吗?去问你的 DevOps 团队 DevOps 团队的任务是维护一个工具链,以便自动交付新代码,按需扩展,以及五个 9 的正常运行时间。 在空闲时间,他们致力于提高性能和控制成本。 对于大的应用程序,可以有数千个虚拟机或容器,每个虚拟机或容器都有一堆软件, 还有负载平衡器和自动扩容等云服务,所有这些都必须进行配置和维护。 这一切都在不断发展中。\n我之前了解过的一个大型独角兽公司拥有数百名开发人员,每天更新代码超过 100 次, 云上有超过 4000 台虚拟机,每月收集数 PB 的数据。 而他们的 DevOps 团队只有十几个人手,直到去年才有 VP。 对他们来说,这是一个艰巨且繁重的任务。\n应付这无数的挑战已经超出了人类的能力范围。\n幸好,AIOps 正在成为一种解决方案。\nAIOps 一词是由 Gartner 创造的, 他将其解释为:\nAIOps 结合了大数据,机器学习和可视化技术,通过更强的洞察力来优化 IT 运维。 IT 的领导者应该开始部署 AIOps,以优化当前的性能分析,\n并在未来两到五年内将使用范围扩展到 IT 服务管理和自动化。 虽然 Gartner 创造了这个术语,但以我拙见,这还没达到标准。 他的定义以循环中的人为中心,以他的描述 AIOps 基本上是一种高级的大数据分析。 要解决 DevOps 困境,我们要定一个更高的目标。\n那么,AIOps 应该是什么? 我们先从它不应该是什么开始:一个对现有的运维系统的修饰,软件供应商将\u0026rdquo;以 AI 驱动\u0026rdquo;作为卖点。 这种情况已经发生了,当新的技术威胁到现有利益时,往往会发生这种情况。 仅仅向已有工具添加一个 API 是不够的,如果决策需要人为干预,那就不能算是 AIOps。\n这是一些 AIOps 的关键要求: - AIOps 系统从你的数据中学习并适应应用程序的工作模式 + 这意味着它不会每次都做同样的事情 - AIOps 系统无需人工干预即可制定和实施决策 + 你可以让人参与循环,直到你完全信任这个系统 - AIOps 系统能持续运行 + 它能成为你的交付中的标准单元\n向 AIOps 的过渡正处于起步阶段,但它的热度正在上升,而且已经有了成功案例。 风险投资正在下注,大小软件供应商都正在为市场带来新的解决方案。 从几年前的日志分析系统开始,自动化根本原因分析再到故障预测的出现。 入侵检测系统现在可以从异常流量中学习,有些甚至可以跨公司。 最近,预测自动扩容系统首次亮相。 Optune 和 Opsani 的 AI 系统能够判断虚拟机类型、实例和应用程序参数, 并使用客户现有的 DevOps 工具链和监控系统将它们部署到测试或生产环境中。\nDevOps 正在取代传统的 IT 部门,它的名称被改变,角色职能也发生了变化, 但 IT 部门要解决的挑战并没有消失,它们的规模被乘以了微服务架构的固有规模。 因此,我们需要为这些挑战设计新的系统,AIOps 必须在未来几年内发展, 超越 Gartner 的愿景,使 DevOps 能够应对发展的规模和速度。\n", "auhtor": "Bert Armijo", "translator": "p01son6415", "original": "https://dzone.com/articles/aiops-the-future-of-devops-is-here", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-15-zabbix-monitor-jenkins/", "title": "使用 Zabbix 监控 Jenkins", "type": "wechat", "date": "2019-04-15 00:00:00 +0000 UTC", "tags": ["jenkins", "zabbix"], "description": "介绍了如何使用 Zabbix 监控 Jenkins", "content": " 本文假设读者已经了解 Jenkins 基本概念及插件安装,Zabbix 基础概念。基于 Zabbix 3.4,Jenkins 2.8 做实验\n 笔者最近的工作涉及到使用 Zabbix 监控 Jenkins。在谷歌上搜索到的文章非常少,能操作的就更少了。所以决定写一篇文章介绍如何使用 Zabbix 监控 Jenkins。\n下图为整体架构图:\n整体并不复杂,大体步骤如下:\n 在 Jenkins 上安装 Metrics 插件,使 Jenkins 暴露 metrics api。 配置 Zabbix server 及 agent 以实现监控及告警 为方便读者实验,笔者将自己做实验的代码上传到了 GitHub,链接在文章末尾。使用的是 Docker Compose 技术(方便一次性启动所有的系统)。\n接下来,我们详细介绍 Metrics插件及如何实现 Zabbix 监控 Jenkins。\n1. 使 Jenkins 暴露 metrics api 安装 Metrics 插件,在系统配置中,会多出“Metrics”的配置,如下图: 配置项不复杂。我们需要点击“Generate\u0026hellip;”生成一个 Access Key(生成后,记得要保存)。这个 Key 用于身份校验,后面我们会用到。\n保存后,我们在浏览器中输入URL:http://localhost:8080/metrics/\u0026lt;刚生成的 Access Key\u0026gt; 验证 Jenkins 是否已经暴露 metrics。如果看到如下图,就说明可以进行下一步了。\n1.1 Metrics 插件介绍 Metrics 插件是基于 dropwizard/metrics 实现。它通过4个接口暴露指标数据:/metrics,/ping,/threads,/healthcheck。\n1.2 Metrics 插件:/metrics 接口介绍 点击上图中的metric链接(http://localhost:8080/metrics/\u0026lt;Access Key\u0026gt;/metrics),它暴露了以下指标数据:\n{ version: \u0026quot;3.0.0\u0026quot;, gauges: {...}, counters: {...}, histograms: {...}, meters: {...}, timers: {...} } 从数据结构中可以看出它将指标分成 5 种数据类型: * Gauges:某项指标的瞬时值,例如:当前 Jenkins executor 的总个数(jenkins.executor.count.value) * Counters:某项指标的总数值,例如:http 请求活动连接数(http.activeRequests) * Meters:一段时间内,某事件的发生概率,例如:Jenkins成功执行的任务每分钟的执行次数(jenkins.runs.success.m1_rate) * Histogram:统计指标的分布情况。例如:Jenkins executor 数量的分布(jenkins.executor.count.history) * Timer:某项指标的持续时间。例如:Jenkins 任务等待时间(jenkins.job.waiting.duration)\n由于指标非常之多,我们就不分别介绍了。具体有哪些指标,读者朋友可以从代码仓库中的 metrics.json 文件了解。\n1.2 Metrics 插件其它接口介绍 /ping:接口返回 pong 代表 Jenkins 存活,如下图: /threads:返回 Jenkins 的线程信息 /healthcheck:返回以下指标: { disk-space: { healthy: true }, plugins: { healthy: true, message: \u0026quot;No failed plugins\u0026quot; }, temporary-space: { healthy: true }, thread-deadlock: { healthy: true } } 2. 配置 Zabbix server 与 agent 实现监控及告警 Zabbix server 通过与 Zabbix agent 进行通信实现数据的采集。而 Zabbix agent 又分为被动和主动两种模式。我们使用的是被动模式,也就是Zabbix server 向 agent 索要数据。\n所以,我们需要在 Zabbix agent 所在机器放一个获取 Jenkins 指标数据的脚本。再配置 Zabbix server 定时从该 agent 获取数据,最后配置触发器(trigger)实现告警。\n接下来的关于 Zabbix 的配置,基于我的 jenkins-zabbix 实验环境,读者朋友需要根据自己的实际情况变更。\n2.1 配置 Zabbix server 如何从 agent 获取指标数据 首先,我们需要告诉 Zabbix server 要与哪些 Zabbix agent 通信。所以,第一步是创建主机,如下图: 第二步,在主机列表中点击“Iterms”进行该主机的监控项设置: 第三步,进入创建监控项页面: 第四步,创建监控项: 这里需要解释其中几个选项为什么要那样填: * Type:是 Zabbix server 采集指标的类型,我们选择的是 Zabbix agent,如上文所说。 * Key:由于我们要监控的指标并不是 Zabbix 预定义的。所以,需要使用用户自定义参数来实现监控 Jenkins 指标。Key 填的值为:jenkins.metrics[gauges.jenkins.node.count.value.value]。jenkins.metrics是需要执行的真正的 Key 名称。而 [] 内是传给该 Key 对应的命令的参数。对于初学者,Zabbix 这部分概念非常不好理解。也许这样会更好理解:在使用用户自定义参数来实现监控的情况下,Zabbix server 会将这个 Key 发送给 agent,然后 agent 根据这个 Key 执行指定的 逻辑 以获取指标数据。这个 逻辑 通常是一段脚本(shell命令或Python脚本等)。而脚本也是可以传参的,[]中的值就是传给脚本的参数。具体更多细节,下文会继续介绍。 * Type of information:监控数据的数据类型,由于我们监控的是 Jenkins node 节点的个数,所以,使用数字整型。 * Update interval:指 Zabbix server 多长时间向 agent 获取一次数据,为方便实验,我们设置为 2s。\n到此,Zabbix server 端已经配置完成。\n2.2 配置 Zabbix agent 使其有能力从 Jenkins 获取指标数据 当 Zabbix agent 接收到 server 端的请求,如 jenkins.metrics[gauges.jenkins.node.count.value.value]。Zabbix agent 会读取自己的配置(agent 启动时会配置),配置内容如下:\n## Zabbix Agent Configuration File for Jenkins Master UserParameter=jenkins.metrics[*], python /usr/lib/zabbix/externalscripts/jenkins.metrics.py $1 根据 Key 名称(jenkins.metrics)找到相应的命令,即:python /usr/lib/zabbix/externalscripts/jenkins.metrics.py $1。并执行它,同时将参数 gauges.jenkins.node.count.value.value 传入到脚本 jenkins.metrics.py 中。jenkins.metrics.py 需要我们在 Jenkins agent 启动前放到 /usr/lib/zabbix/externalscripts/ 目录下。\njenkins.metrics.py 的源码在 jenkins-zabbix 实验环境中可以找到,篇幅有限,这里就简单介绍一下其中的逻辑。\njenkins.metrics.py 所做的事情,无非就是从 Jenkins master 的 metrics api 获取指标数据。但是由于 api 返回的是 JSON 结构,并不是 Zabbix server 所需要的格式。所以,jenkins.metrics.py 还做了一件事情,就是将 JSON 数据进行扁平化,比如原来的数据为:{\u0026quot;gauges\u0026quot;:{\u0026quot;jenkins.node.count.value\u0026quot;: { \u0026quot;value\u0026quot;: 1 }}} 扁平化后变成: gauges.jenkins.node.count.value.value=1。\n如果 jenkins.metrics.py 脚本没有接收参数的执行,它将一次性返回所有的指标如:\n...... histograms.vm.memory.pools.Metaspace.used.window.15m.stddev=0.0 histograms.vm.file.descriptor.ratio.x100.window.5m.p75=0.0 histograms.vm.memory.pools.PS-Old-Gen.used.window.5m.count=4165 gauges.vm.runnable.count.value=10 timers.jenkins.task.waiting.duration.mean=0.0 histograms.vm.memory.non-heap.committed.history.p99=123797504.0 gauges.vm.memory.pools.PS-Eden-Space.used.value=19010928 gauges.jenkins.node.count.value.value=1 histograms.vm.memory.pools.Code-Cache.used.window.15m.mean=44375961.6 ...... 但是,如果接收到具体参数,如 gauges.jenkins.node.count.value.value ,脚本只返回该参数的值。本例中,它将只返回 1。\njenkins.metrics.py 脚本之所以对 JSON 数据进行扁平化,是因为 Zabbix server 一次只拿一个指标的值(这点需要向熟悉 Zabbix 的人求证,笔者从文档中没有找到明确的说明)。\n注意:在 2.1 节中,如果 Key 值设置为:jenkins.metrics,Zabbix server 不会拿 jenkins.metrics.py 返回的所有的指标值自动创建对应的监控项。所以,Key 值必须设置为类似于 jenkins.metrics[gauges.jenkins.node.count.value.value] 这样的值。\n3. 配置 Zabbix server 监控指标,并告警 在经过 2.2 节的配置后,如果 Zabbix server 采集到数据,可通过_Monitoring -\u0026gt; Latest data -\u0026gt; Graph_菜单(如下图),看到图形化的报表:\n图形化的报表: 有了指标数据就可以根据它进行告警了。告警在 Zabbix 中称为触发器(trigger)。如下图,我们创建了一个当 Jenkins node 小于 2 时,就触发告警的触发器:\n至于最终触发器的后续行为是发邮件,还是发短信,属于细节部分,读者朋友可根据自己的情况进行设置。\n小结 在理解了 Zabbix server 与 agent 之间的通信原理的前提下,使用 Zabbix 监控 Jenkins 是不难的。笔者认为难点在于自动化整个过程。上文中,我们创建主机和添加监控项的过程,是手工操作的。虽然 Zabbix 能通过自动发现主机,自动关联模板来自动化上述过程,但是创建”自动化发现主机“和”自动关联动作“依然是手工操作。这不符合”自动化一切“的”追求“。\n最后,如果读者朋友不是历史包袱原因而选择 Zabbix,笔者在这里推荐 Prometheus,一款《Google 运维解密》推荐的开源监控系统。\n附录 Metrics 插件:https://wiki.jenkins.io/display/JENKINS/Metrics+Plugin dropwizard/metrics:https://metrics.dropwizard.io/4.0.0/ Zabbix 监控项类型:https://www.zabbix.com/documentation/3.4/zh/manual/config/items/itemtypes metrics.json: https://github.com/zacker330/jenkins-zabbix/blob/master/metrics.json jenkins-zabbix 实验环境:https://github.com/zacker330/jenkins-zabbix Prometheus:https://prometheus.io/ ", "auhtor": "zacker330", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/social-media/", "title": "社交媒体", "type": "about", "date": "2019-04-12 14:26:05 +0800 +0800", "tags": [], "description": "Jenkins 中文社区的社交媒体", "content": "社区所有的技术、活动类的文章都会同步发布到下面的社交媒体平台上。\n 媒体 方式 负责人 微信公众号 人工 LinuxSuRen 开源中国 人工 donhui 知乎 人工 LinuxSuRen 哔哩哔哩 人工 LinuxSuRen 微博 人工 donhui 领英 人工 LinuxSuRen 思否 SegmentFault 人工 LinuxSuRen CSDN 人工 P01son6415 简书 人工 yJunS 掘金 人工 zacker330 腾讯 云+社区 自动同步 LinuxSuRen 企鹅号 自动同步 LinuxSuRen 百家号 自动同步 LinuxSuRen ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-12-brief-analysis-the-encryption-algorithm-of-the-built-in-jenkins-user-database/", "title": "简析 Jenkins 专有用户数据库加密算法", "type": "wechat", "date": "2019-04-12 00:00:00 +0000 UTC", "tags": ["jenkins"], "description": "本文对 Jenkins 专有用户数据库加密算法进行简要分析", "content": " 认识Jenkins专有用户数据库 Jenkins 访问控制分为:安全域(即认证)与授权策略。\n其中,安全域可以采用三种形式,分别为:Jenkins 专有用户数据库、LDAP、Servlet 容器代理。 在哪里看到加密后的用户密码信息? Jenkins 专有用户的数据信息存放位置:$JENKINS_HOME/users/\n每个用户的相关信息存放在各自的 config.xml 文件中: $JENKINS_HOME/users/$user/config.xml\n在 config.xml 文件中的 passwordHash 节点可以看到用户密码加密后的密文哈希值: 用户密码是用什么算法加密的呢? 那么问题来了,用户密码是用何种加密方式加密的呢?可否通过解密密文得到明文呢?\n在 GitHub 上查看其源码,通过关键字 #jbcrypt 搜索定位到 HudsonPrivateSecurityRealm.java 这个文件。 HudsonPrivateSecurityRealm.java 具体路径是:jenkins/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java\n源码片段如下:\n/** * {@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.checkpw(rawPass,encPass); } }; /** * Combines {@link #JBCRYPT_ENCODER} and {@link #CLASSIC} into one so that we can continue * to accept {@link #CLASSIC} format but new encoding will always done via {@link #JBCRYPT_ENCODER}. */ public static final PasswordEncoder PASSWORD_ENCODER = new PasswordEncoder() { /* CLASSIC encoder outputs \u0026quot;salt:hash\u0026quot; where salt is [a-z]+, so we use unique prefix '#jbcyrpt\u0026quot; to designate JBCRYPT-format hash. '#' is neither in base64 nor hex, which makes it a good choice. */ public String encodePassword(String rawPass, Object salt) throws DataAccessException { return JBCRYPT_HEADER+JBCRYPT_ENCODER.encodePassword(rawPass,salt); } public boolean isPasswordValid(String encPass, String rawPass, Object salt) throws DataAccessException { if (encPass.startsWith(JBCRYPT_HEADER)) return JBCRYPT_ENCODER.isPasswordValid(encPass.substring(JBCRYPT_HEADER.length()),rawPass,salt); else return CLASSIC.isPasswordValid(encPass,rawPass,salt); } private static final String JBCRYPT_HEADER = \u0026quot;#jbcrypt:\u0026quot;; }; 通过分析该源码得知: 1. 明文通过 jbcrypt 算法得到密文 encPass 2. 密文的格式为:salt: encPass,其中以 #jbcrypt 表示 salt 作为数据头\njbcrypt 是什么? jbcrypt 是 bcrypt 加密工具的 java 实现。 它的 API 非常简单,DEMO 如下,在 HudsonPrivateSecurityRealm.java 中可以看到加密和校验时使用了如下 API:\n// Hash a password for the first time String hashed = BCrypt.hashpw(password, BCrypt.gensalt()); // gensalt's log_rounds parameter determines the complexity the work factor is 2**log_rounds, and the default is 10 String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12)); // Check that an unencrypted password matches one that has previously been hashed if (BCrypt.checkpw(candidate, hashed)) System.out.println(\u0026quot;It matches\u0026quot;); else System.out.println(\u0026quot;It does not match\u0026quot;); 经验证,用 jbcrypt 对同一个明文加密后因为 salt 一般不同,加密后的密文一般不同。\nbcrypt 精要概况 bcrypt 是不可逆的加密算法,无法通过解密密文得到明文。 bcrypt 和其他对称或非对称加密方式不同的是,不是直接解密得到明文,也不是二次加密比较密文,而是把明文和存储的密文一块运算得到另一个密文,如果这两个密文相同则验证成功。 总结 综上, Jenkins 专有用户数据库使用了 jbcrypt 加密, jbcrypt 加密是不可逆的,而且对于同一个明文的加密结果一般不同。\n", "auhtor": "donhui", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-10-getting-started-with-docker-for-java-applications/", "title": "Java 应用使用 Docker 的入门指南:建立一个 CI/CD 流水线", "type": "wechat", "date": "2019-04-10 00:00:00 +0000 UTC", "tags": ["cd", "ci", "docker", "jenkins", "pipeline"], "description": "本文是容器化现有 Java 应用以及使用 Jenkins 建立一个端到端部署流水线的指南", "content": " Docker 已经非常出名并且更多的组织正在转向基于 Docker 的应用开发和部署。这里有一个关于如何容器化现有 Java Web 应用以及使用 Jenkins 为它建立一个端到端部署流水线的快速指南。\n为此我使用了非常著名的基于 Spring 的宠物商店应用,它代表了一个很好的示例,因为大多数应用都遵循类似的体系结构。\n步骤 构建宠物商店应用。 运行一次 Sonar 质量检查。 使用该 Web 应用准备 Docker 镜像。 运行容器以及执行集成测试。 如果所有测试成功,推送该镜像到一个 dockerhub 账户。 所有的代码都在这里。\n这里是可用于以上步骤的 Jenkins 流水线代码:\nnode { 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(\u0026quot;ravisankar/ravisankardevops:${env.BUILD_TAG}\u0026quot;,'.') stage 'test image' image.withRun('-p 8888:8888') {springboot -\u0026gt; sh 'while ! httping -qc1 http://localhost:8888/info; do sleep 1; done' git 'https://github.com/RavisankarCts/petclinicacceptance.git' sh 'mvn clean verify' } stage('Results') { junit '**/target/surefire-reports/TEST-*.xml' archive 'target/*.jar' } stage 'push image' image.push() } } 最初的步骤只是检出代码并运行构建。有趣的部分从这个步骤开始,它使用 dockerhub 凭证在 Docker 上下文中运行。\nstep 3 'bake image' docker.withRegistry('https://registry.hub.docker.com','docker-hub-credentials') 这个步骤构建 Docker 镜像。Docker build 命令将 dockerhub 仓库名称和 tag 名称作为一个参数,而构建位置作为另一个参数。\ndef image = docker.build(\u0026quot;dockerhub registry name\u0026quot;:\u0026quot;tag name\u0026quot;,'location of docker file') def image = docker.build(\u0026quot;ravisankar/ravisankardevops:${env.BUILD_TAG}\u0026quot;,'.') 这里使用 Dockerfile 来构建 Docker 镜像。 Dockerfile 的内容如下:\nFROM tomcat:8 ADD target/*.war /usr/local/tomcat/webapps 下一步是运行镜像并执行测试:\nstage 'test image' image.withRun('-p 8888:8888') { springboot -\u0026gt; sh 'while ! httping -qc1 http://localhost:8888/info; do sleep 1; done' git 'https://github.com/RavisankarCts/petclinicacceptance.git' sh 'mvn clean verify' } withRun 步骤用来帮你运行你刚才构建的 Docker 镜像并暴露应用可以暴露的端口。我有另一个测试代码库,它被构建和执行,将对正在运行的镜像运行测试。\n最后一步是推送该镜像到一个 dockerhub registry 或者你的组织建立的任何内部 registry 。\nstage('Results') { junit '**/target/surefire-reports/TEST-*.xml' archive 'target/*.jar' } stage 'push image' image.push() ", "auhtor": "Ravi Sankar", "translator": "donhui", "original": "https://dzone.com/articles/getting-started-with-docker-for-java-applications", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-08-becoming-contributor-intro/", "title": "介绍:成为一名 Jenkins 贡献者的旅程", "type": "wechat", "date": "2019-04-08 00:00:00 +0000 UTC", "tags": ["jenkins", "community", "developer", "contributing", "newcomer"], "description": "如何从零开始成为开源社区贡献者", "content": " 作为一名软件工程师,这些年来在我工作过的不同公司里用到过许多开源软件(包括框架、库、工具等)。 然而,在此之前我从没有以一名贡献者的身份参与过开源项目。\n自从我向 Jenkins 提交第一个简单又滑稽的 commit 已经过去六个月(2018 年 9 月)了, 我也尝试过作出更多贡献。然而总的来说,向开源项目贡献代码是具有挑战的, 特别是像 Jenkins 这样有着很长生命周期的项目,项目中不乏遗留代码和系统知识。 它通常难以入手,也很难想到一个计划来持续贡献使你的付出从长远看来是有意义的。\n对于 Jenkins 社区来说,我在尝试加入社区时所遇到的困难是其它人也有可能会面临的, 因此我决定分享我成为 Jenkins 活跃贡献者的心路历程。\n我计划大概每月发布一篇博文来描述我的这段旅程,我将从简单容易入手的项目开始, 随着时间推移再介绍更加复杂的项目。\n从哪开始 jenkins.io 要成为 Jenkins 的贡献者,首先会看到的就是 jenkins.io, 在顶部导航中\u0026rdquo;社区\u0026rdquo;下拉列表里第一个\u0026rdquo;参与\u0026rdquo;的链接就能将我们带到\u0026rdquo;参与和贡献\u0026rdquo;这个页面。\n在这个页面中列举了我们能够参与 Jenkins 项目和社区的许多方式。尽管它展示了所有可能的选项供读者选择,但一下子看上去令人有些无所适从。\n这个页面被分成了左右两个部分,左边提供了参与社区的方法,右边是向社区贡献的方法。\n参与社区的建议 在“参与和贡献”页面的左侧是有关参与社区的建议,其中包括结交他人、审阅修改或者提供反馈信息。\n这里面最让我困惑的是沟通渠道,里面列出的沟通渠道有 几个邮件列表 还有 IRC 和 Gitter 频道。\n当我第一次尝试参与时,我订阅了许多邮件列表和几个 IRC 和 Gitter 频道,但我很快发现里面有重要的讨论正在进行, 并且活跃的讨论中多数是关于特定的用户或开发者的问题。因此,我不建议你一开始在这上面花太多时间, 除非你是要为其他用户提供帮助(当你是经验丰富的 Jenkins 用户时可能会有这种情况)或者你已经有一个明确的问题需要提问。\n看一看社区成员如何互相帮助是好事,但是对新人来说它的信息量过于庞大。如果你的兴趣在于向 Jenkins 项目作贡献(不管是翻译、文档还是代码), 这些对话不会对你有太大的帮助。\n向社区贡献的建议 在“参与和贡献”页面的右侧有一些关于如何贡献的建议,主要分为:编写代码,翻译,文档和测试。\n在之后的博客中,我将介绍所有的这些贡献类型,以及如何参与的建议包括如何审阅 Pull Requests(PRs)或提供反馈 (反馈问题或者复现其它用户反映过的问题,提供额外信息来帮助维护者复现和修复它们。)\n开源之旅的第一次贡献 当看到「参与和贡献」页面时,我发现我可以帮助改进这个页面的一些内容。本来我打算选择其中一个作为这篇文章的第一个例子,但当我阅读贡献指南时, 我发现了一个更简单的贡献。我认为它可以更好的说明开始贡献社区是多么的简单,于是我决定就用它来当例子。\n网站代码仓库 在「文档」菜单中有一个链接 jenkins.io 的贡献指南, 这个 CONTRIBUTING 文件是大多数开源项目代码仓库的根目录中都会有的常见文件。\n点击链接跳转到 jenkins.io 代码仓库,这个仓库包含了网站的源代码其中也包括这篇文章。 事实上,我首先查看的是贡献指南,以便了解如何为网站做出贡献的相关信息。\n找到一个失效链接 通过阅读贡献指南,我了解了 Awestruct 静态站点生成器,它是用于将代码仓库中的 AsciiDoc 源文件转换为网页的工具。 然而,当我点击链接想查看更多信息时,我发现这个链接失效了——域名已经过期。\n为何不修复它? 这是一个好机会,我用它来向新人展示开始贡献是多么容易。\n创建代码仓库分支 第一步,通常是 fork 代码仓库,并克隆到本地。\n进行修改 下一步就是对相应文件进行修改。我创建了一个新的分支 “alternative-awestruct-link” 并对它作了如下修改:\n确保构建正确并且通过测试 尽管在这次的情况下,我的贡献并不针对网站的实际页面,而是对贡献指南(因此不太可能造成什么破坏),但是最好习惯每个贡献都遵循规范流程, 这样才能确保之后有所改变时构建也能够正常进行。\n如贡献指南所述,要构建此项目,我们只需在代码仓库的根目录中以默认的 “make” 作为 target 来运行构建命令。\n一旦命令执行完成,如果没有出现报错,我们就可以进行下一步:创建 Pull Request\n创建 PR 把我的改动 commit 并 push 到远程库以后,我就需要创建一个 PR 了。 有一个简单的方法,只需单击推送完成后在 git 日志中显示的链接,如果愿意的话也可以通过 GitHub UI 创建 PR; 或者甚至可以使用 GitHub CLI 的 “hub” 来完成它。\n这次我直接点击了链接,它将我跳转到 Github 的创建 PR 页面,我在这个页面上添加描述并创建了 PR。\n当创建这个代码仓库的 PR 后,可以发现有一些检查开始运行。Jenkins 代码仓库配置了 “Jenkins on Jenkins”, 它会为每个代码仓库运行 Jenkinsfile 中描述的相应 CI 流水线。\n检查结束后,可以在 PR 中看到结果:\n如果想看到执行的细节,可以点击 “Show all checks” 链接:\nPR review 现在我们已经创建好了 PR 并通过了自动测试,只需要等待代码 review 了。\n一旦 PR 被审核通过然后被 merge,你的贡献就会被整合到代码仓库的主分支并成为下次版本更新的一部分。\n我已经作出了贡献! 我做的这个贡献是微不足道的,它的复杂性很小,如果你的目标在于为 Jenkins 项目本身贡献代码,它可能看起来不是很有趣。\n然而对于我作为一名贡献者,这是一个熟悉代码库、贡献指南、jenkins.io 网站背后的技术的很好的方式; 并且最重要的是,我开始“放下恐惧”,为 Jenkins 这样的开源项目做出了贡献。\n因此,如果你同我一样,请不要犹豫。来吧,找到你自己的第一个贡献。每一个细节都很重要!\n", "auhtor": "romenrg", "translator": "P01son6415", "original": "https://jenkins.io/blog/2019/03/29/becoming-contributor-intro/", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-03-the-benefits-and-challenges-of-continuous-integration/", "title": "持续集成的收益与挑战", "type": "wechat", "date": "2019-04-03 00:00:00 +0000 UTC", "tags": ["continuous integration", "ci"], "description": "本文介绍了持续集成的定义,并解释了实施CI的各种收益与挑战", "content": " 毫无疑问,持续集成( CI )已成为一个软件开发的主流原则。CI 的收益在业界众所周知的,并且很难找到反对实施它的人。\n在这里,我想把那些收益收集起来放到一个中心化的地方。但是我认为扮演反面角色并试图找出持续集成的弊端或挑战也是很有趣的。\n什么是持续集成? 从根本上说, 持续集成( CI )是一种开发实践,开发人员每天都要将代码集成到共享的仓库中。在该仓库中,代码被自动构建进行验证用来在这个流程中检验尽早的发现任何问题。这允许团队花更少的时间回溯,而花更多的时间构建新特性。\n持续集成的收益 1、缓解风险 据 Martin Fowler 说,持续集成的最大收益是减轻风险。由于延迟了代码集成,团队将不断增加合并冲突的数量和严重性。当团队频繁集成(使用自动构建),他们减轻了潜在风险的数量,因为他们总是知道系统的当前状态。\n2、质量保证 实施持续集成的团队对他们的操作更有信心。他们知道自动构建会立即捕获缺陷,这使他们能够保证质量。 他们也不会猜测系统中 bug 的数量,这允许他们能够向队友提供准确的数量,并为客户提供更好的服务。\n3、提高可见性和加强团队合作 自动构建为团队提供了对其系统的完全可见性。他们知道问题的数量,并能快速的解决问题。提高可见性可以让团队有机会在小问题变成大之前通过协作解决。\n持续集成的挑战 1、组织文化变革 一些企业更喜欢传统的方法,并且可能很难实施持续集成。 他们必须对员工进行再培训,这就意味着要对现有的业务进行大修。管理者可能会抵制因为持续集成并不能帮助他们实现公司的直接目标(例如:金钱在质量之上)。\n2、难以维护 构建一个自动化的代码仓库不是一个简单的任务。 团队必须构建适当的测试套件,并花时间编写测试用例,而不是开发代码。 起初,这可能会让他们放慢速度,让他们对按时完成自己的项目失去信心。如果测试套件不稳定,它可能在某些天内完美地工作,但其他天可能不起作用。 然后团队将不得不花费更多的时间来弄清楚发生了什么。\n3、大量的错误信息 对于较大的开发团队,他们可能每天都会看到 CI 错误消息,并开始忽略它们,因为它们还有其他任务和关注点。 他们可能会开始将一个破坏的构建视为一个正常的事情,并且缺陷可能开始堆积在一起。\n", "auhtor": "Jeffrey Lee", "translator": "donhui", "original": "https://dzone.com/articles/the-benefits-and-the-drawbacks-of-continuous-integ", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/03/2019-03-18-weekly-version/", "title": "Jenkins 更新通知", "type": "wechat", "date": "2019-03-20 00:00:00 +0000 UTC", "tags": ["weekly"], "description": "Jenkins LTS、Weekly 以及简体中文插件更新", "content": " Jenkins LTS 2.164.1 更新内容如下: Java 11 现已全面支持。 自 2.150.x 开始在 Java 11 上运行 Jenkins 的多项改进,包括:支持插件在它们的元数据中申明最小 Java 版本,并拒绝加载不兼容的插件,以及当运行在 Java11 上时安装新的 JAXB 插件后允许使用 JAXB 的 API. (博客发布的申明, 运行在 Java 11, 升级到 Java 11, issue 52012, issue 52282, issue 55076, issue 55048, issue 55980, issue 55681, issue 52285) 当列出一个指定目录时 list-jobs 不再进行递归。 (issue 48220) 增加一个新的 CLI 命令 disable-plugin 来禁用一个或多个已安装的插件,并可以选择同时重启 Jenkins. (issue 27177) 更新 Trilead SSH 库以支持 OpenSSH 使用 AES256-CTR 加密。 (issue 47603, issue 47458, issue 55133, issue 53653) 在 Jenkins CLI 中增加对 ed25519 关键算法的支持。 (issue 45318) 减少以 ZIP 格式下载归档或者工作空间文件时 SECURITY-904 对性能的影响。 (issue 55050) 在插件向导中增加语言分类,并会根据浏览器的语言设置自动安装本地化插件。 (pull 3626) Windows Service Wrapper 从 2.1.2 更新到 2.2.0,Windows Agent Installer 从 1.9.3 更新到 1.10.0,支持禁用、重命名以及归档服务日志。 (pull 3854, Windows Service Wrapper 变更日志, Windows Agent Installer Module 变更日志) SSHD 模块从 2.5 更新到 2.6,当自定义值设置为 org.jenkinsci.main.modules.sshd.SSHD.idle-timeout system property 时,设定一个合适的 Apache Mina 空闲超时时间。 (issue 55978, 全部变更日志) 开发者: 登陆和注册页面在 2.129 中重新设计了,现在可以从多个插件中接收风格贡献 (SimplePageDecorator 的视图页面 footer) (issue 54325) Jenkins 每周版 2.168 更新内容如下: 优化移动端的登陆、加载和重启界面。 通知管理员关于潜在的不安全的权限设置,导致以虚拟系统用户运行构建。 在 Microsoft Docker 中的 Windows Server 2016 上工作空间和归档文件的浏览不可用。(在 2.154 中引入) 开发者: StringParameterValue.getValue() 现在返回 String 以避免不必要的类型转换。 简体中文插件 0.0.14 新增了多条中文词条,更多细节从查看变更日志。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/03/2019-03-20-cdf-launch/", "title": "Jenkins 正在加入持续交付基金会", "type": "wechat", "date": "2019-03-20 00:00:00 +0000 UTC", "tags": ["cdf", "general", "community"], "description": "Jenkins 社区牵头成立 CDF", "content": "今天Linux 基金会与 CloudBees、Google 和一些其他公司启动了一个新的开源软件基金会,也就是持续交付基金会(CDF). CDF 相信持续交付的力量,它旨在培养与支持开源生态,以及厂商中立的项目。\nJenkins 的贡献者们已经决定,我们的项目应该加入这个新的基金会。 实际上,这样的讨论持续了多年,大致的动机简洁摘要在这里。\n此时,作为一名用户,又意味着什么呢?\n 首先,不会有大的中断。还是同样的人,URL 地址不会变,也会有正常的发布。决策方式也会延续,pull request 也不会发生变化。改变会逐步的进行。\n 这是 Jenkins 项目在这个领域的成熟和重要性的又一证明。在全球有25万个 Jenkins 在运行着,这着实从 IoT 到游戏、从云原生应用到机器学习项目撼动着整个软件研发的世界。对于任何寻求开放异构 DevOps 策略的人来说, Jenkins 是一个显然、安全的选择。\n CDF 创建了一个公平竞争的环境,这被组织中的贡献者所熟知,同时也会带来更多的贡献者,让 Jenkins 发展的更好、更快。在过去的几年里, Jenkins 项目正在稳步地增长,更多的结构使之变得清晰起来,CDF 是这一轨迹中的最新一步。\n 任何认真的研发团队都会把多种工具和服务结合起来,以覆盖整个软件研发领域。这些团队为了把这些工具集成起来投入了大量的工作。 Jenkins 将会在 CDF 旗下与其他项目紧密合作,使得这些软件之间减少重复。\n 我们的用户作为从业者尝试在他们的组织中改善软件研发流程。他们认为 CI/CD 和自动化可以释放组织所需要的生产力,但对他们的组织而言,并不总是那么显著。因此,我们的用户往往无法得到必要的支持。CDF 将会倡导持续交付的实践,因为这并不是来自某个厂商或项目,它将会联系可以提供帮助的人。\n 因此,我希望你能明白为什么我们会对此感到如此兴奋!\n实际上,对我们来说,已经为这个想法努力了将近两年。毫不夸张地说,整个 CDF 的想法 源自 Jenkins 项目。\n为此,已经有很多人在幕后做了大量的工作。但有些人扮演了举足轻重的角色,我须亲自感谢他们。为 Chris Aniszczyk 的耐心、坚持,R. Tyler Croy 酝酿并推动着这个想法,Tracy Miranda 将这些想法变成事实。\n", "auhtor": "kohsuke", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/03/2019-03-13-electron-pipeline-demo/", "title": "Electron 应用的流水线设计", "type": "wechat", "date": "2019-03-13 00:00:00 +0000 UTC", "tags": ["Jenkins", "Pipeline", "Electron"], "description": "跨平台构建的流水线 demo", "content": " 审校:LinuxSuRen(https://github.com/LinuxSuRen)\n 面向读者:需要了解 Jenkins 流水线的基本语法。\nElectron 是由 Github 开发,用 HTML,CSS 和 JavaScript 来构建跨平台桌面应用程序的一个开源库。\n本文将介绍 Electron 桌面应用的流水线的设计。\n但是如何介绍呢?倒是个大问题。笔者尝试直接贴代码,在代码注释中讲解。这是一次尝试,希望得到你的反馈。\n完整代码 pipeline { // 我们决定每一个阶段指定 agent,所以, // 流水线的 agent 设置为 none,这样不会占用 agent agent none // 指定整条流水线的环境变量 environment { APP_VERSION = \u0026quot;\u0026quot; APP_NAME = \u0026quot;electron-webpack-quick-start\u0026quot; } stages { stage(\u0026quot;生成版本号\u0026quot;){ agent {label \u0026quot;linux\u0026quot; } steps{ script{ APP_VERSION = generateVersion(\u0026quot;1.0.0\u0026quot;) echo \u0026quot;version is ${APP_VERSION}\u0026quot; }} } stage('并行构建') { // 快速失败,只要其中一个平台构建失败, // 整次构建算失败 failFast true // parallel 闭包内的阶段将并行执行 parallel { stage('Windows平台下构建') { agent {label \u0026quot;windows \u0026amp;\u0026amp; nodejs\u0026quot; } steps { echo \u0026quot;${APP_VERSION}\u0026quot; } } stage('Linux平台下构建') { agent {label \u0026quot;linux \u0026amp;\u0026amp; nodejs\u0026quot; } // 不同平台可能存在不同的环境变量 // environment 支持阶段级的环境变量 environment{ SUFFIX = \u0026quot;tar.xz\u0026quot; APP_PLATFORM = \u0026quot;linux\u0026quot; ARTIFACT_PATH = \u0026quot;dist/${APP_NAME}-${APP_PLATFORM}-${APP_VERSION}.${SUFFIX}\u0026quot; } steps { script{ // Jenkins nodejs 插件提供的 nodejs 包装器 // 包装器内可以执行 npm 命令。 // nodejs10.15.2 是在 Jenkins 的全局工具配置中添加的 NodeJS 安装器 nodejs(nodeJSInstallationName: 'nodejs10.15.2') { // 执行具体的构建命令 sh \u0026quot;npm install yarn\u0026quot; sh \u0026quot;yarn version --new-version ${APP_VERSION}\u0026quot; sh \u0026quot;yarn install\u0026quot; sh \u0026quot;yarn dist --linux deb ${SUFFIX}\u0026quot; // 上传制品 uploadArtifact(\u0026quot;${APP_NAME}\u0026quot;, \u0026quot;${APP_VERSION}\u0026quot;, \u0026quot;${ARTIFACT_PATH}\u0026quot;) }}} // 将括号合并是为了让代码看起来紧凑,提升阅读体验。下同。 } stage('Mac平台下构建') { agent {label \u0026quot;mac \u0026amp;\u0026amp; nodejs\u0026quot; } stages { stage('mac 下阶段1') { steps { echo \u0026quot;staging 1\u0026quot; } } stage('mac 下阶段2') { steps { echo \u0026quot;staging 2\u0026quot; } } } } } } stage(\u0026quot;其它阶段,读者可根据情况自行添加\u0026quot;){ agent {label \u0026quot;linux\u0026quot;} steps{ echo \u0026quot;发布\u0026quot; } } } post { always { cleanWs() } } // 清理工作空间 } def generateVersion(def ver){ def gitCommitId = env.GIT_COMMIT.take(7) return \u0026quot;${ver}-${gitCommitId}.${env.BUILD_NUMBER}\u0026quot; } def uploadArtifact(def appName, def appVersion, def artifactPath){ echo \u0026quot;根据参数将制品上传到制品库中,待测试\u0026quot; } 代码补充说明 因为 Electron 是跨平台的,我们需要将构建过程分别放到 Windows、Linux、Mac 各平台下执行。所以,不同平台的构建任务需要执行在不同的 agent 上。我们通过在 stage 内定义 agent 实现。如在“Mac平台下构建”的阶段中,agent {label \u0026quot;mac \u0026amp;\u0026amp; nodejs\u0026quot; } 指定了只有 label 同时包括了 mac 和 nodejs 的 agent 才能执行构建。\n多平台的构建应该是并行的,以提升流水线的效率。我们通过 parallel 指令实现。\n另外,默认 Electron 应用使用的三段式版本号设计,即 Major.Minor.Patch。但是笔者认为三段式的版本号信息还不够追踪应用与构建之间的关系。笔者希望版本号能反应出构建号和源代码的 commit id。函数 generateVersion 用于生成此类版本号。生成的版本号,看起来类似这样:1.0.0-f7b06d0.28。\n完整源码地址:https://github.com/zacker330/electronjs-pipeline-demo\n小结 上例中,Electron 应用的流水线设计思路,不只是针对 Electron 应用,所有的跨平台应用的流水线都可以参考此思路进行设计。设计思路大概如下:\n 多平台构建并行化。本文只有操作系统的类型这个维度进行了说明。现实中,还需要考虑其它维度,如系统位数(32位、64位)、各操作系统下的各版本。 各平台下的构建只做一次编译打包。并将制品上传到制品库,以方便后续步骤或阶段使用。 全局变量与平台相关变量进行分离。 最后,希望能给读者带来一些启发。\n参考: 持续交付的八大原则:https://blog.csdn.net/tony1130/article/details/6673741 Jenkins nodejs 插件:https://plugins.jenkins.io/nodejs Electron 版本管理:https://electronjs.org/docs/tutorial/electron-versioning#semver ", "auhtor": "zacker330", "translator": "", "original": "https://showme.codes/2019-03-10/electronjs-pipeline-demo/", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/03/2019-03-13-gsoc2019-announcement/", "title": "Jenkins 已经被 Google Summer Of Code 2019 接受!", "type": "wechat", "date": "2019-03-13 00:00:00 +0000 UTC", "tags": ["gsoc", "gsoc2019", "events", "community"], "description": "19年的 Google Summer Of Code 正式起航", "content": " 作为 Jenkins GSoC 管理员团队的代表,我很高兴地宣布 Jenkins 在2019年的 Google Summer of Code上 已经被接受。 今年,我们邀请了学生和导师加入 Jenkins 社区,并一起努力增强 Jenkins 生态圈。\n这里提供一些数字,这是有史以来最大的一次 GSoC,今年共有206个组织参与。并且,希望对 Jenkins 而言也是最大的一年。 我们有25个项目想法,而且有超过30个准导师(不断增多!)。 这已经超过了2016年以及2018年的总和。 有很多的插件,特别兴趣小组以及子项目已经加入了今年的 GSoC.而且,我们已经收到了十几个学生的消息以及第一次贡献,耶!\n下一步? GSoC 已经正式启动,请期待更多的学生在我们的Gitter 频道和邮件列表中联系项目。 在特别兴趣小组和子项目频道中已经有了很多沟通。 我们会努力帮助学生找到他们感兴趣的项目,在这个领域探索,并帮助他们在4月9日的截止日前准备好他们的项目提议。 然后,我们将会继续这个申请,选择项目并分配导师团队。\n所有关于 Jenkins GSoC 的信息都可以在子项目页面上找到。\n我是一个学生。如何申请? 在/projects/gsoc/students[学生的信息]页面中有完整的申请指导。\n我们鼓励感兴趣的学生尽早联系 Jenkins 社区并开始探索项目。所有的项目在对应的页面上都有聊天室与邮件列表。 我们也会为学生组织工作日的会议,在这些会议上你可以见到管理员和导师,并向他们提问。 另外,加入我们的Gitter 频道和邮件列表,以便收到项目中即将到来的事情。\n3月25日开放申请,但你现在就可以准备了!利用这段申请前的时间来讨论并改进你的项目提议。 我们也建议你着手熟悉 Jenkins 并开始探索你的提议的领域。项目的想法包括快速开始的指导,以及有助于初期研究时对新手友好的问题。 如果没有看到任何感兴趣的,你可以提出你自己的项目想法或者 查看由其他参与 GSoC 的组织提出的想法。\n我想要成为一名导师。会不会太晚了? 不晚!我们正在寻找更多的项目想法,以及 Jenkins 的贡献者或用户中对 Jenkins 富有热情并想要指导学生的人。 无须底层经验,导师可以和学生一起研究项目并给出技术指导。 我们尤其对 Java 技术栈方向感兴趣,以及一些新的技术和领域(例如:Kubernetes, IoT, Python, Go 或者其他的)。\n你可以提议一个新项目或者加入已有的。查看博客寻找导师以及导师的信息中的细节。 如果你想要提议一个新项目,那么请在3月11日之前完成,以便学生有时间探索并准备他们的提议。\n今年,导师并不必须要有 Jenkins 开发上的很强的专业知识。目标是指导学生参与到 Jenkins 社区。 如果需要特殊的专业知识,GSoC 组织管理员会帮助寻找顾问。\n重要的日期 3月11日 - 停止新的 GSoC 项目提议 4月9日 - 停止接受学生的申请 5月6日 - 宣布接受了的项目,团队开始社区合作以及编码 8月26日 - 结束编码 9月3日 - 宣布结果 查看 GSoC 时间线了解更多信息。 在 GSoC 期间和之后,我们也会组织 Jenkins 相关的特别活动(例如:在 Jenkins World 上)。\n", "auhtor": "oleg_nenashev", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/03/2019-03-13-ready-for-CDF/", "title": "为 Continuous Delivery Foundation 的成立感到兴奋", "type": "wechat", "date": "2019-03-13 00:00:00 +0000 UTC", "tags": ["cdf", "cicd", "jenkins", "opensource"], "description": "CDF 就要来啦", "content": "大概十一年前,我就开始为现在被称为 Jenkins 的项目做贡献,自己当时其实也并不知道在做什么。但是接下来发生的事情令人感觉难以置信,数以百计的贡献者加入,成千上万的新用户开始使用 Jenkins,每天都会运行数以百万条的流水线。这样的增长是充满挑战性的,用户的增长意味着问题的增长,问题的增长就意味着需要新的解决方式。 在大约两年半之前,我在2017年的 Jenkins World Contributor Summit 大会上面对一大群 Jenkins 的贡献者们,为我的所谓的 \u0026lsquo;Jenkins软件基金会\u0026rsquo; 做了宣传,那就是,不要羞于从 Python 社区汲取思想,在我的朋友 Chris Aniszczyk 和 Linux 基金会的帮助下,这个基金会变成了一个更加全面的 *持续交付基金会*(CDF),我的同事 Tracy Miranda 一直在领导这项工作,帮助推动 CDF 的成立。\nKohsuke 为 jenkinsci-dev@ mailing list 撰写了一篇很好的概述文章,其中列举了如果 Jenkins 项目一旦建立后就应该加入 Continuous Delivery Foundation 的原因。如果你对 Jenkins 项目感兴趣,但是还没有阅读过这边文章的话,那我认为你应该花些时间来阅读 Kohsuke 的这份邮件。但是在 这篇文章 中,我 想分享我愿意帮助建立持续交付基金会(CDF)的原因。\n持续交付(CD)已经成为我职业生涯中不可或缺的一部分,甚至在 Jez Humble 将此概念清晰地表述之前,我就开始学习 CD 并且对它一直充满热情。我认为它对软件的开发实践至关重要,当有人说他们没有练习使用 CI 或 CD 时,我感觉这就像回到了原始社会。想象一下,如果有人说 \u0026ldquo;呃,我们在这里有一个采用 Source Control 的项目,但领导们觉得这个东西不太靠谱\u0026rdquo;,我想你肯定会惊掉下巴。\u0026rdquo;在这个时代竟然还有开发团队都不使用源代码管理?\u0026rdquo;。总体来说,我认为CD已经是现代软件开发的基础了。\n持续交付也 不是 说只依赖于 Jenkins 这样的单一工具,它也是依赖于其他的用于协同工作的许多工具。虽然我可能觉得 Jenkins 是所有工具中占最中心位置的工具,但也不是说 Jenkins 是这些工具中唯一优秀的一款工具。但是不幸的是,像 Jenkins 这样的许多开源社区往往对他们的世界有着一定的狭隘观点。他们只专注于他们的事情,虽然这是有道理的,但这及可能导致错失交叉合作产生新价值的机会。\n我们所依赖 CD 的许多工具现在都是完全支持的,或者一小部分由不同的供应商支持。Jenkins 从 CloudBees、微软和 Red Hat 获得了大量投资。在过去的五年中,我逐渐认识到像 CDF 这样的基金会需要在这些不同公司中保持中立的位置。我们为企业贡献者提供一套指导方针,规则和期望,这样开源项目就会更有可能从他们那里获得支持。无论是宣传,代码或是现金,帮助企业贡献者在与我们其他人在一个相同的中立立场上,都会有助于确保开源工作的长久性。而且基金会制定规则的附加好处是,公司的参与者不会有意或无意地想要去超越对方或某个贡献者。\n在免费和开源项目的早期阶段,我们自欺欺人地认为每个人都会阅读我们的许可证,订阅我们的“开源精神”,提出问题并修复问题,或者为我们贡献代码。但 现实情况是,运营大型开源社区其实需要更多的资源。它不仅需要人,需要基础设施,而且还需要钱。像 CDF 这样的基金会为依赖项目或以其他方式投资项目的组织提供了一种有意义的参与方式。 Jenkins 项目的资金预算很紧张,我们每年的花费大约在10,000-15,000美元之间。如果我们要将我们捐赠的资产,提供的免费服务或我过去十一年来所做的事情都收取报酬的话,那么这个数字每年在60,000-80,000美元之间。 Kohsuke 可以证明我有能力为 Jenkins 项目提供免费的东西,但免费的东西并不是每年都保证会有的。为了更好的发展,Jenkins 需要一个稳定的预算,类似于像 FreeBSD Foundation 这样的大型基金会,这样我们便可以投资于服务和人员。\n如果您发现自己在担心开源的可持续性,那么请查看不同的社区,众筹或其他意识形态工具(如许可变更),并且请允许我帮助您。一致的预算是让大型开源项目可持续发展的重要因素。因为开源项目靠的是 *人*。确保有才能的作家,开发人员,营销人员,测试人员和设计师继续提供支持,就代表着他们雇主必须代表他们投入时间的成本,或者他们需要通过其他方式获得报酬。我坚信开源基金会能够为更大的免费和开源项目发展提供解决 预算 问题的途径。\nCDF虽然尚未启动,但我已经对它的潜力感到兴奋。因为这个基金会不仅适用于Jenkins项目,还适用于整个持续交付领域。\n", "auhtor": "rtyler", "translator": "yuzp1996", "original": "https://brokenco.de/2019/01/31/lets-go-cdf.html", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/03/2019-01-08-mpl-modular-pipeline-library/", "title": "MPL - 模块化的流水线库", "type": "wechat", "date": "2019-03-06 00:00:00 +0000 UTC", "tags": ["jenkins", "pipeline", "shared-library"], "description": "Jenkins 流水线共享库技术实践", "content": " MPL - 模块化的流水线库 尽管通过自动化部署加快了开发速度,但由于在 DevOps 方面缺少协作,我们一个客户正因此而放慢产品的上市时间。虽然他们也投入了资源来做 DevOps ,但每条生产流水线都是独立设置的,迫使团队为每个项目重新造轮子。更糟糕的是,由于没有跨团队协作,平台中的任何错误又会出现在每条新的流水线中。许多客户都有类似的问题存在,因此我们决定开发一个既能帮助现有客户,又能适应未来使用需求的通用工具。使用通用框架且标准化的 CI/CD 平台是最显而易见的选择,但这将导致缺少灵活性的单体结构(monolithic structure),最终会变得举步维艰。每个团队都需要在自己的流水线上工作,基于此,我们开发了一个方便 DevOps 流水线的每个可重用部分可供以后使用的解决方案 — Jenkins 驱动的模块化流水线库。\n解决方案:模块化流水线库 模块化流水线库(译注:modular pipeline library,简称 MPL)是一个高度灵活的 Jenkins 流水线共享库,它可以轻松将最佳实践共享到整个公司。它具有清晰的模块化结构,先进的测试框架,多级嵌套的能力,流水线配置系统,被改进了的错误处理机制以及许多其他有用的组件。\n我们将通过以下几部分内容深入了解并解释 MPL 是如何工作的:\n 探索用于构建 MPL 的技术和工具 回顾MPL,并说明它为何有效 一步一步在流水线样例中使用 MPL 深入研究 MPL 的一些重要的组件,例如测试框架和嵌套库 首先,让我们介绍构建 MPL 时使用到的关键技术。\n使用共享库和 Jenkins 流水线构建 MPL 我们的 Jenkins 自动化平台最近收到了一些 Jenkins 流水线的更新。这些更新允许我们创建一个 Jenkinsfile 文件来描述整条流水线,并用于执行一系列不言自明的脚本。这提高了最终用户对 CI/CD 自动化流程的可视化程度,并提高了 DevOps 团队对流水线的可支持性。\n然而,流水线存在一个很大的问题:很难用唯一的流水线支持多个 Jenkinsfile 文件(因此存在多少个项目就存在多少个 Jenkinsfile 文件)。我们需要一个地方存放公共逻辑,这正是 Jenkins 共享库能够实现的。共享库用于存放流水线公共的部分,它定义在 Jenkinsfile 文件中,并允许在其中使用接口简化自动化脚本。\n虽然共享库允许你存储公共逻辑并操作 Jenkins,但它们并没有提供一种好的方式去使用这些公共逻辑。所以,MPL 通过允许用户创建易于理解的流程描述来优化流水线和共享库,然后方便其他团队使用。\nMPL 致力于创建跨团队协作 DevOps 流程 通过 MPL,我们现在能够跨团队协作和共享 DevOps 实践,轻松地为特定的项目指定特定的流水线,并能在将它们集成到 MPL 库中之前进行调试和测试。每个团队都可以创建一个嵌套库,在其中增加流水线和模块,并在流水线中使用,这样还可以提高流水线的可视化程度。MPL 能够适用于任何包含 Jenkinsfile 文件的项目,还可以根据项目团队的需要灵活地管理它。\nMPL 的核心是提供一种简单的方法:\n 通过引入模块分离流水线和步骤 使用简单的接口描述模块中的步骤 测试所描述的模块并与其他流水线和项目共享结果 MPL 中还有许多其他功能,但本质上它是一个解决 DevOps 一般性协作问题的平台。为了简化开发和手动测试,MPL 提供了模块覆盖和继承模型,允许用户在不影响其他任何情况下测试项目中的特定修复。在 Jenkins 中,一个模块就是一个文件,其中包含脚本步骤和逻辑,以实现简单的目标(构建工件,运行测试,创建图像等)。这些模块在流水线的阶段中可以被组合使用,而且任何了解 Jenkins 流水线语法的人都可以轻松读懂。\nMPL 允许用户使用库的核心特性(结构,模块,管道)并创建嵌套库以满足特定 DevOps 团队的需求。DevOps 团队可以在他们的项目中使用任何自定义的逻辑来组装一条完整的流水线。他们还可以通过多种方式覆盖和继承核心 MPL 模块,或者轻松地与其他团队分享自定义模块。接下来的信息,展示了这些模块的适用范围:\n你还可以在模块中指定某些流水线所需的后续步骤。例如,动态部署模块的执行会创建测试环境,当流水线结束时,它又会销毁该测试环境。想要仔细查看 MPL 调用过程,请查看下图:\n此图显示了 MPL 的执行。首先,你必须创建一个 Jenkins 任务,它将调用 Jenkinsfile(例如,当源代码被更改时),之后 Jenkinsfile 将调用流水线。流水线逻辑可以被定义在这些位置:MPL 端、Jenkins 任务的流水线脚本中 、嵌套库或项目 Jenkinsfile 中。最后,流水线的各个阶段将调用模块,而这些模块所使用的特性,可能来自 groovy 逻辑,流水线步骤或者共享库中的步骤。\n现在我们已经完成对解决方案的概述,接下来,让我们通过一个简单的流水线来了解 MPL 是如何工作的。\n流水线在 MPL 中执行的示例 假设你有一个常规的 Java Maven 项目。你在项目中创建 Jenkinsfile,并希望使用 DevOps 团队准备的默认流水线。MPL 本身就提供一个简单的流水线:核心 MPLPipeline 。这是一个非常简单的流水线,但对于想要尝试 MPL 的人来说,这是一个很好的开端。我们来看一下这个简单的 Jenkinsfile 文件:\n@Library('mpl') _ MPLPipeline {} 这个 Jenkinsfile 文件只包含两行代码,一行加载 MPL 逻辑,另一行运行流水线。大多数的共享库实现了像这样的接口,调用步骤并提供参数。MPLPipeline 只是一个自定义的流水线步骤,因为它位于 vars 目录中。MPLPipeline 结构非常简单,执行步骤如下:\n 初始化 MPL MPL 使用 MPLManager 单例对象来控制流水线 使用默认值合并配置并将其存储 指定阶段所需的默认配置并预定义一些有用的配置 定义一个包含4个阶段和后续步骤的声明式流水线: 检出(Checkout)- 获取项目源代码 构建(Build)- 编译,静态分析,单元测试 部署(Deploy)- 将制品上传到动态环境(dynamic environment)并运行应用程序 测试(Test)- 检查与其他组件的集成 后续步骤(Poststeps)- 清理动态环境,发送通知等 运行已定义的流水线 这是 MPL 开始发挥其魔法并实际运行的地方 MPL 的主要阶段只有一步,即 MPLModule。此步骤包含 MPL 的核心特性:执行包含流水线逻辑的模块。你可以在 MPL 代码仓库中找到默认模块,这些模块位于 resources/com/griddynamics/devops/mpl/modules 目录中,包括:Checkout,Build,Deploy 和 Test 模块。在每个模块的目录中,我们都可以找到真正执行相应阶段逻辑的 Groovy 文件。下图是简化了的 MPL 代码仓库结构图:\n检出阶段启动时,MPLModule 按名称加载模块(默认为阶段名称),并运行 Checkout/Checkout.groovy 文件中的逻辑:\nif( CFG.'git.url' ) MPLModule('Git Checkout', CFG) else MPLModule('Default Checkout', CFG) 如果配置中包含该 git.url 选项,它将加载一个 Git Checkout 模块。否则,它将运行该 Default Checkout 模块。所有被调用的模块使用与父模块相同的配置,这就是 CFG 被传递给 MPLModule 调用的原因。在以上代码中,我们没有指定 git.url 配置,因此它将运行 Checkout/DefaultCheckout.groovy 中的逻辑。模块名称中的空格是将模块映射到特定文件夹的分隔符。\n在 Default Checkout 模块中,只有一行代码 checkout scm,它负责克隆 Jenkins 任务中指定的源代码仓库。这就是检出阶段所做的一切,MPL 对于这么小的阶段似乎有些多余,我们只需要在这里讨论它,以展示 MPL 在模块中的工作方式。\n当流水线运行 Maven Build 模块时,也是同样的运行逻辑:\nwithEnv([\u0026quot;PATH+MAVEN=${tool(CFG.'maven.tool_version' ?: 'Maven 3')}/bin\u0026quot;]) { def settings = CFG.'maven.settings_path' ? \u0026quot;-s '${CFG.'maven.settings_path'}'\u0026quot; : '' sh \u0026quot;\u0026quot;\u0026quot;mvn -B ${settings} -DargLine='-Xmx1024m -XX:MaxPermSize=1024m' clean install\u0026quot;\u0026quot;\u0026quot; } 这个阶段稍微复杂一些,但是操作很简单:我们使用默认名称为 Maven 3 的工具来运行 mvn clean install 命令。这些模块是脚本化的流水线(scripted pipeline),所以你可以执行所有 Jenkins 流水线支持的步骤。这些文件不需要任何特定的和复杂的语法,只需要一个普通的文件,其中包含步骤和 CFG, CFG 是包含了阶段配置的预定义变量。MPL 模块从父模块继承了沙盒(sandbox),因此你的脚本执行将是安全的,并且和一个普通的 Jenkins 流水线一样在 Jenkins 重启后还能生效。\n在 Deploy 文件夹中,Openshift Deploy 模块具有相同的结构。它的主要目的中是为了展示如何在模块中定义后续步骤(poststep):\nMPLPostStep('always') { echo \u0026quot;OpenShift Deploy Decommission poststep\u0026quot; } echo 'Executing Openshift Deploy process' 首先,我们定义了 always 后续步骤。它最终会被存放到 MPLManager 对象中(译注:https://github.com/griddynamics/mpl/blob/master/src/com/griddynamics/devops/mpl/MPLManager.groovy#L40),在真正执行后续步骤时被调用。我们可以多次定义 always MPLPostStep:所有后续步骤都将按先进后出(FILO)顺序存放和执行。因此,我们可以在同一模块中定义需要完成和撤消操作的后续步骤逻辑,例如动态环境的销毁。这样就可以确保在流水线完成时执行操作。\n在部署阶段之后,流水线会执行测试阶段,但是在测试阶段并没有太多有趣的事情发生。然而,测试中有一个非常重要的事情,那就是 MPL 本身的测试。\nMPL 本身的测试 MPL 的测试框架基于 LesFurets 的 JenkinsPipelineUnit,其中一个很小的区别是它能够测试 MPL 模块。测试整个流水线被认为是不现实的,因为流水线可能非常复杂,为这些怪物编写测试就像一项西西弗斯任务(sisyphean task,译注:永无尽头而又徒劳无功的任务)。而使用用少量的步骤测试一个黑盒要容易得多,可以确保任务能正常工作。\n在 MPL 源代码中,你可以找到构建模块的测试用例:所有测试都存放在 test/groovy/com/griddynamics/devops/mpl/modules 目录中,Build/BuildTest.groovy 文件内有多个测试用例。MPL 库的构建阶段会执行这些测试,测试的步骤如下:\nLoading shared library mpl with version snapshot MPLModule.call(Build, {maven={tool_version=Maven 2}}) Build.run() Build.MPLModule(Maven Build, {maven.tool_version=Maven 2}) MavenBuild.run() MavenBuild.tool(Maven 2) MavenBuild.withEnv([PATH+MAVEN=Maven 2_HOME/bin], groovy.lang.Closure) MavenBuild.sh(mvn -B -DargLine='-Xmx1024m -XX:MaxPermSize=1024m' clean install) Build.fileExists(openshift) 测试运行 MPLModule 自定义配置和模拟步骤,以检查在执行期间,工具是否已根据提供的配置更改为 Maven 2。我们使用此类测试覆盖所有测试用例,确保模块按预期工作,并且流水线将正常工作。如果需要,你可以测试整条流水线,但模块测试是简化测试过程的一种方法。\n现在我们已经了解了如何测试 MPL 模块,现在是时候看看 MPL 的一个关键特性,即嵌套库。\n嵌套库的好处 在大型公司中,支持一个大型库是没有意义的。每个部门都需要多个(不同于标准的)配置选项,并针对标准流水线进行调整,这会带来不必要的工作量。MPL 通过引入嵌套库来解决这些问题。下图展示了使用嵌套库与仅仅使用主库的区别:\n嵌套库与共享库相同,都通过导入 MPL 使用其特性,模块和流水线。此外,它允许将一些与团队相关的逻辑与公司的通用逻辑分离。以下是具有嵌套库的 MPL 的结构:\n你可以在重写的流水线中导入 MPL,指定一些附加模块的路径,覆盖模块逻辑,并由 Jenkins 负责协调(译注:此处原文是You can import the MPL in the overridden pipeline, specify the path of some additional modules, override module logic, and use Jenkins power moves: there are no limitations. 本人能力有限,无法真正理解作者的意思)。当另一个团队需要你的模块时,你只需向公司 MPL 基础仓库提交变更请求,如果变更请求通过,就可以与他们共享你的功能模块。\n因为嵌套库可以覆盖 MPL 或 Jenkins 流水线的基本功能,所以嵌套库可以调试和修改 MPL 提供的步骤(例如 MPLModule)和流水线。你可以覆盖任何功能,因为这些覆盖仅影响你自己的流水线。经常验证的嵌套库,可以与其他团队讨论,看看它是否也适用于其他嵌套库。\n嵌套库的嵌套层级数是没有限制的,但我们建议仅使用两层级( MPL 和嵌套库),因为在低层级上配置和测试嵌套库非常复杂。\n强大的模块覆盖 进一步了解嵌套库和项目端模块后,我们知道,模块名称是可以与上层库中模块名同名的。这是覆盖上层模块逻辑的好方法——使用自己的模块替换 Build/Build.groovy——真正执行时就会执行你的模块中的逻辑,而不是上层模块的。下图说明了模块覆盖是如何工作的:\n更棒的是,MPL 的优点之一是你仍然可以使用上层模块!MPL 具有防止循环调用的机制,因此同一运行分支中不会再次运行同一模块。但是,你可以轻松地通过在一个模块中调用原始模块来使用上层逻辑。\n上面的 Petclinic-Selenium 示例中,使用了默认值 MPLPipeline(您可以在 MPL Wiki 页面上找到它),并在 .jenkins 目录中包含项目级别模块。这些模块将在库模块之前调用。例如,Checkout 模块没有放在项目级别,因此它将从 MPL 调用,但 Build 模块存在于 .jenkins 项目端的目录中,它将被调用:\nMPLPostStep('always') { junit 'target/surefire-reports/*.xml' } MPLModule('Build', CFG) if( fileExists('Dockerfile') ) { MPLModule('Docker Build', CFG) } 如代码所示,项目中的 Build 模块注册了后续步骤,接着调用原始的 Build 模块,最后调用 Docker Build 模块。流水线的后续阶段更复杂,但所有模块覆盖基本原理都相同。现实中,有些项目可能很棘手,需要对现有模块进行一些小调整。但是,你可以在项目级别的模块中轻松调整,并考虑如何将功能移动到嵌套库或 MPL 中。\n结论:MPL 为 DevOps 带来了什么 许多 DevOps 团队和公司都使用臃肿,限制多的的和错误的 CI/CD 自动化平台。这增加了用户的学习曲线,导致团队工作更慢,并提高了生产成本。DevOps 团队发现,相同的问题经常在不同的项目中出现,而缺乏协作意味着团队每次都必须单独修复它们。\n但是,通过 MPL,DevOps 团队拥有一个共享、简单、灵活的 CI/CD 平台。可以改善生产过程中的用户支持,协作和整体项目源代码。通过利用 MPL,你的公司可以找到自动化共识,实现跨公司协作的目标,并重用来自大型社区的最佳实践。而且这些都是开源工具。如果你对构建 MPL 感兴趣,请联系我们以了解更多信息!\n其他资源 Jenkins Pipeline Engine Jenkins Shared Libraries MPL GitHub repository 概述和演示视频: 介绍 概述 MPL Build的演示 嵌套库的演示 流水线的演示 ", "auhtor": "sparshev", "translator": "zacker330", "original": "https://jenkins.io/blog/2019/01/08/mpl-modular-pipeline-library/", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/star-plan/", "title": "社区贡献激励方案", "type": "about", "date": "2019-03-03 00:00:00 +0000 UTC", "tags": [], "description": "激励可以让社区活动更有趣", "content": " 为了激励社区成员积极地为社区作出贡献,我们会不定期给予积极活跃、付出重大贡献的小伙伴一定形式的奖励。\n定期激励:每个季度被选中的贡献者,可以在人民邮电出版社微店中自行挑选图书一本。\n大会门票赠送:不定期会有合作社区的大会门票赠送给有需要的贡献者。\n其他激励: 此外,还会有其他形式的激励。\n下面是历次的奖励记录:\n大会门票赠送 不定期会有合作社区的大会门票赠送给有需要的贡献者。\n需要大会门票的成员需要在 GitHub 的 jenkins-zh/jenkins-zh 仓库提交一个 issue 用来申请门票,在该 issue 中需要提供最近贡献的 PR(Pull Request)链接。\n下面的表格中包括所有大会的历次赠票记录:\n 大会 举办时间 成员 奖励 申请链接 Jenkins User Conference China 2019年11月2日 donhui 门票一张 #138 Jenkins User Conference China 2019年11月2日 tomatofrommars 门票一张 #139 社区聚会 日期 城市 成员 备注 2020-1-5 北京 linuxsuren 50元 2020-1-5 北京 donhui 50元 2020-1-5 北京 linan607 50元 2020-1-5 北京 yJunS 50元 论坛帖子 不定期激励 成员 奖励 日期 提供方 anxk 端午礼盒 2020-06 vivo walker0921 端午礼盒 2020-06 vivo 定期激励 每个季度被选中的贡献者,可以在人民邮电出版社微店中自行挑选图书一本。\nNO.3 时间范围:2019年9月~2020年4月\n赞助方:人民邮电出版社\n 成员 奖励 wenjunzhangp 《微服务实战(Dubbox +Spring Boot+Docker)》 zhaoying818 《微服务设计》 0N0thing 《DevOps实践指南》 wst021 《DevOps入门与实践》 walker0921 《Python编程从入门到实践》 NO.2 时间范围:2019年6月~8月\n赞助方:人民邮电出版社\n 成员 奖励 donhui 《人生护城河 如何建立自己真正的优势》 yJunS 《精通 jQuery(第二版)》 linan607 《持续交付 2.0 业务引领的 DevOps 精要》 P01son6415 《算法 第四版》 hummerstudio 《极简主义——风靡欧美的工作与生活理念》 NO.1 时间范围:2019年3月~5月\n赞助方:人民邮电出版社\n 成员 奖励 donhui 《黑客与画家》 zacker330 《基础设施即服务》 yJunS 《黑客与画家》 ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/02/2019-02-27-jenkins-script-console-in-practice/", "title": "批量修改 Jenkins 任务的技巧", "type": "wechat", "date": "2019-02-27 00:00:00 +0000 UTC", "tags": ["Jenkins"], "description": "Jenkins 脚本命令行的一种实践", "content": " 通过脚本命令行批量修改 Jenkins 任务 最近,笔者所在团队的 Jenkins 所在的服务器经常报硬盘空间不足。经查发现很多任务没有设置“丢弃旧的构建”。通知所有的团队检查自己的 Jenkins 任务有没有设置丢弃旧的构建,有些不现实。\n一开始想到的是使用 Jenkins 的 API 来实现批量修改所有的 Jenkins 任务。笔者对这个解决方案不满意,经 Google 发现有同学和我遇到了同样的问题。他使用的更“技巧”的方式:在 Jenkins 脚本命令行中,通过执行 Groovy 代码操作 Jenkins 任务。\n总的来说,就两步:\n 进入菜单:系统管理 \u0026ndash;\u0026gt; 脚本命令行 在输入框中,粘贴如下代码:\nimport jenkins.model.Jenkins import hudson.model.Job import jenkins.model.BuildDiscarderProperty import hudson.tasks.LogRotator // 遍历所有的任务 Jenkins.instance.allItems(Job).each { job -\u0026gt; if ( job.isBuildable() \u0026amp;\u0026amp; job.supportsLogRotator() \u0026amp;\u0026amp; job.getProperty(BuildDiscarderProperty) == null) { println \u0026quot; \\\u0026quot;${job.fullDisplayName}\\\u0026quot; 处理中\u0026quot; job.addProperty(new BuildDiscarderProperty(new LogRotator (2, 10, 2, 10))) println \u0026quot;$job.name 已更新\u0026quot; } } return; /** LogRotator构造参数分别为: daysToKeep: If not -1, history is only kept up to this days. numToKeep: If not -1, only this number of build logs are kept. artifactDaysToKeep: If not -1 nor null, artifacts are only kept up to this days. artifactNumToKeep: If not -1 nor null, only this number of builds have their artifacts kept. **/ 脚本命令行介绍 脚本命令行(Jenkins Script Console),它是 Jenkins 的一个特性,允许你在 Jenkins master 和 Jenkins agent 的运行时环境执行任意的 Groovy 脚本。这意味着,我们可以在脚本命令行中做任何的事情,包括关闭 Jenkins,执行操作系统命令 rm -rf /(所以不能使用 root 用户运行 Jenkins agent)等危险操作。\n除了上文中的,使用界面来执行 Groovy 脚本,还可以通过 Jenkins HTTP API:/script执行。具体操作,请参考 官方文档。\n问题:代码执行完成后,对任务的修改有没有被持久化? 当我们代码job.addProperty(new BuildDiscarderProperty(new LogRotator (2, 10, 2, 10)))执行后,这个修改到底有没有持久化到文件系统中呢(Jenkins 的所有配置默认都持久化在文件系统中)?我们看下 hudson.model.Job 的源码,在addProperty方法背后是有进行持久化的:\npublic void addProperty(JobProperty\u0026lt;? super JobT\u0026gt; jobProp) throws IOException { ((JobProperty)jobProp).setOwner(this); properties.add(jobProp); save(); } 小结 本文章只介绍了批量修改“丢弃旧的构建”的配置,如果还希望修改其它配置,可以参考 hudson.model.Job 源码。\n不得不提醒读者朋友,Jenkins 脚本命令行是一把双刃剑,大家操作前,请考虑清楚影响范围。如果有必要,请提前做好备份。\n", "auhtor": "zacker330", "translator": "", "original": "https://showme.codes/2019-02-23/jenkins-script-console-in-practice/", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/02/2019-02-27-contribution-inspire/", "title": "社区贡献激励活动", "type": "wechat", "date": "2019-02-27 00:00:00 +0000 UTC", "tags": [], "description": "Jenkins 中文社区送福利", "content": "自 Jenkins 官方微信公众号开通以来,收到了很多热心、愿意参与开源社区的同学的贡献。这里,包括有 Jenkins 官方博客中的博文翻译,也有 Jenkins 中文站点维护的 Pull Request。我能够看到的是,有些同学从英文技术文章的翻译过程中,对 Jenkins 相关技术的理解更加深入了;而有的则从对 GitHub 不甚了解到逐渐熟悉社区贡献的大致流程;对于深度参与社区贡献的同学,更是能够在“中文本地化”以及 Jenkins 其他的特别兴趣小组(SIG)会议讨论上获得最新的动态。\n本着给社区贡献者谋福利的想法,Jenkins 中文社区携手“人民邮电出版社”给大家提供三本技术相关的书籍。从19年3月开始,截止到5月,我们会给予三名贡献者每人一本书。我们会在下次公众号文章中介绍评选规则,欢迎任何一位认可开源、希望参与开源的朋友提出你的建议,不要吝惜你的 PR。获选的同学,按照贡献量可以从下面的列表中依次任选一本:\n最后,再次让我们对“人民邮电出版社”给予开源社区的大力支持表示感谢。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/02/2019-02-20-java11-preview-availability/", "title": "Java 11 预览支持已在 Jenkins 2.155+ 中可用", "type": "wechat", "date": "2019-02-20 00:00:00 +0000 UTC", "tags": ["core", "developer", "java11", "community", "platform-sig"], "description": "Java 11 预览支持已在 Jenkins 2.155+ 中可用", "content": " NOTE: 这是由 Java 11 支持团队 联合撰写的博客。 在 12 月 18 号(UTC时间下午4点)我们也会在 Jenkins 在线 Meetup 展示对 Java 11 的预览支持。(链接)\n Jenkins 作为领先的开源自动化服务器之一,目前仍然只支持到 Java 8。在 9 月 25 日 OpenJDK 11 发布了。这是一个长期支持版本,并将持续多年,我们想要在 Jenkins 项目中对这个版本进行全面的支持。在过去的一年中,许多贡献者一直致力于在项目中支持 Java 11(Jenkins JEP-211)。这是一条艰辛的道路,但是现在,代表 Jenkins Platform SIG,我们很高兴的宣布在 Jenkins 每周发布提供 Java 11 预览!\n为什么我们需要 Java 11 的预览?\n这是因为它可以提供给 Jenkins 贡献者和早期使用者一个在明年年初(译者注:此文发布于 2018 年)GA 发布之前尝试这些变化的途径。它也可以帮助我们进行更多的探索性测试,并且有希望在 Jenkins 正式地提供 Java 11 支持之前,解决大部分的问题。\n在这篇文章中,我们将会介绍如何在 Java 11 环境下运行 Jenkins,还有如何调查兼容性问题并报告它们。\n背景 你可能还记得,在 2018 年 6 月我们举办了一个针对 Java 10+ 支持的在线黑客马拉松。作为黑客马拉松的一部分,我们提供了 Java 11 的实验性支持。这次活动对我们来说非常成功。我们可以在 Java 10 和 Java 11-ea 环境下运行 Jenkins 以及一些主要的功能 —— 包括流水线、JobDSL、Docker/Kubernetes plugin、Configuration as Code、BlueOcean 等。它让我们相信我们可以在 Jenkins 中提供Java 11支持而不会发生破坏性变化。在这场马拉松之后 Oleg Nenashev 创建了 \u0026ldquo;Java 10+ support in Jenkins\u0026rdquo;(之后修改为只针对支持 Java 11)。Jenkins Platform SIG 也已成立,以协调 Java 11 的支持工作和其他平台的支持工作(打包,操作系统支持等)。\n一组贡献者一直持续致力于 Java 11 支持,他们主要在关注上游的功能性补丁、在开发工具中提供 Java 11 支持、测试和解决已知的兼容性问题。详细的状态的更新,请参阅 Platform SIG 的会议记录。从 Jenkins 2.148 开始,Jenkins 在多个不同的 Linux 和 Windows 平台下成功的在最新的 OpenJDK 11 版本下运行。我们进行了大量的自动化和探索性测试,除了一些例外(见下文),大部分 Jenkins 插件运行良好。GA 版本发布需要的自动化测试工作还在进行,但是我们已经成功的运行了 Jenkins core 的测试,通过了全部的 Acceptance Test Harness,以及在推荐插件上运行通过了 Plugin Compat Tester。我们也部署了一个临时的为 Java 11 搭建的 Experimental Update Center,可以为 Java 11 的早期采用者提供快速的问题修复。使用Java 11 运行时,Jenkins 2.155+ 将会默认使用此更新中心,这就是我们宣布此版本的预览可用性的原因。\n在 2018 年 11 月 19 日,我们在 Platform SIG 会议的幻灯片上展示了当前的 Java 11 支持的状态,我们同意发布 Java 11 的可用性预览,以便我们可以提供内容让 Jenkins 用户得以进行评估。 在 12 月 4 日的下一次会议上,所有障碍都已得到解决,Platform SIG 会议签署发布了Java 11 预览版。\n在 Docker 中运行 Jenkins 和 Java 11 从 Jenkins 2.155 开始,我们开始为 Jenkins master 和 agent 提供 Docker 镜像。 所有这些镜像都基于官方的由 Docker 社区维护的 openjdk:11-jdk 镜像。这里有一些关于迁移到其他基本镜像的讨论,但是我们决定在预览可用性的范围中将其排除。基于同样的原因,我们目前不提供 Alpine 镜像。\nJenkins master 镜像 官方的 jenkins/jenkins 镜像现在已经提供了 Java 11 的支持。你可以向下面这样简单在 Java 11 的环境中运行 Jenkins。\ndocker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:jdk11 可以使用下面这些标签:\n jdk11 - 最新的包含 Java 11 支持的每周发布 2.155-jdk11 - 包含 Java 11 支持的每周发布= 这些镜像完全和 jenkins/jenkins documentation 兼容。例如:你可以使用 plugins.txt 来安装插件、挂载卷或者通过环境变量传递额外选项。\nAgent 镜像 如果你通过 Docker 或 Kubernetes 插件使用容器化的 agent,我们也发布了 Jenkins agent 的官方 Docker 镜像:\n jenkins/slave jenkins/jnlp-slave jenkins/ssh-slave 所有的镜像都可以使用 latest-jdk11 标签来获取 JDK 11 的捆绑。同时为这些过时的名字抱歉!\n实验性 Jenkins master 镜像 为了简化测试,我们也在 DockerHub 提供了一些实验性的镜像。 对于这些镜像,我们为其搭建好了持续交付流水线,所以不需要等待 Jenkins 的每周发布,就可以获得补丁。\n jenkins4eval/blueocean-platform-support - 等同于 jenkinsci/blueocean 标签: latest-jdk11 这个镜像捆绑了在 Java 11 上运行时需要的所有的 Jenkins 流水线和 Blue Ocean 的补丁 如果你想要使用流水线,使用这个镜像 jenkins/jenkins-experimental - 等同于 jenkins/jenkins 标签: latest-jdk11 这个镜像是从 Jenkins core 的 java11-support 分支中发布的 这个分支可能轻微的领先或落后于 master 分支,我们可能会用这个分支去快速发布补丁给 Java 11 用户 我们最终会把这个实验性流水线移到新的在 jep:217 中创建的 jenkins4eval 组织中去。\n在 Java 11 中运行 jenkins.war 在 Docker 外运行 Jenkins 并没有那么简单。这是因为 Jenkins 依赖一些在 Java 11 中已经被移除的模块。我们计划在 GA 发布中以某种方式解决掉这个问题 (参见 JENKINS-52186),但是现在,我们还需要一些手动操作才能在 Java 11 中运行 Jenkins WAR。\n 下载 2.155 版本的 Jenkins WAR 下载下面这些库到 jenkins.war 所在的目录中去 jaxb-api-2.3.0.jar (保存为 jaxb-api.jar) jaxb-core-2.3.0.1.jar (保存为 jaxb-core.jar) jaxb-impl-2.3.0.1.jar (保存为 jaxb-impl.jar) javax.activation v.1.2.0 (保存为 javax.activation.jar) 运行下列命令 Run Jenkins with ${JAVA11_HOME}/bin/java \\ -p jaxb-api.jar:javax.activation.jar --add-modules java.xml.bind,java.activation \\ -cp jaxb-core.jar:jaxb-impl.jar \\ -jar jenkins.war --enable-future-java --httpPort=8080 --prefix=/jenkins 已知的兼容性问题 为了帮助用户追踪兼容性问题,我们新创建了 Known Java 11 Compatibility Issues wiki 页面。\n几个重要的问题和障碍:\n Pipeline: Support Plugin 有一个已知的在 Java 11 中运行会产生的上下文持久性问题 (JENKINS-51998) 我们已经在 Experimental Update Center for Java 11 中部署了一个临时的修复版本。修复版本号: 3.0-java11-alpha-1。 如果你使用 Jenkins 流水线,请确认你使用了这个版本,否则你的 Job 会几乎立即失败 当你更新实例到 Java 11 时,请确认没有正在运行的流水线。 JENKINS-54305 - JDK Tool Plugin 不提供 JDK 11 的安装器 JENKINS-52282 - Java Web Start 在 Java 11 中已经不再可用, 所以我们不再可能在网页图形界面中启动 agent。我们也没有计划提供一个替代品。 我们也在其它插件中发现了一些次要的不兼容问题,但是我们不认为它们对于预览可用性来说是一个阻碍。\n报告兼容性问题 如果你碰到了任何有关 Java 11 兼容性的问题,请在我们的 bug 跟踪工具中报告问题。并为这类问题添加 java11-compatibility 标签,这样它们会自动出现在 wiki 页面中,并被分级。\n对于安全性问题,请使用标准的 漏洞报告流程。尽管我们在预览发布时,会公开修复 Java 11 相关的问题,但是遵守这个安全流程也会帮助我们调查它对 Java 8 用户的影响。\nJava 11 支持团队 一旦 Java 11 支持发布,我们希望会有插件和 Jenkins core 的回归 (regression)报告。我们关心的部分之一就是不同平台的本地库,还有其它的 Java 的版本的问题。同样,这里也存在第三方库和 Java 11 不兼容的风险。为了减轻这些风险,我们创建了 Java 11 支持团队。这个团队将会专注于对到来的问题进行分级、帮助 review PR、在一些情况下也会修复问题。这个团队的工作流程可在 JEP-211 文档中看到。\n我们不希望 Java 11 支持团队 去修复所有的发现的问题,我们将会和 Jenkins core 和插件的维护者一起解决它们。假如你有兴趣加入这个团队,可以在 Platform SIG Gitter Channel 中联系我们。\n贡献 我们感谢任何一种对 Java 11 支持的贡献, 包括在 Java 11 下运行 Jenkins,报告和解决兼容性问题。\n 假如你想要进行一些探索性测试,我们推荐你在你的其中一个测试实例中尝试 Java 11 支持。我们对这样的测试感激不尽。我们在上面提供了问题报告的准则。 假如你是一个插件的开发者/维护者,我们非常感谢你能在 Java 11 中测试你的插件。为了帮助你,我们创建了 Java 11 Developer guidelines。这个页面阐述了如何在 Java 11 下测试你的插件,同时它也列出了在开发工具中的已知的问题。 无论你做什么,请通过向 Platform SIG mailing list发送邮件告诉我们你的体验。这些信息将帮助我们跟踪变化和贡献。有关迁移复杂性的任何其他反馈将不胜感激!\n下一步是什么? 在 12 月 18 号(UTC时间下午4点)我们也会在 Jenkins 在线 Meetup 展示对 Java 11 预览支持(链接)。在这个 meetup 上我们将会总结目前的 Java 11 预览支持的状态。如果你是插件开发者,我们还将会组织单独的会议讨论有关在 Java 11 下测试插件以及有关修复兼容性问题的常见最佳实践。如果你有兴趣,请关注 Platform SIG 的公告。\n在下一周,我们将会专注于处理来自早期使用者的反馈并且修复一些发现的兼容性问题。我们还将继续为明年的 GA 发布开发 Java 11 支持补丁 (JENKINS-51805)。除此之外,我们将会开始在子项目中提供 Java 11 支持,包括 Jenkins X 和 Jenkins Evergreen。\n", "auhtor": "oleg_nenashev", "translator": "cizezsy", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/02/2019-02-13-outreachy-audit-log-plugin/", "title": "Jenkins 对审计日志的支持", "type": "wechat", "date": "2019-02-13 00:00:00 +0000 UTC", "tags": ["community", "outreachy", "outreachy2018"], "description": "Outreachy 实习生提供了 Jenkins 对审计日志的支持", "content": "今年是 Jenkins 项目首次参与 Outreachy. Outreachy 是一个类似于 Google Summer of Code (GSoC) 的项目, 实习生有偿地为开源项目工作。 关键的不同之处在于,Outreachy 面向那些在他们国家的技术行业中受到歧视或偏见的小众群体。 当我了解到这个项目后,由于它的包容性与社区建设与我的理念相符就立即自愿作为导师来参与。 我很高兴地说,Jenkins 项目和我的雇主 CloudBees 对此非常支持。\n基于我们之前在 GSoC 上指导学生的付出,今年我们已经加入 Outreachy 并指导了两个实习生。 在 Outreachy 的这次活动中,我们的实习生 David Olorundare 和 LathaGunasekar 将与我一起研发 Jenkins 对审计日志的支持。 我很高兴欢迎 David 和 Latha, 并期待他们能在软件工程专业和对开源社区的贡献上都有所收获。 请继续关注后续博客对他们的介绍。\n该审计日志支持项目在 Jenkins 和 Apache Log4j 之间形成了一个新的链接,这给予我们的实习生学习 更多有关开源治理和认识新朋友的机会。 作为奖金,该项目旨在为支持高级的业务检测提供便利,例如:在认证事件中检测潜在的入侵尝试。 我们也会编写一个 JEP 来描述由插件提供的审计日志 API,以及其他插件如何定义并记录除 Jenkins 核心以外插件的审计事件。\n我期待我们将会一起完成了不起的作品,而且我希望在将来能够帮助更多的 Outreachy 实习生!\n", "auhtor": "jvz", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/how-to-involve/", "title": "如何参与", "type": "about", "date": "2019-01-05 22:56:04 +0800 +0800", "tags": [], "description": "参与 Jenkins 中文社区的具体步骤", "content": " 为什么要参与开源社区 翟志军:想亲身参与一个开源社区,了解其运行机制。而为什么选择 Jenkins 中文社区?是想更多人了解持续交付。 zhangc819:日常工作里经常需要开源社区的力量来解决问题、学习经验,参与开源社区建设也是为了给社区提供更多的力量,相互左右才能壮大下去。 如何参与 Jenkins 中文社区 参与 Jenkins 中文社区的方式不只有 Coding 一条路可选,还有很多方式,比如:\n 发表或翻译 Jenkins 相关的文章,并发表到社区网站及微信公众号。 Jenkins 本地化。 成为 Jenkins 线下或线上活动的志愿者。 Review 别人提交到 Pull Request。 发现 Jenkins 社区哪里可以改善,然后提个 Issue 或 Pull Request。 等等。所有你能想到的,促进 Jenkins 中文社区发展的事情都算是参与 Jenkins 中文社区。\n但是,具体怎么做呢?\n首先,我们都是基于 Git 工具进行协作的,所以,你需要会一些 Git 及 GitHub 的基础操作。\n分支策略主要是提供执行并行任务时的参考指引,方便社区贡献者借鉴使用。\n接下来,咱们分别介绍每一种参与方式。\nJenkins 中文社区代码仓库列表 那么,我们可以向哪些源代码仓库进行贡献呢?以下是各仓库的链接及简单介绍:\n wechat:存放 jenkins-zh.cn 网站的文章。也就是发文章可在此仓库提 PR。 jenkins-zh:Jenkins 中文社区网站源码,由 Hugo 实现。 wechat-backend:Jenkins 微信公众号机器人。 hugo-jenkins-theme:Jenkins 中文社区网站主题。 artwork:Jenkins 中文社区的艺术作品,比如 Jenkins 中文社区 Logo。 贡献 Jenkins 中文社区的具体工作 具体有哪些工作,可以让我们参与?\n翻译 Jenkins 相关文章 所有的翻译任务都会列在 GitHub的看板上。可以在看板上找到自己感兴趣的文章,然后将其拖到“In progress”列。这样可以避免重复的翻译。\n当然,为保证翻译质量,希望大家能做到:\n 认真、负责第一位。 翻译任务通常不建议超过两周。 遵守翻译规范。 Jenkins 中文本地化 本地化的工作包括:\n 对 Jenkins 官方网站及 博客 的翻译。Pull Request 提交到: cn.jenkins.io 代码仓库 。 维护 简体中文语言插件 Pull Request 提交到 localization-zh-cn-plugin 。 发表 Jenkins 原创文章 原创内容包括:Jenkins 相关、持续集成、持续交付、DevOps\n在 Jenkins 中文社区提交的 PR 通过后,会发布在多个不同的媒体平台上,目前包括:\n Jenkins 中文社区网站 Jenkins 微信公众号 开源中国博客 简书专栏 掘金 发表原创文章的步骤 Fork wechat 仓库,如果你还没有 fork。 在本地,参考 范文 写文章。动手前请仔细阅读请阅读规范。如果实在不明白的话,你也可以参考其它仓库中 articles 目录下的其它文章来写就好。 将本地的提交,推到自己的仓库。 在 GitHub 上提一个 PR。 关于排期 为了尽可能满足你期望的发布日期,可以自行选择,但同时需要满足如下的条件:\n 为保障大家有足够的时间进行 Review,建议排到一周以后 工作日 避免同一天有相同类型的文章 提 PR 时的要求 PR 的标题格式:[类型-文章排期] 标题 在 PR 类型列表前的 [] 中加入一个 x,例如:[x] 更多内容请参考 PULL_REQUEST_TEMPLATE.md\n分享 你可以在本站或者 Meetup 上分享你在使用 Jenkins 或者相关技术时总结的经验、教训、成果等。\n维护本站点 你可以从了解本站的架构开始。小到错别字修正,大到站点风格、架构完善都需要你的参与。\nReview 别人提交到 Pull Request Review 代码也算贡献社区的一种方式。\nLinus 说过:“Given enough eyeballs, all bugs are shallow(足够多的眼睛,就可让所有问题浮现)”。所以,当有贡献者提 Pull Request 到 Jenkins 中文社区的任何一个代码仓库,原则上,我们都需要两人及以上的人对该 Pull Request 进行 review。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/channels/", "title": "交流", "type": "about", "date": "2019-01-04 21:13:30 +0800 +0800", "tags": [], "description": "Jenkins 中文社区交流指南", "content": " 为了方便各位 Jenkins 的爱好者、用户以及贡献者之间互相交流,我这里列出来一些途径:\n 邮件组 即时聊天 在本站留言 邮件组 Jenkins 社区有很多 邮件组 ,感兴趣的童鞋请自行翻阅。本文仅介绍中文相关的邮件组:\n Jenkins 中文用户邮件组 查看历史 订阅 取消订阅 求助 Jenkins 中文本地化兴趣邮件组 查看历史 订阅 取消订阅 求助 注意:点击上面的订阅或者取消都应该会弹出一个发送邮件的窗口,请不要做任何修改,邮件正文保持空白(不要添加邮件签名等内容)直接发送即可。邮件发送成功后,会收到确认的回复。鉴于邮件组是由 Google 提供的服务,无法科学上网的童鞋是无法查看历史邮件的。\n 即时聊天 即时聊天是一种很方便的线上交流方式,你有可能及时地收到大家的帮助,但是不要认为其他人有回答问题的义务。你没有能及时地得到帮助,可能是因为大家在忙、消息太多而被忽略、问题描述的不够详细等等。因此,建议大家在提问之前尽可能保证自己已经对问题理解的很清楚,并在提问时尽可能地给出上下文、复现步骤;当没有及时得到回答的话,可以把问题发送到邮件组(发送之前,请在邮件组中搜索其他人是否已经解决过类似问题),相信遇到过类似问题的人也会尽可能帮助你。\n Jenkins Gitter 中文聊天室 欢迎你!\n留言 本站的留言系统建立在 Github 提供的 Issues 上。欢迎大家在遵守社区行为规范的基础上积极地留言互动。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/course/", "title": "Jenkins 培训", "type": "slide", "date": "2019-01-03 22:50:02 +0800 +0800", "tags": [], "description": "Jenkins 培训大纲", "content": " class: center, middle\nJenkins 培训 大纲 Jenkins 项目介绍 安装、部署 传统环境 容器环境 插件管理 构建任务 流水线 多分支流水线 API 计算节点管理 静态 动态 大纲 日志、任务外部存储 权限、认证体系 安全防护 备份、恢复 集成 社区介绍 Gitter \u0026amp;\u0026amp; 邮件组 Meetup 特别兴趣小组(SIG) 基础设施 安装、部署 Jenkins 的版本分为长期支持版(LTS)和每周更新版。\n 安装手册 Docker 插件管理 介绍 仓库 托管 计算节点管理 节点类型 固定 动态(虚拟机、Docker、Kubernetes) 通道 SSH JNLP 标签(label) 表达式 流水线(Pipeline) Jenkins 流水线采用 Groovy 来编写,通常会保存在代码库根目录下名为 Jenkinsfile 的文件中。根据写法不同,分为:脚本式、申明式流水线。\n快速入手,参考:\n 语法生成器 步骤列表 例子 复用 IDE 插件 .left[.footnote[https://linuxsuren.github.io/blog/devops/jenkins/pipeline/]]\n多分支流水线(Multi-branch Pipeline) 对于使用 Git 作为代码仓库的团队来说,Jenkins 的多分支流水线能够充分地利用 Git 的分支功能,简化重复的工作。简单来说,它可以根据既定的策略动态地创建、删除流水线。而对于部分 Git 服务,还能很好地支持 Pull Request 的流水线构建。\nAPI Jenkins 的大部分操作支持通过 HTTP API 进行调用,可以返回 JSON、XML 的数据格式。\nclass: center, middle\n社区介绍 Jenkins Community\n沟通交流 推荐的交流途径包括:Gitter、Google 邮件组。不同的主题,会有不同频道、组。\n 普通用户(中文、英文) 开发者 特别兴趣小组 .left[.footnote[https://remarkjs.com]]\nMeetup 线上、线下交流活动。每年,在国内很多城市都组织一些线下交流活动。\n 北京 西安 上海 深圳 分享的主题通常包括:特性介绍、案例分享、工作坊等。\n.left[.footnote[https://www.meetup.com/Beijing-Jenkins-Area-Meetup/]]\nclass: center, middle\n特别兴趣小组 Jenkins Special Interest Groups\n.left[.footnote[SIGs]]\n??? here is the note\n中文本地化 致力于改善 Jenkins 的中文用户的使用体验。涉及的范围包括: Jenkins 核心和插件以及官方网站。欢迎加入!\n 官网(Jenkins、JX) Jenkins 及其插件 Jenkins 官方微信公众号 定期会议 .footnote[Chinese Localization]\n宣传与推广 平台 实训项目-1 热身练习 1. 构建 Maven 项目 2. 制品归档 3. 构建 Docker 镜像 4. 参数化构建,指定 Docker 镜像 Tag\n进阶练习 1. 构建 Maven 项目并发布到 Nexus 2. 使用私有 Nexus 中的依赖进行构建 3. 构建 Docker 镜像并推送到 Harbor 4. 构建 Heml Charts 并推送到 Chartmuseum\n.footnote[实训 demo 项目]\n实训项目-2 基于 Kubernetes 的持续交付 1. 基于 deployment 进行交付 2. 基于 helm charts 进行交付\n.footnote[实训 demo 项目]\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/event/README/", "title": "", "type": "event", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 该目录下,保存 Jenkins 社区相关的活动内容。文件格式为 Markdown,包含的头信息(字段)包括如下:\n type 活动类型,目前只支持 meetup(必需) city 活动举办地(必需) hostDate 活动时间(必需) year 活动所属年份,用于按年度分开展示(必需) poster 活动海报(必需) topic 活动主题 speakers 分享人,数组格式 sponsors 赞助商(公司、社区等),数组格式 abstract 活动简介 agenda 活动日程 time 时间 item 事项 status 活动状态 发起活动 希望发起活动的人或者组织,请按照如上格式写入一个 Markdown 文件中,并打开一个 Pull Request 到该仓库,等待审核。\n分享人 对某个活动感兴趣的同学,请在目录 content/speaker 下以 JSON 格式增加自己的个人信息,文件名为 GitHub 账户 ID。然后在您感兴趣的活动中的 speakers 下添加您的 ID。\n赞助 如果您所在的企业、出版社、社区等对某个活动感兴趣,打算给 Jenkins 开源社区活动一定的赞助,请参考“分享人”的流程添加自己的信息。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/event/beijing-2019-04-20/", "title": "", "type": "meetup", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "/images/meetup/cloud-native-community-day.jpeg" }, { "uri": "https://jenkins-zh.cn/event/beijing-2019-06-22/", "title": "", "type": "meetup", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "/images/meetup/ci-cd.jpeg" }, { "uri": "https://jenkins-zh.cn/event/beijing-2019-07-27/", "title": "", "type": "meetup", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "/images/meetup/ci-cd.jpeg" }, { "uri": "https://jenkins-zh.cn/event/beijing-2019-08-24/", "title": "", "type": "meetup", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "/images/meetup/kaiyuan.jpg" }, { "uri": "https://jenkins-zh.cn/event/beijing-2019-10-25/", "title": "", "type": "hackthon", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 资源需求 志愿者 五名志愿者,负责场地秩序维护、活动事项问题解答等工作。具体包括如下: * 拍照/摄像 1~2名 * 签到、场地布置 1~2名 * 文案、宣传 1~2名\n志愿者福利: * 免费参加自本活动启动时一年内的所有活动 * 活动纪念品 * 赠送与本社区有合作关系的其他公司或者社区组织的活动门票\n技术教练 Kubernetes、Jenkins 领域的技术教练(导师)各两名,负责参赛选手过程中的问题解答,服务器资源 维护管理。\n技术教练福利: * 免费参加自本活动启动时一年内的所有活动 * 活动纪念品 * 赠送与本社区有合作关系的其他公司或者社区组织的活动门票\n服务器 Kubernetes 集群,1个 master 节点,5个计算节点。每个节点的配置为:4C+8G内存+40G硬盘。\n另外,需要提供的还有:PVC。\n其他物资 贴纸、鼠标垫、书、T恤、雨伞、笔、马克杯、背包等。\n睡袋、毯子。\n合作 合作的社区或者企业,需要共同宣传本次活动,形式不限。\n", "auhtor": "", "translator": "", "original": "", "poster": "/images/meetup/hackthon.png" }, { "uri": "https://jenkins-zh.cn/event/online-2020-04-22/", "title": "", "type": "meetup", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "/images/meetup/hackthon.png" }, { "uri": "https://jenkins-zh.cn/meeting/", "title": "", "type": "meeting", "date": "2020-06-10 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " Jenkins 中文社区例会,每个双周周三(遇到法定节假日时延后)的 21:00 进行。准备参加的小伙伴,需要提前安装好 zoom 软件, 然后点击 https://zoom.us/j/691718976 即可进入会议。\n注意事项⚠️ 要发言的小伙伴要提前找好一个相对比较安静的环境 不发言的时候,及时关闭麦克风🎤 例会是讨论社区的事情,而不是技术分享 如何接入? 可以下载桌面客户端,或者移动客户端来接入会议。\n如果不想下载软件,或者由于某种原因无法访问国外网站的,可以点击此处打开国内的 Web 客户端, 直接在浏览器中参加会议。\n会议 ID 为:691718976\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/ops/monitoring-and-alarm-draft/", "title": "", "type": "ops", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 基础设施监控和预警 目前计划是,先利用云平台服务商自身提供的监控预警手段,如果达不到要求,则再考虑其它方法。\n设置监控预警的步骤 登录云服务器管理控制台; 到左侧边栏展开运维与监控,找到云监控平台; 在云监控平台页面左侧找到报警服务; 添加联系人,也就是告警消息接收人,这里支持电话、手机短信、邮件、钉钉等通知; 添加报警规则(选择阈值报警)、设置阈值和通知方式,这里支持的规则已经很全;(还支持回调函数,这个方便故障恢复); 注意事项 告警电话不是免费的,我了解到的阿里云服务实例类型 xn4,75 RMB 包 6 个月 500 通电话; 短信免费 1000 条 / 月,这个对于简单的场景应该足够; (备注:这里的短信或者电话等额度可在云监控平台页的资源消耗那里查看到。)\n推荐监控和预警实施方式 消息发送方式采用短信和邮件; 监控项目和阈值 公网流出带宽使用率; 内存使用率; 磁盘使用率; CPU 使用率(Host.cpu.total); 恢复动作 人工干预(这个待补充,因为之前出现的两次问题原因还不明确,如何恢复的也还不了解); 自动化恢复(这个待补充,需要在 1 明确后进行); 监控和预警设置的权限 阿里云平台有个 RAM (Resource Access Management) 权限管理台,可以新建 RAM 账户,给 RAM 账户设置权限,例如,单独给云监控的权限对应 AliyunCloudMonitorFullAccess(对应有个云监控只读权限)。\n待确定的内容 监控项目和阈值; 预警消息接收人; 人工干预恢复之前是怎么恢复的? ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "字段说明: * 包含 logo 的才会显示出来\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/alauda/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/harmony-cloud/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/hogwarts/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/jingdongyun/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/junzi/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/kaiyuanshe/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/kubesphere/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/pinganyun/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/press/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/partner/ucloud/", "title": "", "type": "partner", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/sponsor/hogwarts/", "title": "", "type": "sponsor", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/sponsor/juzi/", "title": "", "type": "sponsor", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/sponsor/ucloud/", "title": "", "type": "sponsor", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/", "title": "", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "本教程由 Jenkins 中文社区发起,并由每一位 Jenkins 的爱好者、用户或者开发者共同维护。\n文档以 Markdown 的格式来编写,并采用 Hugo 生成静态网站,每当该仓库的 master 分支发生变化后,就会由 hugo-plugin 构建并自动上线。\n每一位贡献者,都需要通过发起 Pull Request 的方式来帮忙完善、改进该 Jenkins 中文教程。\n在每个 Markdown 文件的头部,我们以 YAML 格式附加了一些信息,支持的字段如下:\n 字段名称 说明 type 固定值:tutorial title 教程标题(必填项) toc 是否显示目录结构,为 true 时显示 author 作者,首位编写本教程的人,值为 GitHub ID(必填项) editors 协作者,作者以外的所有完善过本教程的人,值为 GitHub ID references 本教程涉及的参考资料链接,包括的字段:name、link katacoda Jenkins 中文社区维护的 Katacoda 交互式教程项目的 ID ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/weibo/weibo-operating-charter/", "title": "", "type": "weibo", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " Jenkins 官方微博运营章程 该文旨在说明 Jenkins 官方微博运营规范。\n需要讨论的问题 运营者选取形式\n志愿或其他形式 发布的内容\n同步微信公众号/同步 Twitter/类似其他机构官方账号与粉丝互动 发布内容的形式(分享/原创长微博)\n微博官方提供了分享微博和发布长微博的接口。 发布的时间/频率 微博的自动化\n 维护 Jenkins weibo plugin,需要进一步测试(较长时间无人维护,可能存在接口变动)\n 开发新的插件 对评论的回复 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/12/2018-12-19-Jenkins-survey/", "title": "2018年 Jenkins 国内使用情况调查问卷", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["survey"], "description": "共建开放、包容、活跃的 Jenkins 社区", "content": "近年来,在数字化转型的压力之下,以 DevOps 和微服务为代表的云原生技术,作为企业数字化转型的重要支撑,活跃于开源技术的舞台。 而 DevOps 作为一种理念,落地交付必然离不开 CI/CD 等工具的支持。 Jenkins 在此方面的重要作用,相信大家也是有目共睹。Jenkins 之所以深受国内用户的喜爱,不仅因为它开源免费、功能强大、插件众多,其背后社区的开放、包容和活跃,更是其生命力之所在!\n在新的一年里, Jenkins 社区希望能够更好地推广和传播这项技术,使越来越多的 Jenkins 中文用户能在实际工作中体会它的魅力。正因如此,我们发起了 “2018年 Jenkins 国内使用情况调查问卷”,希望通过这份问卷的互动,我们能够更加清晰 Jenkins 社区2019年的发展方向。\n请扫一扫下面的二维码,或者在微信中长按识别,完成下面的问卷。只需要占用您大概1~2分钟的时间。\n问卷有效时间,从 2018年12月19日 到 2019年1月9日 截止。\n另外,还有两则好消息与大家分享。\n第一则好消息是 Jenkins 中文站点已经正式上线,大家可以在上面找到入门教程、使用案例以及优秀的技术博客,我们会不断完善相关文档和教程。当然,无论是贡献文档、代码,还是其他任何形式的贡献,非常欢迎大家参与其中。从来没有参与过开源项目的朋友也不用担心,可以通过微信公众号留言给我们,志同道合的小伙伴们会主动与你联系,助你一同踏入精彩的开源世界。\n另一则好消息是我们将通过此官方微信公众号,陆续推出 Jenkins 相关系列视频,由浅入深地为使用者们介绍 Jenkins 相关知识及使用经验。对于“如何构建特定语言的项目”、“如何在 Kubernetes 集群中更好地利用 Jenkins ”以及“如何排查问题”等大家感兴趣的热门话题,都可以从这些视频中得到经验分享。\n最后,欢迎订阅 Jenkins 中文邮件组与我们进行交流和互动。衷心希望能够通过更多小伙伴的加入,不断完善开源社区氛围,深度技术互动,协力共建一个更加开放、更加包容、更加活跃的 Jenkins 社区!\n有内容、有态度的 Jenkins 社区,期待有你同行!\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/api/", "title": "API", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "API\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/advocacy-and-outreach/", "title": "Advocacy and Outreach", "type": "tags", "date": "2020-05-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/ai/", "title": "Ai", "type": "tags", "date": "2019-04-22 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/best-practice/Android/", "title": "Android 应用构建", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "本教程将展示 Jenkins 如何使用 Jenkins 和 Gradle 构建一个简单的 Android 应用程序。并涵盖打包,测试,交付的过程。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/announcement/", "title": "Announcement", "type": "tags", "date": "2020-05-18 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/ansible/", "title": "Ansible", "type": "tags", "date": "2019-05-20 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/asktheexperts/", "title": "Asktheexperts", "type": "tags", "date": "2019-09-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/authentication/", "title": "Authentication", "type": "tags", "date": "2020-06-17 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/automation/", "title": "Automation", "type": "tags", "date": "2020-06-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/aws/", "title": "Aws", "type": "tags", "date": "2019-08-23 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/azure-devops/", "title": "Azure Devops", "type": "tags", "date": "2020-05-20 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/benchmark/", "title": "Benchmark", "type": "tags", "date": "2019-07-04 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/blog/", "title": "Blog", "type": "tags", "date": "2020-01-10 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/blueocean/", "title": "Blueocean", "type": "tags", "date": "2019-08-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/c-stat/", "title": "C Stat", "type": "tags", "date": "2019-11-18 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/categories/", "title": "Categories", "type": "categories", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cd/", "title": "Cd", "type": "tags", "date": "2020-02-17 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cdf/", "title": "Cdf", "type": "tags", "date": "2020-03-05 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cdsummit/", "title": "Cdsummit", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cfp/", "title": "Cfp", "type": "tags", "date": "2019-05-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/ci/", "title": "Ci", "type": "tags", "date": "2020-02-17 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/ci-cd/", "title": "Ci/Cd", "type": "tags", "date": "2020-05-12 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cicd/", "title": "Cicd", "type": "tags", "date": "2020-04-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cli/", "title": "Cli", "type": "tags", "date": "2019-10-25 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cloud-native/", "title": "Cloud Native", "type": "tags", "date": "2020-04-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/cloudbees/", "title": "Cloudbees", "type": "tags", "date": "2020-03-09 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/community/", "title": "Community", "type": "tags", "date": "2020-06-24 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/community-bridge/", "title": "Community Bridge", "type": "tags", "date": "2020-03-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/communitybonding/", "title": "Communitybonding", "type": "tags", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/configuration/", "title": "Configuration", "type": "tags", "date": "2020-03-10 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/configuration-as-code/", "title": "Configuration as Code", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/continuous-integration/", "title": "Continuous Integration", "type": "tags", "date": "2019-04-03 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/contributing/", "title": "Contributing", "type": "tags", "date": "2019-04-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/contributors/", "title": "Contributors", "type": "tags", "date": "2019-11-22 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/contributorsummit/", "title": "Contributorsummit", "type": "tags", "date": "2019-09-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/core/", "title": "Core", "type": "tags", "date": "2019-07-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/coverage/", "title": "Coverage", "type": "tags", "date": "2019-05-22 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/credentials/", "title": "Credentials", "type": "tags", "date": "2019-07-04 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/12/2018-12-5-custom-war-packager/", "title": "Custom WAR Packager", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["tools", "docker", "jenkins-x", "cloud-native"], "description": "打造你自己的 Jenkins!了解自定义 WAR/Docker Packager", "content": "我打算给 Jenkins 管理员和开发者介绍一个新的工具 Custom WAR Packager。该工具可以打包 Jenkins 的自定义 WAR 发行版、 Docker 镜像和 Jenkinsfile Runner 包。 它可以打包 Jenkins、插件以及配置为开箱即用的发行版。 Custom WAR Packager 是我们在博客 A Cloud Native Jenkins(/blog/2018/09/12/speaker-blog-a-cloud-native-jenkins/) 中介绍过的无状态 Jenkins master 工具链的一部分。这个工具链已经在 Jenkins X 中被使用,用于构建 serverless 镜像(https://github.com/jenkins-x/jenkins-x-serverless)。\n在这篇文章中,我将会介绍几种 Custom WAR Packager 常见的使用场景。\n== 历史\n正如 Jenkins 本身一样,Custom WAR Packager 开始于一个小的开发工具。在 Jenkins 内运行集成测试很长时间以来都是一个难题。 对此,我们有三个主要的框架: Jenkins Test Harness, Acceptance Test Harness, 和 Plugin Compatibility Tester. 这些框架都需要一个 Jenkins WAR 文件来运行测试。但是假如你想在类似 AWS 一样的自定义环境中进行 Jenkins 测试呢? 或者,你希望基于 Pluggable Storage 的环境也可以复用 Jenkins 流水线测试,来确保没有回归缺陷?\n这并不是一个无意义的问题。Jenkins 项目中有重大的活动正在进行:云原生 Jenkins、Jenkins Evergreen 以及 Jenkins X。 这些都需要很多集成测试来保障持续部署流程。为了复用已有的框架,我们需要打包一个自带配置的 WAR 文件,使得可以在已有的框架中运行集成测试。 这正是 Custom WAR Packager 于 2018年4月 创建的原因。到 2018年9月,它相继支持了 Docker 镜像和 Jenkinsfile Runner, 后者由 Kohsuke Kawaguchi 创建并由 Nicolas de Loof 完善。\n== 包含的内容?\nCustom WAR Packager 是一个工具,可以作为命令行、Maven 插件或者 Docker 来用。 它从用户那获取配置和包。所有内容都由一个 YAML 配置文件管理:\nimage::/images/post-images/2018-10-16-cwp/cwp_flow.png[Custom WAR Packager 构建流程]\n它支持多种输入类型。插件列表可以来自 YAML,pom.xml 或一个 BOM(jep:309[] 提出的 Bill of Materials) 文件。 Custom WAR Packager 不仅支持发布版本,还可以构建部署到 增量仓库 (Jenkins 核心及插件的 CD 流程 - jep:305[]), 甚至直接从 Git 或指定目录中构建。它允许构建的包来自任何源,而无需等待官方的发版。 构建过程也非常快,因为,插件已经通过 Commit ID 缓存到了本地的 Maven 仓库中。\nCustom WAR Packager 还支持下面的配置选项:\n** Jenkins 配置即代码 的 YAMl 文件 ** Groovy Hooks (例如:预配置的 init hooks) ** 系统属性\n== WAR 打包\n每当这个库构建时会打包出来一个 WAR 文件。 通常,Custom WAR Packager 会根据下面对 Jenkins 核心和 JCasC 的配置把所有内容打包的一个 WAR 文件中。\n样例配置:\nbundle: groupId: \u0026quot;io.jenkins.tools.war-packager.demo\u0026quot; artifactId: \u0026quot;blogpost-demo\u0026quot; vendor: \u0026quot;Jenkins project\u0026quot; description: \u0026quot;Just a demo for the blogpost\u0026quot; war: groupId: \u0026quot;org.jenkins-ci.main\u0026quot; artifactId: \u0026quot;jenkins-war\u0026quot; source: version: 2.138.2 plugins: - groupId: \u0026quot;io.jenkins\u0026quot; artifactId: \u0026quot;configuration-as-code\u0026quot; source: # Common release version: 1.0-rc2 - groupId: \u0026quot;io.jenkins\u0026quot; artifactId: \u0026quot;artifact-manager-s3\u0026quot; source: # Incrementals version: 1.2-rc259.c9d60bf2f88c - groupId: \u0026quot;org.jenkins-ci.plugins.workflow\u0026quot; artifactId: \u0026quot;workflow-job\u0026quot; source: # Git git: https://github.com/jglick/workflow-job-plugin.git commit: 18d78f305a4526af9cdf3a7b68eb9caf97c7cfbc # etc. systemProperties: jenkins.model.Jenkins.slaveAgentPort: \u0026quot;9000\u0026quot; jenkins.model.Jenkins.slaveAgentPortEnforce: \u0026quot;true\u0026quot; groovyHooks: - type: \u0026quot;init\u0026quot; id: \u0026quot;initScripts\u0026quot; source: dir: src/main/groovy casc: - id: \u0026quot;jcasc\u0026quot; source: dir: casc.yml == Docker 打包\n为了打包 Docker,Custom WAR Packager 使用官方的 Docker 镜像 jenkins/jenkins 或同样格式的其他镜像。构建中,WAR 文件会被该工具所替换。这也就意味着镜像的 所有 特色在该自定义构建中都可用: plugins.txt, Java 选项, Groovy hooks 等等。\n## ... ## WAR configuration from above ## ... buildSettings: docker: build: true # Base image base: \u0026quot;jenkins/jenkins:2.138.2\u0026quot; # Tag to set for the produced image tag: \u0026quot;jenkins/custom-war-packager-casc-demo\u0026quot; 例如:示例 展示了打包带有将构建日志存储到 Elasticsearch 的 Docker 镜像。 尽管这些已经作为了 jep:207[] 和 jep:210[] 的一部分,你还是可以查看这个示例,了解该 Docker 镜像是如何配置、连接到 Elasicsearch、 然后启动外部的日志存储,而不需要改变日志的界面。一个 Docker Compose 文件对于运行整个集群是必要的。\n== Jenkinsfile Runner 打包\n这可能是 Jenkinsfile Runner 最有意思的模式。 三月份,在开发者列表中 宣布了 一个新的项目 Jenkinsfile Runner。 大体的思路是,支持在单一 master 上只运行一次并打印输出到控制台的 Jenkins 流水线。 Jenkinsfile Runner 作为命令或一个 Docker 镜像来运行。 虽然只推荐 Docker 的形式,但是 Custom WAR Packager 都能够生成。 有了 Jenkinsfile Runner 你可以像下面的方式来运行流水线:\ndocker run --rm -v $PWD/Jenkinsfile:/workspace/Jenkinsfile acmeorg/jenkinsfile-runner 当我们开始在云原生特别兴趣小组(Cloud Native SIG)中开始研究无状态(也就是“一次”)时, 有一个想法就是使用 Custom WAR Packager 和其他已有的工具(Jenkinsfile Runner, Jenkins Configuration as Code 等)来实现。 也许只是替换 Jenkinsfile Runner 中的 Jenkins 核心的 JAR 以及插件,但这还不够。 为了高效,Jenkinsfile Runner 镜像应该启动的 *很快*。在这个实现中,我们使用了 Jenkins 和 Jenkinsfile Runner 一些实验性的选项, 包括:类加载预缓存、插件解压等等。有了这些后,Jenkins 使用 configuration-as-code 和几十个插件可以在几秒钟内启动。\n那么,如何构建自定义 Jenkinsfile Runner 镜像呢?尽管现在还没有发布,我们继续实现上面提到的内容。\n##... ## WAR Configuration from above ##... buildSettings: jenkinsfileRunner: source: groupId: \u0026quot;io.jenkins\u0026quot; artifactId: \u0026quot;jenkinsfile-runner\u0026quot; build: noCache: true source: git: https://github.com/jenkinsci/jenkinsfile-runner.git commit: 8ff9b1e9a097e629c5fbffca9a3d69750097ecc4 docker: base: \u0026quot;jenkins/jenkins:2.138.2\u0026quot; tag: \u0026quot;onenashev/cwp-jenkinsfile-runner-demo\u0026quot; build: true 你可以从 这里 找到用 Custom WAR Packager 打包 Jenkinsfile Runner 的例子。\n== 更多\n还有很多其他的特色没有在本文中提到。例如:它还可以修改 Maven 构建配置或增加、替换 Jenkins 核心中的库(例如:Remoting)。 请查看 Custom WAR Packager 文档 获取更多信息。这个库中还有很多示例。\n如果你有兴趣对这个库做贡献,请创建 PR 并抄送 @oleg-nenashev 和 Raul Arabaolaza,第二位维护者正在研究 Jenkins 自动化测试流程。\n== 下一步?\n还有很多值得改进的地方可以让这个工具更加高效:\n 增加对插件依赖传递的检查以便在构建过程中发现冲突 允许在 YAML 配置文件中设置各种系统属性和 Java 选项 改进 Jenkinsfile Runner 的性能 集成到 Jenkins 集成测试流程中,(查看 Jenkins 流水线库中的 essentialsTest()) 还有很多其他的任务需要在 Custom WAR Packager 中实现,但是,现在它已经能够让 Jenkins 用户构建他们自己的发行版。\n", "auhtor": "oleg_nenashev", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/data-science/", "title": "Data Science", "type": "tags", "date": "2020-05-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/datascience/", "title": "Datascience", "type": "tags", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/declarative-pipeline/", "title": "Declarative Pipeline", "type": "tags", "date": "2020-05-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/deployment/", "title": "Deployment", "type": "tags", "date": "2020-03-10 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/developer/", "title": "Developer", "type": "tags", "date": "2020-04-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/devops/", "title": "Devops", "type": "tags", "date": "2020-06-30 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/devops-jenkins/", "title": "Devops Jenkins", "type": "tags", "date": "2019-09-23 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/devops-%E6%8C%87%E6%A0%87/", "title": "Devops 指标", "type": "tags", "date": "2020-03-02 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/devops-%E7%8A%B6%E6%80%81/", "title": "Devops 状态", "type": "tags", "date": "2020-03-02 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/devops-%E7%8A%B6%E6%80%81%E6%8A%A5%E5%91%8A/", "title": "Devops 状态报告", "type": "tags", "date": "2020-03-02 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/devopsworld2019/", "title": "Devopsworld2019", "type": "tags", "date": "2019-09-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/docker/", "title": "Docker", "type": "tags", "date": "2020-05-28 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/12/2018-12-26-official-docker-image/", "title": "Docker Hub 上的官方 Jenkins 镜像", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["docker"], "description": "正确地使用 Jenkins 镜像", "content": " 目前,在 Docker Hub 上有三个不同的仓库正(或曾经)被当作“官方” Jenkins 镜像。 本文是为了申明哪个是当前的官方镜像(截至2018年12月).\n官方的 docker pull jenkins/jenkins\n例如:https://hub.docker.com/r/jenkins/jenkins/ 是正确的仓库。\n在我的博客 对于使用 Jenkins 官方 Docker 镜像推荐的方法 上也有一些记录。\n废弃的 jenkins 已经废弃了很久。 我们停止使用和更新该镜像的简短原因是,我们每次发版时都需要人工参与。 jenkinsci/jenkins 同样已经废弃了很久,但为了过渡,我们会同时更新 jenkins/jenkins(正确的那个) 和 jenkinsci/jenkins。 2018年12月初,我们停止更新 jenkinsci/jenkins(如果您感兴趣的话,查看 INFRA-1934 可以获取更多详情)。\n感谢您的阅读!\n", "auhtor": "batmat", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/docs/", "title": "Docs", "type": "tags", "date": "2019-05-27 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/documentation/", "title": "Documentation", "type": "tags", "date": "2020-06-24 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/elections/", "title": "Elections", "type": "tags", "date": "2019-11-12 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/electron/", "title": "Electron", "type": "tags", "date": "2019-03-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/events/", "title": "Events", "type": "tags", "date": "2020-02-18 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/evergreen/", "title": "Evergreen", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/flagger/", "title": "Flagger", "type": "tags", "date": "2019-04-26 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/general/", "title": "General", "type": "tags", "date": "2019-03-20 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/git/", "title": "Git", "type": "tags", "date": "2020-03-27 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/git-secrets/", "title": "Git Secrets", "type": "tags", "date": "2019-11-29 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/github/", "title": "Github", "type": "tags", "date": "2020-06-17 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/gitlab/", "title": "Gitlab", "type": "tags", "date": "2019-09-11 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/golang/", "title": "Golang", "type": "tags", "date": "2020-04-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/governance/", "title": "Governance", "type": "tags", "date": "2019-11-12 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/grafana/", "title": "Grafana", "type": "tags", "date": "2020-06-03 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/gsoc/", "title": "Gsoc", "type": "tags", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/gsoc2019/", "title": "Gsoc2019", "type": "tags", "date": "2020-02-18 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/gsoc2020/", "title": "Gsoc2020", "type": "tags", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/hacktoberfest/", "title": "Hacktoberfest", "type": "tags", "date": "2019-11-22 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/iaac/", "title": "Iaac", "type": "tags", "date": "2020-04-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/installers/", "title": "Installers", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/istio/", "title": "Istio", "type": "tags", "date": "2019-04-26 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/j-%E8%BD%AC%E6%8D%A2%E6%9B%B2%E7%BA%BF/", "title": "J 转换曲线", "type": "tags", "date": "2020-03-02 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jacoco/", "title": "Jacoco", "type": "tags", "date": "2019-05-22 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/java/", "title": "Java", "type": "tags", "date": "2019-12-19 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/java11/", "title": "Java11", "type": "tags", "date": "2019-07-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jcasc/", "title": "Jcasc", "type": "tags", "date": "2020-04-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jenkins/", "title": "Jenkins", "type": "tags", "date": "2020-06-30 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/meetups/", "title": "Jenkins Area Meetup", "type": "about", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "Jenkins 中国本地活动", "content": " 各地活动组织者 城市 组织者 邮箱 北京 Rick 📭 希望在当地组织活动? 我们非常欢迎全国各地的 Jenkins 爱好者积极地承担起在当地组织 Jenkins 线下活动的责任。为了能够保证我们社区的健康发展,申请人需要清楚、明确地了解下面的权益和义务:\n权益 组织线下活动是比较累但有趣的工作,要举办一次好的活动,需要投入不少的精力来筹划、安排、宣传等。因此,活动组织者将会享受到如下的权益:\n 优先获得合作社区(公司)举办的会议门票 社区协调场地、茶歇以及礼品等赞助 丰富的人脉资源 使用社区邮箱 其他社区提供的激励 义务 在享受权益的前提,必须要尊重和遵守我们的义务要求:\n 积极主动,有自驱力 一年内,平均每月要参加一次社区线上例会(如有其他事情耽搁,可以在会议记录中备注) 所在地一年内至少要举办一次线下活动 活动形式 我们欢迎每一位愿意一起合作、组织的个人、企业、社区,形式包括但不局限于:\n 案例、经验分享 工作坊,实际操作演练 活动拍照、录像 茶歇、场地赞助 礼品、奖品赞助 下面是目前收集到的,在国内组织过 Meetup 的城市。\n 北京 上海 西安 杭州 成都 深圳 广州 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/cli/", "title": "Jenkins CLI", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "Jenkins CLI 有两个版本,分别是 Jenkins 内置、用 Golang 编写的。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/cli/jcli/", "title": "Jenkins CLI", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " Jenkins CLI 可以帮忙你轻松地管理 Jenkins。不管你是一名插件开发者、管理员或者只是一个普通的 Jenkins 用户,它都是为你而生的!\n特性 支持多 Jenkins 实例管理 插件管理(查看列表、搜索、安装、上传) 任务管理(搜索、构建触发、日志查看) 支持配置即管理 在浏览器中打开你的 Jenkins 重启你的 Jenkins 支持通过代理连接 ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jenkins-ci/", "title": "Jenkins Ci", "type": "tags", "date": "2019-11-18 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/12/2018-12-12-gasc/", "title": "Jenkins Configuration-as-Code: 看,我都不用手动配置", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["configuration-as-code", "jenkinsworld", "jenkinsworld2018"], "description": "JCasC 允许我们在启动时或通过 web UI 按需在 Jenkins master 上应用一组 YAML 文件", "content": " NOTE: 这篇文章是 Configuration-as-Code 系列的第一部分。\nJenkins 非常灵活,如今已成为实现 CI/CD 的事实标准,同时拥有一个活跃的社区来维护几乎所有工具和用例的插件。但是灵活也是要付出代价的:除了 Jenkins 核心之外,许多插件需要一些系统级别的设置才能正常工作。\n在某些情况下,“Jenkins 管理员”是一个全职职位。 Jenkins 管理员在负责维护基础设施的同时,还要为一个巨大的 Jenkins master 提供数百个已安装的插件和数千个托管作业。 维护最新的插件版本是一项挑战,故障转移(failover)也会是一场噩梦。\n这就像几年前系统管理员必须要为每个服务管理特定的机器一样。 在 2018 年,通过使用基础架构自动化工具和虚拟化,一切都可以作为代码进行管理。 需要一个新的应用服务器作为你的应用的暂存环境吗?那你只需要部署一个 Docker 容器。 基础设施缺少资源吗?那就在你喜欢的云服务上分配更多资源来使用 Terraform。\n在这种情况下,Jenkins 管理员的角色怎么样?他们是否还要花费数小时来点击网页表单上的复选框?也许他们已经采用了一些自动化、依赖于 Groovy 脚本或一些自己写的 XML 模板。\n今年早些时候我们发布了第一个 alpha 版本的 “Jenkins Configuration-as-Code” (JCasC),它是一种基于 YAML 配置文件和自动模型发现的 Jenkins 配置管理新方法。\u0026rdquo;JCasC\u0026rdquo; 已经升级为顶级 Jenkins 项目。 同时,对应的 Jenkins 增强提案已经被接受。\nJCasC 能为 Jenkins 管理员做些什么? JCasC 允许我们在启动时或通过 web UI 按需在 Jenkins master 上应用一组 YAML 文件。 与 Jenkins 用于实际储存配置的详细 XML 文件相比,这些配置文件非常简洁易读。 这些文件还有用户友好的命名约定,使管理员能够轻松地配置所有 Jenkins 组件。\n下面是一个例子:\n[source, yaml] jenkins: systemMessage: \u0026ldquo;Jenkins managed by Configuration as Code\u0026rdquo;\nsecurityRealm: ldap: configurations: - server: ldap.acme.com rootDN: dc=acme,dc=fr managerPasswordSecret: ${LDAP_PASSWORD} cache: size: 100 ttl: 10 userIdStrategy: CaseInsensitive\ngroupIdStrategy: CaseSensitive 如你所见,不需要很长的解释你就可以理解这个 YAML 文件如何配置你的 Jenkins master。\n== 优点\nJCasC 最直接的好处就是可重复性。 管理员现在可以使用完全相同的配置通过一个简单的设置来引导新的 Jenkins master。 这允许他们创建一个测试实例并检查升级插件在沙盒环境中的影响。 这也使他们对故障转移和灾难恢复方案更有信心。\n当管理员开始在源代码管理中管理 Jenkins 的 YAML 配置文件时,他们也会感受到类似使用 Terraform 一样的好处。 这样做可以让他们对 Jenkins master 配置进行审核,使其具有可逆性。 他们可以建立一个合理的配置改变运行 Jenkins 实例的工作流,并确保在实际应用任何修改到他们的 Jenkins master 之前配置是健康的。\n最后也是最重要的是,由于能够快速设置 Jenkins master 并且能用一组共享的 YAML 配置文件控制它们,管理员现在可以给每个团队提供一个 Jenkins 实例,并且在安装插件有更高的灵活性。 只要他们还在使用 Jenkinsfiles 管理构建定义(build definition),master 就会或多或少地成为你们团队的短期的基础架构。\n使用 Configuration-as-Code,我们可以不再像对待宠物那样对待我们的 Jenkins master,而像对待牛那样管理它们,你也可以毫不费力地替换它们。 欢迎来到 “as-code” 的世界。\n.他们仍然很可爱,对吧? Cattle not pets\nOk, 那么之后呢? 你可以在项目中阅读有关 Jenkins Configuration-as-Code 插件的更多信息。 与社区和贡献者们交流,加入我们的 gitter 频道, 或者来我们的 Jenkins World 一起讨论 JCasC 项目及其未来!\n另外,不要错过 Configuration-as-Code 系列的下一篇文章,我们将会了解 JCasC 如何处理密码及其他凭据等敏感数据。\n", "auhtor": "ndeloof", "translator": "arjenzhou", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jenkins-x/", "title": "Jenkins X", "type": "tags", "date": "2020-02-17 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/", "title": "Jenkins 中文社区", "type": "page", "date": "2019-09-07 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-15-kubecon-cn/", "title": "Jenkins 中文社区邀您来上海共同参与2019年的国际开源盛宴", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["cloud-native", "kubernetes", "kubecon", "ci", "cd", "cdsummit"], "description": "", "content": " KubeCon + CloudNativeCon | Open Source Summit | 持续交付峰会 中国2019 2019年4月10日,旧金山 - Linux基金会是一家以开源促进大众创新的非营利组织,今天公布将于2019年6月24至26日在中国上海举行的 KubeCon + CloudNativeCon + Open Source Summit 中国2019日程。\nOpen Source Summit 中国2019前身为 LinuxCon + ContainerCon + CloudOpen 中国(LC3),是开源社区寻求合作、共享信息、了解当今最有影响力的开源技术和议题的重要平台,包括:云原生、无服务器、微服务、物联网、人工智能、网络、Linux 等。\n2019年,首次将Open Source Summit中国和KubeCon + CloudNativeCon中国整合成一项活动,只需购票一次即可参加KubeCon + CloudNativeCon + Open Source Summit中国。\n本届持续交付峰会将由 CNCF 承办在大会的第 0 天举行,汇聚了各个开源 CI/CD 社区。\nJenkins 中文社区成员在大会上将进行分享 Jenkins 中文社区成员夏润泽(北京优帆科技有限公司)将在大会上作为演讲嘉宾为大家带来主题为 Jenkins X 在 kubernetes 之上运行的无服务器 Jenkins 的分享。\nJenkins 中文社区邀您参与社区共同成长 在开源盛会开展的同时,我们希望能够与更多的小伙伴们一同在线上完善开源社区氛围、线下深度互动,努力构建一个有内容、有态度的优质技术社区。\n", "auhtor": "runzexia", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/01/2019-01-16-localization-zh-cn-plugin/", "title": "Jenkins 中文语言包", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "Jenkins 中文版本升级通知", "content": "部分 Jenkins 中文用户可能已经发现,在最近升级 Jenkins 版本,或下载较新的 Jenkins 后,界面上很多部分显示的是英文。对此,我简单介绍一下原因以及如何安装中文插件。\n各种语言的本地化资源文件都是集中存放在 Jenkins Core 及其插件中,这对于要做本地化贡献的人来说,需要向很多代码仓库中提交 PR。最明显的一个现象就是,这些仓库不一定都会有熟悉中文的维护者,因此导致 PR 无法真实、及时地进行 Review 以及合并发布。基于以上的考虑,我开发了简体中文插件,并从 Jenkins 2.145 版本中把大部分的中文本地化资源文件迁移到了该插件中。而且,最终会对 Jenkins Core 以及流行的插件中所有的中文本地化资源文件进行迁移。\n安装简体中文插件也很简单,只要在 Jenkins 的插件管理界面上,搜索*中文*就能找到该插件。安装并重启后就能看到中文界面。\n更多细节请查看 变更记录 。欢迎对中文本地化工作感兴趣的同学加入我们!\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/01/2019-01-30-k8s-jenkins-secet-agent/", "title": "Jenkins 和 Kubernetes -云上的神秘代理", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["jenkinsworld", "jenkinsworld2018", "cloud-native", "kubernetes"], "description": "运行在 K8S 上的 Jenkins 动态节点", "content": " 最近我们构建和部署服务的方式与原来相比简直就是突飞猛进,像那种笨拙的、单一的、用于构建单体式应用程序的方式已经是过去式了。我们努力了这么久,终于达到了现在的效果。现在的应用为了提供更好的拓展性和可维护性,都会去拆解成各种相互依赖小、解耦性强的微服务,这些服务有各自的依赖和进度。如果你想去构建你所负责的服务,那么从一开始,就应该使用 CI/CD 的方式;当然,如果你走上了这条路, Jenkins 就是你的良师益友。\n如果你是做微服务的话,那让我们在开始之前先花些时间想一想。如果你只在 Jenkins 上构建单体式应用程序,那你肯定每天都会运行很多 Jenkins job, 而且还要不厌其烦地运行很多次。所以,我们应该好好想清楚怎么样来做出一些改变来适应这种事情。其实只需要付出一些努力,Jenkins 就可以帮我们很好地解决这种事情。\n我的 Jenkins 的进阶之路 作为一个 Devops 从业者,我遇到的最大问题是如何管理并优化自己的 Jenkins agent 结构。如果只是用 Jenkins 玩玩,实验性地跑一些流水线,那根本不用考虑 agent 的事情。如果你每天要跑成百上千条流水线的话,那考虑怎么去做优化就是一件非常非常重要的事情了。在 Jenkins 进阶之路中,我也尝试了各种不同的方式来寻找最好的 Jenkins agent 的使用方式。相信如果你也和我一样经历过,那下面这些事情你一定会很熟悉喽。\n下面是我在这些年中使用 Jenkins 的各个阶段.\n 所有的构建都在 master 节点上跑,在这个节点上运行所有的组件. (我给这个阶段起了个可爱的名字, Hello Jenkins) 创建一个 Jenkins EC2 代理,并且在这个代理上运行所有的构建,怎么说呢, 就是大而全,这个节点什么都能做。如果需要同时做多条任务,那就把这个大而全的节点克隆一份。 (这个阶段我起的名字是 Monster Agent.) 为每种服务创建不同的 Jenkins EC2 的节点 (这个阶段我起的名字叫做 Snowflake Agent.) 在容器中运行流水线的所有步骤。 打个比方,在 Jenkins 中使用 Docker Plugin 这个插件将代理挂载到容器中,或者使用 multi-stage Dockerfiles 把所有构建,测试打包的流程都封装起来。这两种方法都是很好的容器抽象化的开端,并且允许您轻松地将制品从一个容器复制到另一个容器。当然了,每一种方法都是需要访问 Docker engine 的。为了让我的 Jenkins 代理能够正常工作,现在我用以下几种方式来管理 docker host 在我的 Jenkins 主容器中运行一个Docker engine - Docker in Docker (DinD) 把主机上的 Docker socket 挂载到我的容器中来,让我的容器能够以 sidecar 的方式运行。 为 Jenkins 主服务器配置单个外部 EC2 Docker 主机,以用于在容器中启动构建 使用 EC2 插件和包含 Docker Engine 的 AMI 动态启动代理,然后运行多阶段 Dockerfile 中的所有步骤 以上这些阶段各有利弊,但都是为了让我们从管理 Jenkins 节点中解放出来。不过,最近我又进阶到了另外一个阶段:Jenkins on Kubernetes.\n一旦你在 Jenkins 中把构建节点和 job 都容器化了的话,迁移工作平台将变的十分简单易行。在这里郑重声明一下,在我用这个方法之前我一直没有接触过 Kubernetes,一次也没有。也就是说,在 Google Cloud Platform(GCP)GKE 中创建 Kubernetes 集群,使用 Helm Chart启动 Jenkins master ,并在 Kubernetes 集群中的 Jenkins 代理中运行构建是非常简单的。\n流水线脚本中启动 K8s 中的代理 这篇文章就是为了向大家说明,如何配置 Jenkins 才能使流水线脚本能够在 K8s 集群中启动 Jenkins 节点。首先你要先安装 Kubernetes plugin 这个插件。有意思的是,当我用 Helm chart 来安装我的 Jenkins 时,安装好的 Jenkins 里面已经有了这个插件。还有一个前提,是你启动的 Jenkins 节点要和你的 Jenkins master 在同一个 K8s 集群里。\n一旦在 K8s 中运行了你的 Jenkins master 节点,那只需要再简单地配置几步,就能启动一个小构建啦。\n配置 Jenkins Master 为了保证 Jenkins 能够访问 K8s 集群的资源,首先你需要按照以下步骤创建一些凭据:\n 进入 Jenkins 的 UI 界面,点击左边导航栏里的凭据链接 点击 Stores scoped to Jenkins 列表下 global 中的 Add credentials (将鼠标悬停在链接旁边即可看到箭头) 点击添加凭证 写好 Kubernetes Service Account 将范围设置为全局 点击 OK 按钮 这样之后 Jenkins 就可以使用这个凭据去访问 K8s 的资源啦\n在 Jenkins Master 中配置云 下一步就是在 Jenkins 中设置云的配置\n 进入 Jenkins UI 界面,点击 系统管理 → 系统设置 进入管理界面后查找 『云』,一般在下面,然后点击 『新增一个云』,选择 kubernetes 类型 然后这些是必填的参数 Name: 这个自定义, 默认的是kubernetes Kubernetes URL: https://kubernetes.default- 这个一般是从你的 service account 自动配置的 Kubernetes Namespace: 一般是 default 除非你要在一个特殊的命名空间 ,否则不要动他 Credentials: 选择上一步你创建的凭据 Jenkins URL: http://\u0026lt;your_jenkins_hostname\u0026gt;:8080 Jenkins tunnel: \u0026lt;your_jenkins_hostname\u0026gt;:5555 - 这就是用来和 Jenkins 启动的 agent 进行交互的端口 你看,只需要几个参数就能在 K8s 集群中启动一些节点了,当然你的环境有需要的话,你也可以做一些其他的调整\n现在你已经可以通过定义一些 pod 来让 Jenkins master 访问 K8s 集群了。pod其实是 K8s 中的概念,在一个 pod 中里面会有一个或者多个容器,它们共享网络还有存储,然后我们可以在这个 pod 中执行一些构建工作。每一个 Jenkins 节点都是作为 K8s pod 来启动的。这个 pod 里面经常都会包含一个默认的 JNLP 的容器,还有一些你在 pod 模板中定义的容器。现在有至少两种方法来定义你的 pod template。\n通过 Jenkins UI 配置一个 pod template 还是老地方 Manage Jenkins → Configure Systems 还是老地方 找到之前配置 Jenkins K8s 的地方 点击 Add Pod Template button 选择 Kubernetes Pod Template 输入下面的值 Name:自定义 Namespace: default-除非你想换个你在上一步自定义的命名空间 Labels: 自定义 - 这个将用来匹配你在 jenkinsfile 中的 label 值 Usage: 如果你想让这个 pod 作为默认节点的话,就选择 \u0026ldquo;Use this node as much as possible\u0026rdquo;, 如果选择 \u0026ldquo;Only build jobs with label matching expressions matching this node\u0026rdquo; 的话 那就是只有在 Jenkins 脚本中定义的label匹配的构建才能使用这个节点 The name of the pod template to inherit from: - 这个可以置空. 现在还用不到 Containers: 你想在这个 pod 中启动的容器,在下面会有详细的介绍 EnvVars: 你想在 pod 中注入的环境变量 下面会有接受 Volumes: 你想在 pod 中挂载的任何一种的卷 需要记住,在一个 pod 中会有不止一个容器,它们都是同生共死的。如果你是用 Helm chart 安装 Jenkins 的话,pod 中就会包含 JNLP 这个容器,这个容器也是 Jenkins agent 中必须包含的。然而为了完成更多的服务的构建,你还需要添加一些其他工具链的容器。\n添加容器模板 进入 Jenkins UI 界面,回到上一步创建 pod template 的地方 点击 Add Container 按钮, 选择 Container Template 输入下面的值 Name:自定义 Docker image: 根据你自己的需求来写,比如你在构建一个用 go 写的应用,那你就可以输入 golang:1.11-alpine3.8 Label: 表明要用在流水线脚本中引用此容器模板的标签字符串 Always pull image: - 如果你想让 pod 启动的时候都去拉取镜像 那就选择这个 你可以保留其他参数的默认值,但是你可以看到该插件可以对你的 pod 以及在其中运行的各个容器进行很详细地控制。你可以通过此插件设置在 Kubernetes pod 配置中的任何值。你还可以通过输入原始 YAML 来注入配置数据。你无需因选项过多而分心,选择配置它们中得一小部分就可以获得工作环境啦。\n您可以单击容器模板中的“添加环境变量”按钮,将环境变量注入特定容器,也可以单击模板中的“添加环境变量”按钮,将环境变量注入所有的容器。 以下环境变量会自动注入默认的 JNLP 容器,来保障它能自动连接到 Jenkins 主服务器:\n JENKINS_URL: Jenkins 网页界面网址 JENKINS_JNLP_URL: Jenkins 特定 slave 中 jnlp 的 url JENKINS_SECRET: 身份验证的密钥 JENKINS_NAME: Jenkins 代理的名称 如果单击“添加卷”按钮,您将看到几个用于添加卷的选项,在这里我使用 Host Path Volume 选项将 docker socket 安装在 pod 中。然后,我可以运行安装了 Docker 客户端的容器,并且来构建和推送 Docker 镜像。\n此时,我们为 Kubernetes 集群创建了一个云配置,并定义了一个由一个或多个容器组成的 pod。现在,我们如何使用它来运行 Jenkins 工作? 很简单,只需要我们在 Jenkins 流水线脚本中通过标签引用 pod 和容器就可以了。 本文中的示例是使用脚本流水线,当然您可以使用声明式流水线语法实现相同的结果:\nnode('test-pod') { stage('Checkout') { checkout scm } stage('Build'){ container('go-agent') { // This is where we build our code. } } } 用 jenkinsfile 来实现相同的功能 通过 UI 配置插件现在看起来是很不错的。但是有一个明显的问题是,配置不能像源代码一样能够进行版本控制和存储。幸运的是,您可以直接在 Jenkinsfile 中创建整个 pod 定义。哈哈,在 Jenkinsfile 中有什么你不能做的???\n可以将 UI 或 YAML 定义中可用的任何配置参数添加到 podTemplate 和 containerTemplate 部分。 在下面的示例中,我已经定义了一个包含两个容器模板的 pod。 pod 标签将会用于节点,表示我们想要启动此 pod 的实例。 直接在节点内定义但没有在容器块中定义的任何步骤,都可以在默认的 JNLP 容器中运行。\n容器块用于表示该容器块内的步骤应在具有给定标签的容器内运行。我已经定义了一个标签为 golang 的容器模板,我将用它来构建 Go 可执行文件,我最终将其打包成 Docker 镜像。在 volumes 中,我已经指出我想要挂载主机的 Docker 套接字,但我仍然需要 Docker 客户端使用 Docker API 与它进行交互。因此,我已经定义了一个标签为 docker 的容器模板,该模板使用安装了 Docker 客户端的镜像。\npodTemplate( name: 'test-pod', label: 'test-pod', containers: [ containerTemplate(name: 'golang', image: 'golang:1.9.4-alpine3.7'), containerTemplate(name: 'docker', image:'trion/jenkins-docker-client'), ], volumes: [ hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock', ], { //node = the pod label node('test-pod'){ //container = the container label stage('Build'){ container('golang'){ // This is where we build our code. } } stage('Build Docker Image'){ container(‘docker’){ // This is where we build the Docker image } } } }) 在我的基于 Docker 的流水线脚本中,我构建了 Docker 镜像并将它们推送到了 Docker 仓库,对我来说,能够复制这些配置信息非常重要。完成后,我已准备好使用 gcloud(Google Cloud SDK)构建我的镜像,并将该镜像推送到 Google Container Registry,以便部署到我的 K8s 群集。\n为此,我使用 gcloud 镜像指定了一个容器模板,并将我的 docker 命令更改为 gcloud 命令。 就这么简单!\npodTemplate( name: 'test-pod', label: 'test-pod', containers: [ containerTemplate(name: 'golang', image: 'golang:1.9.4-alpine3.7'), containerTemplate(name: 'gcloud', image:'gcr.io/cloud-builders/gcloud'), ], { //node = the pod label node('test-pod'){ //container = the container label stage('Build'){ container('golang'){ // This is where we build our code. } } stage('Build Docker Image'){ container(‘gcloud’){ //This is where we build and push our Docker image. } } } }) 在 Kubernetes 上运行 Jenkins master、 Jenkins 代理,构建和部署示例应用程序其实只花了我几个小时。但这之后,我花了一个周末的时间才深入了解了平台。如果你学得够快,我相信你在几天内就可以完全掌握并且灵活运用这个平台了。\n", "auhtor": "devmandy", "translator": "yuzp1996", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/11/2018-11-14-first-voice/", "title": "Jenkins 微信订阅号", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "来自 Jenkins 官方的消息", "content": "Jenkins 作为 CI/CD 领域里非常有实力和生命力的平台,不但在国外有很多用户,在国内也有很多的拥趸者。大家拥抱 Jenkins,不仅仅因为它是新的方向,更因为这背后有着一个非常开放、活跃的开源社区。\n为了使更多的 Jenkins 中文用户,能够及时、准确地获得来自官方的最新动态,经过社区贡献者的讨论,大家一致认为,开通 Jenkins 微信订阅号是非常必要也非常有意义的一件事情。同时,Jenkins 的创始人 Kohsuke Kawaguchi 先生对这个想法非常认同,他亲自签名并授权,对我们创建 Jenkins 微信订阅号提供了巨大的支持和鼓励。\n于是,Jenkins 微信订阅号便在今天,正式与您见面了。\n随着 Jenkins 订阅号的开通,我们将有更加直接的平台来与各位分享社区目前在做的一些事情。在这之前,我们早已着手进行 Jenkins 中文本地化的相关工作。目前社区贡献者主要在做的事情包括:创办并维护 Jenkins 以及 Jenkins X 的中文官网、Jenkins Core 以及插件的本地化等。\n如果您愿意和其他 Jenkins 用户进行线下面对面的交流和分享,Jenkins Area Meetups(后文简称“JAM”) 将会是一个不错的选择。目前,在社区贡献者和技术爱好者的共同努力下,我们已经在北京、深圳、西安等地成功举办过多次 JAM 活动。在 JAM 上,您除了可以体验到很多有关 Jenkins 的实际应用、最新特性之外,还可以结识社区里的朋友并进行深度互动。\nJenkins 社区贡献者们秉承传播 Jenkins 技术、加强互动交流、推动 Jenkins 中文本地化的理念,将在今后定期举办多种多样的线上线下活动。我们尊重任何形式、任何规模的贡献,并热忱地欢迎新贡献者的加⼊,也欢迎您联系我们来分享您的心得、体会,或者共同举办一次 JAM 活动。Jenkins 官网对如何参与有更加详细的说明,有任何问题,欢迎大家留言给我们。\n我们衷心希望,随着 Jenkins 订阅号的开通,能够与更多的小伙伴们一同在线上完善开源社区氛围、线下深度互动,努力构建一个有内容、有态度的优质技术社区。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jenkins-%E6%B5%81%E6%B0%B4%E7%BA%BF/", "title": "Jenkins 流水线", "type": "tags", "date": "2019-11-29 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/12/2018-12-26-security-updates/", "title": "Jenkins 的重要安全更新", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["core", "security"], "description": "重要安全更新", "content": " 我们刚刚发布了版本 2.154 和 LTS 2.150.1 的 Jenkins 安全更新,修复了多个安全漏洞。 由于 2.150.1 是新的 LTS 中的第一个版本,而且,我们还发布了上一个 LTS 2.138.4 版本的安全更新。 这使得管理员们可以安装今天的安全修复,而不必立即升级到新的 LTS 版本。\n查看 link:/security/advisory/2018-12-05[安全报告],了解有哪些被修复。 查看我们的 link:/doc/upgrade-guide/2.138/#upgrading-to-jenkins-lts-2-138-4[LTS 2.138.4 升级指导],了解影响范围。\n当前修复中有关之前发布变更的部分 在八月和十月份的 Jenkins 核心安全更新中,包括一项改进,可以通过设置多个系统属性来禁用。 那些变更是 SECURITY-595 修复的重要部分,因此,我们强烈建议禁用。而且,之前发布的文档已更新。\n", "auhtor": "daniel-beck", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jenkinsworld/", "title": "Jenkinsworld", "type": "tags", "date": "2019-09-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jenkinsworld2018/", "title": "Jenkinsworld2018", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jira/", "title": "Jira", "type": "tags", "date": "2019-05-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jjb/", "title": "Jjb", "type": "tags", "date": "2020-04-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jmh/", "title": "Jmh", "type": "tags", "date": "2019-07-04 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/jte/", "title": "Jte", "type": "tags", "date": "2019-07-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/k8s/", "title": "K8s", "type": "tags", "date": "2020-03-10 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/kafka-kubernetes-helm/", "title": "Kafka Kubernetes Helm", "type": "tags", "date": "2019-11-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/kind/", "title": "Kind", "type": "tags", "date": "2020-04-29 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/kubecon/", "title": "Kubecon", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/kubernetes/", "title": "Kubernetes", "type": "tags", "date": "2020-05-20 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/kubesphere/", "title": "Kubesphere", "type": "tags", "date": "2020-06-30 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/linux/", "title": "Linux", "type": "tags", "date": "2020-07-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/machinelearning/", "title": "Machinelearning", "type": "tags", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/maven/", "title": "Maven", "type": "tags", "date": "2019-05-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/monitoring/", "title": "Monitoring", "type": "tags", "date": "2020-07-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/multi-branch/", "title": "Multi Branch", "type": "tags", "date": "2019-12-31 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/multibranch/", "title": "Multibranch", "type": "tags", "date": "2019-09-11 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/mysql/", "title": "Mysql", "type": "tags", "date": "2020-04-29 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/neuroscience/", "title": "Neuroscience", "type": "tags", "date": "2020-06-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/newcomer/", "title": "Newcomer", "type": "tags", "date": "2019-04-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/nexus-oss/", "title": "Nexus Oss", "type": "tags", "date": "2020-05-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/nginx/", "title": "Nginx", "type": "tags", "date": "2019-04-25 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/ngrok/", "title": "Ngrok", "type": "tags", "date": "2020-03-27 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/open-source/", "title": "Open Source", "type": "tags", "date": "2020-06-30 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/opensource/", "title": "Opensource", "type": "tags", "date": "2020-03-16 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/ops/", "title": "Ops", "type": "ops", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/outreach-programs/", "title": "Outreach Programs", "type": "tags", "date": "2020-05-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/outreachy/", "title": "Outreachy", "type": "tags", "date": "2019-02-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/outreachy2018/", "title": "Outreachy2018", "type": "tags", "date": "2019-02-13 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/performance/", "title": "Performance", "type": "tags", "date": "2019-07-04 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/pipeline/", "title": "Pipeline", "type": "tags", "date": "2020-05-08 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/pipeline-authoring/", "title": "Pipeline Authoring", "type": "tags", "date": "2020-03-16 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/platform-sig/", "title": "Platform Sig", "type": "tags", "date": "2020-05-28 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/plugin/", "title": "Plugin", "type": "tags", "date": "2019-09-19 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/pluginmanagement/", "title": "Pluginmanagement", "type": "tags", "date": "2019-10-25 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/plugins/", "title": "Plugins", "type": "tags", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/programming/", "title": "Programming", "type": "tags", "date": "2020-07-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/progressive-delivery/", "title": "Progressive Delivery", "type": "tags", "date": "2019-04-26 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/react/", "title": "React", "type": "tags", "date": "2019-09-19 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/react-plugins-gsoc-gsoc2019/", "title": "React Plugins Gsoc Gsoc2019", "type": "tags", "date": "2019-11-14 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/release/", "title": "Release", "type": "tags", "date": "2020-05-25 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/remote-file/", "title": "Remote File", "type": "tags", "date": "2019-08-05 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/remoting/", "title": "Remoting", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/scalability/", "title": "Scalability", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/scm/", "title": "Scm", "type": "tags", "date": "2020-03-27 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/screwdriver/", "title": "Screwdriver", "type": "tags", "date": "2020-03-05 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/security/", "title": "Security", "type": "tags", "date": "2020-04-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/shared-library/", "title": "Shared Library", "type": "tags", "date": "2019-03-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/shipper/", "title": "Shipper", "type": "tags", "date": "2019-04-26 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/sig/", "title": "Sig", "type": "tags", "date": "2020-03-16 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/software-development/", "title": "Software Development", "type": "tags", "date": "2020-07-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/software-engineering/", "title": "Software Engineering", "type": "tags", "date": "2020-07-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/spec/", "title": "Spec", "type": "tags", "date": "2019-05-20 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/sponsor/", "title": "Sponsors", "type": "sponsor", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/spring-boot/", "title": "Spring Boot", "type": "tags", "date": "2019-05-24 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/springboot/", "title": "Springboot", "type": "tags", "date": "2019-05-20 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/survey/", "title": "Survey", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/t-mobile/", "title": "T Mobile", "type": "tags", "date": "2020-02-28 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/", "title": "Tags", "type": "tags", "date": "2020-05-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/template/", "title": "Template", "type": "tags", "date": "2019-09-19 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/toolchains/", "title": "Toolchains", "type": "tags", "date": "2020-03-24 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/tools/", "title": "Tools", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/ui/", "title": "Ui", "type": "tags", "date": "2020-04-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/updatebot/", "title": "Updatebot", "type": "tags", "date": "2019-11-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/use-cases/", "title": "Use-cases", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/ux/", "title": "Ux", "type": "tags", "date": "2020-06-24 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/vault/", "title": "Vault", "type": "tags", "date": "2020-04-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/vscode/", "title": "Vscode", "type": "tags", "date": "2020-03-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/webhook/", "title": "Webhook", "type": "tags", "date": "2019-12-23 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/webhooks/", "title": "Webhooks", "type": "tags", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/websocket/", "title": "Websocket", "type": "tags", "date": "2020-02-10 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/", "title": "Wechats", "type": "wechat", "date": "2020-07-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/weekly/", "title": "Weekly", "type": "tags", "date": "2019-03-20 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/weibo/", "title": "Weibos", "type": "weibo", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/wiki/", "title": "Wiki", "type": "tags", "date": "2019-11-22 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/windows/", "title": "Windows", "type": "tags", "date": "2020-05-28 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/02/2019-02-27-windows-installers/", "title": "Windows 安装程序更新", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["windows", "platform-sig", "installers"], "description": "平台特别兴趣小组提供了 Windows 安装程序的更新", "content": " Jenkins 的 Windows 安装程序已经存在很多年了,它是用户在 Windows 上安装 Jenkins Master 作为服务的一种方式。 从被开发出来至今,它还没有什么新特性,但现在是时候做出改变了。\n首先,让我们瞧瞧现版本安装程序的使用经验。\n第1步 启动安装程序 这是使用 WiX Toolset Windows 安装程序的默认界面外观,算不上太好看,而且没有太多对安装程序进行说明的品牌信息。\n第2步 安装目录 同样,没有太多的品牌信息。\n第3步 安装 除了选择安装位置外,安装程序大体上没有提供一些安装 Jenkins 的选项。\n问题 现在的安装程序存在一些问题,平台特别兴趣小组会修复这些问题,并为用户提供新的安装体验。\n 安装程序只支持32位安装。 用户不能选择 Jenkins 作为 Windows 服务启动时的端口以及账户。 安装程序捆绑了32位的 Java Runtime,而没有使用已存在的 JRE。 安装程序不支持 Jenkins for Java 11中的实验性支持。 JENKINS_HOME 目录并不适合现代 Windows。 安装程序中没有品牌。 前进 使用实验性的 Jenkins Windows 安装程序,大部分问题都已解决!\n 安装程序将只支持64位系统,这也是如今大多数 Windows 系统的现状,所以能让更多的用户能够使用安装包来安装 Jenkins。 用户能够为服务输入用户信息,同时选择端口以便于 Jenkins 验证端口是否可用。 安装程序不再捆绑 JRE 而是在操作系统中寻找合适的 JRE。如果用户想要使用一个不同的 JRE,可以在安装时指定。 安装程序已经支持 Java 11,包括在 Java 11 预览上面列出的组件。 JENKINS_HOME 目录被放置在启动服务用户的 LocalAppData 目录下,这与现代 Windows 文件系统布局一致。 安装程序已经升级带有品牌了,这让它看起来更酷并能提供一个更好的用户体验。 截图 以下是新安装程序的系列屏幕截图:\n第1步 启动安装程序 Jenkins logo 现在是安装程序 UI 的重要组成部分。\n第2步 安装目录 在安装程序的所有阶段,Jenkins logo 和名称都出现在标题中。\n第3步 选择账户 安装程序现在允许您指定要运行的帐户的用户名/密码,并检查该帐户是否具有 LogonAsService 权限。\n第4步 端口选择 安装程序还允许您指定 Jenkins 运行的端口,并且在输入和测试有效端口之前不会继续。\n第5步 JRE 选择 安装程序现在不再捆绑 JRE,而是在系统上搜索兼容的 JRE (现在是 JRE 8)。 如果你想使用与安装程序搜索到不同的 JRE,你可以浏览目录并指定它。只支持 JRE 8 和 JRE 11 Runtime。如果发现选定的 JRE 是版本11,安装程序将自动添加必要的参数和其他 jar 文件,以便在 Java 11下运行。\n第6步 安装 用户能在安装程序中输入的所有选项也可以在命令行上覆盖以进行自动部署。可以覆盖的完整属性列表即将推出。\n接下来的步骤 新版本安装程序正在被平台特别兴趣小组的成员 Review 中,但我们需要人测试安装程序并给予反馈。你过你对测试新安装程序感兴趣的话,请加入平台特别兴趣小组 gitter room 获取更多信息。\n在新安装程序中还使用了许多一些正在研发的东西(例如,在进行升级时保留端口和其他选择),但它已接近发布。\n除了基于 MSI 的 Windows 安装程序的更新之外,平台特别兴趣小组还在努力接管 Chocolatey Jenkins 软件包并为每次更新发布一个版本。\n", "auhtor": "slide_o_mix", "translator": "arjenzhou", "original": "https://jenkins.io/blog/2019/02/01/windows-installers/", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/wordcloud/", "title": "Wordcloud", "type": "tags", "date": "2020-06-29 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/wordpress/", "title": "Wordpress", "type": "tags", "date": "2020-04-29 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/work/", "title": "Work", "type": "tags", "date": "2020-06-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/zabbix/", "title": "Zabbix", "type": "tags", "date": "2019-04-15 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/notify/email/", "title": "email", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "我们可以通过发送电子邮件的方式来通知流水线的构建状态。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/notify/", "title": "notify", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "notify\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/pipeline/", "title": "pipeline", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "流水线相关\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/plugin-dev/", "title": "plugin-dev", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "plugin dev\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/scm/", "title": "scm", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "有关 SCM 的教程\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-12-what-is-cicd/", "title": "什么是 CI/CD?", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["ci", "cd"], "description": "本文介绍了 CI/CD 的概念及应用场景", "content": " CI/CD 的出现改变了开发人员和测试人员发布软件的方式。本文是描述这一变化的系列文章第一篇, 这些文章将提供各种工具和流程的讲解,以帮助开发人员更好的使用 CI/CD。\n从最初的 瀑布模型, 到后来的 敏捷开发, 再到今天的 DevOps, 这是现代开发人员构建出色产品的技术路线。 随着 DevOps 的兴起,出现了持续集成,持续交付(CI/CD)和持续部署的新方法, 而传统的软件开发和交付方式在迅速变得过时。过去的敏捷时代里, 大多数公司的软件发布周期是每月、每季度甚至每年(还记得那些日子吗?), 而在现在 DevOps 时代,每周、每天甚至每天多次都是常态。 当 SaaS 成为业界主流后尤其如此,您可以轻松地动态更新应用程序, 而无需强迫用户下载更新组件。很多时候,用户甚至都不会注意到正在发生变化。\n开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期, 大多数团队都有自动化流程来检查代码并部署到新环境。 我们一直在关注自动化测试流程,但这将在之后的文章中介绍。 今天,我们将介绍什么是 CI/CD/CD ,以及现代软件公司如何使用工具将部署代码的流程自动化。\n持续集成注重将各个开发者的工作集合到一个代码仓库中,通常每天会进行几次, 主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。 持续交付的目的是最小化部署或发布过程中团队固有的摩擦, 它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布(理想情况下)。 持续部署是一种更高程度的自动化,无论何时代码有较大改动, 都会自动进行构建/部署。\n以上的每一个阶段都是交付流水线的一部分。 Humble 和 Ferley 在他们的书作《持续交付:通过自动化构建、测试和部署实现可靠软件版本发布》中解释说: 「对软件的每次更改都要经过一个复杂的过程才能发布,该过程包括多个测试和部署阶段进行软件的构建。 反过来看,这个过程需要许多人之间的合作,甚至可能需要几个团队间合作。 部署流水线对这一过程进行建模,并且它的持续集成和发布管理工具能让您在代码从版本控制转移到各种测试和部署时, 查看和控制每次更改的过程。」\n持续集成(CI) 通过持续集成,开发人员能够频繁地将其代码集成到公共代码仓库的主分支中。 开发人员能够在任何时候多次向仓库提交作品,而不是独立地开发每个功能模块并在开发周期结束时一一提交。\n这里的一个重要思想就是让开发人员更快更、频繁地做到这一点,从而降低集成的开销。 实际情况中,开发人员在集成时经常会发现新代码和已有代码存在冲突。 如果集成较早并更加频繁,那么冲突将更容易解决且执行成本更低。\n当然,这里也有一些权衡,这个流程不提供额外的质量保障。 事实上,许多组织发现这样的集成方式开销更大,因为它们依赖人工确保新代码不会引起新的 bug 或者破坏现有代码。 为了减少集成期间的摩擦,持续集成依赖于测试套件和自动化测试。 然而,要认识到自动化测试和持续测试是完全不同的这一点很重要,我们会在文章结尾处详细说明。\nCI 的目标是将集成简化成一个简单、易于重复的日常开发任务, 这样有助于降低总体的构建成本并在开发周期的早期发现缺陷。 要想有效地使用 CI 必须转变开发团队的习惯,要鼓励频繁迭代构建, 并且在发现 bug 的早期积极解决。\n持续交付(CD)实际上是 CI 的扩展,其中软件交付流程进一步自动化,以便随时轻松地部署到生成环境中。 成熟的持续交付方案也展示了一个始终可部署的代码库。使用 CD 后,软件发布将成为一个没有任何紧张感的例行事件。 开发团队可以在日常开发的任何时间进行产品级的发布,而不需要详细的发布方案或者特殊的后期测试。\nCD 集中依赖于部署流水线,团队通过流水线自动化测试和部署过程。此流水线是一个自动化系统, 可以针对构建执行一组渐进的测试套件。CD 具有高度的自动化,并且在一些云计算环境中也易于配置。\n在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。否则,将继续进入下一个测试, 并在连续通过测试后自动进入下一个阶段。流水线的最后一个部分会将构建部署到和生产环境等效的环境中。 这是一个整体的过程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证。\nAWS 上提供了可靠的当前 CI/CD 的展示,亚马逊是云计算的提供商之一,提供出色的 CI/CD 流水线环境和实验过程, 有众多开发资源可供选择,您可以将它们在一个易于配置和监控的流水线中组合起来。\n许多人认为持续交付的吸引力主要在于,它自动化了从提交代码到仓库,再到测试和发布产品过程的所有步骤。 这是构建和测试过程细致的自动化,但是如何发布以及发布什么仍然是需要人工操作,持续部署可以改变这一点。\n持续部署(CD) 持续部署扩展了持续交付,以便软件构建在通过所有测试时自动部署。在这样的流程中, 不需要人为决定何时及如何投入生产环境。CI/CD 系统的最后一步将在构建后的组件/包退出流水线时自动部署。 此类自动部署可以配置为快速向客户分发组件、功能模块或修复补丁,并准确说明当前提供的内容。\n采用持续部署的组织可以将新功能快速传递给用户,得到用户对于新版本的快速反馈,并且可以迅速处理任何明显的缺陷。 用户对无用或者误解需求的功能的快速反馈有助于团队规划投入,避免将精力集中于不容易产生回报的地方。\n随着 DevOps 的发展,新的用来实现 CI/CD 流水线的自动化工具也在不断涌现。这些工具通常能与各种开发工具配合, 包括像 GitHub 这样的代码仓库和 Jira 这样的 bug 跟踪工具。此外,随着 SaaS 这种交付方式变得更受欢迎, 许多工具都可以在现代开发人员运行应用程序的云环境中运行,例如 GCP 和 AWS。\n最受欢迎的自动化工具是 Jenkins(以前的 Hudson), 这是一个由数百名贡献者和商业公司 Cloudbees 支持的开源项目。 Cloudbees 甚至聘请了 Jenkins 的创始人,并提供了一些 Jenkins 培训项目和附加组件。 除了开源项目之外,还有一些更现代化的商业产品例如 CircleCI,Codeship 和 Shippable。 这些产品各有优缺点,我鼓励开发人员在开发流程中一一尝试它们,以了解它们在您的环境中的工作方式, 以及它们如何与您的工具、云平台、容器系统等协作。\n在 mabl 中,我们在 Google Cloud Platform 上进行构建, 因此,我们正在寻找与 GSP 兼容或者最好是已经集成进 GSO 的产品。我们尝试过 CircleCI,Codeship 和 Shippable, 下面有一个简单的表格,展示了每个工具的一些细节:\n我们最终选择了 Codeship,我认为我们的选择是正确的, 也感谢 Codeship 团队的支持。\n接下来? 一旦部署了现代化的 CI/CD 流水线,您可能会意识到开发人员工作流程中的一些工具和流程也需要进行现代化改造。 测试是一个要着重关注的领域,如果您的部署频率是每天或者一天多次,您的每次测试可能需要数小时甚至一晚上才能完成。 mabl 正在使用机器学习解决这个问题。\n", "auhtor": "Izzyazeri", "translator": "p01son6415", "original": "https://dzone.com/articles/what-is-cicd", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/12/2018-12-19-scaling-network-connections/", "title": "从 Jenkins Master 扩展网络连接", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["jenkinsworld", "jenkinsworld2018", "cloud-native", "performance", "scalability", "remoting"], "description": "从 Jenkins Master 扩展网络连接", "content": "Oleg Nenashev 和我今年将在旧金山的 DevOps World | Jenkins World 上,做从 Jenkins Master 扩展网络连接 的演讲。 多年来,我们一直致力于分析、优化和加强 Remoting channel, 才有了现如今 master 能够协调 agent 的活动,并且接收构建的结果。 尽管许多技术可以改进服务,比如优化代理启动器,但是想要有质的改变,只有从根本上改变传播的内容和方式。\n3月,JENKINS-27035 引入了一个框架,用于检查 Remoting channel 在高级别上的通信。 以前,开发人员只能使用一般的低级工具,例如 Wireshark, 它不能精确的识别 Jenkins 负责通信的代码片段。\n在过去的几个月里,Cloud Native SIG 在解决根本原因方面取得了进展。 Artifact Manager on S3 plugin 已经发布并与 Jenkins Evergreen 整合, 支持在 agent 和 Amazon 服务器之间,进行大制品的上传和下载, 源生插件允许由 agent 生成的所有构建的日志内容(例如在 steps 的 sh 中) 直接定向流到外部存储服务,如 AWS CloudWatch Logs。 与此同时也开始上传 junit 格式的测试结果,这些测试结果有时会变的很大,将直接从 agent 到存储数据库。 所有这些努力都可以减轻 Jenkins Master 和本地网络的负载,而不需要开发人员修改他们的 pipeline 脚本。\n其他方法也在酝酿之中。 虽然“一次性”的 agent 在新的 vm 或容器中运行,可以极大地提高可重复性, 但是每一次构建都需要传输兆字节的 Java 代码,所以 Jenkins 的特征是需要对它们建立预缓存。 使用 Apache Kafka 的工作正在进行中,以使得通道在网络故障时更加健壮。 最引人注目的是,这个提议 Cloud Native Jenkins MVP 将消除单个 Jenkins Master 服务处理数百个构建的瓶颈。\n", "auhtor": "jglick", "translator": "sailingwithoutwind", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/best-practice/Android/android-best-practice/", "title": "使用 Jenkins 构建 Android 应用", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 本教程将展示 Jenkins 如何使用 Jenkins 和 Gradle 构建一个简单的 Android 应用程序。\n如果你是一个对 CI/CD 概念不了解的 Android 开发者,或者你熟悉这些概念却不知道如何使用 Jenkins 完成构建,那么本教程很适合你。你将在 GitHub 上获取一个简单的 Android 应用项目,并包含单元测试。\n耗时:本教程需要 20-40 分钟来完成(假设你的机器已经满足配置要求)。\n配置要求 对于本教程,您将需要:\n 安装有 macOS、Linux 或 Windows 操作系统的机器,并拥有以下配置:\n 最小 256 MB 内存,推荐 512MB 以上。\n 10 GB 硬盘空间,用于安装 Jenkins,您的 Docker 镜像和容器。\n 安装有以下软件:\n Docker - 在安装 Jenkins 页面的安装 Docker 章节阅读更多信息。\n注意:如果您使用 Linux,本教程假定您没有以 root 用户的身份运行 Docker 命令,而是使用单个用户帐户访问本教程中使用的其他工具。\n Git 和 GitHub Desktop。\n 在 Docker 中运行 Jenkins 在本教程中,将 Jenkins 作为 Docker 容器并从 jenkinsci/blueocean Docker 镜像中运行。\n要在 Docker 中运行 Jenkins,请遵循下面的 macOS 和 Linux 或 Windows 相关文档说明进行操作。\n你可以在 Docker 和 Installing Jenkins 页面的 Downloading and running Jenkins in Docker 部分阅读更多有关 Docker 容器和镜像概念的信息。\n在 macOS 和 Linux 系统上 打开终端窗口。\n 使用下面的 docker run 命令运行 jenkinsci/blueocean 镜像作为 Docker 中的一个容器(记住,如果本地没有镜像,这个命令会自动下载):\n docker run \\ --rm \\ -u root \\ -p 8080:8080 \\ -v jenkins-data:/var/jenkins_home \\ -v /var/run/docker.sock:/var/run/docker.sock \\ -v \u0026quot;$HOME\u0026quot;:/home \\ jenkinsci/blueocean ① `-v jenkins-data:/var/jenkins_home` 表示将容器中的 /var/jenkins_home 目录映射到 Docker volume,并将其命名为 jenkins-data。如果该卷不存在,那么 docker run 命令会自动为你创建卷。 ② `-v \u0026quot;$HOME\u0026quot;:/home` 将主机上的 $HOME 目录(即你的本地)映射到(通常是 /Users/\u0026lt;your-username\u0026gt; 目录)到容器的 /home 目录。 继续向导 在 Windows 系统 打开命令提示窗口。\n 使用下面的 docker run 命令运行 jenkinsci/blueocean 镜像作为 Docker 中的一个容器(记住,如果本地没有镜像,这个命令会自动下载):\n docker run ^ --rm ^ -u root ^ -p 8080:8080 ^ -v jenkins-data:/var/jenkins_home ^ -v /var/run/docker.sock:/var/run/docker.sock ^ -v \u0026quot;%HOMEPATH%\u0026quot;:/home ^ jenkinsci/blueocean 对这些选项的解释,请参考上面的 macOS 和 Linux 说明。 继续安装向导。 访问 Jenkins/Blue Ocean Docker 容器 如果你有一些使用 Docker 的经验,希望或需要使用 docker exec 命令通过一个终端/命令提示符来访问 Jenkins/Blue Ocean Docker 容器,你可以添加如 \u0026ndash;name jenkins-tutorials 选项(与上面的 docker run),这将会给 Jenkins/Blue Ocean Docker 容器一个名字 \u0026ldquo;jenkins-tutorials\u0026rdquo;。\n这意味着你可以通过 docker exec 命令访问 Jenkins/Blue Ocean 容器(通过一个单独的终端/命令提示窗口),例如:\ndocker exec -it jenkins-tutorials bash 安装向导 在你访问 Jenkins 之前,你需要执行一些快速的\u0026rdquo;一次性\u0026rdquo;步骤。\n解锁 Jenkins 当你第一次访问一个新的 Jenkins 实例时,要求你使用自动生成的密码对其进行解锁。\n 当在终端/命令提示窗口出现两组星号时,浏览 http://localhost:8080 并等待 Unlock Jenkins 页面出现。\n 再次从终端/命令提示窗口,复制自动生成的字母数字密码(在两组星号之间)。\n 在 Unlock Jenkins 页面,粘贴该密码到 Administrator password 字段并点击 Continue。\n 使用插件自定义 Jenkins 在解锁 Jenkins 后,Customize Jenkins 页面出现。\n在该页面,点击 Install suggested plugins。\n安装向导显示了正在配置的 Jenkins 的进程,以及建议安装的插件,这个过程可能需要几分钟。\n创建第一个管理员用户 最后,Jenkins 要求创建你的第一个管理员用户。\n 当 Create First Admin User 页面出现,在相应的字段中指定你的详细消息并点击 Save and Finish。\n 当 Jenkins is ready 页面出现,点击 Start using Jenkins。\n注意:该页面可能表明 Jenkins is almost ready!如果相反,点击 Restart。\n 如果该页面在一分钟后没有自动刷新,使用你的 web 浏览器手动刷新。\n 如果需要,登录 Jenkins,你就可以开始使用 Jenkins 了!\n停止和重启 Jenkins 在本教程的其余部分,你可以通过在终端/命令提示窗口输入 Ctrl-C 停止 Jenkins/Blue Ocean Docker 容器,也可以运行上面 docker run ... 命令启动容器。\n要重启 Jenkins/Blue Ocean Docker 容器:\n 在上面的 macOS、Linux 或 Windows 上运行相同的 docker run \u0026hellip; 命令。\n注意:如果有更新的话,该进程会更新 jenkinsci/blueocean Docker 镜像。\n 浏览 http://localhost:8080。\n 等待直到登录页面出现并登陆。\n Fork 和 clone GitHub 示例仓库 通过将应用程序源代码所在的示例仓库 fork 到你自己的 GitHub 账号中,并 clone 到本地,你就可以获取一简单的 Android 应用程序。\n 请确保你登陆了你的 GitHub 账户。如果你还没有 GitHub 账户,你可以在 GitHub 网站免费注册一个账户。\n 将示例仓库 jenkins-android-sample fork 到你的账户的 GitHub 仓库中。\n 将你的 GitHub 账户中的 jenkins-android-sample 仓库 clone 到你的本地机器,确保你的项目路径为:\n macOS 系统配置为 /Users/\u0026lt;your-username\u0026gt;/Documents/GitHub/jenkins-android-sample\n Linux 系统配置为 /home/\u0026lt;your-username\u0026gt;/GitHub/jenkins-android-sample\n Windows 系统配置为 C:\\Users\\\u0026lt;your-username\u0026gt;\\Documents\\GitHub\\jenkins-android-sample\n 在 Jenkins 中创建你的流水线项目 回到 Jenkins,如果有必要的话重新登录,点击 Welcome to Jenkins!下方的 create new jobs。\n注意:如果你无法看见以上内容,点击左上方的 New Item。\n 在 Enter an item name 域中,为新的流水线项目指定名称(例如 jenkins-android-sample)。\n 向下滚动并单击 Pipeline,然后单击页面末尾的 OK。\n 4.(可选)在下一页中,在 Description 字段中填写流水线的简要描述。\n 点击页面顶部的 Pipeline 选项卡,向下滚动到 Pipeline 部分。\n 在 Definition 域中,选择 Pipeline script from SCM 选项。此选项指示 Jenkins 从源代码管理(SCM)仓库获取你的流水线,这里的仓库就是你 clone 到本地的 Git 仓库。\n 在 SCM 域中,选择 Git。\n 在 Repository URL 域中,填写你本地仓库的目录路径,这是从你主机上的用户账户 home 目录映射到 Jenkins 容器的 /home 目录:\n MacOS系统 - /home/Documents/GitHub/jenkins-android-sample Linux系统 - /home/GitHub/jenkins-android-sample Windows系统 - /home/Documents/GitHub/jenkins-android-sample 点击 Save 保存你的流水线项目。你现在可以开始创建你的 Jenkinsfile,这些文件会被添加到你的本地仓库。\n 创建 Jenkinsfile 为初始流水线 现在我们将开始创建初始流水线,它将使用 Jenkins 构建你的 Android 应用程序。你的流水线将被创建为 Jenkinsfile,它将被提交到你本地的 Git 仓库(jenkins-android-sample)。\n首先,创建一个初始流水线来下载 Android 编译环境的 Docker 镜像,并将其作为 Docker 容器运行。同时添加一个 \u0026ldquo;Build\u0026rdquo; 阶段到流水线中,用于协调整个过程。\n 使用你最称手的文本编辑器或者 IDE,在你本地的 jenkins-android-sample Git 仓库的根目录创建并保存一个名为 Jenkinsfile 的文本文件。\n 复制以下声明式流水线代码并粘贴到 Jenkinsfile 文件中:\n pipeline{ agent { docker { image 'allbears/jenkins-android:1.0.1' //① } } stages { stage('Build'){ steps { sh './gradlew clean \u0026amp;\u0026amp; rm -rf ./app/build/' //② sh './gradlew assembleRelease' //③ } } } } ① 这里的 image 参数是用来下载 allbears/jenkins-android:1.0.1 Docker 镜像(如果你的机器还没下载过它)并将该镜像作为单独的容器运行。你也可以用 `docker pull allbears/jenkins-android:1.0.1` 命令预先将镜像下载到你的宿主机上。 ② 这里的 sh step 是在编译前进行一些准备动作,对你的工程环境进行清理,确保工作时,编译工程环境干净。 ③ 这里的 sh step 运行的是一个 gradle 构建 release 包的命令。 保存对 Jenkinsfile 的修改并且将其提交到你本地的 jenkins-android-sample Git 仓库。例如,在 jenkins-android-sample 目录下,运行以下命令:\ngit add .\n继续运行:\ngit commit -m \u0026ldquo;Add initial Jenkinsfile\u0026rdquo;\n 再次回到 Jenkins,如果有必要的话重新登录,点击左侧的 Open Blue Ocean 进入 Jenkins 的 Blue Ocean 界面。\n 在 This job has not been run 消息框中,点击 Run,然后快速点击右下角出现的 OPEN 链接,观察 Jenkins 运行你的流水线项目。如果你不能点击 OPEN 链接,点击 Blue Ocean 主界面的这一行来使用这一特性。\n注意:你可能需要几分钟时间等待第一次运行完成。在 clone 了你的本地 jenkins-android-sample Git 仓库后,Jenkins 接下来做了以下动作,构建过程如图所示:\n 将项目排入队列等待在 agent 上运行。\n 下载 jenkins-android Docker 镜像,并且将其运行在 Docker 中的一个容器中。\n 执行 assembleRelease 包构建 Release 包。\n 构建成功结束后,该界面将会变成绿色的,构建后的产物将会保存在 /var/jenkins_home/workspace/jenkins-android-sample/app/build/outputs/apk/release 目录下。\n点击上面的 X 就可以回到主界面。\n增加单元测试阶段 打开你的 Jenkinsfile 文件,编辑。 下面的代码复制到你的 Jenkinsflie 中并置于 Build 阶段下方,保存。 stage('UnitTest'){ steps { sh './gradlew test' } } ① `stage('UnitTest')` 这里增加了一个 UnitTest 的 stage,之后会出现在 Jenkins UI 上。 ② `sh './gradlew test'` 这里的 sh step 运行的是一个 gradle 执行单元测试的命令,该命令执行之后会进行单元测试。 最终代码如下所示:\npipeline{ agent { docker { image 'allbears/jenkins-android:1.0.1' } } stages { stage('Build'){ steps { sh './gradlew clean \u0026amp;\u0026amp; rm -rf ./app/build/' sh './gradlew assembleRelease' } } stage('UnitTest'){ steps { sh './gradlew test' } } } } 继续 保存对 Jenkinsfile 的修改并将其提交到你的本地 jenkins-android-sample Git 仓库。例如,在 jenkins-android-sample 目录下,运行以下命令:\ngit add .\n继续运行:\ngit commit -m \u0026ldquo;Add \u0026lsquo;Test\u0026rsquo; stage\u0026rdquo;\n 再次回到 Jenkins,如果有必要的话重新登录,进入 Jenkins 的 Blue Ocean 界面。\n 点击上方的运行,然后快速点击右下方出现的 OPEN 链接,观察 Jenkins 运行你修改过的流水线项目。如果你不能点击 OPEN 链接,点击 Blue Ocean 主界面的 top 行来使用这一特性,如下图。\n 可以看到在我们的 UI 中增加了一个 UnitTest 的阶段,点击右上方的 X 回到 Blue Ocean 主界面。\n 流水线增加交付阶段 回到你的文本编辑器/ IDE,打开你的 Jenkinsfile。 复制以下声明式流水线代码,并粘贴到 Jenkinsfile 中 UnitTest 阶段的下方: stage('Archive') { steps { archiveArtifacts artifacts: 'app/build/outputs/**/*.apk', fingerprint: true } } ① `stage('Archive')` 这里定义了一个名为 Archive 的 stage,之后会出现在 Jenkins UI 上。 ② `archiveArtifacts` 这一行执行了一个归档构建产物的操作,执行完这步操作后我们将在任务界面看见我们执行成功后的产物输出。 最终的代码如下:\npipeline{ agent { docker { image 'allbears/jenkins-android:1.0.1' } } stages { stage('Build'){ steps { sh './gradlew clean \u0026amp;\u0026amp; rm -rf ./app/build/' sh './gradlew assembleRelease' } } stage('UnitTest'){ steps { sh './gradlew test' } } stage('Archive') { steps { archiveArtifacts artifacts: 'app/build/outputs/**/*.apk', fingerprint: true } } } } 继续 保存对 Jenkinsfile 的修改并将其提交到你的本地 jenkins-android-sample Git 仓库。例如,在 jenkins-android-sample 目录下,运行以下命令:\ngit add .\n继续运行:\ngit commit -m \u0026ldquo;Add \u0026lsquo;Archive\u0026rsquo; stage\u0026rdquo;\n 再次回到 Jenkins,如果有必要的话重新登录,进入 Jenkins 的 Blue Ocean 界面。\n 点击上方的运行,然后快速点击右下方出现的 OPEN 链接,观察 Jenkins 运行你修改过的流水线项目。如果你不能点击 OPEN 链接,点击 Blue Ocean 主界面的 top 行来使用这一特性,如图。\n 可以看到我们的 UI 中多了一个 Archive 阶段,构建完成后点击 X 关闭回到我们 Job 主界面,我们可以发现这时多了一个产物的归档下载连接。\n总结 刚刚使用 Jenkins 构建了一个简单的 Android 应用程序,覆盖编译,测试,产物输出的全过程,当然其中还有些优化点,比如我们可以将编译环境中的 Gradle 路径挂载到宿主机,避免每次运行都需要下载依赖包。\n", "auhtor": "Sakuragi", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/01/2019-01-23-configuring-jenkins-pipeline-with-yaml-file/", "title": "使用 YAML 文件配置 Jenkins 流水线", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["pipeline"], "description": "这也是一种自定义流水线 DSL 的方法", "content": " 几年前,我们的 CTO 写了一篇关于 使用 Jenkins 和 Docker 为 Ruby On Rails 应用提供持续集成服务 的文章。这些年,我们一直使用这个 CI 流水线解决方案,直到我们最近决定做一次升级。为什么呢?\n Jenkins 的版本过低,已经很难升级 Wolox 过去几年增长显著,一直面临着如何伸缩的问题 只有极少数人如何修复 Jenkins 服务的问题 配置 Jenkins 任务不是一件简单的任务,使我们的项目启动过程变慢 更改每个作业运行的命令也不是一件简单的任务,并且有权限更改的人并不多。 Wolox 拥有广泛的项目,语言种类繁多,使得这个问题尤为突显。 考虑到这些问题,我们开始深入研究最新版的 Jenkins,看看如何提升我们的 CI 服务。我们需要构建一个新的CI服务,至少要解决以下问题:\n 支持 Docker 构建。我们的项目依赖的一个或多个 Docker 镜像的执行(应用,数据库,Redis 等) 如有必要,易于配置和复制 易于增加新项目 易于修改构建步骤。工作在项目上的所有人都应该能修改它,如果他们希望执行 npm install 或 yarn install 安装Jenkins和Docker 安装 Jenkins 非常简单,直接从 官方教程 选择一种方式安装。\n以下是我们在 AWS 上的安装步骤:\nsudo rpm — import https://pkg.jenkins.io/debian/jenkins.io.key sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat/jenkins.repo sudo yum install java-1.8.0 -y sudo yum remove java-1.7.0-openjdk -y sudo yum install jenkins -y sudo yum update -y sudo yum install -y docker 从 GitHub 上自动添加项目 从 Github 上自动添加项目可以通过 GitHub Branch Source 插件实现。它能将 GitHub 的组织中符合规则的项目自动添加到 Jenkins 中。唯一的约束就是在每一个分支下都必须有一个 Jenkinsfile,用于描述如何构建项目。\n易于修改的配置 我们之前使用 Jenkins 最痛苦的是修改项目的构建步骤。在 Jenkins 任务中,你会看到像以下代码(用于构建):\n#!/bin/bash +x set -e # Remove unnecessary files echo -e \u0026quot;\\033[34mRemoving unnecessary files...\\033[0m\u0026quot; rm -f log/*.log \u0026amp;\u0026gt; /dev/null || true \u0026amp;\u0026gt; /dev/null rm -rf public/uploads/* \u0026amp;\u0026gt; /dev/null || true \u0026amp;\u0026gt; /dev/null # Build Project echo -e \u0026quot;\\033[34mBuilding Project...\\033[0m\u0026quot; docker-compose --project-name=${JOB_NAME} build # Prepare test database COMMAND=\u0026quot;bundle exec rake db:drop db:create db:migrate\u0026quot; echo -e \u0026quot;\\033[34mRunning: $COMMAND\\033[0m\u0026quot; docker-compose --project-name=${JOB_NAME} run \\ -e RAILS_ENV=test web $COMMAND # Run tests COMMAND=\u0026quot;bundle exec rspec spec\u0026quot; echo -e \u0026quot;\\033[34mRunning: $COMMAND\\033[0m\u0026quot; unbuffer docker-compose --project-name=${JOB_NAME} run web $COMMAND # Run rubocop lint COMMAND=\u0026quot;bundle exec rubocop app spec -R --format simple\u0026quot; echo -e \u0026quot;\\033[34mRunning: $COMMAND\\033[0m\u0026quot; unbuffer docker-compose --project-name=${JOB_NAME} run -e RUBYOPT=\u0026quot;-Ku\u0026quot; web $COMMAND 在构建步骤后,执行 Docker 构建的清理工作:\n#!/bin/bash +x docker-compose --project-name=${JOB_NAME} stop \u0026amp;\u0026gt; /dev/null || true \u0026amp;\u0026gt; /dev/null docker-compose --project-name=${JOB_NAME} rm --force \u0026amp;\u0026gt; /dev/null || true \u0026amp;\u0026gt; /dev/null docker stop `docker ps -a -q -f status=exited` \u0026amp;\u0026gt; /dev/null || true \u0026amp;\u0026gt; /dev/null docker rm -v `docker ps -a -q -f status=exited` \u0026amp;\u0026gt; /dev/null || true \u0026amp;\u0026gt; /dev/null docker rmi `docker images --filter 'dangling=true' -q --no-trunc` \u0026amp;\u0026gt; /dev/null || true \u0026amp;\u0026gt; /dev/null 尽管这些命令并不复杂,但是更改其中的任何命令都需要具有权限的人员来操作相应的 Jenkins 任务,并清楚知道自己需要做什么。\nJenkinsfile的成与败 使用当前的 Jenkins 版本,我们可以利用 Jenkins pipeline 对我们的构建流进行建模,并保存到一个文件中。 该文件会被签入代码库。因此,任何有权访问它的人都可以修改其中的步骤。棒极了。\nJenkins 流水线还支持:\n Docker 及多个镜像可用于构建 使用 withEnv 设置环境变量,还支持很多其它内建的 函数 这为 Wolox 提供了完美的用例。我们可以将构建配置写入到一个被检入到代码库的文件中,并且允许任务有权限访问的人修改。但是,一个简单的 Rails 项目的 Jenkinsfile 看起来却像这样:\n# sample Jenkinsfile. Might not compile node { checkout scm withEnv(['MYTOOL_HOME=/usr/local/mytool']) { docker.image(\u0026quot;postgres:9.2\u0026quot;).withRun() { db -\u0026gt; withEnv(['DB_USERNAME=postgres', 'DB_PASSWORD=', \u0026quot;DB_HOST=db\u0026quot;, \u0026quot;DB_PORT=5432\u0026quot;]) { docker.image(\u0026quot;redis:X\u0026quot;).withRun() { redis -\u0026gt; withEnv([\u0026quot;REDIS_URL=redis://redis\u0026quot;]) { docker.build(imageName, \u0026quot;--file .woloxci/Dockerfile .\u0026quot;).inside(\u0026quot;--link ${db.id}:postgres --link ${redis.id}:redis\u0026quot;) { sh \u0026quot;rake db:create\u0026quot; sh \u0026quot;rake db:migrate\u0026quot; sh \u0026quot;bundle exec rspec spec\u0026quot; } } } } } } } 这样的文件不仅难以理解,还难以修改。这样的构建逻辑非常容易被破坏,如果你不熟悉 Groovy。如果你对 Jenkins 流水线是如何工作的一无所知,就更容易了。这样,修改或增加一个新的 Docker 镜像就变得不简单,也容易导致混淆。\n通过 YAML 配置 Jenkins 流水线 就个人而言,我总是期望为 CI 配置简单的配置文件。这次我们有机会构建使用 YAML 文件配置的 CI。经过分析,我们总结出以下这样的 YAML,它已经能满足我们的需求:\nconfig: dockerfile: .woloxci/Dockerfile project_name: some-project-name services: - postgresql - redis steps: analysis: - bundle exec rubocop -R app spec --format simple - bundle exec rubycritic --path ./analysis --minimum-score 80 --no-browser setup_db: - bundle exec rails db:create - bundle exec rails db:schema:load test: - bundle exec rspec security: - bundle exec brakeman --exit-on-error audit: - bundle audit check --update environment: RAILS_ENV: test GIT_COMMITTER_NAME: a GIT_COMMITTER_EMAIL: b LANG: C.UTF-8 它描述了项目基本的配置、构建过程中需要的环境变量、依赖的服务、还有构建步骤。\nJenkinsfile + Shared Libraries = WoloxCI 经过调研 Jenkins 和流水线之后,我们发现可以通过扩展共享库(shared libraries)来实现。共享库是用 Groovy 编写的,可以导入到流水线中,并在必要时执行。\n如果你细心观察以下 Jenkinsfile,你会看到代码是一个接收闭包的方法调用链,我们执行另一个方法将一个新的闭包传递给它。\n# sample Jenkinsfile. Might not compile node { checkout scm withEnv(['MYTOOL_HOME=/usr/local/mytool']) { docker.image(\u0026quot;postgres:9.2\u0026quot;).withRun() { db -\u0026gt; withEnv(['DB_USERNAME=postgres', 'DB_PASSWORD=', \u0026quot;DB_HOST=db\u0026quot;, \u0026quot;DB_PORT=5432\u0026quot;]) { docker.image(\u0026quot;redis:X\u0026quot;).withRun() { redis -\u0026gt; withEnv([\u0026quot;REDIS_URL=redis://redis\u0026quot;]) { docker.build(imageName, \u0026quot;--file .woloxci/Dockerfile .\u0026quot;).inside(\u0026quot;--link ${db.id}:postgres --link ${redis.id}:redis\u0026quot;) { sh \u0026quot;rake db:create\u0026quot; sh \u0026quot;rake db:migrate\u0026quot; sh \u0026quot;bundle exec rspec spec\u0026quot; } } } } } } } Groovy 语言足够灵活,能在在运行时创建声明式代码,这使我们能使用 YAML 来配置我们的流水线!\nWolox-CI介绍 wolox-ci 诞生于 Jenkins 的共享库。以下是关于 Wolox-CI 的具体使用方式。\n使用 wolox-ci,Jenkinsfile 被精简成:\n@Library('wolox-ci') _ node { checkout scm woloxCi('.woloxci/config.yml'); } 它会检出代码,然后调用 wolox-ci。共享库代码会读取到 YAML 文件,如下:\nconfig: dockerfile: .woloxci/Dockerfile project_name: some-project-name services: - postgresql - redis steps: analysis: - bundle exec rubocop -R app spec –format simple - bundle exec rubycritic –path ./analysis –minimum-score 80 –no-browser setup_db: - bundle exec rails db:create - bundle exec rails db:schema:load test: - bundle exec rspec security: - bundle exec brakeman –exit-on-error audit: - bundle audit check –update environment: RAILS_ENV: test GIT_COMMITTER_NAME: a GIT_COMMITTER_EMAIL: b LANG: C.UTF-8 然后,Jenkins 就会执行你的构建任务。\n共享库有一个好处是我们可以集中扩展和修改我们的共享库代码。一旦添加新代码,Jenkins 就会自动更新它,还会通知所有的任务。\n由于我们有不同语言的项目,我们使用 Docker 来构建测试环境。WoloxCI 假设有一个 Dockerfile 要构建,并将在容器内运行所有指定的命令。\nconfig.yml 各部分介绍 config部分 这是 config.yml 的第一部分,用于指定基本配置,包括项目的名称,Dockerfile 的路径。Dockerfile 用于构建镜像,所有的命令都运行在该镜像的容器中。\nServices 部分 这部分定义了哪些服务被暴露到容器中。WoloxCI 支持以下开箱即用的服务:postgresql、mssql 和 redis。你还可以指定 Docker 镜像的版本。\n增加一个新的服务类型也不难。你只需要在该目录下(https://github.com/Wolox/wolox-ci/tree/development/vars)添加,然后告诉共享库该服务是如何被转换的,如https://github.com/Wolox/wolox-ci/blob/development/src/com/wolox/parser/ConfigParser.groovy#L76\nSteps 部分 在此部分列出的命令,都会被运行在 Docker 容器中。你可以在 Jenkins 界面上看到每一步的执行结果。\nEnvironment 部分 如果构建过程需要一些环境变量,你可以在这部分指定它们。Steps 部分中描述的步骤执行过程中,Docker 容器会提供你设置好的所有环境变量。\n总结 目前,WoloxCI 还在我们所有项目中一小部分项目进行测试。这让有权限访问它的人通过 YAML 文件更改构建步骤。这是对我们 CI 工作流程来说是一个重大改进。\nDocker 使我们轻松更换编程语言,而不用对 Jenkins 安装做任何的更改。并且,当检查到 GitHub 组织中的新项目(项目中有 Jenkinsfile)时,Jenkins GitHub Branch Source 插件会自动添加新的 Jenkins 项目。\n所有这些改进节约了我们维护 Jenkins 的大量时间,并使我们可以轻松扩展而无需任何额外配置。\n译者小结 本文最大的亮点是它介绍了一种实现自定义构建语言的方式。通过 Jenkins 的共享库技术,将构建逻辑从 Jenkinsfile 中移到了 YAML 文件中。同样的,我们可以将构建逻辑移动 JSON 文件中,或者任何格式的文件中,只你的共享库能解析它,并将它转换成 Jenkins 能理解的格式。\n", "auhtor": "Matias De Santi", "translator": "zacker330", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E5%85%AC%E5%91%8A/", "title": "公告", "type": "tags", "date": "2020-05-28 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/pipeline/shared-library/", "title": "共享库", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "待补充\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/", "title": "关于我们", "type": "about", "date": "2019-09-07 00:00:00 +0000 UTC", "tags": [], "description": "有关于 Jenkins 中文社区相关介绍", "content": "Jenkins 中文社区是由 Jenkins 国内的爱好者、贡献者组成,共同推广以及完善 CI/CD 技术的学习试用和落地。我们秉承开源的精神,在社区治理上高度开放,代码、文档以及设计等开源免费,致力于为我们的用户带来更好的体验。\n为了能让 Jenkins 的技术爱好者、用户有个方便讨论、学习的场所,我们提供了社区论坛、微信群。另外,在我们定期的网络研讨会上,会邀请业界的讲师来分享关于 DevOps 的技术话题。回放的视频可以在哔哩哔哩上找到。除了线上、线下的交流活动的内容外,社区还有很多志愿者提供的原创、翻译博文会在社区官网、Jenkins 官方微信公众号上发布,并在开源中国、知乎等平台进行转载。\n另外,本着以开源技术服务开源用户的精神,社区还维护着多个开源项目,包括:Jenkins 国内定制发行版、Jenkins CLI、简体中文插件。\n我们欢迎任何人以任何形式为开源社区做贡献,为了保障社区的基础设施得以健康、持续地运营下去,在此呼吁更多对开源事业认可的企业以及个人给予捐助。\n每个双周周三 21:00 的社区例会上,我们会公开讨论社区的事务。\n请准守我们的行为规范,文明留言。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/about/about-site/", "title": "关于本站", "type": "about", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "本站的架构", "content": "Jenkins 中文社区站点是基于 Hugo 生成的静态文件,托管在 GitHub Page 上。下面列出相关的源码位置:\n 网站内容 网站主题 微信订阅号 ", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/12/2018-12-25-year-in-review/", "title": "回顾 2018: 革新的一年", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["core", "community"], "description": "Jenkins 创始人 KK 先生的年终总结", "content": "临近年终,是一个思考总结、展望全局的好时机。那就让我们暂时从日常繁复的工作中停下脚步,一起来盘点 Jenkins 在 2018 这一年的得失与喜乐。\n在整个行业中,对进一步自动化的不懈追求仍在继续。我们正以前所未有的速度编写软件,与此同时,对于软件的需求似乎越来越高,我觉得越来越多的企业和高管都敏锐地意识到软件和开发者已登基为王。在底层的角度,我遇到的每个团队都认为软件交付自动化是他们的“软件工厂”的关键部分,对这些团队而言,创建、管理具有不可思议的灵活性和可视性的自动化十分重要。\n自诞生14年以来,Jenkins 将继续在实现这一目标上发挥重要作用,总之,增长的步伐似乎正在加速。在这个发展飞快的行业里,成为这一成就的一份子着实让我感到自豪。\n把 Jenkins 打造为每个人都会使用的工具,这具有很大的责任感。所以在 Jenkins 社区,我们一直都十分努力。事实上,在各个领域和层面上来说,*2018年是整个项目历史上最具有创新性的一年*。\n 随着不断发展壮大,我们亟需探索出能使更多人更好地参与其中的方法。JEPs 和 SIGs 便应运而生。2018年,我们看到了这些形式得到了巨大的吸引力。经过一年的运营,我认为我们已经学到了很多东西,希望我们会在此基础上继续改进。 这些新的形式带来了新的协作方式。例如:中文本地化 SIG运营的 微信公众号和本地化网站。平台 SIG 在 Java 11 support 中也给予了不少帮助。 我也很高兴看到新一批领导者。由于害怕遗漏一些人,所以我不打算在此一一列出,我们在今年秋天祝贺他们中的许多人作为 Jenkins 大使(请在明年提名更多人!)。那些领导关键工作的人往往是那些不熟悉这些角色的人。 一些领导者也努力发掘新的贡献者。我们正在有意识地思考,我们哪一部分的潜在贡献者没有被发掘出来,为什么没有被发掘出来。这也是任一个企业都在做的事情。同时我们也是 Google Summer of Code 和 Outreachy 参与者。 今年我们的安全流程和修复速度再次大幅提升,反映出用户对我们的信任也随之增强。例如,我们今年推出了遥测系统,通知我们更快地开发出更好的修复方案。 现在,社区改进的最重要的地方是我们为您使用的软件带来的影响。在这一方面,我认为我们在2018年做得不错,产生了我所谓的“五个超级武器”\n Jenkins X 可能是今年最明显的创新,使得在 Kubernetes 上创建现代云应用程序变得更加容易。这也标志着 Jenkins 社区及其使命的重大扩展。 Jenkins Configuration as Code 在今年达到了一重要的里程碑 \u0026ldquo;1.0\u0026rdquo; ,并且他继续获得更大的动力。 \u0026ldquo;Cloud Native Jenkins\u0026rdquo; 是我为新努力作的术语,把 Jenkins 转换为 Kubernetes 上大规模运行的通用 CI/CD 引擎。这里还有许多东西需要定义,但你已经可以看到如 Serverless Jenkins 这样的好东西了。 Evergreen 是另一个需要推出的新项目,它有着雄心勃勃的主题——大量地简化了 Jenkins 的使用和操作。 流水线方面的努力形成了一个新的 SIG,我期待它在2019年带来的新影响。 Jenkins 社区能够将用户可见的改变与社区的改进结合在一起,这不仅是不算秘密的秘密,也是社区不断发展的能力。 展望2019年,毫无疑问,随着我们不断地学习和实践,上述提到的事情将不断地发展、变化、融合和分裂。\n所以,请在 Twitter 上关注 @jenkinsci 和 @jenkinsxio,了解我们将如何发展的最新动态,加入我们的社区来共同构建震撼世界的软件。多少开源项目敢说出这种话呢?\n", "auhtor": "kohsuke", "translator": "arjenzhou", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/notify/email/email/", "title": "在 Jenkins 中配置邮件服务器", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 我们需要在系统管理》系统设置中配置邮件服务器的信息。\n在邮件通知区域,给出类似如下的配置:\n 配置项 样例值 说明 SMTP服务器 smtp.exmail.qq.com 用户默认邮件后缀 @jenkins-zh.cn SMTP服务器 smtp.exmail.qq.com 用户名 demo@jenkins-zh.cn 密码 demo 使用SSL协议 SMTP端口 465 Reply-To Address demo@jenkins-zh.cn 字符集 UTF-8 腾讯企业邮箱 上面给出的例子就是腾讯企业邮箱的配置,对于密码部分,我们需要生成客户端密码。\n流水线 当我们通过上面的步骤,将邮件服务器配置成功后,就可以使用类似如下的流水线步骤来发送邮件了。\nmail bcc: '', body: 'Here is the content.', cc: 'demo@jenkins-zh.cn', from: '', replyTo: '', subject: 'subject', to: 'demo@jenkins-zh.cn'\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2018/11/2018-11-21-validate-jenkinsfile/", "title": "在 VS Code 中校验 Jenkinsfile", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "VS Code 中的 Jenkinsfile 插件", "content": "在日常工作中,我经常需要创建或修改很多 Jenkinsfile,有时还会发生错误。这是一个非常繁琐的流程——修改 Jenkinsfile,提交、推送,然后等 Jenkins 提醒你少加了一个括号。\nCommand-line Pipeline Linter(https://jenkins.io/doc/book/pipeline/development/) 可以有效地减少编写 Jenkinsfile 所需要的调试时间,但是它也有一些不方便的地方。你需要使用像 curl 或 ssh 的工具来连接你的 Jenkins,还需要正确地记住验证 Jenkinsfile 的命令。尽管如此,对我来说,这个方案还是不尽如人意。\n鉴于每天都会使用 VS Code,于是我开始着手为此研发插件,使得校验 Jenkinsfile 变得更加友好。\nJenkins Pipeline Linter Connector 的作用就是,把当前打开的文件推送到你的 Jenkins,然后在 VS Code 中显示校验结果。\n你可以在 VS Code 插件浏览器中或通过下面的地址找到该插件 https://marketplace.visualstudio.com/items?itemName=janjoerke.jenkins-pipeline-linter-connector 。\n该插件会在 VS Code 中添加四个配置选项,你必须要使用这些选项来配置用于验证的 Jenkins。\n jenkins.pipeline.linter.connector.url 是 Jenkins 期望的 POST 请求地址,包含你要校验的 Jenkinsfile 文件。通常为 *http:///pipeline-model-converter/validate*。 jenkins.pipeline.linter.connector.user 允许指定你的 Jenkins 用户名。 jenkins.pipeline.linter.connector.pass 允许指定你的 Jenkins 密码。 jenkins.pipeline.linter.connector.crumbUrl 当你的 Jenkins 启用了 CRSF 时必须指定。通常为 *http:///crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)*。 ​ ", "auhtor": "janjoerke", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/01/2019-01-16-webhook-firewalls/", "title": "在安全防火墙内通过 WebHook 触发构建", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["jenkins", "webhooks", "security"], "description": "谁说局域网里就不能带 GitHub 的 WebHook 玩?", "content": " 在这篇文章中,我将向大家展示,如何让运行在防火墙内的 Jenkins 依然可以实时地收到 GitHub 的 WebHook。当然,你也可以把这个方法应用到如 BitBucket、 DockerHub 或任何可以推送 WebHook 的其他服务中。但是,下面的步骤仅适用于托管在 GitHub 上的项目。\n什么是 WebHook 简单地描述下什么是 WebHook:事件消息(通常是 JSON,也可以是其他的)由服务端以 HTTP(S) 协议发送到监听的客户端。\n事件流自左到右,Jenkins 会监听类似 /github-webhook/ 或 /dockerhub-webhook/ 等路径上的 HTTP 请求,唤醒并执行一些任务。\nGitHub 或 BitBucket 可能会报告一个新的提交或 PR,DockerHub 报告一个上游的镜像发生了变更。这些事情的共同之处在于,它们会推送给 Jenkins,并期待可以推送成功(例如:可以访问到 Jenkins)。在网络是开放的情况下时,例如 GitHub 企业版 或 Jenkins 在监听公网时,这是可以正常工作的。\n内网环境 当有东西挡在中间时,也就是防火墙:\n(_按照行业标准,所有防火墙都必须能起到屏障的作用。因此,无论如何,请不要在你的组织内搞破坏_)\n当你在笔记本电脑上运行 Jenkins 并希望从 GitHub 接收 WebHook 时,这也是一样的。可能是为了测试你的设置,也可能是为了在 Mac 上运行 iOS 版本构建,又或者是部分网络没有暴露在互联网中,这都是合理的。 除非你的笔记本电脑可以让整个互联网访问到(这当然不太可能),或者你的网络配置得恰到好处,否则网络连接将无法流动,此时 WebHook是不可用的。\n没关系,我们可以退而求其次,使用轮询变更的方式。只是这样很糟糕。你会用尽 API 配额,还无法实时地获取变更,这真的不是一个好方法。\n问题可能也是机会 我们可以解决这个问题,但也可以把这个视为一个机会。有的东西在互联网中不可访问,或者以某些默认的方法锁定是一个特色,不是一个 Bug。你可以很大程度上减少你的攻击面,同时可以进行深度防护:\n一个 WebHook 转发服务 输入 link:https://smee.io/[Smee] 这个很容易记住的名字。这是一个由 GitHub 提供的 link:https://github.com/probot/smee[开源软件项目],还能以服务的方式托管在 GitHub 上。这可以为你捕获并转发 WebHook。我会用一个图来给你解释它。\nGitHub 把一个事件(该场景下是通过 HTTPS/json)推送给 Smee.io(也就是圆圈标记的部分,暴露在互联网上并能被 GitHub 访问到),而 Jenkins 通过一个客户端使用一个向外的连接订阅 Smee 。注意箭头的方向:Jenkins 只有一个向外的连接。\n这一点很重要,只要防火墙允许向外访问就可以工作(像 NAT 以及其他网络通常就是这样的)。如果 Jenkins 无法访问外部的任何服务,那么,本文也就当然不会有什么帮助了(但是这通常不会出现的)。\n设置 步骤1:首先,访问 https://smee.io/ 并点击 “Start a new channel”:\n你会得到一个唯一的 URL(你应该拷贝出来以便后续使用):\n然后,在你运行 Jenkins 的地方安装 smee 客户端:\nnpm install --global smee-client\n(这让 smee 命令行客户端可以接收并转发 WebHook)。\n现在,启动 smee 客户端并指向你的 Jenkins。在该案例中,我的 Jenkins 运行在 8080 端口(这是默认的,如果在你的笔记本上运行的话,根据需要修改端口和 smee 地址):\nsmee --url https://smee.io/GSm1B40sRfBvSjYS --path /github-webhook/ --port 8080\n这样的话,会连接 smee 服务并转发 WebHook 到 /github-webhook/(最后的斜线很重要,不要丢了)。当运行起来,你将会从日志里看到,它已经连接并转发 WebHook。只要你希望能收到 WebHook 就需要保持该命令的运行。\n下一步,你需要配置一个使用 GitHub 的流水线。这里我从头开始配置。如果你已经有了一个的话,可以跳过:\n我选择 GitHub 作为代码仓库:\n然后,选择你的仓库。这将会设置好来准备接收来自 GitHub 的 WebHook(如果你已经有了流水线,并使用 GitHub 作为 SCM 源,那么也是可以的)。\n最后一步,是告诉 GitHub 为那个仓库(或组织也可以)发送 WebHook 事件给 Smee(最终会由 Jenkins 接收到)。\n选择你的 GitHub 仓库设置选项卡,并点击 “add webhook”:\n然后,配置 WebHook:\n 粘贴从上面步骤中拷贝的 smee 的 URL 选择 application/json 作为内容类型 选择 send everything(你可以选择你想要的事件,但我只是处于简单这么做)。 点击 Add Webhook(或 update) 它看起来应该像这样:\n好,现在 WebHook 应该可以了。你可以在你的仓库中添加一个变更,并稍后检查构建状态:\n祝你好运!\n", "auhtor": "michaelneale", "translator": "linuxsuren", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E5%9C%A8%E7%BA%BF%E5%88%86%E4%BA%AB/", "title": "在线分享", "type": "tags", "date": "2019-06-09 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/backup-restore/", "title": "备份与恢复", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "备份与恢复\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E5%A4%96%E6%8C%82%E7%A8%8B%E5%BC%8F-%E5%AE%89%E5%85%A8-%E6%80%A7%E8%83%BD-gsoc-gsoc2019/", "title": "外挂程式 安全 性能 Gsoc Gsoc2019", "type": "tags", "date": "2019-10-28 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/pipeline/multi-branch/", "title": "多分支流水线", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "待补充\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E5%AE%B9%E5%99%A8%E5%8C%96/", "title": "容器化", "type": "tags", "date": "2020-02-21 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E5%AF%BC%E5%B8%88/", "title": "导师", "type": "tags", "date": "2019-08-16 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E5%BC%80%E6%BA%90/", "title": "开源", "type": "tags", "date": "2019-07-30 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/plugin-dev/pipeline/demo/", "title": "待完善", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "待完善\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/backup-restore/demo/", "title": "待补充", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "待补充\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E5%BF%97%E6%84%BF%E8%80%85/", "title": "志愿者", "type": "tags", "date": "2019-08-09 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/auth/lost-password/", "title": "忘记密码", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 如果忘记了 Jenkins 的管理员密码的话,也不用担心,只要你有权限访问 Jenkins 的根目录,就可以轻松地重置密码。\n通常情况 Jenkins 的根目录,默认是在当前用户(启动 Jenkins 的操作系统用户)目录的 .jenkins 中。对于 unix 系统而言,也就是 ~/.jenkins。\n我们打开配置文件 vim ~/.jenkins/config.xml 后,把字段 useSecurity 的值设置为 false,然后重新启动 Jenkins。你就会发现不需要登陆也能进入管理页面。\n进入页面系统管理-\u0026gt;全局安全配置中,选择启用安全,然后在授权策略中勾选任何用户可以做任何事(没有任何限制)。保存后,找到你希望重置密码的用户,输入新的密码即可。\n其他情况 如果 Jenkins 的根目录在当前用户目录下话,可以通过查找对应进程的方式来确认,下面以 Linux 系统为例说明:\n~# ps -ef | grep jenkins root 26386 26359 0 Jul23 pts/0 00:24:04 java -Duser.home=/var/jenkins_home -Djenkins.model.Jenkins.slaveAgentPort=50000 -jar /usr/share/jenkins/jenkins.war 分析上面的输出,可以得出,该 Jenkins 的根目录为:/var/jenkins_home。\nJENKINS_HOME 如果你的环境变量里设置了 JENKINS_HOME 的话,那么, Jenkins 的根目录就可能是 JENKINS_HOME 指向的目录。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/06/2019-06-24-becoming-contributor-newbie-tickets/", "title": "成为一名 Jenkins 贡献者:对新手友好的工单", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["jenkins", "community", "developer", "contributing", "newcomer"], "description": "修复 Jenkins 核心中的一个缺陷——从工单到 PR,再到发布", "content": " 两个月前,我发表了一篇介绍性文章, 成为一名 Jenkins 贡献者的旅程。在那篇第一次发表的文章 review 过后,学习到了我们可以参与和贡献的多种途径。 因此,在这个站点仓库中有对首次、基础的贡献的描述。\n现在,我们将会在这篇文章中探索更多高级的贡献,向 Jenkins 核心中提交代码。\n从工单和过程开始 新手贡献指导以及 Jenkins Jira 查看位于 jenins.io 上的开发者章节可能是最好的起点, 参考链接也很方便。同时,向 Jenkins 贡献的新手指导也很有用,因为它指出了不同的仓库、工具(例如问题跟踪系统)以及治理文档。 此外,它还描述了提交消息、代码风格约定、PR 指导等的最佳实践。\n一旦我们对之前描述的有了一般性的了解,并想要真正地开始编码,我们可能会对该做些什么感到困惑。\n似乎浏览Jenkins 问题跟踪系统是顺其自然 的下一步,因为那里充满了已经由社区报告了的潜在的缺陷和待改进的部分。然而,你很容易被无数的可能性列表所淹没。 请记住一点,对于一个像这样有十年历史之久的项目,很多是为新手准备的。因此,通过newbie-friendly tickets来过滤可能是最好的主意。\n选择一个工单 在我案例中,我花了一些时间来浏览带 newbie-friendly 标签的工单,直到发现了一个我似乎感兴趣并看起来有能力修复的:\n过程 在这个阶段,当我们准备接手这个工单时,最好让社区中的其他人知道我们正在开始解决它。我们可以很容易做到这一点, 只要把工单分配给我们自己即可(查看工单概览下的 “_Assign_” 按钮)。\n在 Jenkins 的 Jira 中把工单分配给我们自己的话,可以让其他的贡献者知道我们正在处理;另外,为了保证其他人有兴趣对此一起做贡献时,可以知道 该去联系谁或者如何询问状态。也就是说,把工单分配给你自己,并不意味着其他贡献者就无法继续推进。Jenkins 是一个开源项目,欢迎任何人创建他们自己 的 PR,因此,任何人都可以在工单中提出自己的方案。但是,你也能想到,如果工单分配给某个人的话,大多数人在开始工作前也可能会去联系承接人。\n与之相关的是,请牢记当我们把工单分配给自己时,不应该在这个工作上拖延太久。其他的贡献者,可能会由于工单已被分配而忽略。\n当我们马上就要开始工作时,推荐的做法是先点击\u0026rdquo;Start Progress\u0026ldquo;按钮。这个动作,会把状态修改为“_In progress_”,对社区而言, 意味着我们正在处理这个工单。\n在我们的电脑设置必要的工具 配置,安装和测试 正如在该旅程的第一篇文章中描述的,开始为某个仓库做贡献的第一步 是首先派生到我们自己的 GitHub 账号下,然后,克隆到你的电脑上。\n正如,在 Jenkins Core 仓库中的CONTRIBUTING 文件里 所描述的,让仓库在本地运行的必要步骤。它包括,安装必要的开发工具:Java Development Kit (https://adoptopenjdk.net/[OpenJDK] 为推荐的选择),Maven 以及任意支持 Maven 项目的 IDE。注意,安装 JDK 和 Maven 的步骤在贡献指南中有链接。\n当安装并配置好所需要的工具后,我们就准备好了在本地构建 Jenkins,也可以运行测试。\n开始干活 复查工单细节 现在,我准备好开始处理工单了,我必须仔细查看细节,以便全面地理解问题所在。\n我计划处理的工单的描述中有两个链接。第一个是,体现真正缺陷的截图。它展示出当点击按钮\u0026rdquo;所有\u0026ldquo;时,几个不兼容的插件是如何被选中的,甚至尽管预期的行为是仅选中兼容的插件。 第二个链接是代码片段的引用,它展示了当检查一个插件更新是否与当前版本兼容时需要考虑的校验。\n本地复现问题 尽管我现在已经对该缺陷的细节了解清楚了,但还没有亲眼见过。因此,对我而言,下一个符合逻辑的步骤就是在本地复现。\n为了在我们的电脑上复现该缺陷,可以利用源代码构建出 Jenkins的本地 war 文件,或者也可以 下载最新可用的 Jenkins 版本,并在本地运行。 当我处理该工单时,最新可用的版本为 2.172;当我自行构建源码时看到的版本为 2.173-SNAPSHOT,也就是社区正在进行的下一个版本。\n通常来说,在本地复现缺陷是一个好的主意,这不仅仅是为了能更好的理解,也可以确保问题真实存在。它可能只在报告者的环境中发生(例如:一些用户 错误的配置)。或者,是已经修复了的久的缺陷。也有可能是某人在工单还没有提出时已经修复了。或者,可能是贡献者在修复后忘记了更新工单的状态。\n因此,基于以上的所有原因,我在本地运行最新版本的 Jenkins。从终端进入到 war 文件所在的目录,然后运行 java -jar jenkins.war, 就会在本地启动 Jenkins,访问路径为 http://localhost:8080。\n从首页上,切换到插件管理页面(在左侧点击 “_管理 Jenkins_” 的链接,然后选择在列表中选择 “_管理插件_”)。\n在管理插件的页面中,有一个插件更新的列表。对我而言,由于复用了之前安装的旧的 JENKINS_HOME 目录,已经有一些插件出现在这里,并需要 更新。这使得我可以测试这个假定会失败的行为。\n当我点击了底部的“全选”选项,得到了如下结果:\n正如在它在工单中报告的,该行为是不一致的。在上一个版本中,\u0026rdquo;全选\u0026ldquo;的行为已经改变(试图改进),是为了只选中兼容的插件。然而, 正如在截图中看到的,该行为并未像期待的那样。现在,不管是“全选”还是“兼容性的“插件都会被选中,一些有兼容性问题的插件也会被无意中被选中。\n尝试修复 当在阅读原始 PR 中关于“全选”行为变更的讨论时,我看到了一个采用分离的\u0026rdquo;兼容性的\u0026ldquo;按钮的建议,而保留\u0026rdquo;全选\u0026ldquo;按钮的传统行为。 我喜欢这个主意,因此,我决定把它作为我的变更提议的一部分。\n在这个阶段,我对需要做的变更有了清晰的想法。包括:1)界面UI,为“兼容的”插件增加一个按钮,2)当按钮点击后 JS 代码应用变更,然后3) 后端的方法来决定一个插件是否为兼容的。\n应用变更 正如在贡献指南中推荐的,我创建了一个独立的 feature 分支来处理这个工单。\n复查完代码后,我花了一些时间来搞清楚应该做哪些修改,包括前端和后端的代码。关于我修改的更多细节,你可以看一下在我的 PR 中的变更。\n简单总结下,我了解到经典的 Jenkins UI 是使用Jelly来编写的, 在了解它的基本原理后,我修改文件 index.jelly 让包括新的选择器,并关联检查兼容性插件的函数到这个选择器上,当点击 “_全选_” 时 复用已有的函数 “toggle” 来勾选所有的复选框。我同时必须要为未经检查兼容性的情况修改 JavaScript 函数 checkPluginsWithoutWarnings 的行为,因为现在已经有了一个真正的 “_全选_” 按钮,未经检查的情况不再考虑。然后,我在类 UpdateSite.java 中添加了一个后端的 Java 方法 isCompatible, 来调用所有检查不同的兼容性的方法,并最终返回一个结果。在这次修改中,我还增加了一个自动化测试来验证该方法的正确行为,为项目增加了代码测试覆盖率。 最后,我修改了文件 table.jelly 来从前端调用后端的方法,替换了之前没有把所有类都考虑进去的方法。\n正如你所看到的,变更涉及到了不同的技术,甚至你遇到的是简单的场景,却不是很熟悉。我的建议是,不要让这些困难让你停止了前进的脚步。作为一名软件工程师, 我们应该专注于让我们永远不过时的技能,而不是只了解特定的技术; 在特定的场景下,要适应不同的框架,学习一切为了完成任务所需要的新技术,采用跨框架的原则和最佳实践以提供高质量的方案。\n结果 经过上面的修改后,UI 界面上出现一个新的选项,三个选项对应的行为也如预期的一致:\n发布变更 提交一个 Pull Request 在 Jenkins 核心仓库里的贡献指南中,有一章关于变更提议的内容,描述了为我们的变更创建一个 Pull Request (PR) 所必须要遵守的步骤。\n此外,这个仓库中还有一个PR 模板, 将会在创建一个新的 PR 时自动加载,作为一个让我们给复查者提供必要信息的基础。我们期望的是:工单链接,描述变更的变更日志条目, 完成提交者的检查单,并提醒期望的复查者(如果有的话)。\n在我的案例中,我在创建 PR 时遵照模板,完成了所有部分。 我添加了 Jira 工单链接,提供了两条变更日志条目,完成了提交者的检查单,并增加了三位期望的复查者(并介绍了我为什么认为条目的复查会是有价值的)。 我还添加了工单中提到的原始 PR 链接,以便提供更多的上下文。\n通过和合并的流程 正如在贡献指南中申明的,一个 PR 需要有两个人通过才能被合并;这可能需要几天到几周的时间。有时候,有一个复查者通过了,一周后没有额外的复查 也认为足够设置 PR 为 ready-for-merge。然而,合并所需要的时间以及通过的数量可能不同,这取决于变更的复杂度或者对 Jenkins Core 的影响面。\n当收到必要的通过建议后,一个 Jenkins Core 的维护者讲会把 PR 设置为 ready-for-merge,并会在准备下次发布时被合并到 master 分支。\n对我而言,在提交 PR (四月十四日)当天,我收到了 Daniel(工单的报告者,也是我“期望的复查者”)的复查。他给出了几个非常有用的建议, 我据此进行了修改。之后,Daniel 再次复查我的 PR 并给了一些小的备注,并被核准。之后一周,没有任何动态,我根据 Daniel 的建议增加了一些修改, 最后,Daniel 通过我的 PR,这使得 PR 添加上了 ready-for-merge 的标签,并在后来的某天被合并了(四月二十六日)。\n发布 每次新的发布,仓库的维护者会选择被添加 ready-for-merge 标记的 PR 合并到 master 分支,准备变更日志(通常会采用 PR 作者的提议)并 继续创建新的版本。此时,PR 的作者不需要有额外的参与。\n每周,Jenkins 都会发布一个新的版本,因此,当你的 PR 被合并后,你的变更非常有可能会成为下一个每周发布版的 Jenkins 的一部分。\n最终,你的变更也会到达长期支持 (LTS) 版本,这是一个不同的发布线,目标是更加保守的用户。 这个发布线是与每周发布的版本选择同步的,每12周一个最新的每周发布版会作为新的 LTS 版本基线。在此期间,中间的 LTS 版本只会包括重要的缺陷修复, 来自每周发布版 cherry-pick。新的功能通常会等到下一个 LTS 的基线被确定后。\n鉴于在这篇博客中描述的例子,在合并后 *它发布在了 Jenkins 2.175*(每周发布版)。并可能会包括在下一个 LTS 中, 应该是在下个月发布(2019年6月)。\n完工! 就这么多!到此,我们已经覆盖了向 Jenkins Core 提出一个新的提议的完整生命流程。我们回顾了从流程的开始,在 Jenkins 缺陷跟踪系统中挑选 一个工单;一直到最后,发布我们的变更到一个新的 Jenkins 版本。\n如果你从未但是想要做贡献,我希望这篇文章能够激励你回到标记了 newbie-friendly 的工单列表中, 找到一个你感兴趣的,按照上面描述的步骤,知道你看到自己的变更发布到了一个新的 Jenkins 版本中。\n记住,不要尝试在你的首个工单中解决一个复杂的问题,有很多更轻松的方法你可以做贡献,而且,不管多小都是有帮助的!\n", "auhtor": "romenrg", "translator": "linuxsuren", "original": "https://jenkins.io/blog/2019/05/30/becoming-contributor-newbie-tickets/", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E6%8B%9B%E5%8B%9F/", "title": "招募", "type": "tags", "date": "2019-08-16 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E6%8C%81%E7%BB%AD%E4%BA%A4%E4%BB%98/", "title": "持续交付", "type": "tags", "date": "2019-08-14 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E6%8C%81%E7%BB%AD%E6%B5%8B%E8%AF%95/", "title": "持续测试", "type": "tags", "date": "2019-08-14 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/use-cases/continue-test/", "title": "持续测试", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "jmeter -n -t test-plan.jmx -l testresult.jtl\n-n 无界面运行\n-t 指定测试计划文件\n-l 测试日志文件\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/plugin/update-center/", "title": "插件更新中心", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " Jenkins 安装完成后,默认的插件更新中心地址为 https://updates.jenkins.io/update-center.json\n除了正式版本以外,部分插件也会发布一些 alpha 或者 beta 版本,以便让部分用户体验实验性功能。我们可以在插件管理-》高级部分,修改为如下地址:\nhttps://updates.jenkins.io/experimental/update-center.json\n镜像地址 维护方 镜像中心地址 Jenkins 中文社区 https://updates.jenkins-zh.cn/update-center.json 清华大学 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 华为开源镜像站 https://mirrors.huaweicloud.com/jenkins/updates/update-center.json ", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/api/plugin/", "title": "插件相关", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/plugin/", "title": "插件管理", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "插件管理\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/04/2019-04-15-security-spring-cleaning/", "title": "春季安全清查", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["plugins", "security"], "description": "Jenkins 管理员们应该关注的安全问题", "content": "今天我们公布了一个 安全报告, 主要是关于 Jenkins 的插件中 还没有被修复 的问题。 发生了什么?\nJenkins 安全团队将 漏洞反馈分类发布在 Jira 和我们的非公开邮件列表中。 一旦我们确定它不是由 Jenkins 安全团队成员维护的插件,我们会尝试将该问题通知插件维护者,以帮助我们开发,审查和发布修复。\n这种情况下,我们会发布 安全报告,将这些问题告知用户,即使没有发布修复版本。 这样可以让管理员作出决定,是否继续使用具有未解决的安全漏洞的插件。 今天发布的报告里大多数都是这样的安全问题。\n在这个列表中看到您感兴趣的插件并且想要帮忙?了解如何 认领一个插件。\n", "auhtor": "daniel-beck", "translator": "p01son6415", "original": "https://jenkins.io/blog/2019/04/03/security-advisory/", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/best-practice/", "title": "最佳实践", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "Jenkins 应用最佳实践\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/scm/git/", "title": "有关 Git 的教程", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "有关 Git 的教程\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/scm/git/git/", "title": "有关 Git 的教程", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "待完善\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/scm/svn/", "title": "有关 svn 的教程", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "有关 svn 的教程\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/scm/svn/svn/", "title": "有关 svn 的教程", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "待完善\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/api/core/", "title": "核心", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E6%B2%BB%E7%90%86/", "title": "治理", "type": "tags", "date": "2020-02-12 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/event/", "title": "活动", "type": "meetup", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "Jenkins 社区相关活动安排及介绍", "content": "sdfsdds\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/pipeline/pipeline/", "title": "流水线", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "待完善\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/plugin-dev/pipeline/", "title": "流水线插件", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "plugin dev\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E6%B5%8B%E8%AF%95/", "title": "测试", "type": "tags", "date": "2019-08-14 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E7%A4%BE%E5%8C%BA/", "title": "社区", "type": "tags", "date": "2020-02-12 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/", "title": "管理", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "jcli 是用 Go 语言编写的 Jenkins 命令行客户端, 可以帮助你轻松地管理多个 Jenkins 实例,更多细节介绍,请阅读官方文档。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E7%B2%BE%E8%8B%B1%E7%BB%A9%E6%95%88/", "title": "精英绩效", "type": "tags", "date": "2020-03-02 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/wechat/articles/2019/01/2019-01-09-jenkins-evergreen/", "title": "自动更新、易于使用的 Jenkins", "type": "wechat", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": ["jenkinsworld", "jenkinsworld2018", "evergreen"], "description": "借助 Evergreen 持续提供易于使用的 Jenkins", "content": " 当我第一次 写 Jenkins Evergreen 相关的文章 , 后来被称为 \u0026ldquo;Jenkins Essentials\u0026rdquo;,我提到的一系列的未来的发展在接下来的几个月里已经变成了 现实 。 今年在旧金山举办的 DevOps World - Jenkins World 会议上,我会介绍 Jenkins Evergreen 背后哲学的更多细节,展示我们已经做了什么,并且讨论这个激进的 Jenkins 发行版的走向。\n正如我在第一篇博客以及 JEP-300 中所讨论的 Jenkins Evergreen 的前两大支柱是我们关注的要点.\n自动更新的发行版 不出所料, 实现安全、自动地更新Jenkins发行版(包括核心和插件)所需的机制需要很多的工作。在 Baptiste 的演讲中 他将讨论如何使 Evergreen \u0026ldquo;走起来\u0026rdquo;,而我会讨论 为何 自动更新的发行版很重要。\n持续集成和持续交付变得越来越普遍,并且是现代软件工程的基础 ,在不同的组织当中有两种不同的方式使用 Jenkins 。在一些组织当中,Jenkins 通过 Chef ,Puppet 等自动化工具有条不紊的被管理和部署着。然而在许多其他组织当中, Jenkins 更像是一个 设备 ,与办公室的无线路由器不同。当安装完毕,只要它能继续完成工作,人们就不会太多的关注这个设备。\nJenkins Evergreen 发行版通过确保最新的功能更新,bug 修复以及安全性修复始终能安装到 Jenkins 当中,\u0026ldquo;让 Jenkins 更像是一个设备\u0026rdquo;。\n除此之外, 我相信 Evergreen 能够向一些我们现在没有完全服务的团队提供良好的服务:这些团体希望能够以 服务 的形式使用 Jenkins 。我们暂时没有考虑提供公有云版本的 Jenkins 。我们意识到了自动接收增量更新,使用户可以在无需考虑更新 Jenkins 的情况下进行持续开发的好处。\n我相信 Jenkins Evergreen 可以并且可以提供相同的体验。\n自动配置默认值 Jenkins 平台真正强大的地方是可以为不同的组织提供不同的模式和做法。对于很多新用户来说,或一些只希望使用通用案例的用户来说, Jenkins 的灵活性与让用户做出合适的选择形成了悖论。使用 Jenkins Evergreen,很多常用的配置将自动配置,使 Jenkins 变成开箱即用的工具。\n默认情况下将包括 Jenkins 流水线和 Jenkins Blue Ocean,我们也删除了一些 Jenkins 的遗留功能。\n我们同样在使用非常棒的 Configuration as Code 进行工作, Configuration as Code 现在已经完成了1.0版本的发布, 我们通过它实现自动进行默认配置。\n现状 迄今为止,这个项目取得了重大的进展,我们非常高兴有用户开始尝试 Jenkins Evergreen,现在 Jenkins Evergreen 已经可以被 早期使用者 尝试. 不过我们现在 不 推荐在生产环境中使用 Jenkins Evergreen 。\n我们希望能够得到您的反馈和想法在我们的 Gitter channel !\n", "auhtor": "rtyler", "translator": "runzexia", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/agent/", "title": "计算节点", "type": "tutorial", "date": "2020-02-27 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "计算节点的配置与管理\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/auth/", "title": "认证", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "认证\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E8%B4%A1%E7%8C%AE%E6%BF%80%E5%8A%B1/", "title": "贡献激励", "type": "tags", "date": "2019-09-05 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E8%BD%AF%E4%BB%B6%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/", "title": "软件生命周期", "type": "tags", "date": "2019-08-14 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E8%BF%90%E8%90%A5%E8%BD%AC%E5%9E%8B/", "title": "运营转型", "type": "tags", "date": "2019-11-06 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/auth/keyclock/", "title": "通过 KeyCloak 认证", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/auth/oic-auth/", "title": "通过 OpenID 认证", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " 如果忘记了 Jenkins 的管理员密码的话,也不用担心,只要你有权限访问 Jenkins 的根目录,就可以轻松地重置密码。\n通常情况 Jenkins 的根目录,默认是在当前用户(启动 Jenkins 的操作系统用户)目录的 .jenkins 中。对于 unix 系统而言,也就是 ~/.jenkins。\n我们打开配置文件 vim ~/.jenkins/config.xml 后,把字段 useSecurity 的值设置为 false,然后重新启动 Jenkins。你就会发现不需要登陆也能进入管理页面。\n进入页面系统管理-\u0026gt;全局安全配置中,选择启用安全,然后在授权策略中勾选任何用户可以做任何事(没有任何限制)。保存后,找到你希望重置密码的用户,输入新的密码即可。\n其他情况 如果 Jenkins 的根目录在当前用户目录下话,可以通过查找对应进程的方式来确认,下面以 Linux 系统为例说明:\n~# ps -ef | grep jenkins root 26386 26359 0 Jul23 pts/0 00:24:04 java -Duser.home=/var/jenkins_home -Djenkins.model.Jenkins.slaveAgentPort=50000 -jar /usr/share/jenkins/jenkins.war 分析上面的输出,可以得出,该 Jenkins 的根目录为:/var/jenkins_home。\nJENKINS_HOME 如果你的环境变量里设置了 JENKINS_HOME 的话,那么, Jenkins 的根目录就可能是 JENKINS_HOME 指向的目录。\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/plugin/configuration-as-code/", "title": "配置即代码", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": " Jenkins Configuration as Code Plugin 允许用户将系统配置等 Jenkins 的配置信息写入到一个 YAML 文件中。这样,可以将 Jenkins 的配置标准化,便于在团队内部复用,易于传播、便于快速搭建开箱即用的 Jenkins 服务。\n借助这个插件,我们几乎不再需要通过人工在 UI 界面上点击的方式来配置 Jenkins 服务。而且,绝大部分其他插件几乎(甚至)不需要做任何调整,就可以与该插件兼容。\n配置文件加载流程 类型 描述 文件 $JENKINS_HOME/war/WEB-INF/jenkins.yaml 单一文件 目录 $JENKINS_HOME/war/WEB-INF/jenkins.yaml.d 加载该目录下所有以 yml,yaml,YAML,YML 为后缀的文件 系统属性 casc.jenkins.config 环境变量 CASC_JENKINS_CONFIG 系统配置 无 UI 配置 文件 $JENKINS_HOME/jenkins.yaml 查找顺序为:系统属性-\u0026gt;环境变量-\u0026gt;系统配置-\u0026gt;该文件,这个配置文件,只加载先找到的 资源加载协议 支持的 URI 协议包括:https, http, file\n如果不在上面协议的范围内的话,则尝试以文件(或目录)的方式加载。\n多配置文件 从上面可以看出来,CASC 是支持同时加载多个配置文件的。那么,如果多个配置文件中有相同字段的话,是怎么处理的呢?\n 数组:合并 相同字段:报错 CLI 除了可以在 UI 界面上操作 CasC 的相关功能,CLI 也有对应的支持。\n$ jcli casc Configuration as Code Usage: jcli casc [command] Available Commands: apply 从应用已有的配置 export 导出配置及代码的配置 open 在浏览器中打开配置及代码的页面 reload 重新加载配置及代码的配置 schema 获取配置及代码的结构 注意:该功能从 jcli v0.0.24 开始支持。详情,请参考对应的 PR 链接。\nRestful API 导出配置 curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/export\n查看 Schema curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/schema\n重新加载配置 curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/reload\n从请求中应用配置 curl -X POST -u admin:112e74ac1ded9b9af4854e594405819df9 http://localhost:8080/configuration-as-code/apply\n", "auhtor": "linuxsuren", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tutorial/management/mirror/", "title": "镜像源", "type": "tutorial", "date": "0001-01-01 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "下面是部署在中国的和 Jenkins 相关的镜像源。这里只是收录,无法保证源的可信度, 如果大家在使用的过程中,发现有任何问题后,可以在下面留言。\n 维护方 描述 清华大学 不同操作系统下的安装包,以及通用的 War 包,插件等 华为开源镜像站 不同操作系统下的安装包,以及通用的 War 包,插件等 腾讯云 北京理工大学 USTC Jenkins 官方也给出了其他镜像源列表。\n下面是一些国外的镜像源\n 维护方 描述 XMisson 对于插件镜像源的配置,请参考这里的说明。\n", "auhtor": "", "translator": "", "original": "", "poster": "" }, { "uri": "https://jenkins-zh.cn/tags/%E9%BB%91%E5%AE%A2%E6%9D%BE/", "title": "黑客松", "type": "tags", "date": "2019-08-16 00:00:00 +0000 UTC", "tags": [], "description": "", "content": "", "auhtor": "", "translator": "", "original": "", "poster": "" }]