工件存储库和持续交付管道

版本控制是部署前置时间、部署频率和MTTR的两个最重要的预测因素之一。为什么它对DevOps组织如此重要?

在去年九月的JavaOne期间,我参加了一个关于构件库,作为持续讨论(#c9d9)的一部分,这是一系列关于敏捷、持续交付和DevOps的社区小组讨论。持续讨论是由Electric Cloud发起的一个社区倡议持续交付在SpaceX、思科(Cisco)、通用电气(GE)和E*TRADE等企业,通过自动化构建、测试和部署流程。

在这里观看小组的录音:

或者只是读一下我对小组的一些见解:

工件存储库的好处

我对我们得到的答案很着迷,因为这正是我们从每个人那里听到的,我们试图成为用户反馈理想的公司,这与我们试图宣扬的完美一致。我所听到的是两件事,一是持续集成和部署的工具软件的管道穿过从开发人员到生产和自动化,Rest API,能够从任何方向连接,CI服务器从一边和另一边的部署工具,所有的合规和扫描和所有这些部分,这是一种纯粹的管,另一个是信息,我对工件的了解,关于我的工件的元数据,关于第三方工件的元数据,这又回到了什么是版本?一个版本就够了吗?版本是否表达了工件的状态?当我查看工件时,我能知道它通过了哪个QA级别吗?它在我的持续交付管道中的什么位置?所有这些都是元数据。

我想说,工件存储库和将一些文件扔到某个地方并从那里获取之间最大的区别是这两点。文件系统是愚蠢的,我们不太了解那里的文件文件系统对自动化不是很友好,当你使用二进制工件存储库时,它是一种文件系统存储,但有了上面的两层,你可以有关于工件的信息,你可以添加它,你可以查询它,你可以围绕它自动化部署工具,应该能够查询工件,给我最新构建的所有工件,但前提是它们通过了某些质量关口并与目标平台匹配,并且以自动方式完成,这样我就不需要在交付过程中进行任何人工干预。这两个与我想说的本质是一个好的工件存储库,它带来的不同的特点,例如它必须是通用的,因为它需要支持所有的在一个地方从自动化的角度来看也为信息的角度来看,因为您需要跟踪所有这些不同的部分从所有这些不同的技术到一条信息,你有一个Jar文件,当它穿过那些俄罗斯娃娃包内部的战争,在Debian包中打包,在Docker镜像中打包,然后是Vagrant盒子的一部分。当您拥有一个完整的Vagrant框时,您需要能够指出Java代码中的哪一行搞砸了一切。当你可以通过所有这些俄罗斯娃娃链获得元数据流时,这也是可能的,为此你需要一个工具,所以通用是一件大事,它是自动化和信息这两者的结果。

企业仓库的挑战:依赖管理和可追溯性

包管理是一个非常困难的领域,它看起来不是这样,感觉上也不是这样,从服务器抓取几个文件并将它们放在文件系统上的某个已知位置有多难,但几十年来人们一直没有把它做好。我把它称为“依赖管理,欢迎来到地狱”,我们讨论了我们在JFrog中学习的所有不同的打包类型,当我们在Artifactory和Bintray中添加对它们的支持时,以及它们是如何糟糕的,其中一些以相同的方式,其他的以各种奇怪和不同的方式,但它们都很糟糕。

这样做的问题是这些问题会影响到用户,比如“npm unpublish”门发生了,每个人都受苦,这只是糟糕的设计NPM注册表但它影响到每个人。嵌入到工件存储库中的依赖管理旨在保护开发人员免受这些问题的困扰。回到NPM的大门,一旦NPM缓存发生了所有的用户都没有注意到,所有的技术都是这样。Artifactory是在Maven Central完全混乱的时候作为NPM注册中心开始的,这就是我们开始做的,现在我们非常清楚,我们需要为我们所做的所有新技术继续这样做。

Docker hub每隔几天就会出现一次巨大的慢速,而使用Artifactory的人甚至都不知道这一点。依赖管理是中央存储库的一部分,因为它是抽象的,简化了用户的依赖管理,使他们更有效率,对我来说,这是最重要的部分。

昨天我做了一个比较Maven, Bazel和Gradle的演讲。Bazel不支持传递依赖,Gradle在早期也不支持。在maven中,没有简单的方法来禁用它,如果你有传递依赖之类的东西,你可以用maven Enforcer插件来失败构建,但它是内置的,你没有这种灵活性来禁用它。我们与认为传递依赖是好还是不好的听众进行了非常有趣的讨论。我认为这里的黄金路径是拥有传递依赖关系是一种非常严格的依赖管理,当你可以确定版本而不需要处理依赖关系本身时,如果你碰巧有这个包,确保它是这个版本,但我并不关心你是否需要这个包,但如果你需要,就用它。

企业仓库面临的挑战:分布式团队/应用/基础设施

当我们讨论二进制文件时,局部性意义重大,我们讨论过比特对二进制文件大小的容忍度,我们提到过这是一定程度上的。对于开发团队来说,将他们的工件存储库带到团队中是非常重要的,因为存在延迟,并且缓慢的工件存储库与任何其他存储库一样令人讨厌,您需要做一些需要花费很长时间才能下载的事情,并且生产力当然会下降。现在,在一个高效的工作环境中,您在附近有一个工件存储库,这是一种标准,真正的问题是您如何在所有这些存储库之间进行同步,欧洲的团队在生产了工件并进入睡眠状态后,美国的团队将如何尽快获得这些工件。对于工件存储库来说,重要的是要在本地安装,但要能够在任何可能的拓扑结构中同步,并通过防火墙等所有网络障碍。

这是我们可以讨论的另一种局部性,我提到的局部性是对开发团队的局部性,但对CI管道的局部性是另一种。如果您的持续集成服务器在云端,那么将工件存储库放在持续集成服务器所在的位置非常重要,如果您使用Amazon,那么您需要将工件存储库放在Amazon中,如果您将它们放在Google cloud上,则需要将它们放在Google cloud上。这是一组完全不同的问题,我们通过在每个云和每个区域上提供Artifactory作为服务成功地解决了这些问题,所以如果您在该区域没有在亚马逊上安装CI服务器,我们将确保您的Artifactory服务器在那里。那是一个新位置它应该与我们之前讲过的开发者位置同步。上面一层是管理所有这些东西,现在你需要有一个一致的配置在25服务器,10是一个大陆,在云中10在其他大陆,5,现在你添加一个新的码头工人生产库,你怎么能确保所有的配置都是相同的,和多长时间登录到他们实际上做的每一个变化。当您在世界各地推出工件存储库的企业设置时,您需要记住这一点。

好消息,最新版本的Artifactory可以清理未使用的层会自动生成,更重要的是可以使用基于校验和的存储,如果有很多Docker映像依赖于同一个基本映像,那么这个基本映像的所有公共层都将存储在新的基础映像上。我们可以尝试在我们编写的包管理中修复的东西,有一些问题我们无法处理,这是在依赖管理器的手中,无论他们搞砸了什么,我们都无法修复,但是当涉及到存储和提供这些二进制文件时,我们会尽我们所能来改进它。Docker是一家出色的技术公司和杰出的技术人员的一个很好的例子,当涉及到所有这些Linux内核隔离进程和所有这些东西时,他们绝对是杰出和天才的,但我们认为他们最强大的部分不是依赖管理和工件管理。

企业仓库面临的挑战:安全性和治理

我们有两种安全顾虑,第一种是访问控制第二个是内容控制。在访问控制中,我们需要从不同的角度来分离权限,首先,它可以是谁应该看到一些东西,但是当我们在谈论内部环境时,这真的不是一个问题,因为通常人们被允许看到并使用来自不同存储库和不同组的包或工件。这个控制,我们使用它来确保任何需要的东西到达正确的地方,例如,我们不会在生产环境中以未经测试的工件结束,不是因为我们是吝啬的人,想要限制它,使它在“只需要的基础上”,但是当我们设置了这些栅栏,当我们建造了这堵墙,我们可以保证任何需要从一个地方到另一个地方的东西都不会混淆,不会在其他地方发现自己,当然,如果我们有面向公众的服务,那么验证人员也是一件大事。

另一方面是内容的信任,我们如何知道我们的包和工件中的内容实际上是安全的?在这里,我的感觉很复杂,因为我知道有些公司建立自己的商业战略是基于这种威胁,开源是危险的,软件包中有巨大的威胁,有时他们很幸运,他们得到了心脏出血之类的东西,但通常我觉得这是一个威胁人们购买他们产品的行业。另一方面,挖掘人工制品并从中寻找内容本身就是一个有趣的话题,不仅对于安全性而言,安全性肯定是其中的一部分,如果我们能发现一个漏洞那就太好了,我不建议在此基础上构建策略,但能够进行影响分析并了解重要的内容,它也具有安全性方面的内容。

了解工件中发生了什么,不仅是为了安全性,也是为了许可证遵从性和性能,我想知道我的体系结构中是否有一些很慢的组件,它比知道我有一些漏洞更重要还是更重要?这可能也是一件大事。它主要是为了质量,然后才是真正的安全,但它有助于建立两者。