本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

机器可以完成工作,一个关于 Kubernetes 测试、CI 和自动化贡献者体验的故事

“大型项目有很多不那么令人兴奋但却很辛苦的工作。我们更看重自动化重复工作所花费的时间,而不是劳累。如果工作无法自动化,我们的文化是承认并奖励所有类型的贡献。然而,英雄主义是不可持续的。” - Kubernetes 社区价值观

与许多开源项目一样,Kubernetes 托管在 GitHub 上。我们认为,如果项目存在于开发人员已经工作的地方,使用开发人员已经熟悉的工具和流程,那么参与的门槛将是最低的。因此,项目完全采用了这项服务:它是我们工作流程、问题跟踪器、文档、博客平台、团队结构等的基础。

这个策略奏效了。它奏效得如此之好,以至于项目很快就超越了贡献者作为人类的能力。接下来是一段不可思议的自动化和创新之旅。我们不仅需要在不坠毁的情况下在飞行中重建飞机,我们还需要将其改造成火箭飞船并送入轨道。我们需要机器来完成这项工作。

工作内容

最初,我们专注于需要支持像 Kubernetes 这样复杂的分布式系统所要求的巨大测试量。必须通过端到端 (e2e) 测试来执行实际故障场景,以确保功能正常。不幸的是,e2e 测试容易出现偶然失败 (flakes),并且需要一小时到一天才能完成。

进一步的经验揭示了机器可以为我们完成工作的其他领域

  • PR 工作流程
    • 贡献者是否签署了我们的 CLA?
    • PR 是否通过了测试?
    • PR 可以合并吗?
    • 合并提交是否通过了测试?
  • 分类
    • 谁应该审查 PR?
    • 是否有足够的信息将问题路由给合适的人?
    • 问题是否仍然相关?
  • 项目健康状况
    • 项目发生了什么?
    • 我们应该关注什么?

在开发自动化以改善现状时,我们遵循了一些指导原则

  • 遵循适用于 Kubernetes 的推/拉控制循环模式
  • 优先选择无状态、松散耦合且能做好一件事的服务
  • 优先赋能整个社区,而非少数核心贡献者
  • 自食其力,避免重复造轮子

Prow 登场

这使我们创建了 Prow 作为我们自动化的核心组件。Prow 有点像 GitHub 事件的 If This, Then That,内置了 命令插件和实用程序的库。我们将 Prow 构建在 Kubernetes 之上,以摆脱对资源管理和调度问题的担忧,并确保更愉快的操作体验。

Prow 让我们能够做这些事情:

  • 允许我们的社区通过评论诸如“/priority critical-urgent”、“/assign mary”或“/close”等命令来分类问题/PR
  • 根据代码更改量或涉及的文件自动标记 PR
  • 处理长时间不活跃的问题/PR
  • 自动合并符合我们 PR 工作流程要求的 PR
  • 运行定义为 Knative Builds、Kubernetes Pods 或 Jenkins 作业的 CI 作业
  • 执行组织范围和每个仓库的 GitHub 策略,例如 分支保护GitHub 标签

Prow 最初由构建 Google Kubernetes Engine 的工程生产力团队开发,并由 Kubernetes SIG Testing 的多名成员积极贡献。Prow 已被其他几个开源项目采用,包括 Istio、JetStack、Knative 和 OpenShift。Prow 入门 需要一个 Kubernetes 集群和 kubectl apply starter.yaml(在 Kubernetes 集群上运行 Pod)。

一旦 Prow 部署到位,我们开始遇到其他扩展瓶颈,因此开发了额外的工具来支持 Kubernetes 所需规模的测试,其中包括

  • Boskos:管理资源池中的作业资源(例如 GCP 项目),为作业签出并自动清理它们(附带监控
  • ghProxy:一个针对 GitHub API 使用进行优化的反向代理 HTTP 缓存,以确保我们的令牌使用不会达到 API 限制(附带监控
  • Greenhouse:允许我们使用远程 bazel 缓存,为 PR 提供更快的构建和测试结果(附带监控
  • Splice:允许我们批量测试和合并 PR,确保我们的合并速度不受测试速度的限制
  • Tide:允许我们通过 GitHub 查询而不是按队列顺序合并 PR,与 Splice 结合使用可显著提高合并速度

扩展项目健康状况

解决了工作流自动化问题后,我们转而关注项目健康状况。我们选择使用 Google Cloud Storage (GCS) 作为所有测试数据的真实来源,这让我们能够依赖已建立的基础设施,并允许社区贡献结果。然后,我们构建了各种工具来帮助个人和整个项目理解这些数据,其中包括

  • Gubernator:显示给定 PR 的结果和测试历史记录
  • Kettle:将数据从 GCS 传输到可公开访问的 BigQuery 数据集
  • PR 面板:一个工作流感知的面板,允许贡献者了解哪些 PR 需要关注以及原因
  • Triage:识别所有作业和测试中发生的常见故障
  • Testgrid:显示给定作业在所有运行中的测试结果,汇总作业组中的测试结果

我们与云原生计算基金会(CNCF)合作开发了 DevStats,以从我们的 GitHub 事件中获取洞察,例如

超越

如今,Kubernetes 项目横跨五个组织,拥有超过 125 个仓库。项目内有 31 个特别兴趣小组和 10 个工作组协调开发。在过去一年中,该项目在 GitHub 上有超过 13,800 名独立开发者参与

在任何工作日,我们的 Prow 实例运行超过 10,000 个 CI 作业;从 2017 年 3 月到 2018 年 3 月,它运行了 430 万个作业。这些作业大多涉及搭建一个完整的 Kubernetes 集群,并使用真实场景对其进行演练。它们使我们能够确保 Kubernetes 的所有支持版本都能在云提供商、容器引擎和网络插件中正常工作。它们确保最新版本的 Kubernetes 可以在启用各种可选功能的情况下工作,安全升级,满足性能要求,并跨架构工作。

今天CNCF 发布公告,指出 Google Cloud 已开始将 Kubernetes 项目的云资源所有权和管理权移交给 CNCF 社区贡献者,我们很高兴能够开启新的征程。这将使项目基础设施由贡献者社区拥有和运营,遵循与项目其余部分行之相同的开放治理模式。这听起来让您兴奋吗?请在 kubernetes.slack.com 的 #sig-testing 频道与我们交流。

想了解更多信息?请查看这些资源