蚊章汇 - CI
type: channel
link: https://linuxcn.bwsl.wang/tag/CI/
items: 在 GitLab 上构建 CI 流水线
items: 解决 CI/CD 中的仓库阻抗失配
items: 在 Fedora CoreOS 上运行 GitHub Actions
items: 硬核观察 #397 新恶意程序正利用 WSL 隐蔽攻击 Windows
items: CI/CD 管道是什么？
items: CI/CD 平台迁移实践：从 Travis-CI 转移到 Github Action
items: 使用一条 CI/CD 流水线管理所有的产品
items: Linux 内核的持续集成测试
items: ick：一个持续集成系统
items: 系统管理员的 7 个 CI/CD 工具

在 GitLab 上构建 CI 流水线
type: item
date: 2023-08-18T17:45:11+08:00
description: 连续集成 continuous integration （CI）是指代码变更会被自动构建和测试。以下是我为自己的 C++ 项目构建 CI 流水线的过程。本文介绍如何在 GitLab 上配置 CI 流水线。我在前面的文章中介绍了 基于 CMake 和 VSCodium 的构建系统 和 基于 GoogleTest 和 CTest 的单元测试。本文将在此基础上进一步配置 CI 流水线。我会先演示如何布设和运行 CI 流水线，然后再介绍如何配置它。CI 是指提交到代码仓库的代码变更会被自动构建和测试。在开源领域，GitLab 是一个流行的 CI 流水线平台。除了作为中心 Git 仓库外，GitLab 还提供 CI/CD 流水线、 问题跟踪 issue tracking 和 容器注册表 container registry 功能。相关术语在进入正题之前，我先介绍在本文和 GitLab 文档 中会遇到的常见术语。 持续交付 continuous delivery （CD）：自动化供应软件，以供随时交付 持续部署 continuous deployment （CD）：自动化软件发布 流水线 pipeline : CI/CD 的直接构件，它由阶段和作业构成 阶段 stage ：一组作业 作业 job ：某项需要执行的具体任务，比如编译、单元测试等 执行器 runner ：实际执行作业的服务布设 CI 流水线在下面的章节中，我将复用以前的 示例工程。点击 GitLab 仓库页面右上角的 复刻 Fork 按钮复刻代码仓库。设置执行器为了让你对整个流程有所了解，我们先从在本地安装执行器讲起。参照执行器服务 安装指南 安装好服务，然后注册执行器。1、选择 GitLab 项目页面左侧的 设置 Settings ，再选择 CI/CD。2、展开 执行器 Runners 区域，关闭 共享的执行器 Shared runners 选项（黄框处）。特别注意令牌和 URL（绿框处），下一步会用到它们。3、在终端中运行 gitlab-runner register，根据提示输入以下注册信息：GitLab 实例: https://gitlab.com/ （如上图）注册令牌：从执行器区域中获取 （如上图）描述：按需自由填写标签：可以不填执行环境：选 Shell如果有需要，你可以在 ~/.gitlab-runner/config.toml 中修改这些配置。4、用命令 gitlab-runner run 启动执行器。你可以在 GitLab 的项目设置界面执行器区域看到执行器的状态：运行流水线前面已经提过，流水线就是一组由执行器执行的作业。每个推送到 GitLab 的提交都会生成一个附加到该提交的流水线。如果多个提交被一起推送，那么只会为最后一个提交生成流水线。为了演示，我直接在 GitLab 在线编辑器中提交和推送修改。打开 README.md 文件，添加一行数据：现在提交修改。这里注意默认的行为是为提交新建一个分支，为了简便起见，我们择提交到主分支。提交后一会儿后，你就应该改能看到 GitLab 执行器执行的控制台中有输出消息：Checking for jobs... received job=1975932998 repo_url=<https://gitlab.com/hANSIc99/cpp\_testing\_sample.git> runner=Z7MyQsA6 Job succeeded duration_s=3.866619798 job=1975932998 project=32818130 runner=Z7MyQsA6 在 GitLab 项目概览界面左侧选择 CI/CD --> 管道 Pipelines ，查看最近执行的流水线：选中流水线可以在详情界面看到哪些作业失败了，并能查看各个作业的输出。当遇到非零返回值是就认为作业执行失败了。在下面的例子中我通过调用 exit 1 强制让作业执行失败：CI 配置阶段、流水线和作业的配置都在仓库根目录的 .gitlab-ci.yml 文件中。我建议使用 GitLab 内置的流水线编辑器，它会自动对配置进行检查。stages: - build - test build: stage: build script: - cmake -B build -S . - cmake --build build --target Producer artifacts: paths: - build/Producer RunGTest: stage: test script: - cmake -B build -S . - cmake --build build --target GeneratorTest - build/Gene…

