Kubernetes 单体仓库拆分史:2017 贡献者峰会 “Breaking Up The Monolith“ 讨论实录与技术复盘
2026/9/16 9:46:17 网站建设 项目流程

Kubernetes 单体仓库拆分史:2017 贡献者峰会 "Breaking Up The Monolith" 讨论实录与技术复盘

【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community

2017 年 12 月 5 日,KubeCon 前夜,Kubernetes 贡献者峰会(Contributor Summit)在奥斯汀举行,采用"非结构化非会议(unconference)"的开放式鱼缸讨论形式(详见 ContribSummitInformation.md)。其中一场由 Josh Berkus(@jberkus)与 Aaron Crickenberger(@spiffxp)担任记录员的圆桌——breaking-up-the-monolith.md——围绕"是否以及如何拆掉 kubernetes/kubernetes 单体仓库"展开了针锋相对、信息密度极高的辩论。这场讨论记录了当时项目在代码组织上的核心痛点、候选拆分清单(kubectl、client-go、kubeadm、云厂商驱动等)、staging 机制、发布与测试基建的缺口,也直接影响了后来 Kubernetes 多仓库治理格局的形成。读完本文,你将完整还原这场关键讨论的各方论点、决策脉络,并结合本仓库的后续文档理解其历史走向。

一、背景:为什么 2017 年底必须谈"拆库"

彼时 Kubernetes 已经拥有约 90 个仓库(bgrant 在会上的原话:"We're already in the land of 90 repos"),但核心代码库 kubernetes/kubernetes 仍然是一个巨型单体仓库(monorepo)。会议记录开篇即点明本次讨论的三大主题:构建流程(build process)、Issue 跟踪(issue tracking)、工程后勤(logistics)

与会者反复强调的动机可以归纳为两条主线:

  1. 核心无法持续以同样速度增长(erictune):"as the project matures the core can't keep growing at the same rate",项目成熟后核心代码库的膨胀速率必须被控制;
  2. 开发者体验恶化(mattfarina):单体仓库让新贡献者难以进入 Issue 队列、难以找到可贡献的切入点,"difficulty to contribute pushes people away from contributing";
  3. Issue 无人问津(thockin):主仓库中超过 6 周无人处理的 Issue 比比皆是,仅 network 相关就有 400~500 个被废弃的 Issue;
  4. 大量目录没有 OWNERS 文件(spiffxp):数百个目录缺乏负责人,导致通知泛滥、路由混乱。

这些问题的本质,是仓库规模增长与治理能力之间的失衡。

二、第一个问题:我们是否 100% 承诺拆分单体仓库

会议第一轮交锋围绕"拆分意愿"展开,结论是**"承诺拆分,但必须先定义拆分意味着什么"**。长期尝试维护单体仓库"太昂贵了"("We've been trying the monolith for so long and it's too expensive"),但支持与反对双方提出了截然不同的视角:

发言者立场核心观点
erictune支持(有限度)生态可以增长,但"狭义定义的核心"不应继续膨胀
mattfarina支持贡献难度把潜在贡献者推走
clayton谨慎kubectl 永远不会更简单,也许写一个新的反而更容易;"为什么建一个东西而不是花两倍成本建两个"(指拆出一个高性能 client-go + 一个面向人类、可复用的重写版 client-go)
bburns反对声音我们从不量化拆分的成本,只因为"更干净"就喜欢拆,却没有估算人力与复杂度代价
lavalamp反驳 bburns我们已经估算过成本,明知会很痛苦,但别无选择
timstclair质疑落地没有人回答过"如何把一组二进制作为一次发布交付",没有统一计划;测试基建如何覆盖所有组件也是未知数
bburns补充质疑e2e 失败时如何定位导致失败的 commit
dims / matt提出清单应该列出四五个优先级最高的外移项

其中 timstclair 提出的两个问题——多仓库下的发布交付计划测试基建覆盖——成为贯穿整场讨论、乃至之后数年 Kubernetes 代码库治理的核心难题。lavalamp 则给出了一个关键的架构设想(文内标注 TODO link):主仓库(main repo)退化为"集成点",二进制产物由其他仓库生产

三、第二个问题:拆分到底要解决什么问题

会议第二环节尝试厘清目标,而非手段。两个基本假设被摆上桌面:

  • 贡献者速度与(新)贡献者体验正相关
  • "一大团纠缠的面条"(big tangled ball of pasta)难以贡献

