“海外滴滴”Uber的Arm迁移实录:重构大规模基础设施

云工作负载在性价比上的自然演进路径:

Intel ➜ AMD ➜ ARM

不信?来看看 Uber 的做法:

01/Arm架构:云计算新时代

2023 年 2 月,Uber 正式开启了一项战略性迁移:将从本地数据中心迁移至云端,采用 Oracle Cloud Infrastructure(OCI)和 Google Cloud Platform(GCP)作为主要平台。

虽然如此大规模的云迁移本身已极具挑战性,Uber 同时还设立了另一个野心勃勃的目标:在以 x86 为主的服务器环境中引入 Arm 架构。

这么做的原因何在?为了降低成本、提升性价比,并在不可预测的供应链环境中确保硬件灵活性。

随后,Uber 经历了一段充满技术挑战和跨团队协作的旅程,逐步将 Arm 主机纳入服务器集群中。

本文将重点介绍在向多架构环境过渡的过程中,我们遇到了哪些基础设施层面的技术难题。

OCI 战略

想要理解我们为何迁移到基于 Arm 架构的主机,首先要了解 OCI(Oracle Cloud Infrastructure)采用 Ampere 处理器的初衷------能源效率是所有超大规模云服务商采纳 Arm 的核心驱动力。

一直以来,Arm 都以移动设备的低功耗设计闻名,而这一优势已延伸至数据中心产品,Ampere 处理器在单位功耗性能上树立了新标杆。这不仅降低了能源成本,也为 OCI 带来了显著节省。

另一个不那么显眼但同样重要的优势是空间集约化:Ampere 处理器能在更小的数据中心空间内实现更高的计算密度,从而在机架级别实现更高性能,最大限度减少占地面积和基础设施成本。

Uber 的动机是什么?

归根结底,是追求硬件与容量的多样化。

作为致力于成为"零排放公司"的一员,采用高性能、高能效的服务器,是减少环境影响的重要一步。

OCI 实现的能源和空间节省,将直接为 Uber 转化为更佳的成本结构和更强的可持续运营能力。

迁移阶段

Uber 采用多架构环境是一个复杂的过程,涉及多个阶段的 Bootstrap自举、周密规划和跨团队执行。整体流程大致可分为七个阶段,如下图所示:

图 1:Arm 采用流程图

  • **主机准备:**确保主机层软件兼容 Arm 架构
  • **构建准备:**更新构建流水线以支持多架构容器镜像
  • **平台准备:**增强部署系统,添加架构特定的调度约束与保护机制
  • **SKU 验证:**评估硬件可靠性与性能,确认是否可行
  • **工作负载:**改造代码库与容器镜像以支持 Arm
  • **迁移准备:**建立测试与监控机制,验证 Arm 上负载表现
  • **正式迁移:**逐个工作负载迁移至 Arm 环境

尽管采用过程主要遵循顺序流程,但部分阶段是并行进行的,以便加快进度。

下面我们将探讨在基于 Arm 的主机上引导构建基础设施时面临的挑战:

初始目标

最初的目标其实很简单:为 Arm 构建一个服务,并使用现有的部署平台将其部署到基于 Arm 的主机上。但这个看似简单的目标,却揭示出基础设施各层对 x86 的高度依赖。

主机准备

构建与部署服务之前,必须确保主机可支持 Arm。这意味着从最底层开始。

第一步是构建 Arm 兼容的主机镜像,包含操作系统、内核及 Uber 核心基础设施依赖的各类主机级软件。

每个组件都必须被重构、测试并验证,以确保在 Arm 硬件上稳定运行。一旦主机镜像准备完毕,我们就可以将 Arm 主机集成进服务器集群,为下一步构建服务打好基础。

构建服务

最初我们以为构建服务很简单,没想到这一步迅速暴露出问题:我们的构建基础设施在设计时高度依赖单一架构。

多年来,Uber 的容器镜像栈依赖于由 Makisu 支持的集中式 Buildkite™ 流水线。Makisu 是一种高效且快速的容器镜像构建器,专为单一架构构建优化。

尽管 Makisu 表现出色,但它有一个关键限制:它无法为 Arm 交叉编译。

这意味着我们不能简单地打开开关来生成兼容 Arm 的容器镜像。相反,我们必须重新思考如何在集群中构建容器镜像。

更糟糕的是,我们有超过 5000 个服务,其构建流程都紧密绑定 Makisu,包括大量定制化构建步骤。因此,从 Makisu 迁移是一项艰巨的任务。

构建流水线演进

我们没有完全放弃 Makisu,而是选择通过引入一个支持构建 Arm 架构镜像的新容器镜像构建器,来演进我们的构建流水线。

具体方案是:

  • 先用这个新的构建器创建出兼容 Arm 的 Makisu 版本,随后就能用这个 Arm 版 Makisu 为所有其他服务构建 Arm 版本。