解决 CI/CD 中的仓库阻抗失配
type: item
date: 2022-03-26T19:18:00+08:00
description: 对齐部署镜像和描述符是很困难的，但是某些策略可以使整个过程更高效。在软件架构中，当两个组件之间有某些概念性或技术上的差异时会出现 阻抗失配 impedance mismatch 。这个术语其实是从电子工程中借用的，表示电路中输入和输出的电子阻抗必须要匹配。在软件开发中，存储在镜像仓库中的镜像与存储在源码控制管理系统（LCTT 译注：SCM，Source Code Management）中它的 部署描述符 deployment descriptor 之间存在阻抗失配。你如何确定存储在 SCM 中的部署描述符表示的是正确的镜像？两个仓库追踪数据的方式并不一致，因此将一个镜像（在镜像仓库中独立存储的不可修改的二进制）和它的部署描述符（Git 中以文本文件形式存储的一系列修改记录）相匹配并不那么直观。注意：本文假定读者已经熟悉以下概念： 源码控制管理 Source Control Management （SCM）系统和分支Docker 或符合 OCI 标准的镜像和容器 容器编排系统 Container Orchestration Platforms （COP），如 Kubernetes 持续集成/持续交付 Continuous Integration/Continuous Delivery （CI/CD） 软件开发生命周期 Software development lifecycle （SDLC）环境阻抗失配：SCM 与镜像仓库为了更好地理解阻抗失配在什么场景下会成为问题，请考虑任意项目中的软件开发生命周期环境（SDLC），如开发、测试或发布环境。测试环境不会有阻抗失配。现在使用 CI/CD 的最佳实践中开发分支的最新提交都会对应开发环境中的最新部署。因此，一个典型的、成功的 CI/CD 开发流程如下：向 SCM 的开发分支提交新的修改新提交触发一次镜像构建新生成的镜像被推送到镜像仓库，标记为开发中镜像被部署到容器编排系统（COP）中的开发环境，该镜像的部署描述符也更新为从 SCM 拉取的最新描述符。换句话说，开发环境中最新的镜像永远与最新的部署描述符匹配。回滚到前一个构建的版本也不是问题，因为 SCM 也会跟着回滚。最终，随着开发流程继续推进，需要进行更多正式的测试，因此某个镜像 —— 镜像对应着 SCM 中的某次提交 —— 被推到测试环境。如果是一次成功的构建，那么不会有大问题，因为从开发环境推过来的镜像应该会与开发分支的最新提交相对应。开发环境的最新部署被允许入库，触发入库过程最新部署的镜像被标记为测试中镜像在测试环境中被拉取和部署，（该镜像）对应从 SCM 拉取的最新部署描述符到目前为止,一切都没有问题，对吗？如果出现下面的场景，会有什么问题？场景 A：镜像被推到下游环境，如 用户验收测试 user acceptance testing （UAT），或者是生产环境。场景 B：测试环境中发现了一个破坏性的 bug，镜像需要回滚到某个确定正常的版本。在任一场景中，开发过程并没有停止，即开发分支上游有了一次或多次新的提交，而这意味着最新的部署描述符已经发生了变化，最新的镜像与之前部署在测试环境中的镜像不一致。对部署描述符的修改可能会也可能不会对之前版本的镜像起作用，但是它们一定是不可信任的。如果它们有了变化，那么它们就一定与目前为止你测试过的想要部署的镜像的部署描述符不一致。问题的关键是：如果部署的镜像不是镜像库中的最新版本，你怎么确定与部署的镜像相对应的是 SCM 中的哪个部署描述符？ 一言以蔽之，无法确定。两个库直接有阻抗失配。如果要详细阐述下，那么是有方法可以解决的，但是你需要做很多工作，这部分内容就是文章接下来的主题了。请注意，下面的方案并不是解决问题的唯一办法，但是已经投入到生产环境并已经对很多项目起了作用，而且已经被构建并部署到生产环境中运行了超过一年。二进制与部署描述符源码通常被构建成一个 Docker 镜像或符合 OCI 标准的镜像，该镜像通常被部署到一个容器编排平台（COP）上，如 Kubernetes。部署到 COP 需要部署描述符来定义镜像被如何部署以及作为容器运行，如 Kubernetes 部署 或 CronJobs。这是因为在镜像和它的部署描述符之间有本质差异，在这里可以看到阻抗失配。在这次讨论中，我们认为镜像是存储在镜像仓库中不可修改的二进制。对源码的任何修改都不会修改镜像，而是用另一个新的镜像去替换它。相比之下，部署描述符是文本文件，因而可以被认为是源码且可修改。如果遵循最佳实践，那么部署描述符是被存储在 SCM，所有修改都会提交，而这很容易回溯。解决阻抗失配建议的解决方案的第一部分，就是提供一个能匹配镜像仓库中的镜像与对保存部署描述符的 SCM 做的代码提交的方法。最直接的解决方案是用源提交的哈希值标…

