werf是我们的开源GitOps CLI实用程序,用于构建应用程序并将其交付给Kubernetes。在v1.1版中,图像收集器具有一项新功能:按内容标记图像,或基于内容的标记。到目前为止,werf中的典型标记方案涉及使用Git标签,Git分支或Git提交来标记Docker映像。但是所有这些方案都有新的标记策略可以完全解决的缺陷。有关她的详细信息以及她为何如此出色的信息-被削减。从一个Git存储库回滚一组微服务
通常情况下,应用程序被分成或多或少的独立服务。这些服务的发布可以独立发生:一次可以发布一个或多个服务,而其余的应继续工作而不做任何更改。但是从代码存储和项目管理的角度来看,将此类应用程序服务保留在单个存储库中更为方便。在某些情况下,服务实际上是独立的并且未与一个应用程序连接。在这种情况下,它们将位于单独的项目中,并且将通过每个项目中单独的CI / CD流程进行发布。但是,实际上,开发人员通常将一个应用程序分解为多个微服务,但是每个应用程序都有一个单独的存储库和项目……显然是过大了。关于这种情况将进一步讨论:多个此类微服务位于单个项目存储库中,并且发布是通过CI / CD中的单个过程进行的。Git标签和Git标签
假设最常见的标记策略是使用-tag-or-branch。对于Git分支,图像用分支名称标记,对于一个分支,一次只有一个发布的图像为此分支命名。对于Git标签,将根据标签名称对图像进行标签。当创建新的Git标签时(例如,发布新版本时),将为Docker注册表中的所有项目映像创建一个新的Docker标签:myregistry.org/myproject/frontend:v1.1.10
myregistry.org/myproject/myservice1:v1.1.10
myregistry.org/myproject/myservice2:v1.1.10
myregistry.org/myproject/myservice3:v1.1.10
myregistry.org/myproject/myservice4:v1.1.10
myregistry.org/myproject/myservice5:v1.1.10
myregistry.org/myproject/database:v1.1.10
这些新的映像名称通过Helm模式进入Kubernetes配置。部署开始时,团队将werf deploy
更新image
Kubernetes资源清单中的字段,并由于更改的映像名称而重新启动相应的资源。问题:如果以前的实际vykata(Git标签)没有更改图像的内容,而是仅更改了它的Docker标签(一旦重新启动此应用程序,并且因此很简单),则可能会发生这种情况。尽管没有真正的原因可以使此重启。结果,使用当前的标记方案,您必须隔离几个单独的Git存储库,并且出现了组织将这几个存储库推出的问题。通常,这样的方案是过载和复杂的。最好将许多服务组合到一个存储库中并创建此类Docker标签,这样就不会出现不必要的重启。Git提交标记
Werf还具有与Git提交相关的标记策略。Git-commit是Git存储库内容的标识符,并且取决于Git存储库中文件编辑的历史记录,因此使用它在Docker Registry中标记映像似乎合乎逻辑。但是,通过Git commit进行标记与使用Git分支或Git标签具有相同的缺点:- , , Docker- .
- merge-, , Docker- .
- , Git, , Docker- .
Git-
还有另一个与Git分支的标记策略有关的问题。只要按时间顺序顺序收集该分支的提交,就可以使用分支名称进行标记。如果在当前方案中,用户开始重建与某个分支关联的旧提交,则werf将使用对应的Docker标签以及该旧提交的映像的新组装版本来擦除映像。从现在开始使用此标签进行部署时,在pod重新启动期间存在风险,以拉出该映像的另一个版本,结果,我们的应用程序将失去与CI系统的连接,并且将不同步。此外,如果在一个分支中有连续的Push'ah,并且它们之间的时间间隔很小,则旧提交的收集可能晚于新提交的收集:图像的旧版本将使用Git分支的标签擦除新提交。此类问题可以通过CI / CD系统解决(例如,在GitLab CI中,后者的管道将启动以进行一系列提交)。但是,并非所有系统都支持此功能,因此应该有一种更可靠的方法来防止此类基本问题。什么是基于内容的标记?
因此,基于内容的标记到底是什么-按内容标记图像。要创建Docker标签,不使用Git原语(Git分支,Git标签...),而是使用与以下内容关联的校验和:- . - . , ;
- Git. , Git- werf, -.
图像的阶段的
所谓签名充当这样的标识符标签。每个图像由一组的步骤:from
,before-install
,git-archive
,install
,imports-after-install
,before-setup
,... git-latest-patch
等等。每个阶段都有一个标识符,该标识符反映了其内容- 签名阶段 (阶段签名)。由这些阶段组成的最终图像被标记为这些阶段的集合的所谓签名- 阶段签名 -概括了图像的所有阶段。配置中的每个映像werf.yaml
通常将具有其自己的签名,并因此具有Docker标签。舞台签名解决了所有这些问题:- 耐空git commits。
- 抵抗git的提交会更改与映像无关的文件。
- 在重新启动分支的旧Git提交的程序集时,不会导致对映像的当前版本进行研磨时出现问题。
现在,这是推荐的标记策略,并且在所有CI系统的werf中默认使用。如何在werf中启用和使用
为团队显示了相应的选项werf publish
:--tag-by-stages-signature=true|false
在CI系统中,标记策略由命令设置werf ci-env
。以前,已经为它定义了一个参数werf ci-env --tagging-strategy=tag-or-branch
。现在,如果您未指定werf ci-env --tagging-strategy=stages-signature
此选项,则werf将默认使用标记策略stages-signature
。该命令werf ci-env
将自动为命令werf build-and-publish
(或werf publish
)设置必要的标志,因此,无需为这些命令指定其他选项。例如,命令:werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature
...可以创建以下图像:registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6
这里4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
是图像的阶段的签名backend
,并且f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6
是图像的阶段的签名frontend
。当使用特殊功能werf_container_image
,并werf_container_env
在头盔的模板,需要改变什么:这些功能会自动生成正确的图像名称。CI系统中的示例配置:type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy
文档中提供了更多配置信息:总
- 新选项
werf publish --tag-by-stages-signature=true|false
。 - 选项的新值
werf ci-env --tagging-strategy=stages-signature|tag-or-branch
(如果未指定,则默认为stages-signature
)。 - 如果之前使用了Git提交的标记选项(
WERF_TAG_GIT_COMMIT
或选项werf publish --tag-git-commit COMMIT
),那么请确保切换到阶段签名标记策略。 - 新项目最好立即切换到新的标记方案。
- 转换为werf 1.1时,建议将旧项目切换到新的标记方案,但是仍然支持旧的标记或分支。
基于内容的标记解决了本文中强调的所有问题:- Docker标记名称的稳定性可确保git提交为空。
- Git的Docker标记名称的稳定性会提交更改与映像无关的文件。
- 在为旧的Git分支重新启动旧的Git提交的程序集时,使用最新版本的映像不会导致问题。
用它!而且,不要忘了到我们的GitHub来创建一个问题或找到一个现有的问题,加上一个加号,创建一个PR,或者只是看着项目的发展。聚苯乙烯
另请参阅我们的博客: