Kubernetes 前世今生 Borg

Google Borg 简介


特性

  • 物理资源利用率高。
  • 服务器共享,在进程级别做隔离。
  • 应用高可用,故障恢复时间短。
  • 调度策略灵活。
  • 应用接入和使用方便,提供了完备的 Job 描述语言,服务发现,实时状态监控和诊断工具。
有事21:

优势

  • 对外隐藏底层资源管理和调度、故障处理等。
  • 实现应用的高可靠和高可用。
  • 足够弹性,支持应用跑在成千上万的机器上。

基本概念


Borg 架构


 Borgmaster 主进程:(用来接收所有用户请求,请求提交给Rest API)

  • 处理客户端 RPC 请求,比如创建 Job,查询 Job 等。
  • 维护系统组件和服务的状态,比如服务器、Task 等。
  • 负责与 Borglet 通信。
Scheduler 进程:(寻找一个最合适的机器,将作业调度过去)

调度策略:

  • worst fit
  • best fit
  • hybrid
调度优化:
  • Score caching: 当服务器或者任务的状态未发生变更或者变更很少时,直接采用缓存数据,避免重复计算。
  • Equivalence classes: 调度同一 Job 下多个相同的 Task 只需计算一次。
  • Relaxed randomization: 引入一些随机性,即每次随机选择一些机器,只要符合需求的服务器数量达到一定值时,就课以停止计算,无需每次对 Cel l中所有服务器进行 feasibility checking。
Borglet:(每个节点上面的代理,有好几个职责,第一个职责是将节点的计算资源和节点健康状态上报给master,调度器就可以从master里面获取集群所有节点的健康状态和资源的计算能力)
  • Borglet 是部署在所有服务器上的 Agent,负责接收 Borgmaster 进程的指令。

应用高可用


被抢占的 non-prod 任务放回 pending queue,等待重新调度。
多副本应用跨故障域部署。所谓故障域有大有小,比如相同机器、相同机架或相同电源插座等,一
挂全挂。
对于类似服务器或操作系统升级的维护操作,避免大量服务器同时进行。
支持幂等性,支持客户端重复操作。
当服务器状态变为不可用时,要控制重新调度任务的速率。因为 Borg 无法区分是节点故障还是出现
了短暂的网络分区,如果是后者,静静地等待网络恢复更利于保障服务可用性。
当某种“任务 @ 服务器”的组合出现故障时,下次重新调度时需避免这种组合再次出现,因为极大
可能会再次出现相同故障。
记录详细的内部信息,便于故障排查和分析。
保障应用高可用的关键性设计原则是:无论何种原因,即使 Borgmaster 或者 Borglet 挂掉、失联,
都不能杀掉正在运行的服务(Task)。

Borg 系统自身高可用


Borgmaster 组件多副本设计。
采用一些简单的和底层(low-level)的工具来部署 Borg 系统实例,避免引入过多的外部依赖。
每个 Cell 的 Borg 均独立部署,避免不同 Borg 系统相互影响。

资源利用率


通过将在线任务(prod)和离线任务(non-prod,batch)混合部署,空闲时,离线任务可以充分利用计算资源,繁忙时,在线任务通过抢占的方式保证优先得到执行,合理地利用资源。
98% 的服务器实现了混部。
90% 的服务器中跑了超过 25 个 Task 和 4500 个线程。
在一个中等规模的 Cell 里,在线任务和离线任务独立部署比混合部署所需的服务器数量多出约 20%-30%。可以简单算一笔账,Google 的服务器数量在千万级别,按 20%算也是百万级别,大概能省下的服务器采购费用就是百亿级别了,这还不包括省下的机房等基础设施和电费等费用。

Borg 调度原理


什么是 Kubernetes(K8s)?


Kubernetes 是谷歌开源的容器集群管理系统,是 Google 多年大规模容器管理技术 Borg的开源版本,主要功能包括:
基于容器的应用部署、维护和滚动升级(一个应用先跑3个实例,在升级的时候一个个滚动着升级,对用户来说这是无感知的,悄悄的就把版本换掉了)
负载均衡和服务发现
跨机器和跨地区的集群调度
自动伸缩(监控业务cpu等metrics,超过你设置的一些阈值的话,会自动做伸缩的)
无状态服务和有状态服务
插件机制保证扩展性

命令式( Imperative)vs 声明式( Declarative)


声明式系统关注“做什么”

在软件工程领域,声明式系统指程序代码描述系统应该做什么而不是怎么做。仅限于描述要达到什么目的,如何达到目的交给系统。

所谓声明式系统是你将请求提交给这个平台,然后这个平台记录下来,在后台不断慢慢的调整系统当前状态和你期望的状态一致。

声明式系统更多的是对你的期望是什么,剩下的交给系统去管理。

命令式系统关注 “如何做”
在软件工程领域,命令式系统是写出解决某个问题,完成某个任务,或者达到某个目标的的明确步 骤。此方法明确写出系统应该执行某指令,并且期待系统返回期望结果。

 命令式就是要你做什么,每一步都得告诉清楚,而且要严格按照所说的做。

Kubernetes:声明式系统


Kubernetes 的所有管理能力构建在对象抽象的基础上,核心对象包括:
Node:计算节点的抽象,用来描述计算节点的资源抽象,健康状态等;
Namespace:资源隔离的基本单位,可以简单理解为文件系统中的目录结构(对于不同的用户可以通过权限控制来决定用户可以访问哪个namespace,这样也是可以说是资源隔离,每个用户访问特定命名空间下的资源)
Pod:用来描述应用实例,包括镜像地址,资源需求等。 Kubernetes 中最核心的对象,也是打通
应用和基础架构的秘密武器;
Service:服务如何将应用发布成服务,本质上是负载均衡和域名服务的声明。

声明式系统,提供一些API,这些API接收的收声明,可以将期望的状态告诉API,接下来将状态存储到数据库里面,相当于可以做一个持久化,这样就知道系统任何长什么样的,可以有个追述。

对于实时系统,可以以阻塞的方式,你敲一条命令,让其给你一个respones,但是对于分布式的系统,如果每个请求都是阻塞的,那么整个平台效率都不会高的。阻塞的话意味着CPU就等在那了,即使有CPU被人也没有办法获得CPU。

声明式系统更多的是将声明告诉你,然后告诉你期望值,然后一直去满足我的需求,只需要返回一个接收到我的声明式请求就行了。对于客户端就是非阻塞的,就可以去做其他事情,这样就有利于提高整个平台的效率。

 之所以定义了这些对象,除了有一个声明式系统,同时跟业界的各个公司一起定规范,形成了一个统一的API,这套API就是云原生以后统一的API。

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/123406306