在 Fedora CoreOS 上运行 GitHub Actions
type: item
date: 2021-10-03T19:03:12+08:00
description: GitHub Actions 是一项为快速建立持续集成和交付（CI/CD）工作流程而提供的服务。这些工作流程在被称为“ 运行器 runner ”的主机上运行。GitHub 提供的 托管运行器 的操作系统的选择是有限的（Windows Server、Ubuntu、MacOS）。另一个选择是使用 自托管 的运行器，这让仓库管理员对运行器有更多控制。自托管的运行程序是专门为某个存储库或组织服务的。下面的文章介绍了使用 Fedora CoreOS 配置自托管运行程序的步骤。入门Fedora CoreOS 是一个精简的操作系统，旨在便于大规模的部署和维护。该操作系统会自动更新，并默认提供运行容器所需的工具。由于这些原因，Fedora CoreOS 是运行 CI/CD 工作流程的一个极佳选择。配置和配备 Fedora CoreOS 机器的第一步是生成一个 Ignition 文件。Butane 允许你使用更友好的格式（YAML）生成 Ignition 文件。配置一个 Fedora CoreOS 运行器要在 Fedora CoreOS 上执行 GitHub Actions，托管主机需要用于注册和运行该运行器的二进制文件和脚本。从 Actions 运行器项目 下载二进制文件和脚本，并部署在 /usr/local/sbin/actions-runner 下。version: "1.3.0" variant: fcos storage: directories: - path: /usr/local/sbin/actions-runner mode: 0755 user: name: core group: name: core files: - path: /usr/local/sbin/actions-runner/actions-runner-linux.tar.gz overwrite: true contents: source: https://github.com/actions/runner/releases/download/v2.278.0/actions-runner-linux-x64-2.278.0.tar.gz mode: 0755 user: name: core group: name: core 注册和删除令牌为一个项目配置运行器需要一个“ 令牌 token ”。这可以防止在没有正确权限的情况下从项目中注册或删除自托管的运行器。GitHub 提供的令牌有一个小时的过期时间。如果运行器在这个时间之后重新启动，它将需要一个新的注册令牌。该令牌可能出问题，特别是在 Fedora CoreOS 自动更新时。更新过程希望托管主机在收到新数据后至少每隔几周重启一次。幸运的是，可以使用 GitHub REST API 来获取这些令牌，并在托管主机每次重启时自动配置运行器。下面的 manage-runner.sh 脚本使用 API 来获取令牌，删除任何已经配置好的运行器，并用新的令牌注册运行器。#!/bin/bash # Handles the Github Action runner configuration. # Remove and Registration token expires after 1 hour, if we want our runner # to work after a reboot (auto update) we need to refresh the tokens. # First remove the runner with a fresh remove token REMOVE_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/actions/runners/remove-token | jq -r '.token') /usr/local/sbin/actions-runner/config.sh remove --token ${REMOVE_TOKEN} # Then register the runner with a fresh registration token REGISTRATION_TOKEN=$(curl -u ${GITHUB_USER}:${GITHUB_TOKEN} -X POST -H "Accept: application/vnd.github.v3+json" https://api.githu…

硬核观察 #397 新恶意程序正利用 WSL 隐蔽攻击 Windows
type: item
date: 2021-09-18T03:15:36+08:00
description: 新恶意程序正利用 WSL 隐蔽攻击 Windows安全专家发现了针对 WSL 创建的恶意 Linux 安装文件。首批针对 WSL 环境的攻击样本在今年 5 月初被发现，并每过一段时间就出现一次。这表明黑客正在尝试用新的方法来破坏 Windows 设备，并利用 WSL 以逃避检测。这些恶意文件主要依靠 Python 3 来执行其任务，并打包成用于 Linux 的 ELF 可执行文件。这真是无孔不入，恶意软件就以这种形式将 Linux 当成了目标。Travis CI 漏洞暴露数千开源项目的密钥Travis CI 是一个流行的持续集成工具，它提供了与 GitHub 和 Bitbucket 等的无缝整合，能直接克隆用户在 GitHub 中的代码库，然后在虚拟环境中进行构建和测试。它被 90 万个开源项目使用。安全研究人员发现了它的一个严重安全漏洞，会导致 Travis CI 曝光使用它测试的仓库的安全环境变量，如签名密钥、访问证书和 API 令牌。这可能会导致攻击者可借此进入组织的网络。安全研究人员建议所有使用 Travis CI 的项目更换相关的密钥和令牌。而在此事件中，Travis CI 对安全问题的漫不经心激怒了开发者社区，他们甚至要求 GitHub 禁用 Travis CI。作为一家普遍应用的 CI 服务商，这样对信息安全和开发者的漠视，必将带来更大的问题。GitHub Action 不香么？Alphabet 采用激光技术实现 5 公里传输 700TB 数据Google 母公司 Alphabet 关闭了探索将氦气球投放至平流层以实现无线互联网覆盖的项目，但该项目中的用于连接高空气球的自由空间光通信链路（FSOC）等技术保留了下来。目前这项技术正被用于为非洲人民提供高速宽带链接。这种链路有点像是没有电缆的光纤。X 实验室表示，该链路在短短 20 天之内传输了近 700 TB 数据。这种技术在某些场景下很有意义啊，其实包括它的气球项目，在救灾等恶劣环境都很有用。

