可重现的环境对于确保你的开发、测试和运营团队的有效协作至关重要。即使在今天,开发人员浪费他们的时间试图重现一个错误,却发现它实际上与配置错误的环境有关,这种情况太常见了。
没有可重复的环境:
- 对一个用户有效的代码在另一个用户身上却无法运行,即使实际代码是相同的。
- 你的项目变得非常脆弱,因为你永远不知道什么时候升级或安装一个新包会破坏构建。一种 "不要碰它!"的文化盛行。
- 开发人员花在管理和解决环境问题上的时间比花在编码上的时间多。
如果你经历过这些症状中的任何一个,你并不孤单。复杂性产生的原因是:
- 项目通常是由一个开发团队开发的,而不仅仅是一个单一的编码者。
- 你的程序最终需要在多个环境中运行--从开发到测试到CI/CD到暂存和生产--其中一些环境将需要不同的配置。
- 依赖关系会随着时间的推移而改变,当试图重现旧版本程序上报告的错误时,环境会变得无法构建。
确保环境可重现性的最简单方法是使用完全相同的依赖关系,并将其钉在完全相同的版本号上,你知道这将是有效的。然而,在实践中,合规性要求、安全准则以及支持多个部署环境的需要引入了复杂性。
这篇文章旨在帮助你了解典型的可重现性策略的利弊,并向你介绍可以帮助你简化创建和使用可重现环境的方式的工具,尽管要求复杂。
什么是可重复性环境?
简单地说,可重现环境是指运行你的程序所需的组件已经被定义,其他人可以无误地复制它。组件可以包括:
- 操作系统 - 环境可以包括不同的库,这取决于程序要运行的Windows、macOS或Linux操作系统。
- 系统库 - 一些程序可能需要在本地系统上安装额外的软件。
- 开源环境 - 运行环境,由你的程序运行所需的包和库组成。
- 虚拟环境 - 只要有可能,你要确保运行环境被部署在一个虚拟环境中,以防止与目标系统上的现有部署发生冲突。
- 项目库 - 你的程序的专有代码。
- 用户/系统 --需要部署你的项目的目标用户/系统。
这些组件中的每一个都必须被考虑到,以确保在项目的各个层面上解决可复制性。毕竟,除非你自己在做一个充满激情的项目,否则可重现性是必须的,以确保你能:
- 安全地升级软件包。
- 使用一个共同的真理源与其他开发者合作。
- 允许关键成员(开发经理、InfoSec、合规人员等)验证和控制项目中的软件包。
环境可重复性的策略
根据你的组织的需要,你可以使用一些策略来确保可重复环境的实施。下面的策略从简单到复杂不等。
- 共享基线 --包括建立一套可以在多个项目中使用的共同的开放源码包。实施一个工件库可能对这个策略已经足够了。
- Snapshot & Restore - 涉及为你的环境创建一个类似git的提交(包括所有的开源包和依赖),这样你就可以在任何时间点恢复到以前的任何提交。
- 可验证的 - 允许其他成员批准或审核运行环境中的第三方软件包和依赖关系。例如,你的组织可能要求定期进行安全/漏洞审计,或者要求对开源包的许可证进行审计,以确保符合企业准则。
这些策略都不具有排他性。相反,你可以从一个更简单的版本开始,然后根据需要增加额外的功能。但每个策略也可以支持一系列的战术,包括:
- 锁定配置文件 - 以 Python 为例,requirements.txt 或 pipfile.lock 配置文件将允许你把你的依赖品固定在一个特定的版本上,这为环境的可复制性提供了一个良好的起点。
- 确保你也钉住横向依赖关系(即依赖关系的依赖关系)和操作系统级别的依赖关系,这些关系有随时间变化的习惯。
- 非生产环境与 生产环境 - 通常,非生产环境与生产环境不同。例如,测试或CI/CD环境可能包含测试框架和调试器,这在生产环境中是不必要的。因此,你需要一种策略来分离非生产环境和生产环境的依赖关系,同时确保一致性。
- 容器 --类似Docker的容器可以提供一种可重复的方式来创建一个一致的环境。也就是说,你仍然需要确保你构建容器的运行环境是最新的,并为Prod与Non-Prod环境进行适当的配置。
ActiveState平台如何简化可重现的环境
ActiveState平台是一个基于云的服务,让你为你的Python、Perl、Ruby和Tcl运行时环境创建一个单一的真理源。支持上面列出的所有策略,以及针对不同部署环境的依赖性钉住和可继承分支的策略。看看它是如何工作的。
虽然ActiveState平台主要关注开源运行环境,但你也可以把你的项目的GitHub仓库也链接起来。通过这种方式,用户可以用一个命令同时部署你的代码和所需的运行时环境。 看看它是如何工作的。
这样,你就可以用一个命令来部署适合你的每个开发、测试、CI/CD和生产环境的集中式真理源,确保可重复性。