在 Pinterest 上创建 kubernetes 平台

多年来,Pinterest 的 300 亿用户在超过 200 亿个图板上创建了超过 4 亿个图钉。 为了服务这群用户和庞大的内容库,该门户开发了数千种服务,从可由几个 CPU 处理的微服务,到在整个虚拟机群上运行的巨型整体服务。 然后公司的目光落在了 k8s 上的时刻到来了。 为什么“立方体”在 Pinterest 上看起来不错? 您将从我们最近翻译的一篇文章中了解这一点 博客 Pinterest 工程.

在 Pinterest 上创建 kubernetes 平台

因此,有数亿用户和数千亿个 pin。 为了服务这群用户和庞大的内容库,我们开发了数千种服务,从可以由几个 CPU 处理的微服务,到在整个虚拟机群上运行的巨型整体服务。 此外,我们还有各种可能也需要 CPU、内存或 I/O 访问的框架。

在维护这个工具库时,开发团队面临着许多挑战:

  • 工程师没有统一的方式来运行生产环境。 无状态服务、有状态服务以及正在积极开发的项目基于完全不同的技术栈。 这导致为工程师创建了完整的培训课程,也使我们的基础设施团队的工作变得严重复杂化。
  • 拥有自己的虚拟机群的开发人员给内部管理员带来了巨大的负担。 因此,更新操作系统或 AMI 等简单操作需要数周甚至数月的时间。 这导致在看似绝对日常的情况下工作量增加。
  • 在现有解决方案之上创建全球基础设施管理工具存在困难。 由于找到虚拟机的所有者并不容易,因此情况变得更加复杂。 也就是说,我们不知道是否可以安全地提取此容量以在我们基础设施的其他部分中运行。

容器编排系统是统一工作负载管理的一种方式。 它们为提高开发速度并简化基础设施管理打开了大门,因为项目中涉及的所有资源均由一个集中式系统管理。

在 Pinterest 上创建 kubernetes 平台

图 1:基础设施优先级(可靠性、开发人员生产力和效率)。

Pinterest 的云管理平台团队于 8 年发现了 K2017s。 到 2017 年上半年,我们已经记录了大部分生产能力,包括 API 和所有 Web 服务器。 随后,我们对用于编排容器解决方案、构建集群并使用它们的各种系统进行了彻底的评估。 2017 年底,我们决定使用 Kubernetes。 它非常灵活并且得到了开发者社区的广泛支持。

到目前为止,我们已经基于 Kops 构建了自己的集群启动工具,并将现有的基础设施组件(例如网络、安全、指标、日志记录、身份管理和流量)迁移到 Kubernetes。 我们还为我们的资源实现了一个工作负载建模系统,其复杂性对开发人员来说是隐藏的。 现在我们的重点是确保集群的稳定性、扩展集群并连接新客户端。

Kubernetes:Pinterest 方式

在 Pinterest 规模上开始使用 Kubernetes 作为我们的工程师喜欢的平台会遇到很多挑战。

作为一家大公司,我们在基础设施工具上投入了大量资金。 示例包括处理证书处理和密钥分发的安全工具、流量控制组件、服务发现系统、可见性组件以及日志和指标调度组件。 收集所有这些都是有原因的:我们经历了正常的尝试和错误路径,因此我们希望将所有这些设备集成到 Kubernetes 上的新基础设施中,而不是在新平台上重新发明旧轮子。 这种方法总体上简化了迁移,因为所有应用程序支持都已经存在,不需要从头开始创建。

另一方面,Kubernetes 本身的负载预测模型(例如部署、作业和守护进程集)对于我们的项目来说还不够。 这些可用性问题是迁移到 Kubernetes 的巨大障碍。 例如,我们听到服务开发人员抱怨登录设置丢失或不正确。 我们还遇到了模板引擎的错误使用,当使用相同的规范和任务创建数百个副本时,这导致了噩梦般的调试问题。

在同一个集群中维护不同的版本也非常困难。 想象一下,如果您需要在同一运行时环境的多个版本中同时工作,并处理所有问题、错误和更新,那么客户支持会多么复杂。

Pinterest 用户属性和控制器

为了让我们的工程师更轻松地实施 Kubernetes,并简化和加速我们的基础设施,我们开发了自己的自定义资源定义 (CRD)。

CRD 提供以下功能:

  1. 组合不同的本机 Kubernetes 资源,使它们作为单个工作负载运行。 例如,PinterestService 资源包括部署、登录服务和配置映射。 这让开发者不用担心设置DNS。
  2. 实施必要的应用程序支持。 用户只需要根据自己的业务逻辑关注容器规范,而 CRD 控制器则实现所有必要的 init 容器、环境变量和 pod 规范。 这为开发人员提供了根本不同的舒适度。
  3. CRD 控制器还管理本机资源的生命周期并提高调试可用性。 这包括协调期望和实际规范、更新 CRD 状态和维护事件日志等。 如果没有 CRD,开发人员将被迫管理多个资源,这只会增加出错的可能性。

下面是 PinterestService 和由我们的控制器管理的内部资源的示例:

在 Pinterest 上创建 kubernetes 平台

