Kubernetes 的祖先 Google Borg 论文精读
01 背景分析
大规模的后端服务,面对 SRE 操作复杂度的爆炸上升,平均每个 SRE 要管理超过上万台机器,人工操作已经无法满足,同事重复枯燥的运维工极易出错给公司造成损失,分布式系统中极小的概率事件也会常态化的出现,而复杂的 run-time 环境使得 SRE 与 DEV 都很难观察出系统出了什么问题,进而快速处理。
部署的复杂程度也直接影响到了研发效率,开发迭代的需求不能及时部署到线上进行验证,只能等待多个迭代积累之后上线。
大型的 CS 架构应用,占用大量的服务器资源,成为互联网公司的主要成本来源,机器的成本及维护机器的成本都非常的高,为此需要利用软件技术,来自动化管理机器资源,提高 SRE 的工作效率,降低机器资源的使用成本、故障处理的速度等。这样的系统,在 Google 叫做 Borg.
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
运行在一个 Borgcell
(一组机器集合管理单元) 上
3.1 The workload
Borg cells 包括两种类型的 workload.
-
- 长时间运行的服务,并且对请求延迟敏感 (几微秒到几百毫秒之间)。这类服务一般是直接面向终端用户的产品,如 Gmail、Google Docs 和 Web 搜索以及内部基础设施服务(如 BigTable)
-
- 那些运行几秒或者几天即可完成的批处理作业,这类服务对短期性能波动不敏感。
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,以使得负载均衡器可以获取到请求路由指向。
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 的查询和分析,帮助进行计费、调试、故障排查以及长期容量规划。
Dremel 是 Google 开发的一个快速、可扩展的分布式系统,用于分析大量数据。它允许用户使用类似于 SQL 的查询语言来快速执行分析任务,支持与存储在其文件系统中的大型数据集进行交互。Dremel 能够处理 petabyte 级别的数据,并且其架构使得它能够迅速返回查询结果。它是 Google 内部 BigQuery 服务的技术基础。
04 Borg Architecture 架构
Borg cell
部署单元,由一组主机组成。Borgmaster
的逻辑主控制器。经典的主从架构,Borg 作为一个分布式任务系统,必须有一个任务的调度中心与任务的执行器这两个角色。Borglet
的任务执行器进程组成,Borglet
运行在 cell 中的每个主机 上。