人工访问模式-如何优化独特的用例

汉克•哈金斯
软件工程师

根据您的用例,可以通过用户、组、令牌和权限来管理Artifactory中的访问。

我想分享一些我们遇到的场景,以及我们如何优化以获得更好的性能,以及我们希望在即将到来的平台更改中迁移到哪里。

视频记录

大家好,欢迎来到我关于Artifactory访问模式以及如何针对独特用例进行优化的预先录制的会话。我叫汉克·哈金斯。我是第一资本的软件工程师。让我们从这里开始。一点点关于我的事。我在Capital One做了五年的开发者。事实上,在这5年里,我已经和Artifactory合作了4年。

我们的团队正在积极支持Artifactory作为二进制存储的企业解决方案,我们正在确保平台和AWS的稳定性,并为我们的内部开发人员社区提供支持,因为他们使用Artifactory。今天的议程,我想做的第一件事是做一个Artifactory安全管理实体的简要概述,以便我们都在同一页上。然后我们要解决两个不同的问题,它们的要求,我们是如何实现它们的以及我们在每个问题上遇到了什么挑战。然后,我们将以设计访问模式时的一些技巧和学习作为结束,并看看Artifactory下一步的发展方向,这实际上是非常令人兴奋的事情。我们从这里开始。对于Artifactory安全管理实体,如果您使用过Artifactory,这些可能看起来非常熟悉。但我只是想过一遍这些,就像我说的,只是确保每个人都在同一页上并且理解我们将在这里讨论的内容。首先,我们有用户。

用户是访问平台的用户的最低级别标识符。因此,所有请求都绑定到一个用户,包括未经过身份验证的请求,这些请求实际上绑定到默认的匿名用户。而用户,或者管理员用户拥有对平台的全局访问权限。

它们取代了所有其他访问。所以如果你把一个用户标记为管理用户,这就是你所需要的,他们将拥有整个平台的全球访问权限。所以,在用户之后,我们有组,它是多个用户的集合。它只是提供了一种更好地组织更大用户集的访问的方法。

它们可以在内部定义,或者实际上可以从外部源(例如Active Directory)导入组。和用户一样,你可以有管理组和所有用户管理组将具有全局访问权限,就像管理用户一样。在组之后,我们可能还有一个更有趣的安全管理实体,权限,这是所有神奇的事情发生的地方。这就是所有非管理员访问规则定义的地方。

如果你定义…使用权限要做的第一件事实际上是定义它应用的资源,这些资源可以是存储库、构建、发布包、这些包的目的地和管道源。2022世界杯阿根廷预选赛赛程然后,一旦您定义了权限应用于哪些资源,您将定义哪些用户和或组可以访问资2022世界杯阿根廷预选赛赛程源,然后您可以修改他们拥有的访问级别,以便他们可以读取、注释、部署、删除、覆盖和管理访问。最后这里,在底部,我们有访问令牌。

访问令牌可用于授予临时访问,由任何定义要为其创建令牌的组。

在本节课中,我们将主要关注用户、组和权限,而不是令牌。但是令牌非常有趣,如果您希望在组织中授予临时访问权限,则绝对值得一看。因此,对于这里的第一个问题,我们想要创建一个自服务Docker名称空间访问管理情况。这意味着什么呢?

我们需要为用户提供在大型中央Docker存储库中管理单个Docker名称空间文件夹的访问的能力。

对于这个的需求,我们实际上会使用一个外部无状态应用程序web应用程序来提供自助服务,用户可以登录到它,管理对他们命名空间的访问,所有这些状态实际上都保存在Artifactory中。因此,它将完全使用rest api与Artifactory交互来查看和编辑这些访问。在这个应用程序中,我们想要的重要一点是,当用户登录时,他们需要能够看到他们可以访问的所有名称空间的列表。因此,我们需要能够填充Docker名称空间文件夹列表。

他们一登录,就拿来给他看。

这是我们在那个应用程序中真正需要的东西,所以在这里调用它是一个非常重要的需求。然后,每个名称空间文件夹都有两级访问权限。因此,我们有名称空间管理员,可以读取、注释、部署和删除访问。

删除实际上是与覆盖相同级别的访问。所以命名空间管理员可以删除Docker镜像,或者只是重新上传和覆盖Docker镜像,因为他们认为合适。然后我们还有命名空间成员,它们非常类似于没有删除访问权限的管理员。所以他们可以阅读,注释和部署。访问本身应该被授予名称空间文件夹和任何东西在Docker存储库中。为了演示的目的,我们有一个名为Docker local的存储库。这里有两个命名空间文件夹,命名空间1,命名空间2。我知道很多很棒的名字。这就是我们要看的顶层文件夹是命名空间,如果他们能访问命名空间他们就能访问该命名空间下的任何东西。如何实现呢?

这是我们的小仓库。显然,我们需要绑定到该名称空间的权限。我们决定使用的命名约定实际上是大写N的前缀,只是为了将我们的命名空间权限与我们在Artifactory中拥有的所有其他权限分开。它只是有前缀的命名空间这就是我们命名权限的方式。然后我们还加入了一组名字完全相同的人。这群人有点特别。

它不授予任何访问权限,我马上会解释为什么我们有它。现在,这只是一个秘密。让我们仔细看看这个许可。

你也许能猜到我们想用什么。但如果你看左边,很明显,我们会用include模式指向Docker本地存储库,不管命名空间是什么,namespace1/双星号让我们可以访问命名空间1下的任何东西任意数量的文件夹,如果我们只有一个星号,它就是命名空间1文件夹下的任何东西所以这里必须有一个双星号。然后个人用户,如果他们是管理用户,我们给他们读取,注释,部署,删除,如果他们是成员,读取,注释,部署。这里我们有两个例子,两个管理员用户,一个成员用户,名字也很有创意。

好了。为什么会有这个基团呢?为什么会在这里?组本身具有与权限相同的用户。我们创建这些组的原因实际上是为了填充名称空间列表。当时,我们无法获得用户的权限列表但我们可以通过get user details API获得用户的组列表。这些组实际上更像是一个标签,表示这个用户可以访问这个名称空间,专门用来填充这个名称空间列表。为这个专门创建一大堆组看起来有点脏但你知道,我们就是这么做的。这就是我们所做的。那么我们在使用这种方法时遇到了哪些挑战呢?显然,挑战一就是我刚才说的,我们缺少这个有效的权限API,它会给我们一个用户权限列表所以我们不需要所有这些组。

我们没有那个API。所以我们必须创建所有这些组,只是为了有一种有效的方法列出用户可以访问的所有名称空间。

挑战二,一些名称空间超过了组的允许名称长度。所以组名有64个字符的限制。我们的一些用户有非常非常长的命名空间。因此,我们最终不得不截断一些组名,以使它们的长名称空间正常工作。最后,我们只强制使用更短的名称空间,因为如果开始截断组名,可能会遇到这样的情况,即有两个非常长的名称空间名称,后缀可能略有不同,如果将它们截断为64个字符,它们可能是相同的组名,然后就会出现问题,所以这就是我们必须开始强制使用的地方,因为我们无法维护它。然后挑战三,我们实际上遇到了一些性能问题。

随着存储库的增长,我们最终在这个Docker存储库上拥有了数千,我想,超过20,000或更多的权限。这暴露了平台本身的一些问题,我们实际上需要修补才能解决这些问题。幸运的是,JFrog很乐意与我们合作,我们解决了这个问题。

但毫无疑问,这个解决方案对我们有效,它只是给我们带来了一些问题。事实上,直到今天我们还在使用它。所以第二个问题,我们需要允许我们的self - service Docker命名空间是公共的还是私有的。这意味着什么呢?因此,我们需要为用户提供创建可公开访问的Docker名称空间的能力。说到公开,我的意思是,所有Artifactory内部的开发人员都不能访问互联网。因此,在Capital One内部,所有开发人员都可以访问一个公共名称空间。因此他们可以从这个公共名称空间中提取图像。私有名称空间是只有那些拥有部署访问权限的用户,只有那些有权提取图像的用户,甚至只有那些在Artifactory中看到该名称空间的用户。那么这门课的要求是什么呢?

就像我刚才说的,公共Docker名称空间需要匿名可读,或者任何经过身份验证的用户都可以读。私有Docker名称空间应该只能由名称空间管理员和名称空间成员可读。然后,最后,你知道,之前问题一的所有要求仍然适用。