但正如后文所示,在 Arm 上启动 Makisu 的过程引发了一系列连锁反应,最终需要引导构建更多组件。

我们选择了 Google Bazel™ 作为新的容器镜像构建工具,以应对挑战。

这一决策主要基于两大优势:

  • Bazel 能通过 OCI 容器镜像规则实现跨架构构建(即在非宿主架构上构建容器镜像)
  • 我们的 Monorepo 已在使用 Bazel

这一选择也使我们能够复用现有的工程经验与工具链,既保留了现有 Makisu 投入,又通过 Bazel 的跨平台能力打通了 Arm 构建的路径。

打破循环依赖

Bazel 加入构建流程后,我们可以构建出 Arm 版 Makisu。但 Makisu 运行在 Buildkite CI 系统上,而 Buildkite 又依赖我们名为 Odin 的 Stateful 平台。

Odin 又依赖一系列核心主机代理程序(日志、指标、网络等),而这些代理都由 Makisu 构建。这导致一个"循环依赖":我们必须将这些组件由 Makisu 构建迁移至 Bazel 构建,从主机代理 → 有状态平台的组件 → Buildkite → Makisu。

我们使用 Bazel 的多架构功能,系统地处理每一层,逐步改造我们的基础设施。

图2:引导构建栈的组件

分布式构建流程

一旦 Makisu 和整个 Buildkite 栈在基于 Arm 的主机上运行起来,我们迈出了下一个重要步骤:通过为容器镜像设置分布式构建流水线来推进构建设置。

这个新的流水线将构建过程多路复用到 Arm 和 x86 主机上,在每个架构上本地运行 Makisu。

镜像构建完成后,流水线会触发最后一步,使用多架构容器 manifest 将 x86 和 Arm 镜像合并为一个统一的多架构容器镜像。

图 3:分布式容器镜像构建流程

该架构优势显著:

  • 无需整体迁移至 Bazel,节省人力成本
  • 原生支持无法交叉编译的工作负载
  • 避免交叉编译的性能开销,缩短构建时间,帮助我们满足构建延迟的 SLA 要求

但缺点也存在:构建成本翻倍------因为需要为两种架构分别构建容器镜像。

截至本文撰写时,我们每周要进行超过 40 万次容器镜像构建,这种额外成本很快变得非常可观。但即便如此,从单位经济效益来看,向 Arm 架构过渡仍然物有所值。

此外,多架构构建支持渐进式迁移策略,因为同一个镜像标签可以同时部署在 Arm 和 x86 主机上。

首批服务上线

有了多架构镜像构建能力后,下一步是部署支持 Arm 的无状态和有状态平台。

在 Uber,我们在逐步引入生产环境变更时非常谨慎,逐步扩大变更范围,因此构建了基于架构的调度约束和回滚机制。

例如,如果部署的镜像仅有 x86 版本,系统将自动放弃 Arm 调度约束并回滚到 x86 主机。这确保了稳定性。

最终,我们成功在 Arm 主机上部署并运行首批服务,证明了 Arm 与 x86 可共存于 Uber 的生产环境中。

02/结论

对 Uber 来说,这项浩大的工程不仅仅是为了节省成本 ,更是为了实现能效优化可持续发展基础设施灵活性

Arm 处理器在性能功耗比方面设立了新的行业基准,意味着更低的能耗和更高的数据中心部署密度。

基础设施引导构建的初步成功只是更大征程的开始。欢迎关注⌈ CloudPilot AI⌋,获取更多基础设施建设的案例。

推荐阅读

全球化团队如何高效协作?航旅平台 Skyscanner 技术负责人的 3 年实践

云成本直降60%!Karpenter+Spot实例在QA环境的实战优化

多邻国打卡打到 AWS 发烧?小绿鸟年省 20% 实录

相关推荐
金刚猿6 小时前
openfeign 拦截器实现微服务上下文打通
微服务·云原生·架构
Naylor7 小时前
微服务概述
微服务·架构·springcloud
尽兴-8 小时前
Lambda架构与Kappa架构对比详解
hadoop·架构·kafka·lambda·kappa
boring_1118 小时前
从Aurora 架构看数据库计算存储分离架构
数据库·架构
互联网搬砖老肖13 小时前
Web 架构之会话保持深度解析
前端·架构
互联网搬砖老肖20 小时前
Web 架构之攻击应急方案
前端·架构
zizisuo20 小时前
9.3.云原生架构模式
云原生·架构
风虎云龙科研服务器1 天前
英伟达Blackwell架构重构未来:AI算力革命背后的技术逻辑与产业变革
人工智能·重构·架构
邪恶的贝利亚1 天前
《Docker 入门与进阶:架构剖析、隔离原理及安装实操》
docker·容器·架构