CI/CD 管道是什么？
type: item
date: 2021-07-02T18:58:38+08:00
description: 你如何定义持续集成/持续部署管道取决于你组织的要求。 持续集成 continuous integration / 持续部署 continuous deployment （CI/CD）管道是每个 DevOps 计划的基础。 CI/CD 管道打破了传统的开发孤岛，使开发和运营团队能够在整个软件开发生命周期中进行协作。更好的是，转向 DevOps 和 CI/CD 管道可以帮助你的组织以更高的速度更安全地 交付软件。拆解 CI/CD 管道CI/CD 管道有很多定义，所以我总是建议组织定义自己的 CI/CD 管道版本和其他 DevOps 概念，而不是使用其他人的。开源 CI/CD 工具为你提供构建满足组织要求的 CI/CD 管道的自由和选择。形成 CI/CD 管道的阶段是将不同的任务子集分组为 管道阶段。典型的管道阶段包括：构建：开发人员编译应用程序代码。测试：质量保证（QA）团队使用自动化测试工具和策略测试应用程序代码。发布：开发团队将应用程序代码交付到代码库。部署：DevOps 团队将应用程序代码分阶段投入生产。安全性和合规性：QA 团队根据项目要求验证构建。这是组织部署容器扫描工具的阶段，这些工具根据 常见漏洞和暴露 Common Vulnerabilities and Exposures （CVE）检查容器镜像的质量。这些是 CI/CD 管道的标准阶段，但一些组织调整 CI/CD 管道模型以满足他们的要求。例如，为医疗保健市场构建应用程序的组织，具有严格的合规性标准，可以在整个工具链中分发测试、验证和合规性门槛。其他示例可能是依赖于具有开源软件（OSS）的复杂软件供应链的组织。商业组件可能会设立一个门槛，开发团队成员可以在其中为 OSS 包生成 软件物料清单 software bill of materials （SBOM），或者外部商业软件供应商必须将 SBOM 作为其合同可交付成果的一部分进行交付。CI/CD 管道的障碍实施 CI/CD 管道会改变团队的流程和文化。尽管许多开发人员愿意接受某些任务和测试的自动化，但人员可能成为采用 CI/CD 的障碍。从瀑布式流程转向 CI/CD 可能会动摇某些组织中基本的和隐含的权力结构。由于 CI/CD 管道提高了软件交付速度，旧手动流程的“守门人”可能会受到这种变化的威胁。整合机会随着你在文化、流程和工具中达到更高的 DevOps 成熟度水平，包含 CI/CD 工具链的工具的开源根源为一些激动人心的集成创造了机会。分析公司 Forrester 在 2020 年预测， 即时学习 just-in-time learning 将加入 CI/CD 管道。如果你考虑一下，会发现这是有道理的。在当前远程工作的时代，甚至对于新员工的远程入职，这更有意义。例如，组织可以将文档 wiki 与内部流程文档集成到其管道中。更雄心勃勃的组织可以将学习管理系统（LMS）（例如 Moodle）集成到其 CI/CD 管道中。它可以使用 LMS 发布有关新 DevOps 工具链功能的简短视频，开发人员在加入时或在整个管道中更新工具时需要学习这些功能。一些组织正在将群聊和其他协作工具直接集成到他们的 CI/CD 管道中。聊天平台提供警报并支持团队之间的协作和沟通。将 Mattermost、Rocket.Chat 或其他 企业聊天 平台集成到你的 CI/CD 管道中需要预先规划和分析，以确保管道用户不会被警报淹没。另一个需要探索的集成机会是将分析和高级报告构建到你的 CI/CD 管道中。这有助于你利用通过管道传输的数据。总结CI/CD 管道是 DevOps 的基础。开源使其能够适应并灵活地满足你在 DevOps 之旅中实施的运营变更所产生的新需求。我希望看到对统一 DevOps 平台趋势的开源响应，在这种趋势中，组织寻求端到端的 CI/CD 解决方案。这种解决方案的要素就在那里。毕竟，GitLab 和 GitHub 将他们的平台追溯到开源根源。最后，不要忘记每一个成功的 CI/CD 工具链背后的教育和外展。记录你的工具链和相关流程将改善开发人员入职和持续的 DevOps 团队培训。你和你的组织如何定义你的 CI/CD 工具链？请在评论中分享你的反馈。via: https://opensource.com/article/21/6/what-cicd-pipeline作者：Will Kelly 选题：lujun9972 译者：baddate 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出

