本文超过一年。旧文章可能包含过时的内容。请检查页面中的信息自发布以来是否已失效。
Borg:Kubernetes 的前身
十多年来,Google 一直在生产环境中运行容器化工作负载。无论是像 Web 前端和有状态服务器这样的服务作业,像 Bigtable 和 Spanner 这样的基础设施系统,还是像 MapReduce 和 Millwheel 这样的批处理框架,几乎 Google 的所有程序都以容器的形式运行。今天,我们揭开了 Borg 的神秘面纱,这是 Google 传闻已久的内部面向容器的集群管理系统,并在学术计算机系统会议 Eurosys 上发布了详细信息。 你可以在这里找到这篇论文这里。
Kubernetes 直接源自 Borg。许多在 Google 从事 Kubernetes 开发的开发人员以前都是 Borg 项目的开发人员。我们在 Kubernetes 中融入了 Borg 的最佳理念,并试图解决用户多年来在使用 Borg 时发现的一些痛点。
为了让您了解一下,这里有四个来自我们 Borg 经验的 Kubernetes 功能
- Pod。 Pod 是 Kubernetes 中的调度单元。它是一个资源包络,其中运行着一个或多个容器。属于同一个 Pod 的容器保证会被一起调度到同一台机器上,并且可以通过本地卷共享状态。
Borg 有一个类似的抽象概念,称为 alloc(“资源分配”的缩写)。Borg 中 alloc 的常见用途包括:运行一个生成日志的 Web 服务器以及一个将日志发送到集群文件系统(类似于 fluentd 或 logstash)的轻量级日志收集进程;运行一个 Web 服务器,该服务器提供从磁盘目录读取的数据,该目录由一个从集群文件系统读取数据并为 Web 服务器准备/暂存数据的进程填充(类似于内容管理系统);以及与存储分片一起运行用户定义的处理函数。Pod 不仅支持这些用例,还提供了一个类似于在单个 VM 中运行多个进程的环境——Kubernetes 用户可以在 Pod 中部署多个位于同一位置的协作进程,而无需放弃每个容器部署一个应用程序的简单模型。
服务。 虽然 Borg 的主要作用是管理任务和机器的生命周期,但在 Borg 上运行的应用程序受益于许多其他集群服务,包括命名和负载均衡。Kubernetes 使用服务抽象支持命名和负载均衡:服务具有名称并映射到由标签选择器定义的动态 Pod 集(请参阅下一节)。集群中的任何容器都可以使用服务名称连接到服务。在幕后,Kubernetes 会自动将连接到服务的连接负载均衡到与标签选择器匹配的 Pod 之间,并跟踪 Pod 在因故障而重新调度时运行的位置。
标签。 Borg 中的容器通常是集合中一个副本,该集合由对应于 Internet 服务的一个层级(例如 Google 地图的前端)或批处理作业的工作程序(例如 MapReduce)的相同或几乎相同的容器组成。该集合称为作业,每个副本称为任务。虽然作业是一个非常有用的抽象概念,但它可能会受到限制。例如,用户通常希望将他们的整个服务(由许多作业组成)作为一个单体进行管理,或者统一管理他们服务的几个相关实例,例如单独的金丝雀和稳定发布跟踪。另一方面,用户经常希望推理和控制作业中任务的子集——最常见的例子是在滚动更新期间,当作业的不同子集需要具有不同的配置时。
Kubernetes 通过使用标签组织 Pod 来支持比 Borg 更灵活的集合,标签是用户附加到 Pod(实际上是系统中任何对象)的任意键/值对。用户可以通过在他们的 Pod 上使用“job:<jobname>”标签来创建等效于 Borg 作业的分组,但他们也可以使用其他标签来标记服务名称、服务实例(生产、暂存、测试),以及通常情况下,他们的 Pod 的任何子集。标签查询(称为“标签选择器”)用于选择应对其应用操作的 Pod 集。总的来说,标签和 副本控制器 允许非常灵活的更新语义,以及跨越 Borg 作业等效项的操作。
- 每个 Pod 一个 IP。 在 Borg 中,机器上的所有任务都使用该主机的 IP 地址,因此共享主机的端口空间。虽然这意味着 Borg 可以使用普通的网络,但它给基础设施和应用程序开发人员带来了许多负担:Borg 必须将端口作为资源进行调度;任务必须预先声明它们需要多少端口,并以启动参数的形式获取要使用的端口;Borglet(节点代理)必须强制执行端口隔离;命名和 RPC 系统必须处理端口以及 IP 地址。
由于软件定义覆盖网络(例如 flannel 或内置于 公共云 中的网络)的出现,Kubernetes 能够为每个 Pod 和服务提供其自己的 IP 地址。这消除了管理端口的基础设施复杂性,并允许开发人员选择他们想要的任何端口,而无需要求他们的软件适应基础设施选择的端口。后一点对于轻松在 Kubernetes 上运行现成的开源应用程序至关重要——Pod 可以像 VM 或物理主机一样对待,可以访问完整的端口空间,而无需考虑它们可能与其他 Pod 共享同一台物理机。
随着基于容器的微服务架构越来越受欢迎,Google 从内部运行此类系统中学到的经验越来越受到外部 DevOps 社区的关注。通过揭示我们的集群管理器 Borg 的一些内部工作原理,并将我们的下一代集群管理器构建为开源项目(Kubernetes)和公开可用的托管服务(Google 容器引擎),我们希望这些经验能够使 Google 之外的更广泛的社区受益,并推进容器调度和集群管理领域的最新技术。