Skip to main content

Kubernetes 的祖先 Google Borg 论文精读

01 背景分析

大规模的后端服务,面对 SRE 操作复杂度的爆炸上升,平均每个 SRE 要管理超过上万台机器,人工操作已经无法满足,同事重复枯燥的运维工极易出错给公司造成损失,分布式系统中极小的概率事件也会常态化的出现,而复杂的 run-time 环境使得 SRE 与 DEV 都很难观察出系统出了什么问题,进而快速处理。

部署的复杂程度也直接影响到了研发效率,开发迭代的需求不能及时部署到线上进行验证,只能等待多个迭代积累之后上线。

大型的 CS 架构应用,占用大量的服务器资源,成为互联网公司的主要成本来源,机器的成本及维护机器的成本都非常的高,为此需要利用软件技术,来自动化管理机器资源,提高 SRE 的工作效率,降低机器资源的使用成本、故障处理的速度等。这样的系统,在 Google 叫做 Borg.

info

Google Borg 系统是一个集群管理器,运行着数千个应用程序的数以十万计的作业,跨多个由数万台机器组成的集群。

Borg 通过超配、进程级别资源隔离等,实现高效的资源利用率。支持应用高可用,最大限度的减少故障时间,并且可以通过调度策略降低相关故障发生的可能性。Borg 还提供了声明性工作规范语言,名称服务集成,实时作业监控以及分析和模拟系统行为的工具,简化用户操作。

02 设计目标

  • 运维操作 重复度极高,因此可以自动化
    • Deploy
    • Restart
    • Update
    • Migrate
    • Backup
    • Scale
    • ...
  • Borg 必须能够自动地监控机器的资源消耗情况,并快速做出判断,决定哪些 Task 被分配到哪些机器,并执行。
  • Borg 需要随时监控业务系统的状态,并在业务系统偏离状态时触发运维操作使其恢复预期状态,这种自动恢复的能力帮助 SRE 高效地处理线上问题,可以替代 SRE 大量的人工操作。
  • 操作指令应该尽量简洁,这样可以帮助 SRE 高效管理上万台机器。

2.1 技术约束

  • 操作延迟: Borg 的运维任务必须在一个规定的上下界内完成。通常运行时间在 10s 内。
  • 针对不同 Task 的工作负载,可以正确地调度 Task 与机器匹配,以达到最佳的资源利用率。
  • Borg 本身作为一个分布式系统也应该保证高可用特性。
  • 隔离性: 安全隔离、性能隔离

2.2 使用场景

使用 Borg 的通常有两种用户:

  • 业务方开发
    • 提交自己的任务到 Brog 托管任务的执行。
    • 通常 Borg 是为服务应用而打造的,因而 Task 都是一个 Server 进程。
  • SRE
    • 观察运行时的各项指标,保证系统的稳定运行。

而在现代的互联网公司,这两者的身份会彼此模糊,成为现在的 DevOps,运维的任务被分担到所有的研发人员身上,每个研发人员需要对自己的微服务的 Run-time 稳定性复杂,因此所有的 Borg 任务都由最了解自己服务的研发人员来完成。这也得益于,Borg 降低了运维操作的成本,提高了单位人员的效率。

传统的 SRE 工作也从对业务任务的运维,变成了对 Borg 的运维。SRE 无需了解业务系统中的逻辑,专注于维护 Borg 的稳定性即可。

03 User Persoective 用户视角

  • 用户向 Borg 以作业 jobs 的方式提交工作
  • job 由包含着相同程序的一个或多个任务 tasks 组成。
  • job 运行在一个 Borg cell (一组机器集合管理单元) 上

3.1 The workload

Borg cells 包括两种类型的 workload.

    1. 长时间运行的服务,并且对请求延迟敏感 (几微秒到几百毫秒之间)。这类服务一般是直接面向终端用户的产品,如 Gmail、Google Docs 和 Web 搜索以及内部基础设施服务(如 BigTable)
    1. 那些运行几秒或者几天即可完成的批处理作业,这类服务对短期性能波动不敏感。

3.2 Clusters and cells

一个 cell 的机器都归属于单个集群,通过高性能的数据中心级别的光纤网络连接。一个集群部署在一个独立的数据中心建筑中,多个数据中心建筑构成一个 site 。一个集群通常包括一个大规模的 cell 和许多小规模的测试或者特殊目的的 cells。尽量避免单点故障。

3.3 Jobs and tasks

一个典型的 Borg job 的属性包括

  • Name, Id, Metadata: 原数据
  • Owner: 负责此作业的用户或组织单元。
  • the number of tasks: Job 中的任务数量
  • Constraints: 作业的约束,如处理器架构、操作系统版本。
  • Dependencies: 作业之间的依赖关系,指定启动顺序。
  • Resources: 作业需要的资源,如 CPU、内存、磁盘空间、网络带宽等
  • Scheduling Policy: 任务调度的策略、优先级
  • Runtime range: 运行时长的上下界
  • Networking: 网络资源和端口号
  • Commands: 任务执行的命令行指令

