几年前,Pinterest 因策略交付引擎的疏忽而发生了短暂事故。该引擎是一种技术,可确保由开发人员编写并签入源代码控制的策略文档完全交付给评估该策略的生产系统,类似于OPAL。这一事件开启了我们团队的多年旅程,重新思考策略交付并将数百项策略迁移到新的分发模型。我们在 Kubecon 2019 的一次会议演讲中分享了有关我们以前的策略交付系统的详细信息。
从高层次来看,我们想就这个故事引起大家对三个重要的架构决策的关注。
图 1:旧的策略分发架构,使用 S3 和 Zookeeper。
Pinterest 围绕 OPA 提供了包装服务,以管理策略分发、代理配置指标、日志记录和简化的 API。新版本发布后,就会通过 Zookeeper 自动获取策略。策略存在于通过 CI 工作流发布的共享 Phabricator 存储库中。那么问题出在哪里呢?本质上,由于策略存储库的错误提交,每个策略的错误版本(当时有 50 多个)同时发布。这些错误版本发布到 S3,新版本在 Zookeeper 中注册并直接投入生产。这导致我们的许多内部服务同时失败。幸运的是,快速重新运行我们的 CI 发布了已知的良好版本,这些版本(再次)直接投入生产。
这一事件导致多个团队开始重新考虑全局配置(如 OPA 策略)。具体来说,Pinterest 的安全团队和流量团队开始合作开发一种新的配置交付系统,该系统将提供一种机制来定义配置的部署管道。
这篇博文重点介绍了安全团队如何将数百条策略和数十个客户从 Zookeeper 模型转移到更安全、更可靠、更可配置的配置部署方法。
技术这里的核心配置交付故事不是安全团队要讲述的——Pinterest 的流量团队与我们密切合作以了解我们的要求,并且该团队最终负责构建核心技术以实现我们的集成。
总体来说,新的配置管理系统的工作方式如下:
配置所有者在共享存储库中创建他们的配置。服务所有者将配置分组到该存储库中 DSL 中的“工件”中。工件通过管道进行配置,同样位于该存储库的 DSL 中。这定义了哪些系统接收工件以及何时接收。每个管道定义一组步骤和每个步骤的一组交付范围。这些范围在每个想要检索配置的系统上本地生成。例如,可以定义一个管道,首先交付到金丝雀系统,然后交付到生产系统(此处简化):
DSL 还允许配置如何推进管道步骤 — 自动(工作时间内)、自动(24x7)和手动。它还允许配置在继续下一步之前不得超过的度量阈值。
实际分发技术与原始架构并无不同。现在,每个工件(策略组和其他配置)都有专用管道来定义交付范围和交付触发器,而不是在全局 CI 作业中发布策略。这确保每个策略的推出都与该系统隔离,并且可以采用服务所有者认为合适的任何部署策略和安全检查。下图显示了一个高级架构。
图 2:新的策略分发架构,使用配置服务器/边车和专用 UI。
迁移第一阶段:工具和库存在我们开始将策略从全局即时部署模型迁移到有针对性的分阶段部署模型之前,需要收集大量信息。具体来说,对于旧配置存储库中的每个策略文件,我们需要识别:
与该政策相关的服务和 Github 团队使用该策略的系统使用该策略的系统的首选部署顺序幸运的是,大部分信息都可以从 Pinterest 的少数数据源轻松获得。在迁移的第一阶段,我们开发了一个脚本来收集有关每项政策的所有元数据。这包括:读取每个政策文件以从强制性标签注释中提取相关服务名称,从我们的内部库存 API 获取与服务相关的 Github 团队,获取所有具有该政策流量的系统的指标,并根据一些常见的命名约定将这些系统分组为粗略分类。生成这些数据后,我们将其导出到 Google 表格中,以便通过一些手动调整对其进行注释。也就是说,由于所有权数据陈旧,一些系统被错误地归属于所有者,许多系统没有遵循标准、可预测的命名约定。
我们开发的下一个工具是一个脚本,它需要一些输入:要迁移的策略的路径、团队名称和部署步骤。这会自动将策略从旧存储库移动到新存储库,生成包含该策略的工件,并为服务所有者的相关系统定义部署管道。
有了所有这些工具,我们就可以开始根据一些简单的示例测试迁移工具了。
第二阶段:切换逻辑在采用新的策略交付模型之前,团队会在Telefig管理的配置文件中定义他们的策略订阅。我们进行此次迁移的目标之一是确保无缝切换,几乎不需要或根本不需要客户更改。由于新的配置管理提供了范围的概念并在配置存储库中定义了策略订阅,因此我们可以完全依赖新存储库来定义需要策略的位置。我们需要更新我们的 sidecar(OPA 包装器),以便在启动时根据系统属性在本地生成订阅范围。我们选择根据系统的 SPIFFE ID 生成这些范围,这使我们能够将部署与主机的服务和环境紧密结合。
我们还认识到,由于配置系统可以提供任意配置,我们也可以提供一个配置来告诉我们的 OPA 包装器切换其行为。我们将此切换逻辑实现为 OPA 包装器中配置的热重载。创建新配置文件时,OPA 包装器会检测新配置并更改以下属性:
策略在磁盘上的存储位置(重新加载 OPA 运行时引擎)策略如何在磁盘上更新(ZooKeeper 订阅由客户管理的配置文件定义,还是什么都不做,让配置 sidecar 来管理它)指标标签,用于检测切换进度图3:政策切换逻辑流程图。
这种方法的一个好处是,可以在新系统中完全恢复策略分发机制。如果某项服务无法与新部署系统很好地配合使用,我们可以使用新部署系统更新新配置文件,以告知 OPA 包装器使用旧行为。模式之间的切换可以无缝完成,不会造成停机,也不会对使用策略的客户造成影响。
由于策略设置和切换配置都可以在单个存储库中进行,因此每个策略或服务都可以通过单个拉取请求进行迁移,而无需客户输入。新存储库中的所有文件都可以使用我们之前构建的工具生成。这为一系列长期迁移奠定了基础,这些迁移仅对正在迁移的策略产生局部影响。
第三阶段:大量的 Pull 请求此时,我们已为认真开始迁移奠定了基础。在一两个月的时间里,我们开始自动生成针对单个团队或策略的拉取请求。主要是安全和流量团队成员生成并审查了这些 PR,以确保部署的范围正确、与正确的团队相关联并成功推出。
如前所述,我们有数百项政策需要迁移,因此这是一个稳定但漫长的过程,需要分批迁移政策。随着我们对工具的信心逐渐增强,我们将单个 PR 中迁移的政策数量从 1-2 个增加到 10-20 个。
阶段 4:边缘情况与任何计划一样,在我们将策略部署到更加多样化的系统时,出现了一些无法预见的问题。我们发现,一些较旧的有状态系统运行的是较旧的机器映像 (AMI),不支持订阅声明。这给系统带来了直接的阻碍,因为这些系统无法轻易重新启动。
幸运的是,我们的持续部署团队正在积极修改Telefig服务接收更新的方式。我们与 CD 团队密切合作,确保动态升级 Pinterest 的所有系统以使用最新版本的 Telefig。这让我们的工作畅通无阻,让我们能够继续迁移剩余的用例。
第五阶段:平稳着陆解决了旧 Telefig 版本问题后,我们迅速与负责大部分剩余策略的少数团队合作,将所有内容转移到新的配置部署模型中。以下是迁移的大致时间表:
图4:迁移到新政策框架的时间表。
一旦上述指标稳定在 100%,我们就开始清理旧工具。这使我们能够删除数百行代码并大大简化 OPA 包装器,因为它不再需要内置策略分发逻辑。
在此过程结束时,我们现在拥有一个更安全的策略部署平台,使我们的团队能够完全控制他们的部署管道,并将每个部署与该部署中未包含的策略完全隔离。
结论迁移很难。新的工作流程总会遇到阻力,与之交互的人越多,迁移的尾端就越长。这次迁移的主要收获如下。
首先关注衡量标准。为了保持正轨,您需要知道谁会受到影响、剩余工作的范围以及您已经取得的重大胜利。拥有良好的衡量标准还有助于证明项目的合理性,并提供大量资源来炫耀沿途里程碑的成就。
其次,迁移通常遵循帕累托原则。具体来说,20% 的待迁移用例通常会占到 80% 的结果。如上图所示,有两个巨大的迁移高峰(一个在 4 月中旬,另一个在几周后)。这两个高峰代表了两个团队的迁移情况,但它们占整体状态的很大一部分。在确定要迁移哪些系统的优先级时,请记住这一点,因为有时花费大量时间迁移一个团队或系统可能会带来不成比例的回报。
最后,预测问题,但要做好适应的准备。在流程早期花时间思考你的极端情况,但在路线图上留出额外的时间来考虑你无法预测的问题。一点缓冲会让你的心情平静下来,如果你碰巧提前交付了结果,那真是值得庆祝的胜利!
致谢如果没有一大群人在过去几年里齐心协力构建最好的系统,这项工作是不可能实现的。
非常感谢 Traffic 团队的合作伙伴构建了强大的配置部署系统,并将我们作为第一个大规模生产用例。特别感谢 Tian Zhao,他领导了我们的大部分合作,并帮助我们将用例纳入其中。另外还要感谢 Zhewei Hu、James Fish 和 Scott Beardsley。
安全团队在审查架构、迁移计划和拉取请求方面也提供了巨大帮助。特别是 Teagan Todd 在运行许多迁移方面提供了巨大帮助。此外还有 Yuping Li、Kevin Hock 和 Cedric Staub。
当遇到旧系统的问题时,Anh Nguyen 在升级系统底层方面提供了巨大帮助。
最后,感谢拥有大量政策的团队中的合作伙伴,他们通过执行自己的迁移帮助我们推动迁移:Aneesh Nelavelly、Vivian Huang、James Fraser、Gabriel Raphael Garcia Montoya、Liqi Yi (He Him)、Qi LI、Mauricio Rivera 和 Harekam Singh。
作者:Jeremy Krach | Staff Security Engineer, Platform Security
出处:https://medium.com/pinterest-engineering/migrating-policy-delivery-engines-with-almost-nobody-knowing-839f3cf996bc