是如何建立 亿用户的美版 Kubernetes 3 小红书 Pinterest 平台的

是如何建立 亿用户的美版 Kubernetes 3 小红书 Pinterest 平台的

为什么选择 Kubernetes?

在过去的几年里,有 3 亿多 Pinner 在 Pinterest 上保存了超过 2000 亿次 Pin,覆盖了超过 40 亿个 Board。为了服务于这个庞大的用户群和内容池,我们开发了数以千计的服务,从少数几个 CPU 的微服务到占用整个虚拟机群的巨大整体服务。还有来自各种不同框架的批处理作业,它们可以是 CPU、内存或 I/O 密集型。

为了支持这些不同的工作负载,Pinterest 的基础架构团队面临着多种挑战:

容器编排系统提供了统一工作负载管理的方法。它们还为更快的开发速度和更容易的基础架构治理铺平了道路,因为所有运行的资源都由集中式系统管理。

图 1:基础架构优先级(服务可靠性、开发人员生产力和基础架构效率)

Pinterest 的云管理平台团队早在 2017 年就开始了在 Kubernetes 的旅程。到 2017 年上半年,我们将大部分生产工作负载进行了容器化(包括核心 API 和 Web 服务器集群)。然后,通过构建产品集群并在其上运行实际工作负载,来对不同的容器编排系统进行广泛的评估。到 2017 年底,我们决定沿着 Kubernetes 的道路走下去,因为它具有灵活性,而且还有广泛的社区支持。

到目前为止,我们已经基于 Kops 构建了自己的集群引导工具,并将现有的基础架构组件集成到 Kubernetes 集群中,如网络、安全性、指标、日志记录、身份管理和流量等。我们还引入了 Pinterest 特定的自定义资源来模拟我们的独特工作负载,同时对开发人员隐藏运行时的复杂性。我们现在工作的重点是集群稳定性、可扩展性和客户支持。

Kubernetes:Pinterest 选择的路

运行 Kubernetes 来支持 Pinterest 这样规模的工作负载,同时又要让它成为我们工程师喜爱的平台,真的是一个很大的挑战。

作为一个大型组织,我们在基础架构工具上投入了大量资金,例如处理证书和密钥分发的安全工具、支持服务注册和发现的流量组件,以及提供日志和指标的可见性组件。这些组件都是基于艰难的经验教训上构建的,因此我们希望将它们整合到 Kubernetes 内,而不是“重新发明轮子”。这一做法也使得迁移变得更加容易,因为我们的内部应用已经获得了所需的支持。

另一方面,Kubernetes 本机工作负载模型(如部署、作业和守护进程集)并不足以为我们自己的工作负载进行建模。可用性问题是采用 Kubernetes 的巨大障碍。例如,我们曾经听到服务开发人员抱怨丢失或错误配置的原因“扰乱”了他们的终端。我们还看到批处理作业用户使用模板工具生成数百个同一作业规范的副本,最终导致了调试噩梦。

对工作负载的运行时支持也在不断发展,因此在同一个 Kubernetes 集群上支持不同版本将会变得异常困难。想象一下,如果我们需要面对许多版本的运行时,客户支持的复杂性,以及为它们进行升级或修补 bug 该有多大的困难。

Pinterest 自定义资源和控制器

为了让我们的工程师更容易地采用 Kubernetes,并使基础架构开发更快速、更顺畅,我们设计了自己的自定义资源(Custom Resource Definitions,CRD)

CRD 提供了以下功能:

下面是 PinterestService 和由控制器转换的本机资源的示例:

图 2:CRD 到本机资源。左边是用户编写的 Pinterest CR,右边是控制器生成的本机资源定义。

如图所示,为了支持用户的容器,我们需要插入一个初始容器和几个边车容器,以保证安全性、可见性和网络流量。此外,我们在批处理作业中引入了应用配置管理模板和 PVC 模板支持,以及许多环境变量来跟踪身份、资源利用率和垃圾收集。

难以想象工程师会愿意在没有 CRD 支持的情况下手工编写这些配置文件,更不用说维护和调试配置了。

应用程序部署工作流

图 3:Pinterest CRD 概述

图 3 展示了如何将 Pinterest 自定义资源部署到 Kubernetes 集群:

注意:这是新的基于 Kubernetes 的计算平台的早期采用者使用的预发布部署工作流。我们正对这一体验进行改进,使其与我们新的 CI/CD 平台完全继承,以避免暴露过多 Kubernetes 具体的细节。我们期待在即将发布的博文《为 Pinterest 构建 CI/CD 平台》中分享我们的动机、进展和后续影响。

自定义资源类型

基于 Pinterest 的具体需求,我们设计了以下适合不同工作流的 CRD:

我们还有正在构建的 PinterestStatefulSet ,将很快被用于存储和其他有状态系统。

运行时支持

当应用程序容器节点在 Kubernetes 上启动时,它会自动获得一个证书标识自己。此证书用于通过 mTLS 访问机密存储或与其他服务进行通信。同时,配置管理初始容器和守护进程将确保在应用程序容器启动之前就下载好所有必需的依赖项。当应用程序容器准备就绪时,流量边车容器和守护进程将会向容器节点注册到 Zookeeper,以便让客户端可以发现它。甚至在容器节点启动之前,网络守护进程就已经为容器节点设置好了网络。

以上就是服务工作负载的典型运行时支持的示例。其他工作负载类型可能需要稍微不同的支持,但他们都是以容器节点级边车容器、节点级守护进程集或虚拟机级守护进程的形式出现的。我们确保所有这些应用程序都是由基础架构团队部署,以便它们在所有应用程序之间保持一致,从而极大减少我们的维护和客户支持的负担。

测试与质量保证

我们在本机Kubernetes 测试基础上构建了一个端到端的测试管道。这些测试部署到所有的集群。这个管道在到达生产集群之前就已经经历了多次回归。

除了测试基础架构之外,还有监视和报警系统,这些系统持续监控系统组件的健康状态、资源利用率和其他关键指标,在需要人工干预时通知我们。

备选方案

我们考虑了一些自定义资源的备选方案,比如变异许可控制器和模板系统。但是,所有的备选方案都存在重大问题,因此我们选择了 CRD 的路径。

未来的工作

目前,我们在所有的 Kubernetes 集群上运行混合工作负载。为了支持不同大小和类型的工作负载,我们正在开展一下方面的工作:

作者介绍:

本文作者为 Lida Li、June Liu、Rodrigo Menezes、Suli Xu、Harry Zhang、Roberto Rodriguez Alcala。他们均为 Pinterest 软件工程师,负责云计算管理平台。

声明:本文来自用户分享和网络收集,仅供学习与参考,测试请备份。