CI/CD 平台迁移实践：从 Travis-CI 转移到 Github Action
type: item
date: 2021-01-17T02:18:00+08:00
description: LCTT 的 CI 已经在 Travis CI 上运转了多年，一致保持着良好的使用体验。自 2019 年 Github 推出了自家的 CI 工具 Github Action 后，我们就在考虑将 CI 从 Travis-CI 迁移到 Github，以降低维护和沟通的成本，并借助于 GitHub Action Marketplace 实现更强的功能。最近，因为 TravisCI 屡屡部署出错，而我们的账户因为使用的较多，已经超出了免费使用的限制，以此为契机，将 CI 从 Travis CI 迁移到 GitHub Action。项目介绍Translate Project 是 LCTT 翻译组的主要协作项目，几百位译者通过 GitHub 进行围绕开源、Linux、软件工程等领域的文章翻译，从 2013 年来，累计了大量的提交，致使项目下有非常多的文件。Translate Project 借助于 CI 帮助译者对基本的文章格式和拉取请求进行检查；并定时执行命令，以进行所有的申请检查，对于超时未完成翻译的工作进行回收；对于文章的状态进行标记，生成相应的徽章。迁移思路Travis CI 和 Github Action 在使用方面，其实总体差异不会太大，都是基于 YAML 文件格式来编写配置文件。不过，和 Travis CI 不同的是，Github Action 支持多个不同的配置文件，因此，你可以根据不同的场景，设定不同的配置文件，降低单个配置的文件的复杂度。此外，由于我们的脚本中依赖了一些 Travis CI 的环境变量，也需要将其替换为 Github Action 中的相应环境变量，从而确保脚本可以运转。改造实践1. 分析之前的 CI 流程我们在 TravisCI 上的 CI 配置文件如图：总体可以分为三块：命令区：说明了安装阶段和执行阶段的操作有哪些条件区：指定了这个配置文件在哪些条件下会生效部署区：写明了构建产物如何进行部署在命令区中，有预置的安装过程和后续的执行过程。在安装过程中，安装了一些依赖，并将当前的 pages 资源克隆到本地，以继承上一次构建生成的资料。在条件区则指明了仅作用于 master 分支。在部署区便是将前面命令区的执行结果进行部署。在实际的执行过程中，还会根据环境变量不同，决定是否要执行特定的命令，这部分在后续的改造过程中，就可以调整部署，拆分到不同的文件中。2. 直接套用配置文件在完成了基本的分析后，就可以建立新的 Action 配置文件了。由于基本的语法很类似，对于其中的不少内容可以进行直接套用。比如，我们的配置文件在直接套用后，结果如下直接套用的文件已经可以直接运行，不过，这里有很多不满足需要的地方，所以需要做一些修改。3. 恢复 Travis CI 的环境变量由于我们使用的 Badge 等生成脚本并非我所编写，所以在这一次的迁移中，并不打算对齐进行调整，以避免出现故障。而脚本中依赖了一些变量，需要将其重新设置出来。Github Action 提供了一些方法，可以让你手动设置环境变量。你可以在你的构建的步骤中，加入如下代码，从而在构建环境中设定 TRAVIS_BRANCH 和 TRAVIS_EVENT_TYPE 环境变量，确保你可以使用这个环境变量。 - name: Set ENV variables run: | echo "::set-env name=TRAVIS\_BRANCH::${TRAVIS\_BRANCH:-$(echo $GITHUB\_REF | awk 'BEGIN { FS = "/" } ; { print $3 }')}" echo "::set-env name=TRAVIS\_EVENT\_TYPE::$(if [ "schedule" == "${{ github.event\_name }}" ]; then echo "cron"; else echo "${{ github.event\_name }}"; fi)" 此外，由于 set-env 这个方法相对比较危险，你还需要在环境变量中，开启危险函数的执行。jobs: build: runs-on: ubuntu-latest env: ACTIONS\_ALLOW\_UNSECURE\_COMMANDS: true 4. 拆分配置文件Github Action 和 TravisCI 不同的一点是你可以将你的 CI 文件拆分成多个文件，从而降低每一个单独的配置文件的复杂度。根据前面对于流程的分析，可以将我们的 CI 流程拆分成三个部分：生成 badge 文件，应当跟随每一次提交进行生成 status 文件，执行时间较长，可以定期执行根据拉取请求内容进行整理，做核验则将我们的配置文件拆分成三个不同的文件：也得益于拆分…

使用一条 CI/CD 流水线管理所有的产品
type: item
date: 2020-07-08T06:48:18+08:00
description: 统一的持续集成与持续交付的流水线的构想是一种梦想吗？当我加入 WorkSafeBC 负责云端运维和工程流程优化的云端运维团队时，我和大家分享了我的梦想，那就是一个工具化的流水线，每一个产品都可以持续集成和持续交付。根据 Lukas Klose 的说法， 流程 flow （在软件工程的语境内）是“软件系统以稳定和可预测的速度创造价值的状态”。我认为这是最大的挑战和机遇之一，特别是在复杂的新兴解决方案领域。我力求通过一种持续、高效和优质的解决方案，提供一种持续交付模式，并且能够构建正确的事物让我们的用户感到满意。想办法把我们的系统分解成更小的碎片，这些碎片本身是有价值的，使团队能够渐进式地交付价值。这需要业务和工程部门改变思维方式。持续集成和持续交付的（CI/CD）流水线CI/CD 流水线是一种 DevOps 实践，用于更频繁、一致、可靠的地交付代码变更。它可以帮助敏捷开发团队提高部署频率，减少变更准备时间、变更失败率和关键绩效指标（KPI）的平均恢复时间，从而提高质量并且实现更快的交付。唯一的先决条件就是坚实的开发流程、对质量的心态和对需求从构想到废弃的责任心，以及一个全面的流水线（如下图所示）。它简化了工程流程和产品，以稳定基础架构环境；优化工作流程；并创建一致的、可重复的、自动化的任务。正如 Dave Snowden 的 Cynefin Sensemaking 模型所说的那样，这样就允许我们将复杂不可解决的任务变成了复杂可解决的任务，降低了维护成本，提高了质量和可靠性。精简流程的一部分是将 浪费实践类型 wasteful practice types Muri（过载）、Mura（变异）和 Muda（浪费）的浪费降低最低。Muri（过载）：避免过度工程化，避免与商业价值不相关的功能以及过多的文档。Mura（变异）：改善审批和验证流程（比如，安全签批）；推动 左移提前 shift-left 策略以推行单元测试、安全漏洞扫描与代码质量检查；并改进风险评定。Muda（浪费）：避免技术债、错误或前期的详细文档等浪费。看起来 80％ 的重点都集中在提供一种可以集成和协作的工程产品上，这些系统可以采用一个创意和计划、开发、测试和监控你的解决方案。然而，一个成功的转型和工程系统是由 5％ 的产品、15％ 的过程和 80％ 的开发人员组成的。我们可以使用的产品有很多。比如，Azure DevOps 为持续集成（CI）、持续交付（CD）和可扩展性提供了丰富支持，并与 Stryker、SonarQube、WhiteSource、Jenkins 和 Octopus 等开源集成和商用成品（COTS）软件即服务（SaaS）进行集成。对于工程师来说，关注产品总是一种诱惑，但请记住，它们只是我们旅程的 5%。最大的挑战是打破数十年的规则、规定和已经步入舒适区的流程：“我们一直都是这样做的；为什么需要改变呢？”开发和运维人员之间的摩擦导致了各种支离破碎的、重复的、不间断的集成和交付流水线。开发人员希望能访问所有东西，以便持续迭代，让用户使用起来和持续地快速发布。运维人员希望将所有东西锁起来，保护业务、用户和品质。这些矛盾在不经意间导致了很难做到一种自动化的流程，进而导致发布周期晚于预期。让我们使用最近的一次白板讨论中的片段来探索流水线。想要支持流水线的变化是一项困难并且花费巨大的工作；版本和可追溯性的不一致使得这个问题变得更加复杂，因此不断精简开发流程和流水线是一项挑战。我主张一些原则使得每个产品都能使用通用流水线：使一切可自动化的东西都自动化一次构建保持持续集成和持续交付保持持续精简和改进保持一个构建的定义保持一个发布流水线的定义尽早、频繁地扫描漏洞，并且尽快失败尽早、频繁地进行测试，并且尽快失败保持已发布版本的可追踪和监控但是，如果我要打破这些，最重要的原则就是保持简单。如果你不能说明流水线化的原因（是什么、为什么）和过程（如何），你或许是不了解自己的软件过程的。我们大多数人想要的不是最好的、超现代的和具有革命意义的流水线 —— 我们仅仅是需要一个功能强大的、有价值的和能促进工程的流水线。首先需要解决的是那 80% —— 文化、人员和他们的心态。请你的 CI/CD 骑士们穿上闪亮的盔甲，在他们的盾牌上贴上 TLA（ 两个/三个字母的缩写 two/three-lettered acronym ）符号，加入到实践和经验工程的力量中来。统一流水线让我们逐步完成我们的白板会议实践。每个应用使用一套构建定义来定义一个 CI/CD 流水线，用来触发拉取请求的预合并验证与持续集成的构建。生成一个带有调试信息的发布的构建，并且将其上传到 符号服务器。这使开发人员可以在本地和远程生产环境进行调试，而在不用考虑需要加载哪个构建和符号，符号服务器为我们施展了这样的魔法。在构建…