正如您在上面看到的,为了支持自定义容器,我们需要集成一个 init 容器和几个附加组件来提供安全性、可见性和网络流量。 此外,我们创建了配置映射模板并实现了对批处理作业的 PVC 模板的支持,以及跟踪多个环境变量以跟踪身份、资源消耗和垃圾收集。

很难想象开发人员会在没有 CRD 支持的情况下手动编写这些配置文件,更不用说进一步维护和调试配置了。

应用程序部署工作流程

在 Pinterest 上创建 kubernetes 平台

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

  1. 开发人员通过 CLI 和用户界面与我们的 Kubernetes 集群进行交互。
  2. CLI/UI 工具从 Artifactory 检索工作流配置 YAML 文件和其他构建属性(相同版本 ID),然后将它们提交到作业提交服务。 此步骤可确保仅将生产版本交付到集群。
  3. JSS 是各种平台(包括 Kubernetes)的网关。 这里对用户进行身份验证,发放配额,并部分检查 CRD 的配置。
  4. JSS端检查CRD后,将信息发送到k8s平台API。
  5. 我们的 CRD 控制器监视所有用户资源上的事件。 它将 CR 转换为原生 k8s 资源,添加必要的模块,设置适当的环境变量,并执行其他支持工作,以确保容器化的用户应用程序拥有足够的基础设施支持。
  6. 然后,CRD 控制器将接收到的数据传递给 Kubernetes API,以便调度程序处理并投入生产。

注意:此预发布部署工作流程是为新 k8s 平台的第一批用户创建的。 我们目前正在完善此流程,以与我们的新 CI/CD 完全集成。 这意味着我们无法告诉您与 Kubernetes 相关的所有内容。 我们期待在下一篇博文“为 Pinterest 构建 CI/CD 平台”中分享我们的经验和团队在这个方向上的进展。

特殊资源类型

根据 Pinterest 的具体需求,我们开发了以下 CRD 以适应不同的工作流程:

  • PinterestService 是已经运行很长时间的无状态服务。 我们的许多核心系统都是基于一组此类服务。
  • PinterestJobSet 模拟全周期批处理作业。 Pinterest 上的一个常见场景是多个作业并行运行相同的容器,而不考虑其他类似的进程。
  • PinterestCronJob 广泛与小型周期性负载结合使用。 这是本机 cron 与 Pinterest 支持机制一起工作的包装器,负责安全、流量、日志和指标。
  • PinterestDaemon 包括基础设施守护进程。 随着我们为集群提供更多支持,这个家族不断壮大。
  • PinterestTrainingJob 扩展到 Tensorflow 和 Pytorch 进程,提供与所有其他 CRD 相同级别的运行时支持。 由于 Pinterest 积极使用 Tensorflow 和其他机器学习系统,因此我们有理由围绕它们构建单独的 CRD。

我们还在开发 PinterestStatefulSet,它将很快适用于数据仓库和其他有状态系统。

运行时支持

当应用程序 Pod 在 Kubernetes 上运行时,它会自动接收一个证书来标识自己。 该证书用于访问秘密存储或通过 mTLS 与其他服务进行通信。 同时,容器初始化配置器和守护进程将在运行容器化应用程序之前下载所有必需的依赖项。 当一切准备就绪后,流量边车和守护进程将向我们的 Zookeeper 注册模块的 IP 地址,以便客户端可以发现它。 所有这一切都将起作用,因为网络模块是在应用程序启动之前配置的。

以上是工作负载运行时支持的典型示例。 其他类型的工作负载可能需要稍微不同的支持,但它们都以 Pod 级 sidecar、节点级或虚拟机级守护进程的形式出现。 我们确保所有这些都部署在管理基础设施内,并且在应用程序之间保持一致,这最终显着减轻了技术工作和客户支持方面的负担。

测试和质量保证

我们在现有 Kubernetes 测试基础设施之上构建了端到端测试管道。 这些测试适用于我们所有的集群。 我们的管道在成为产品集群的一部分之前经历了多次修改。

除了测试系统之外,我们还有监控和警报系统,可以持续监控系统组件的状态、资源消耗和其他重要指标,仅在需要人为干预时通知我们。

替代品

我们研究了自定义资源的一些替代方案,例如突变访问控制器和模板系统。 然而,它们都面临着巨大的运营挑战,因此我们选择了 CRD 路线。

使用突变准入控制器来引入 sidecar、环境变量和其他运行时支持。 然而,它面临着各种问题,例如资源绑定和生命周期管理,而这些问题在 CRD 中不会出现。

注: Helm 图表等模板系统也广泛用于运行具有类似配置的应用程序。 然而,我们的工作应用程序过于多样化,无法使用模板进行管理。 而且在持续部署的过程中,使用模板时也会出现太多的错误。

即将开展的工作

我们目前正在处理所有集群之间的混合负载。 为了支持不同类型和规模的此类流程,我们在以下领域开展工作:

  • 集群集合将大型应用程序分布在不同的集群中,以实现可扩展性和稳定性。
  • 确保集群稳定性、可扩展性和可见性,以创建应用程序连接和 SLA。
  • 管理资源和配额,使应用程序不会相互冲突,并且集群的规模由我们控制。
  • 一个新的 CI/CD 平台,用于在 Kubernetes 上支持和部署应用程序。

来源: habr.com

添加评论