构造和命名构件存储库的最佳实践

执行概要

“计算机科学中有两个难题:
缓存失效、命名和off-by-1错误。”

莱昂·班布里克,计算机程序员

为您的组织设计正确的存储库命名约定是至关重要的。为任何产品开发创建正确的存储库结构,对于促进一致的产品扩展策略起着至关重要的作用。它不仅减少了随机创建多个存储库的开销,而且帮助团队识别使用存储库管理器的目的。

使用作为您的存储库管理器,结合了强大的通用二进制存储库的功能,在一个地方托管所有不同类型的二进制文件,并具有完全集成到软件开发生命周期的企业级功能。

软件开发涉及开放式的、不断发展的过程。对于参与产品开发的各个团队来说,极其精确地维护存储库结构成为该流程的必要任务之一。挑战在于,对于命名约定或创建存储库结构,没有硬编码的指导原则可以遵循。

JFrog推荐四部分命名结构,包括:

  1. 一个项目产品或团队名称作为项目的主标识符
  2. 技术所使用的工具或包装类型。
  3. 这个包成熟级别,如开发、分期和发布阶段。
  4. 定位器,您的工件的物理拓扑。

请注意:利用JFrog项目有一个额外的好处-项目键将自动添加到命名结构。

该结构生成以下JFrog推荐的存储库命名结构

应该在整个组织中使用:<团队/ projectKey > - <技术> - <成熟度> - <定位器>

附加指南适用于四种不同的Artifactory存储库类型,包括:本地、远程、虚拟和分发。本地存储库命名约定由两个用例组成。第一个是存储的工件是您自己的,第二个是当它们是第三方的时候。远程存储库是Artifactory拓扑的一部分,它们的命名约定应该与为本地存储库定义的命名约定一致,或者它们是中央存储库,使它们成为外部存储库,并赋予它们稍微不同的命名约定。虚拟存储库是拓扑不可知论者,所以他们缺乏定位器。最后但同样重要的是,分布存储库支持多种技术类型,一般以“-dist”结尾。

在为你的存储库设置命名约定时,需要考虑的三个主要类别是:安全性能而且可操作性

在Artifactory中组织存储库时,在存储库级别管理安全权限是最佳实践。这个安全因素将决定您应该管理的不同存储库,这取决于您组织中工作的不同团队。

性能问题因技术的不同而不同,为了确保最高的存储库效率,应该实现清理策略。此外,根据业务价值(取决于您的组织使用Artifactory的方式)和团队的结构,应该在存储库结构上应用可操作性考虑因素。尽管管理员首选的存储库较少,但有时创建具有不同读/写/删除权限的单独存储库更好,以防止团队相互干扰工作。

本白皮书所涵盖的所有这些注意事项将使您能够跨全球拓扑扩展您的Artifactory,并为大规模企业JFrog Artifactory安装提供所需的DevOps支持。

介绍

使用存储库管理器

JFrog Artifactory是一家通用二进制存储库管理器这是为了加快开发周期。这意味着它不仅仅是存储库,但也是一个非常有能力的经理,帮助组织多个存储库,以简化分布式软件开发过程。

在为存储库定义指导方针和约定时,灵活性优于严格的规则。创建弹性指南为Artifactory管理员提供了足够的空间来根据需要定制规则。

命名约定和存储库结构是齐头并进的。选择一个合适的名称并决定是需要单个存储库还是多个存储库总是一件困难的事情。重要的是,您选择的组织结构必须与您的开发、测试、部署和分发流程在组织中的工作方式相适应。这里表示的命名约定和组织结构主要基于一些相当常见的流程,但可能并不适用于所有组织。但是,希望您可以使用这里列出的组织和命名方面的注意事项,使其适应您自己的命名约定。

Artifactory存储库浏览器

创建命名约定

组织经常要处理多个项目技术生命周期,hth华体会最新官方网站,在多个存储库中产生。当你有一个以上的东西时,你需要给它命名。作为开发人员,在过去的几十年里,我们已经了解到一个名称既可以澄清您正在做的事情,也可以混淆它。