Linux 内核的持续集成测试
type: item
date: 2019-08-02T19:26:28+08:00
description: CKI 团队是如何防止 bug 被合并到 Linux 内核中。Linux 内核的每个发布版本包含了来自 1,700 个开发者产生的 14,000 个变更集，很显然，这使得 Linux 内核快速迭代的同时也产生了巨大的复杂性问题。内核上 Bug 有小麻烦也有大问题，有时是系统崩溃，有时是数据丢失。随着越来越多的项目对于持续集成（CI）的呼声，内核持续集成（CKI）小组秉承着一个任务目标：防止 Bug 被合并到内核当中。Linux 测试问题许多 Linux 发行版只在需要的时候对 Linux 内核进行测试。而这种测试往往只在版本发布时或者用户发现错误时进行。有时候，出现玄学问题时，维护人员需要在包含了数万个补丁的变更中匆忙地寻找哪个补丁导致这个新的玄学 Bug。诊断 Bug 需要专业的硬件设备、一系列的触发器以及内核相关的专业知识。CI 和 Linux许多现代软件代码库都采用某种自动化 CI 测试机制，能够在提交进入代码存储库之前对其进行测试。这种自动化测试使得维护人员可以通过查看 CI 测试报告来发现软件质量问题以及大多数的错误。一些简单的项目，比如某个 Python 库，附带的大量工具使得整个检查过程更简单。在任何测试之前都需要配置和编译 Linux。而这么做将耗费大量的时间和计算资源。此外，Linux 内核必需在虚拟机或者裸机上启动才能进行测试。而访问某些硬件架构需要额外的开销或者非常慢的仿真。因此，人们必须确定一组能够触发错误或者验证修复的测试集。CKI 团队如何运作？Red Hat 公司的 CKI 团队当前正追踪来自数个内部内核分支和上游的稳定内核分支树等内核分支的更改。我们关注每个代码库的两类关键事件：当维护人员合并 PR 或者补丁时，代码库变化后的最终结果。当开发人员通过拼凑或者稳定补丁队列发起变更合并时。当这些事件发生时，自动化工具开始执行，GitLab CI 管道开始进行测试。一旦管道开始执行 linting) 脚本、合并每一个补丁，并为多种硬件架构编译内核，真正的测试便开始了。我们会在六分钟内完成四种硬件架构的内核编译工作，并且通常会在两个小时或更短的时间内将反馈提交到稳定邮件列表中。（自 2019 年 1 月起）每月执行超过 100,000 次内核测试，并完成了超过 11,000 个 GitLab 管道。每个内核都会在本地硬件架构上启动，其中包含：aarch64：64 位 ARM，例如 Cavium（当前是 Marvell）ThunderX。ppc64/ppc64le：大端和小端的 IBM POWER 系统。s390x：IBM Zseries 大型机x86\_64：Intel 和 AMD 工作站、笔记本和服务器。这些内核上运行了包括 Linux 测试项目（LTP）在内的多个测试，其中包括使用常用测试工具的大量测试。我们 CKI 团队开源了超过 44 个测试并将继续开源更多测试。参与其中上游的内核测试工作日渐增多。包括 Google、Intel、Linaro 和 Sony 在内的许多公司为各种内核提供了测试输出。每一项工作都专注于为上游内核以及每个公司的客户群带来价值。如果你或者你的公司想要参与这一工作，请参加在 9 月份在葡萄牙里斯本举办的 Linux Plumbers Conference 2019。在会议结束后的两天加入我们的 Kernel CI hackfest 活动，并推动快速内核测试的发展。更多详细信息，请见我在 Texas Linux Fest 2019 上的演讲。via: https://opensource.com/article/19/6/continuous-kernel-integration-linux作者：Major Hayden 选题：lujun9972 译者：LazyWolfLin 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出

ick：一个持续集成系统
type: item
date: 2019-03-02T19:06:15+08:00
description: ick 是一个持续集成（CI）系统。访问 http://ick.liw.fi/ 获取更多信息。更加详细的内容如下：首个公开版本发行这个世界可能并不需要又一个持续集成系统（CI），但是我需要。我对我尝试过或者看过的持续集成系统感到不满意。更重要的是，有几样我感兴趣的东西比我所听说过的持续集成系统要强大得多。因此我开始编写我自己的 CI 系统。我的新个人业余项目叫做 ick。它是一个 CI 系统，这意味着它可以运行自动化的步骤来构建、测试软件。它的主页是 http://ick.liw.fi/，下载页面有指向源代码、.deb 包和用来安装的 Ansible 脚本的链接。我现已发布了首个公开版本，绰号 ALPHA-1，版本号 0.23。（LCTT 译注：截止至本译文发布，已经更新到 ALPHA-6）它现在是 alpha 品质，这意味着它并没拥有期望的全部特性，如果任何一个它已有的特性工作的话，那真是运气好。诚邀贡献ick 目前是我的个人项目。我希望能让它不仅限于此，同时我也诚邀更多贡献。访问治理页面查看章程，入门页面查看如何开始贡献的的小建议，联系页面查看如何联络。架构ick 拥有一个由几个通过 HTTPS 协议通信使用 RESTful API 和 JSON 处理结构化数据的部分组成的架构。访问架构页面了解细节。宣告持续集成（CI）是用于软件开发的强大工具。它不应枯燥、易溃或恼人。它构建起来应简单快速，除非正在测试、构建的代码中有问题，不然它应在后台安静地工作。一个持续集成系统应该简单、易用、清楚、干净、可扩展、快速、综合、透明、可靠，并推动你的生产力。构建它不应花大力气、不应需要专门为 CI 而造的硬件、不应需要频繁留意以使其保持工作、开发者永远不必思考为什么某样东西不工作。一个持续集成系统应该足够灵活以适应你的构建、测试需求。只要 CPU 架构和操作系统版本没问题，它应该支持各种操作者。同时像所有软件一样，CI 应该彻彻底底的免费，你的 CI 应由你做主。（目前的 ick 仅稍具雏形，但是它会尝试着有朝一日变得完美 —— 在最理想的情况下。）未来的梦想长远来看，我希望 ick 拥有像下面所描述的特性。落实全部特性可能需要一些时间。各种事件都可以触发构建。时间是一个明显的事件，因为项目的源代码仓库改变了。更强大的是任何依赖的改变，不管依赖是来自于 ick 构建的另一个项目，或者是包（比如说来自 Debian）：ick 应当跟踪所有安装进一个项目构建环境中的包，如果任何一个包的版本改变，都应再次触发项目构建和测试。ick 应该支持构建于（或针对）任何合理的目标平台，包括任何 Linux 发行版，任何自由的操作系统，以及任何一息尚存的不自由的操作系统。ick 应该自己管理构建环境，并且能够执行与构建主机或网络隔离的构建。这部分工作：可以要求 ick 构建容器并在容器中运行构建。容器使用 systemd-nspawn 实现。 然而，这可以改进。（如果您认为 Docker 是唯一的出路，请为此提供支持。）ick 应当不需要安装任何专门的代理，就能支持各种它能够通过 ssh 或者串口或者其它这种中性的交流管道控制的 操作者 worker 。ick 不应默认它可以有比如说一个完整的 Java Runtime，如此一来，操作者就可以是一个微控制器了。ick 应当能轻松掌控一大批项目。我觉得不管一个新的 Debian 源包何时上传，ick 都应该要能够跟得上在 Debian 中构建所有东西的进度。（明显这可行与否取决于是否有足够的资源确实用在构建上，但是 ick 自己不应有瓶颈。）如果有需要的话 ick 应当有选择性地补给操作者。如果所有特定种类的操作者处于忙碌中，且 ick 被设置成允许使用更多资源的话，它就应该这么做。这看起来用虚拟机、容器、云提供商等做可能会简单一些。ick 应当灵活提醒感兴趣的团体，特别是关于其失败的方面。它应允许感兴趣的团体通过 IRC、Matrix、Mastodon、Twitter、email、SMS 甚至电话和语音合成来接受通知。例如“您好，感兴趣的团体。现在是四点钟您想被通知 hello 包什么时候为 RISC-V 构建好。”请提供反馈如果你尝试过 ick 或者甚至你仅仅是读到这，请在上面分享你的想法。在联系页面查看如何发送反馈。相比私下反馈我更偏爱公开反馈。但如果你偏爱私下反馈，那也行。via: https://blog.liw.fi/posts/2018/01/22/ick_a_continuous_integration_system/作者：Lars Wirzenius 译者：tomjlw 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出