围绕"是否必须拆成独立仓库"出现了重要的分歧与深化:

  1. 模块化不一定等于多仓库(jberkus):其他大型项目经验表明,关键在于"模块化架构",而不必然是"多个仓库";
  2. 在仓库内部模拟多仓库(thockin):与其拆库,不如"移动代码"直到仓库内部看起来像多个子仓库——例如把 kubelet 相关逻辑全部集中到一个目录(除一个 util 目录外),或许本身就是一种改进;
  3. 先拆云厂商驱动(与会共识):"First thing: we're breaking up cloud providers, it helps let the long tail of cloud providers go out"。云厂商是第一个拆出去的对象,存储提供商随后也应有清晰接口;
  4. 明确的接口边界(dchen1107,时任发布经理):发布管理成本巨大,作为发布经理"我不知道另一个仓库里有什么";但清晰的 API 与接口并不需要独立仓库——她举了 Docker 与 CRI 的例子:不搬仓库也拿到了干净的 API
  5. 决策机制缺失(robertbailey):提出本议题时以为大家已达成拆分共识,但显然没有;需要弄清"谁是决策者 / 决策者群体";
  6. 自动化与通知(spiffxp):多仓库对 GitHub 通知更友好,机器人改善了自动化但未解决通知分级;也许该改进通知路由而不是拆库;
  7. 小仓库接入门槛(solly):如果拆分,必须让小型仓库更容易接入自动化与工具链,"我不该自己摸索该问谁",应该有文档,不能出现 Heapster 那样"掉进裂缝里"的仓库。

bgrant 的一锤定音值得注意:"We're already in the land of 90 repos. We don't need to debate splitting, we're already split."——从治理现实看,拆分早已发生(incubator、kubernetes-client 等),争论的焦点其实是如何把拆分做对,尤其是让 API 类型、SDK 与通用工具链真正可复用("We need SDKs to build kube-style APIs")。

四、候选拆分清单:kubectl、client-go、kubeadm 与云厂商

会上形成了初步的"外移候选清单",这份清单与同一峰会其他分会场(如 cloud-provider.md)以及 2017 年 5 月领导力峰会上的 Code Organization and Release Process Improvement 高度呼应:

候选组件会上讨论要点后续走向(以本仓库文档为据)
kubectlclayton 认为 kubectl 本身太大,值得围绕"新东西"重建社区;lavalamp 形容其为"拉入大量包、技术难以下手"的意大利面代码已在拆分依赖的过程中,拥有独立仓库并迁移 Issue(见 0300-0345_CODEORGANIZATION.md)
client-go已独立发布,属于"另一个量级"的问题,需另开会讨论;clayton 提出"高性能版 + 面向人类重写版"双轨思路对应 kubernetes-client 多语言客户端生态
kubeadm留在主仓库是为了赶上发布列车(release train);曾尝试移出但失败;luxas(Lucas Käldström,时任 kubeadm 负责人)提出 kubeadm 仓库必须"权威"并能纳入构建后续成立 Kubeadm Adoption 工作组推动采纳(见 archive/wg-kubeadm-adoption/README.md)
云厂商驱动(cloud providers)首要拆分对象;dims 举例 Google KMS provider 被移出、gRPC 接口 PR 未进 1.9,说明在树外开发更灵活同峰会 cloud-provider.md 记录了 cloud-controller-manager 拆分进展
kubelet / kube-proxythockin 提出疑问:拆这些能带来具体收益吗,还是会带来更多痛苦?"我们清楚这会拖慢节奏"未在本次达成共识,留待后续
存储提供商若拆分应有清晰接口后续由 CSI 承接(同峰会 cloud-provider 讨论中亦有提及)

会议还记录了"已完成 / 进行中"的拆分成果,作为可行性参考:API machinery(staging 化后解除了阻塞)、cloud provider、kubernetes-client 组织。bgrant 总结称:monorepo 中的"velocity 是静态的"("the velocity of things in the monorepo are static")。

五、绕不开的三大工程挑战:发布、测试、依赖

5.1 发布管理:多仓库如何拼出一次发布

这是 timstclair 抛出的最尖锐问题:"没有人回答过我们如何把一组二进制作为一次发布交付,没有统一计划。"其难点在于:

  • 发布经理无法掌握其他仓库内容(dchen1107 作为时任发布经理的切身之痛);
  • 安全更新必须快速送达(Cloud Foundry 两周构建流程被引为反面案例);
  • 多仓库需要"组装发布":各组件在各自仓库测试充分后,由主仓库集成组装(参见 0300-0345_CODEORGANIZATION.md 中"Multi-repo requirements"一节);
  • luxas 特别强调 kubeadm 的"攻击计划":需要为多仓库做一次发布,kubeadm 仓库要权威,且能纳入构建

5.2 测试基建:谁来测、怎么定位回归

与会者担忧拆分后的测试覆盖问题:

  • timstclair:"how are you actually going to get test infra to test all the things";
  • bburns:"how do you actually find the commit that causes a failure in e2e";
  • 会议结论倾向:用更小、更聚焦的测试取代过度依赖 e2e 的做法("Need better, smaller tests overall"),"不要在 e2e 上验证未经文档化的功能"。