本白皮书讨论了存储库命名约定和管理。
有关工件命名约定的其他信息,请参见仓库布局

在我们深入讨论细节之前,让我们回顾一下三个首要问题:

第一个是定义生成的存储库名称使用url.例如,由于Artifactory是区分大小写的,所以使用小写字母是个好主意。更重要的是,避免在您的环境中使用需要URL编码的字符,例如' _ '字符。这将简化Artifactory实例的终端用户的url,从而简化他们的工作,同时也简化了必须管理反向代理和负载平衡器的管理员的工作。

所有程序员都应该熟悉的第二个问题:自文档代码!尽可能确保您的存储库名称是自文档化的。尽管有一个描述字段,但当存储库名称清楚时,事情就简单多了。第三个问题是基于Artifactory UI.识别存储库的最相关的信息应该放在第一位。通过这样做,在应用过滤器选项之后,字母排序将在Artifactory树浏览器中根据名称组件的重要性将相似的存储库放在彼此旁边。

呆伯特漫画,斯科特·亚当斯

第四个问题是基于某些限制,无论您如何设计约定,这些限制都是隐含的。例如,有一些特殊字符(' / ',' \\ ',':',' | ',' ?’, ‘*’, ‘”‘, ‘’’, ‘<‘, ‘>’, ‘+’, 空间)是完全禁止的。名称最多可以是64个字符,远程存储库最多可以是58个字符。还有一些保留的和不推荐的名称,如“回购”和“垃圾”。附加单词“-cache”也被认为是保留的,因为它主要用于为远程存储库自动创建缓存。

命名结构基础

JFrog推荐四部分命名结构,最好按以下顺序。

JFrog四部分命名结构

1.团队或产品

projectKey或团队名称是项目的主标识符.您可以选择根据您的公司命名惯例来定制缩写。在JFrog项目中,会自动使用项目密钥,而不是使用整个产品名称。另一方面,存储库可以在项目外部创建,并在以后分配给它,因此项目密钥不是强制性的,有些人更喜欢使用团队或产品名称。主要思想是选择一个与您的团队相关且易于理解的名称

例如:老虎

为命名约定的项目/团队/产品名称部分选择粒度级别是开发命名约定中最困难的部分之一。这将在本白皮书后面的存储库组织一节中进一步讨论。然而,由于虚拟存储库的存在,如果需要,这也是稍后可以相当容易地更改的内容,因此不要过于担心,而是选择一些易于理解和一致的内容,并查看它是否适合您。

2.技术

技术在很大程度上是指工具或包的类型.Artifactory是一个通用的二进制存储库管理器,其核心功能使其能够存储各种类型的包,这些包涵盖了Maven、NuGet和Docker等技术。每个存储库应该保存一种类型的二进制文件。

以我们的例子为基础:tiger-docker

高级用户
通常,只要存储库类型通过其api和索引响应单个工具(在某些情况下是一系列工具),任何存储库类型都可以具有任何所需的二进制文件。因此,当您选择存储库类型时,您反映了您计划使用什么工具来检索工件。这影响了Artifactory将计算的指标类型。如果您不使用get/put rest API命令以外的任何工具,那么您可能需要考虑通用存储库,并完全避免索引计算的开销。

在命名约定中包含工具或包名称的类型可以帮助开发人员识别工件,从而更容易地基于它们的类型来浏览它们。在大多数情况下,这将准确地反映在存储库创建时所选择的包类型,但您可以选择更具体的类型。例如,如果您的通用存储库存储视频,则可以选择单词“video”作为技术类型。其他的例子还有:用“centos”代替“rpm”或“rhel”,用“ubuntu”代替“deb”。

3.成熟

成熟度指的是包成熟度级别,例如开发、分期和发布阶段。在Artifactory中可以通过许多不同的方式进行工件推广。从较小事件的简单属性标记(例如“通过测试X”),到工件已经通过的较大质量门。为了讨论的目的,我们感兴趣的是促销活动,将工件从一个存储库移动或复制到另一个存储库。

那么我们为什么要这样做呢?这通常是在工件更改其控件状态.在传统的开发模型中,这可能代表在其生命周期的不同阶段拥有软件的实际团队。你可能会有一个"沙盒,当开发人员在他们的办公桌前测试工件时,以及“dev或"快照对于在最初的提交即构建中发生在CI系统之外的构建。然后,工件将移动到“质量保证”、“preprod或"暂存“存储库,最后到一个”释放或"刺激”库。当一个工件退役时,或者当它触发某些保留的管理需求时,工件及其可能的所有依赖项可以移动到“存档”。

那么在DevOps?根据DevOps原则,工件不应该传递给新的团队,而是应该在整个生命周期中由同一个团队拥有。从自动化的角度来看,控制状态不是关于公司内部的团队,而是基于不同的团队环境它们具有不同的权限模型,以确保工件不会过早部署。

继续发扬我们的榜样:tiger-docker-release

虽然这份白皮书的大部分内容都集中在命名约定上,但它实际上是关于工件的组织。在这方面没有比工件成熟度的概念更重要的考虑了。下图说明了一个典型的推广概念。如果质量要求得到满足,工件就会从一个DevOps阶段发展到另一个阶段:

工件的成熟度

4.定位器

定位器本质上是指物理拓扑结构你的神器.拓扑中的每个存储库必须是唯一的。局部存储库它们是真正的本地,这意味着它们的内容是在本地管理/上传的,应该以”——“.作为在其他地方管理的内容的复制活动目标的本地和远程存储库应该以其他服务的指示符结束。

例如,“波士顿”可以用于管理的工件一个数据中心波士顿.为了一致性,访问外部位置的远程存储库应该以“-remote”结尾。这通常会被忽略,特别是对于主要的中央存储库,因为假设用户熟悉“jcenter”和“npmjs”作为名称的中央存储库,但是这样的假设可能会导致混淆。

使用以下存储库名称完成我们的示例:tiger-docker-release-boston

存储库类型

Artifactory拥有四个存储库类型当地的远程而且虚拟.本地和远程存储库是真正的物理存储库,而虚拟存储库实际上是它们的聚合,用于创建搜索和解析工件的受控域。

JFrog Distribution使您能够在整个SDLC中加速大规模部署和并发下载:从CI到CD,通过设备管理-跨越远程站点、混合基础设施、云、边缘、嵌入式设备和物联网车队。了解更多>

本节提供关于如何应用上述命名结构的指南,特别是针对每种存储库类型。

命名约定的任何部分在不相关时都可以是可选的,四部分命名约定的一般概念可以适用于初始约定中没有涉及的其他情况。

1.局部存储库

使用上一节中描述的四部分命名结构,我们可以解决本地存储库命名约定的所有必要考虑事项,包括:项目/组织(业务单元或产品),技术成熟,定位器.如前所述,顺序表示重要性。JFrog的建议是:<团队> - <科技> - <成熟度> - <定位器>,尽管在某些用例中可能应用其他顺序。

本地存储库有两个基本用例:第一个用例当您引用与您自己的组织工件相关的工件时。在这种情况下,定位器是完全基于拓扑考虑的,也是相当不言自明的。另一方面,团队而且成熟稍微复杂一点,基本上取决于所需存储库的数量。团队依赖于业务逻辑和权限。成熟度取决于门和工件的所有权/处置。如果Artifactory实例关注的是部署,而不是生成,那么考虑成熟度实际上比技术更重要是有好处的。但是,遵循统一的命名约定是优先的。

局部存储库
本地存储库是物理的、本地管理的存储库,您可以在其中部署构件。通常,它们用于部署内部和外部发布以及开发构建,但它们也可以用于存储公共存储库(如第三方商业组件)中不广泛可用的二进制文件。使用本地存储库,您的所有内部资源都可以通过一个公共URL从整个组织的单个访问点获得。2022世界杯阿根廷预选赛赛程了解更多>

本地存储库的一个关键次要用例是用于存储第三方工件。这通常涵盖了一种场景,无论出于何种原因,您都无法远程访问第三方工件的源(由于气隙或只是因为它没有http访问),或者您正在实现白名单方法。在这两种情况下,一般来说,技术保持不变,但是团队的名字应该是指示其源位置的东西;例如,tomcat或centos。因为它们通常仍然有一个拓扑,定位器的工作方式也与其他本地存储库相同。成熟,但是,现在不像发布/开发,而是反映了工件的信任级别。所以它可能是“上传”或“白名单”。例如“tomcat-mvn-upload-local”。如果使用本地存储库对处于某个状态的远程服务器进行快照,则这可能是一个日期。例如,“centos7-rpm-oct2017-local”。

2.远程存储库

远程存储库分为两类:

这些是Artifactory拓扑的一部分,在这种情况下,它们的命名约定应该与本地存储库和四个相关部分的命名约定保持一致,定位器指示被远程控制的源存储库。

远程存储库
远程存储库用作在远程站点(如ConanCenter)管理的存储库的缓存代理。工件根据控制缓存和代理行为的各种配置参数在远程存储库中存储和更新。了解更多>

那些是中央存储库.这些是提取您的工件的外部存储库,可以通过它们的源id引用它们,例如ConanCenter.对于严格的一致性,您可以考虑以下模型,< central_name > - <技术>远程,其中默认的Artifactory命名行为使用源代码。通常,这有助于轻松地识别工件。

中央存储库
ConanCenter是C/ c++的中央存储库吗柯南包。

3.虚拟存储库

有两种类型的虚拟存储库名称。

大多数虚拟存储库不包含<定位器>,是由<团队> - <科技> <成熟度>.在许多情况下,用户不需要了解拓扑实现细节。一般来说,最佳实践是所有的消费和写入都通过虚拟存储库完成,而不是通过本地/远程存储库。这样可以省略尽可能多的实现细节,让用户使用单一的知名URL。此外,对于本地存储库,成熟度严格地取决于工件阶段,而对于虚拟存储库,您可以更多地考虑受众。例如,名称中包含“-dev”的虚拟存储库表示开发人员应该使用的虚拟存储库。最后,一个常见的用例是整个公司使用一个虚拟存储库,该虚拟存储库聚集了特定技术的所有存储库,比如Docker,用于解析和读取权限。虽然严格遵守命名约定要求团队名称为“all”或类似的名称(例如all-mvn-release),但更常见的做法是简单地省略团队名称,并使用诸如docker-stage之类的存储库名称。

另一种主要类型的虚拟存储库名称是为了一致性而使用别名,例如,为了符合外部工具或遗留自动化的需求。虚拟存储库允许您为单个或多个存储库创建别名。这可能是一个符合要求的名称,但如果您需要适应遗留构建过程或特定工具以使用特定名称,则它也非常有用。例如,对于自制啤酒,有一个名为“瓶子”的虚拟存储库是很有用的。一般来说,这些名称不符合标准实践,尽管在可能的情况下尽量避免完全违反虚拟存储库似乎符合但实际上并不符合的规则。例如,将虚拟存储库称为“ci-files-local”,因为自动化需求需要这个存储库名称;如果可以避免,显然不建议这样做。

虚拟存储库
虚拟存储库封装了任意数量的本地和远程存储库,并将它们表示为从单个URL访问的统一存储库。它为您提供了一种管理开发人员访问哪些存储库的方法,因为您可以自由地混合、匹配和修改虚拟存储库中包含的实际存储库。您还可以通过定义底层存储库顺序来优化工件解析,这样Artifactory将首先查看本地存储库,然后查看远程存储库缓存,只有这样Artifactory才会通过网络并直接从远程资源请求工件。对于开发人员来说,这很简单。只需请求包,Artifactory将根据您的组织策略安全且优化地访问它。了解更多>

虚拟存储库

存储库组织和管理

现在我们已经建立了基本的存储库命名结构,让我们回顾一下在JFrog Artifactory中组织存储库时需要考虑的不同事项。本质上,存储库组织可以归结为三件事:安全性能而且可操作性.大多数情况下,这些考虑因素将决定你设置的粒度。”团队,以及在较小程度上计算的粒度成熟的水平。

1.安全

Artifactory权限目标允许在单个文件夹甚至文件级别上通过包含/排除模式管理权限。通常,这里的最佳实践是在存储库级别管理权限。对于具有高度结构化组织的存储库,如Maven和RPM,可以在文件夹级别上实现很大的粒度。然而,这对于管理员来说仍然太复杂,无法跟踪(尽管有效的权限分析可以有所帮助)。对于READ权限来说尤其如此,尽管对于它工作的那些技术来说,更细的粒度可能用于写权限。

至少,当您的团队不协作或共享数据时,您应该在相同的技术和成熟度级别中拥有单独的存储库,因此对彼此的软件没有/不需要读取权限。您还可以根据写权限选择提供不同的存储库,并假设它们聚合在虚拟存储库中以供读。这种基于写的存储库的选择在没有被命名空间很好地划分的存储库类型中尤其重要,比如默认的NuGet行为或没有作用域的npm存储库。

2.性能

另一个主要问题是性能.这因技术的不同而有所不同,但对于任何给定的技术,往往存在存储库中有意义的包的最大数量。在Maven中,这往往是数十万个,并且更多地由UI考虑驱动。而在Yum/Debian中,这往往是数以万计的,更多的是由计算索引的整体方法和结果索引文件的大小以及它们对客户端性能的影响所驱动。

另一方面是清理政策。一个完全没有清理策略的人工服务器的存储使用量会增长得非常快,而且通常大多数都不是您真正需要存储的东西。实现清理策略的机制是另一种讨论。有些可以在这里找到。根据组织的业务需求,不同的项目可能有不同的策略。主要的驱动因素是成熟度,如上所述。例如,一个dev-sandbox码头工人注册表可能会有一个策略,声明任何在过去两周内没有下载的Docker标签都应该被删除。另一方面,受监管的行业可能有监管要求,任何已在受监管的生产环境中的物体必须保留十年。在生命周期的这些阶段到不同存储库之间建立可靠的升级模型是至关重要的。但是这些策略对于正在开发的所有应用程序可能也不相同。虽然在生产中处理股票交易的应用程序将受到监管,但同一家公司用于管理午餐点什么的工具可能在其“生产”生命周期完成后不久就会被丢弃,但在实际使用时确实需要维护。

3.可操作性

当涉及到为特定环境中的特定团队管理工件存储库时,将应用其他基本的可操作性考虑因素。通常,这些策略希望在存储库级别处理,因此这将是选择存储库结构的一个驱动决定因素。

第一个相当简单:确定业务价值。如果您正在管理一个跨越公司内多个大型项目和业务单元的Artifactory,除了上述考虑因素外,您还希望能够确定这些不同的项目/单元是如何使用Artifactory服务的。这可能是为了明确的退款,或者仅仅是为了跟踪哪些单位导致了什么样的成本。一旦您想要跟踪公司中某个给定组织单元与其他组织的使用情况,它就应该有自己的存储库,并在命名约定中进行分解,以便于识别。

此外,一旦超出了业务能够成功协调命名约定和目录结构组织的范围,您至少必须拥有单独的存储库。也就是说,如果一个团队太大,不能成功地管理工件的组id /命名约定,而没有可怕的官僚流程,那么最好只是给他们单独的存储库,并且这种限制总是存在的规模。一般来说,写权限,甚至是删除权限,应该合理地明确,以防止团队相互干扰工作。删除权限通常只应该提供给一个非常小的组,而不是基于策略的reaper(请参阅上面性能部分中关于清理策略的讨论)。

考虑到所有这些因素,管理员通常更喜欢更少的存储库。即使您的存储库管理过程自动化程度越高,它的重要性也越小。例如,在强大的DevOps环境中,你可能会遇到这样的情况:每一次测试都被视为一次晋升。虽然使用促进API对于每个测试,为几十个测试中的每一个都建立一个存储库可能没有意义,而是通过跟踪它属性,并为主要管制站预留独立的资料库

建议约定

下表总结了每种存储库类型的最佳实践命名约定和示例。

1.局部存储库

< projectKey /团队> - <科技> - <成熟度> - <定位器>

例子:

  • rtfact-docker-dev-local(其中rtfact是Artifactory的项目键)
  • tigerteam-docker-release-local
名称部分 建议
< projectKey /团队> 这是命名约定中最难的部分。这取决于您想要管理权限/性能/可操作性问题的粒度。

它也可以是一个产品名称,或者引用第三方库的源代码。

在JFrog项目中,它是项目存储库的唯一标识符。项目密钥作为前缀自动添加到项目中创建的资源。2022世界杯阿根廷预选赛赛程

<技术> 内容类型。这是典型的包类型,如:mvn, rpm, docker。

它也可以更具体,如centos或ubuntu。

<成熟度> 过程中的成熟度级别,无论是SDLC过程还是第三方工件的白名单/批准过程。

  • 例如,一个系列,如:
    • Scratch(用于开发人员从他们的系统中共享,例如docker)
    • 开发(用于CI构建)
    • QA(升级版本)
    • Preprod(升级版本)
    • Prod(升级版本以供使用)
    • 存档(为管理目的保留的构建)
  • 对于第三方库,它可能是这样的值:
    • 上传
    • 白名单
    • 2018年1月(通常用于对远程存储库进行快照)
<定位器> 基于物理位置/人工服务ID。对于实际写入的存储库,默认值是' local ',但在多推送复制的情况下,它可能是推送事件源的站点。

一般来说,除非通过复制,否则不应该写入没有“local”指示符的存储库。

2.远程存储库

例子:

  • tiger-mvn-release-boston
  • rtfact-remote
存储库用例 建议
Artifactory拓扑的一部分 对于远程控制另一个工件服务器,根据所远程控制的存储库,使用与本地存储库相同的命名约定。

  • 在本例中应该是远程构件的标识符。
中央存储库 < centralname >远程

" -remote "是可选的,但有助于避免与虚拟存储库命名约定混淆。

  • 也就是jcenter-remote或者jcenter

3.虚拟存储库

< projectKey /团队> - <科技> <成熟度>

例子:

  • rtfact-docker-dev
  • tiger-docker-prod
名称部分 建议
< projectKey /团队> 共享读权限的组。

如果使用虚拟写来控制写,那么可以在写权限级别上进行控制。

<技术> 包类型。
<成熟度> 这部分可以省略。然而,它通常用作写控制特性的一部分和/或专门用于生产。

与本地存储库中的不同,它更有可能从部署模型角度而不是CI角度进行控制。

结论

组织存储库和选择命名约定是JFrog Artifactory管理员需要做的第一个也是最重要的决定之一。虽然良好地使用虚拟存储库可以允许以后进行更改,但最好事先选择一个命名约定。

本白皮书为存储库组织和命名约定提供了各种注意事项,可以帮助您回答以下问题:“我需要多少个存储库?”它提供了一个四部分的公约,< projectKey /团队> - <科技> - <成熟度> - <定位器>,可作为命名和组织结构的基本最佳实践指南。使用这个建议的约定,大多数组织问题变得相当清晰。

尽管团队粒度可能有点挑战,但这种粒度通常是根据安全性能而且可操作性的担忧。虽然您可能需要随着时间的推移调整粒度,但是一个好的命名约定结合使用虚拟存储库可以使这个过程对您的团队来说相对轻松。此外,您可以使用虚拟存储库别名来避免在前进过程中破坏构建。

本白皮书中描述的约定将允许您跨全局拓扑扩展您的Artifactory。它将提供DevOps支持大型企业安装,为许多不同团队和项目的数千名开发人员提供服务。

要么快速释放,要么死亡