系统管理员的 7 个 CI/CD 工具
type: item
date: 2019-03-01T18:17:29+08:00
description: 本文是一篇简单指南：介绍一些顶级的开源的持续集成、持续交付和持续部署（CI/CD）工具。虽然持续集成、持续交付和持续部署（CI/CD）在开发者社区里已经存在很多年，一些机构在其运维部门也有实施经验，但大多数公司并没有做这样的尝试。对于很多机构来说，让运维团队能够像他们的开发同行一样熟练操作 CI/CD 工具，已经变得十分必要了。无论是基础设施、第三方应用还是内部开发的应用，都可以开展 CI/CD 实践。尽管你会发现有很多不同的工具，但它们都有着相似的设计模型。而且可能最重要的一点是：通过带领你的公司进行这些实践，会让你在公司内部变得举足轻重，成为他人学习的榜样。一些机构在自己的基础设施上已有多年的 CI/CD 实践经验，常用的工具包括 Ansible、Chef 或者 Puppet。另一些工具，比如 Test Kitchen，允许在最终要部署应用的基础设施上运行测试。事实上，如果使用更高级的配置方法，你甚至可以将应用部署到有真实负载的仿真“生产环境”上，来运行应用级别的测试。然而，单单是能够测试基础设施就是一项了不起的成就了。配置管理工具 Terraform 可以通过 Test Kitchen 来快速创建更短暂和冥等的的基础设施配置，这比它的前辈要强不少。再加上 Linux 容器和 Kubernetes，在数小时内，你就可以创建一套类似于生产环境的配置参数和系统资源，来测试整个基础设施和其上部署的应用，这在以前可能需要花费几个月的时间。而且，删除和再次创建整个测试环境也非常容易。当然，作为初学者，你也可以把网络配置和 DDL（ 数据定义语言 data definition language ）文件加入版本控制，然后开始尝试一些简单的 CI/CD 流程。虽然只能帮你检查一下语义语法或某些最佳实践，但实际上大多数开发的管道都是这样起步的。只要你把脚手架搭起来，建造就容易得多了。而一旦起步，你就会发现各种管道的使用场景。举个例子，我经常会在公司内部写新闻简报，我使用 MJML 制作邮件模板，然后把它加入版本控制。我一般会维护一个 web 版本，但是一些同事喜欢 PDF 版，于是我创建了一个管道。每当我写好一篇新闻稿，就在 Gitlab 上提交一个合并请求。这样做会自动创建一个 index.html 文件，生成这篇新闻稿的 HTML 和 PDF 版链接。HTML 和 PDF 文件也会在该管道里同时生成。除非有人来检查确认，这些文件不会被直接发布出去。使用 GitLab Pages 发布这个网站后，我就可以下载一份 HTML 版，用来发送新闻简报。未来，我会修改这个流程，当合并请求成功或者在某个审核步骤后，自动发出对应的新闻稿。这些处理逻辑并不复杂，但的确为我节省了不少时间。实际上这些工具最核心的用途就是替你节省时间。关键是要在抽象层创建出工具，这样稍加修改就可以处理不同的问题。值得留意的是，我创建的这套流程几乎不需要任何代码，除了一些轻量级的 HTML 模板，一些把 HTML 文件转换成 PDF 的 nodejs 代码，还有一些生成索引页面的 nodejs 代码。这其中一些东西可能看起来有点复杂，但其中大部分都源自我使用的不同工具的教学文档。而且很多开发人员也会乐意跟你合作，因为他们在完工时会发现这些东西也挺有用。上面我提供的那些代码链接是给 DevOps KC（LCTT 译注：一个地方性 DevOps 组织） 发送新闻简报用的，其中大部分用来创建网站的代码来自我在内部新闻简报项目上所作的工作。下面列出的大多数工具都可以提供这种类型的交互，但是有些工具提供的模型略有不同。这一领域新兴的模型是用声明式的方法例如 YAML 来描述一个管道，其中的每个阶段都是短暂而幂等的。许多系统还会创建有向无环图（DAG），来确保管道上不同的阶段排序的正确性。这些阶段一般运行在 Linux 容器里，和普通的容器并没有区别。有一些工具，比如 Spinnaker，只关注部署组件，而且提供一些其他工具没有的操作特性。Jenkins 则通常把管道配置存成 XML 格式，大部分交互都可以在图形界面里完成，但最新的方案是使用领域专用语言（DSL）（如 Groovy）。并且，Jenkins 的任务（job）通常运行在各个节点里，这些节点上会装一个专门的 Java 代理，还有一堆混杂的插件和预装组件。Jenkins 在自己的工具里引入了管道的概念，但使用起来却并不轻松，甚至包含一些禁区。最近，Jenkins 的创始人决定带领社区向新的方向前进，希望能为这个项目注入新的活力，把 CI/CD 真正推广开（LCTT 译注：详见后面的 Jenkins 章节)。我认为其中最有意思的想法是构建一个云原生 Jenkins，能把 Kubernetes 集群转变成 Jenkins CI/C…