我们仍然有那个自助服务管理应用程序在运行。所以所有这些都需要继续发挥作用。所以这个要求更少,但也要记住第一个的所有内容。那么我们该怎么办呢?我们如何实现这个呢?我们已经有了每个命名空间的权限和组。所以我们想,也许我们可以在现有的范围内工作,为什么要增加更多的东西呢?

我们还是坚持现有的吧。这就是我们所做的。对于私有命名空间,权限没有区别,它有相同的Docker本地存储库,有相同的包含模式,用户有管理员和成员两个用户。你知道,只要没有其他权限授予对这个命名空间的访问它实际上是私有的,所有拥有访问权限的只有这两个用户。那么是什么决定了公共许可呢?

它几乎是一样的,只是添加了一个具有读访问权限的匿名用户。还有一个组,我们调用所有具有也读访问权的用户。因此,您可以创建一个组,该组将在创建新用户时自动添加用户。所以你可以有一个包含所有用户的组。

我想,对于我们的用例来说,我们实际上导入了一个活动目录组里面有所有的用户,所以我们最终只使用那个组。但是你可以在Artifactory中创建一个组,它也可以包含所有的用户。不幸的是,我们将其发布到生产阶段,正如你从这张漂亮的图表中看到的,它进行得不太顺利。

我们有用户在Docker轮询中报告了大量的延迟,无论是经过验证的还是未经验证的,所以我们必须迅速从我们所做的事情中恢复过来,回到绘图板并找出如何更好地做到这一点。那么发生了什么,出了什么问题?显然,我们添加的新东西,匿名用户和所有用户组被添加到所有现有的权限中,实际上增加了很多延迟。所以我们想知道为什么会发生这种情况?所以我们和JFrog合作。它们实际上产生了一些非常有趣的信息。这就是我们讨论Artifactory安全映射缓存的原因。

这是什么?为了让Artifactory更快地检查传入请求的访问,它实际上缓存了安全对象的映射。在这个小图形中,箭头表示缓存映射。所以用户映射到存储库,存储库,映射到权限,当这些请求进入时,它会非常快地检查这些缓存映射,但如果你做的事情与缓存映射的流动方式不一致,你实际上会遇到一些高延迟。这正是发生在我们身上的事。这里,我们让用户映射存储库,存储库映射到权限,我们有组映射存储库映射到权限。这意味着什么呢?让我们看一个例子。一个示例请求,因为artifactory正在通过这些映射检查访问。它要做的第一件事是检查用户可以访问的存储库。假设,我匿名地从Docker本地存储库请求一些东西。它首先要检查的是,匿名用户是否有访问Docker本地存储库的权限?如果是,那么它将检查应用于Docker本地存储库中有匿名用户的每个权限。

一个接一个,它会遍历所有这些。所以我想你可以开始看到我们的问题在哪里了。这正是发生在我们身上的事。

对于这个Docker本地存储库,我们有数千个匿名用户的权限。所以缓存映射本身并没有给我们带来多少好处。因为它必须逐个遍历应用到存储库的每个用户的权限,也就是所有的权限。因此,它必须通过20,000个权限来检查非匿名用户是否有权访问Docker本地存储库中的特定对象。所以它基本上要检查每一个的包含模式。

这适用于这个名称空间吗?继续运行下去,所有Docker请求的速度都大大降低了。假设用户,它没有发现用户有访问存储库的权限,或者即使它有访问存储库的权限,也没有授予它所请求的特定事物的访问权限,接下来它会做的是检查该用户所在的所有组。它会遍历该用户拥有的所有组,检查每个组,看看组是否有访问存储库的权限,它会检查应用到该存储库和该组的所有权限。显然,你能做的最快的事情就是让用户直接拥有存储库的权限,这是最快的事情,查找缓存映射,如果是由组授予,也不会慢太多,只是稍微慢一点。如果用户有很多组,这也会导致问题,因为它必须遍历每个组,并检查该组是否可以访问您试图请求的内容。所以你一定要限制基团的数量。而且您肯定希望限制每个存储库拥有的权限。这是我们从Artifactory安全映射缓存中学到的两个非常重要的东西。我们回头看看这里的情况。

发生了什么事?对,这两个,这两个。通过让匿名用户拥有这些权限,就像我之前解释的那样,它必须遍历所有权限,以查看匿名用户是否有权访问您试图请求的特定名称空间。所有用户组都是一样的,即使你通过了身份验证,如果你试图从Docker local请求Docker映像,它也会做完全一样的事情,它会经过用户本身,假设用户本身没有访问那个命名空间的权限。

你只是想从别人的命名空间,一个公共命名空间中取出一张图片,你必须做同样的事情,它必须遍历所有的权限。这两个都是问题。因此,我们必须找出如何以不同的方式来做这件事,以极大地加快解决这些问题的速度。所以我们最终要做的就是把我们的存储库分成两部分。Docker本地,我们决定为所有的公共命名空间服务。然后我们有一个单独的Docker私有本地存储库,其中包含我们的私有名称空间。

命名空间权限本身在这种情况下是非常相似的,唯一的区别是一个额外的权限,我们将调用一个公共读,它在Docker上,local,授予对整个存储库的公共读访问权。这种方法肯定更有效。我们会在这里看到更多细节。就像我说的,公众许可,和我们在第一个问题上看到的完全一样。

它在同一个Docker本地回购,相同的包含模式,用户在那里有相同的访问权限。4因此,与私有权限的唯一区别是存储库。所以不是Docker, local,而是应用到Docker私有本地存储库。

同样的包含模式,同样的用户访问。好了,我强调了区别,以防你没注意到。然后我们有公共读权限,它在Docker本地存储库上,不需要包含模式,它适用于所有东西。这就是我们匿名读取和所有用户读取权限的地方。

这样就快多了如果匿名请求进入,对于公共命名空间,它会检查是否能访问Docker本地?是的。然后它将遍历Docker本地的每个权限

匿名用户。你猜怎么着?现在只剩下一个了。所以,砰,立刻完成。

所有用户组都是一样的情况。从缓存映射的角度看,快多了。然后,如果你请求,比方说,你试图匿名请求一个私有的,来自私有命名空间的东西,首先,它会检查,匿名用户是否有访问这个私有存储库的权限?没有。所以403立刻禁止了。

好了。这样就快多了。你可以肯定地说,Artifactory在设计时就考虑到了拆分你的存储库,在一个存储库上拥有一堆权限肯定是它允许的一种方法,但这似乎不是Artifactory的设计方式,它实际上是在鼓励你拆分你的存储库。让我们来看看我们遇到的挑战。

显然,我们的原始设计会对用户造成影响,这是我们应该预见到的,我们应该更好地测试。

有效的性能测试是非常重要的。你肯定想要确保你要对生产做的事情,你已经彻底确保不会造成任何严重的影响。我觉得我们完全可以做得更好。所以这绝对是我们在这个项目中遇到的最大挑战。另外,我没有提到,我们的回滚过程很慢。

我们把它发布到生产环境中,很明显,我们现在有数千个匿名用户的权限,所有的用户组都在那里。

为了解决这个问题,我们必须迭代地遍历并从数千个权限中删除这些权限。这花了一段时间。所以你知道,很明显,我们想立即为我们的用户提供救济,或者至少尽快。在这种情况下,它需要一段时间才能通过,更新数千个权限不是一个快速的过程。这是我们遇到的另一个问题。实际上,我认为我们还必须写脚本来检查和恢复更改。

我们还没准备好。所以这也很好。接下来是挑战三,我们必须打破单一回购的思维模式。从创建Artifactory之初,我们对每种包类型只有一次回购。

它只是让我们更容易管理,所以我们在一段时间内一直这样做,不幸的是,随着Docker存储库规模的增长,它……它变得难以管理,特别是在我们试图强制执行的这个新的权限模型下。

这在未来是不可行的,所以当我们做出决定时,我们将把它分成几部分,我们将有公共的一面和私人的一面。老实说,在这一点上,我们确实在朝着将我们的存储库分解成更小的部分的方向前进。

现在越来越多了。我们希望能在团队层面上取得更多进展。每个团队一个仓库。尽管它将极大地增加我们拥有的存储库数量,但它绝对是访问管理方面的正确方向,它肯定会加强这一点。所以在设计访问模式时的技巧和学习。