3.4 Priority, quota, and adminssion control

优先级和配额用于防止运行的比实际能容纳多的这种负载情况。每个 job 都有一个 priority 优先级,一个小的正整数。高优先级的 task 可以在牺牲较低优先级的 task 来获取资源,甚至是以抢占方式。

Borg 为不同用途定义不同的优先级:

  • Monitoring 监控
  • Production 生产
  • Batch processing 批处理
  • Best effort 最低优先级

针对 Production 级别的 jobs 是禁止 task 互相抢占的。优先级决定 jobs 在 cell 中处于 Running还是 Pending 状态。 Quota 配额被用于确定调度哪些 jobs。配额表示为一段时间内(通常为几个月)给定优先级的资源量(CPU、RAM、磁盘等)。这些值指定了用户的 job 在请求时间段内可以使用的最大资源量。配额检查是准入控制的一部分,配额不足情况下,job 会被拒绝调度。

高优先级的配额成本比低优先级要高。生产级别的配额仅限于 cell 中实际可用资源,因此用户提交满足生产级别 job 运行预期的资源配额。虽然不建议用户配置超买,但是很多用户都会比实际的需要配额要大,以防止后续用户增长可能造成的资源短缺。对于超买,应对方案就是超卖。

配额分配的使用在 Borg 之外进行处理,和物理容量设计密切相关,结果反映在不同数据中心的配额价格和可用性上。Borg 通过 capability 系统,给予某些用户特殊权限,如允许管理员删除或者修改任意 cell 中的 job,或者运行用户访问受限的内核功能或者 Borg 操作,如禁用其 jobs 预算。

3.5 Naming

只是提供创建和运行是不够的,服务客户端和相关系统需要能够访问到对应的服务,即使被重新调度到新的机器上。因此,Borg 针对每个 task 创建一个稳定的 "Borg name service" (BNS),包括 cell 名,job 名和 task 数量。

Borg 用这个 Naming 将 task 的主机名和端口写入到 Chubby 一致且高可用的文件中,该文件用于 RPC 系统查找 task 端。

  • BNS 名也用于 task DNS 名构成基础。
  • 如用户 ubar 在 cell cc 上执行的 job jfoo 第 50 个 task,可以通过 50.jfoo.ubar.cc.borg.google.com 访问。
  • Borg 还会在发生变化的时候把 job 大小和 task 健康信息写入到 Chubby,以使得负载均衡器可以获取到请求路由指向。
info

Chubby 是 Google 的一个分布式锁服务,用于提供一致性和高可用性。在 Borg 中,Chubby 用来存储任务的主机名和端口信息,方便 RPC 系统定位任务。此外,Chubby 也用于维护任务的健康和状态信息,帮助负载均衡器正确路由请求。

3.6 Monitoring 监控

几乎所有运行在 Borg 上的 task 都包含一个内建的 HTTP server,用于发布 task 的健康信息和数千个性能指标, 如 RPC 延迟。Borg 监控这些 HTTP 端点,并在出现问题时可以重启任务。其它的数据会被监控工具追踪展示在 Dashboards 上并且在服务级别 (SLO) 问题时告警。

  • UI Web: 允许用户通过 Web 界面 Sigma 查看作业状态和资源使用情况,以及进行故障排查。
  • 日志管理: 应用程序生成的日志通过日志轮转机制管理,这样做是为了防止占用过多磁盘空间。即使任务结束,日志也会被保留一段时间,以便进行故障排查。
  • 任务状态注释: 如果任务没有运行,Borg 会提供注释来指出任务是"有待处理的"(即待调度或正在等待资源),并建议如何修改作业的资源请求,以便更好地匹配集群的资源供应(cell)。
  • 数据记录与分析: Borg 记录所有作业的提交和任务的事件,包括每个任务的资源使用情况,并将这些信息存储在一个可扩展的只读数据库中。Dremel 系统用来对这些数据进行类似 SQL 的查询和分析,帮助进行计费、调试、故障排查以及长期容量规划。
info

Dremel 是 Google 开发的一个快速、可扩展的分布式系统,用于分析大量数据。它允许用户使用类似于 SQL 的查询语言来快速执行分析任务,支持与存储在其文件系统中的大型数据集进行交互。Dremel 能够处理 petabyte 级别的数据,并且其架构使得它能够迅速返回查询结果。它是 Google 内部 BigQuery 服务的技术基础。

04 Borg Architecture 架构

  • Borg cell 部署单元,由一组主机组成。
  • Borgmaster 的逻辑主控制器。经典的主从架构,Borg 作为一个分布式任务系统,必须有一个任务的调度中心与任务的执行器这两个角色。
  • Borglet 的任务执行器进程组成,Borglet 运行在 cell 中的每个主机上。