5.3 依赖管理:godeps 的噩梦

timallclair 直言:"我担心依赖管理,godeps 已经是噩梦,多仓库只会更糟。" 这一担忧在后续 Kubernetes 全面转向 Go modules 后才得到缓解。此外 dims 指出 monorepo 的连带污染问题:vendor 会把不关心的 SDK(如 AWS SDK)拖进来——"如果只做 OpenStack 相关工作,在主仓库里很难获得合入批准,但在自己的仓库里就容易得多"。

六、staging 机制:在拆与不拆之间的第三条路

本场讨论反复出现的"staging"概念,值得单独说明。它是 Kubernetes 在仓库内部模拟多仓库的中间态:代码仍留在主仓库,但按 k8s.io 包路径组织成"伪仓库",通过符号链接进入 vendor 目录供 Go 工具链消费,再由发布机器人用git filter-branch将各 staging 目录切分成真实仓库推送到外部(详见本仓库文档 contributors/devel/sig-architecture/staging.md)。

会上围绕 staging 的价值与边界形成了几个重要判断:

  • "staging 状态是解决了一半的状态"(lavalamp):API machinery 正是因为到达 staging 状态而被解除了阻塞;thockin 则认为 staging 已经"解决"了问题,因为"你得先把纠缠的依赖解开才能 staging";
  • staging 可作为"已拆分"的观察窗口(pwittrock):可以从 staging 仓库的实例中看到拆分带来的收益或问题;
  • erictune 的呼吁:请把"已经开工但没拆完"的分拆工作做完("finish some of our started-but-not-finished breakaparts");
  • 同峰会 cloud-native-design-refactoring-across-k8s.md 也列出了跨仓库重构的相关 Issue 与 util 目录整合工作,可视作 staging 路径上的具体任务。

根据 staging.md 的记载,该机制最终演化为成熟的发布机器人(publishing bot)体系:支持多分支发布(master 及 release-1.28 至 release-1.31 等)、为发布仓库自动打kubernetes-前缀标签、并自 v1.17.0 起同步生成与主仓库 tag 对应的语义化v0.x.y标签以无缝衔接 Go modules。

七、没有结论的结论:走向"软件还是发行版"之问

这场讨论没有形成投票式的决议,但沉淀了几点关键共识:

  1. 拆分已既成事实,争论焦点是治理(bgrant:"我们已经有 90 个仓库");主仓库将演化为集成点,二进制产物由其他仓库生产(lavalamp);
  2. 必须量化成本:bburns 的"我们不测量成本"之问,与 lavalamp"我们已经估算过"的回答,共同指向同一个行动——拆分必须基于成本收益而非审美偏好;
  3. 扩展点需要接口而非拆库:CRI(Docker 例)、cloud provider、CRD、SDK 都是"不搬仓库也能拿 API"的证明;
  4. 对基础设施的依赖会加重(spiffxp):"增加对集成工具的依赖会带来现在没有的开销与流程",但多数 OSS 从业者期望多仓库,且 GitHub 通知在多仓库下更易管理;
  5. 自动化接入要有文档与统一入口(solly):不能让小仓库"掉进裂缝";
  6. thockin 将终极问题抛给全场:"我们是'一个软件'还是'一个发行版'(a piece of software or a distribution)?"——这个问题的答案决定了 monorepo 的未来形态。

回望本仓库的目录结构,这场 2017 年会议所讨论的分拆蓝图——kubectl 归 SIG CLI、云厂商驱动外置、client-go 独立发布、kubeadm 拥有独立工作组的采纳计划、staging 目录与发布机器人常态化——都在后续 Kubernetes 社区治理文档中得到了印证。对于研究大型开源项目代码库治理的工程师而言,这份会议记录是理解"monorepo 拆分之痛"的第一手史料:它诚实地记录了成本、分歧、技术债务与长期投入,而非一份粉饰过的决策白皮书。

延伸阅读

  • 本场会议原始记录:breaking-up-the-monolith.md
  • 2017 年 5 月领导力峰会同主题记录:0300-0345_CODEORGANIZATION.md
  • staging 目录与发布机制:contributors/devel/sig-architecture/staging.md
  • 云厂商拆分进展:events/2017/12-contributor-summit/cloud-provider.md
  • kubeadm 采纳工作组:archive/wg-kubeadm-adoption/README.md
  • 峰会整体信息与议程:events/2017/12-contributor-summit/ContribSummitInformation.md

【免费下载链接】communityKubernetes Community Documentation项目地址: https://gitcode.com/GitHub_Trending/com/community

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询