显然,我想指出的第一点是我们从JFrog支持中学到的非常有趣的事情,那就是Artifactory安全映射缓存非常值得记住,如果您能够习惯思考Artifactory解析这些访问实体的方式,那么您可以将其应用到您试图计划的任何情况。所以无论你想要解决的用例是什么,我都要记住这一点,这肯定是我之前给出的两个技巧,你不想让一个用户上有太多的组,你也不想让一个存储库上有太多的权限。

这两件事也一定要记住。

这就是我的想法。第二,尽可能与JFrog解决方案团队合作,你知道,他们可能无法预见可能出现的每一种情况,但他们肯定可以借鉴过去帮助其他客户的经验,有时是非常大的客户。所以他们有大规模解决方案的经验。所以他们有一些,他们肯定有一些知识当涉及到如何最好地实现某些事情时。所以我肯定,肯定会使用JFrog解决方案,特别是如果你要对你的平台做一些大规模的改变。

非常非常重要。然后还要理解所有可能发挥作用的Artifactory约束,例如最大组名、长度。

我们遇到的,在Artifactory中有这样的事情,它们肯定会影响到你,你一开始没有想过它们,但你为这些事情做计划是非常重要的,因为如果你实现了,你知道,你的解决方案的95%然后你意识到我们的5%的客户,我们需要迁移的东西,我们不能,因为我们刚刚遇到了这个我们甚至没有想过的约束,你知道,这是你不想遇到的事情,因为它会推迟你的时间线,它会,你知道,给你的用户带来麻烦,这是非常非常小心的事情。所以一定要记住。

同时,性能测试有效,具有长期预期的数据规模。虽然Docker名称空间现在只有几百个,但未来会有上万个。所以如果你能在这个范围内进行测试,看看你不会遇到任何情况。

这是非常非常有用的。所以这也是值得思考的问题。最后,要有一个回滚计划。

当你发布新东西时,有一个回滚计划总是好的。而且,你知道,即使没有回滚计划,也有一个B计划,如果出现问题,你可以做一些事情来立即缓解问题,也许不是完全回滚,但你知道,一些中间解决方案将有助于缓解问题。拥有它总是好的。这就是我们从这两个问题中得到的一些技巧和经验。那么Artifactory下一步将走向何方?

项目,就是这样。版本717发布了这些新项目,这是一种组织存储库构建、发布包和管道的新方法,更像是一个团队,你知道,一个团队的资源,只是把它们聚集在一起,然后让他们灵活地控制对自己资源的访问。2022世界杯阿根廷预选赛赛程伴随着这些项目,你得到了这些全局和项目角色,它们是实际上非常类似于权限,但它们专门适用于项目。它们也可以应用于资源环境。所以你可以给你的资源贴上标签,我猜,用开发,2022世界杯阿根廷预选赛赛程产品环境,然后你可以让这些角色专门应用到这些不同的环境,这真的很有趣。

这是我们一定要研究的。

我们还没有做太多的项目,但这绝对是我们想要尝试的方向。那么,是什么让项目变得伟大呢?

他们正在将细粒度的访问管理从平台管理员转移到更多的团队来管理自己。因此,虽然有更多的Access Management分布是很好的,但我们可能要小心给予多大的灵活性。

我们有很多需要考虑的安全审计问题,我们还需要确保在那里保持职责隔离。

你知道,你不想让你的用户有能力伤害自己。所以在分配这种控制的时候你必须小心。就像我之前说的,这是根据应用程序团队和环境将单个存储库分解为更小存储库的又一个例子。所以,这绝对是Artifactory试图让我们进入的方向。希望在接下来的几个月里,我们可能会朝着这个方向前进。所以,是的,朝着那个方向走是很好的。在这些项目中,很重要的一点是记住,你需要理解新的基于角色的访问控制是如何被缓存以优化性能的,比如。我们之前看过的缓存,那是在项目出现之前,这些项目中可能会有一些新的缓存结构。

我有一种感觉,它可能有点类似于他们以前的,但可能只是角色而不是权限。

但这是我们可以与JFrog讨论的问题,并确保我们在实现新项目结构时牢记这一点。就是这样。今天就到这里。

非常感谢大家来观看我的讲座。希望你们学到了一些东西。

如果你有任何问题,我一定会在这里和你聊天,我希望你有祝你的swampp休息愉快。再次感谢。

要么快速释放,要么死亡