人工CI管道中的Docker注册表和容器生命周期

之前的一篇博文我们讨论了持续集成(CI)流程对docker映像的重要性,以及如何进行设置私有Docker注册表在Artifactory中支持推广管道。配置看起来有点像这样:

artifactorydockerpipeline

这张照片里有一个詹金斯CI管家。我们常说,你应该建立和促进你的通过自动化实现Docker容器但这到底是什么样子的呢?在这篇文章中,我将概述建立一个健壮的Docker管道的核心原则确保自动发布docker映像一个安全的Docker注册表。在以后的文章中,我将讨论在Jenkins管道中使用Jenkins Artifactory插件的实现。当然,Jenkins并不是你唯一可以提升自己的工具。任何可以调用REST API的工具,无论是像Jenkins、Bamboo、Travis这样的CI工具,还是像Ansible、Chef或Puppet这样的编排工具,都可以从一个Docker注册表提升到另一个Docker注册表。

层的分离

以下是你在设置管道时应该遵循的一些原则:

  1. 没有Docker映像/标签能够到达生产Docker注册表,除非在构建时进行测试。
  2. 部署的应用程序应该使用Docker运行。
  3. 尽管如此,我们仍然需要一个生命周期,它允许我们轻松地更新Docker镜像的基础层,以接收安全更新。

要做到这一点,我们应该把Docker映像想象成包含两组层,每一组都可以有多个层。第一组层是框架层,我的应用程序安装在其上,第二组层是安装和配置应用程序的层。

ourlayers736

例如,我可能在tomcat上运行一个.war文件的应用程序。框架映像将是一个基本的操作系统映像(例如ubuntu: trusted),然后在此基础上安装JDK和Tomcat。这将被称为“框架映像”(当然,在这种情况下,我可以只使用基本的Tomcat Docker容器,但重点是展示如何为您的需要构建框架层)。

在此之上,我们添加了“应用层”。在本例中,我们只需添加WAR文件和创建“应用程序映像”所需的任何配置文件。

框架层

框架映像是找到大多数安全更新的地方。您希望定期对其进行更新,但也希望确保安全更新不会破坏您的构建。因为这个映像必须在注入到应用程序开发管道之前进行测试,所以关键的方面是您拥有它。根据我们的经验,在将映像用于应用程序安装之前,通常至少要对其进行一些小的修改,但是即使您除了测试它的工作之外没有进行任何更改,也要拥有它!这使得一个框架镜像的dockerfile最小:

yourorg-docker-dev.jfrog.io /ubuntu:值得信赖的维护人员yourorgcom

在这种情况下,我们所做的就是把它从docker-dev虚拟Docker注册表,它将检索官方Ubuntu映像的最新标签来自Docker Hub,然后我们可以添加一个所有权标签(这样就有人知道该呼叫谁来询问测试过程),并将其推送到本地Docker注册表,作为属于您的注册表,然后测试它并将其提升到Docker -prod注册表。

应用层

应用程序映像看起来像这样:

从yourorg-docker -刺激.jfrog.io /项目/框架:最新维护人员you@yourorg.com添加https://yourorg.jfrog.io/yourorg/java-暂存——/…/ app - [释放].战争/var/lib/tomcat7/webapps/app.war

所以在这种情况下,我从生产Docker注册表中获得“prod批准”的框架Docker容器,并使用Artifactory的RELEASE关键字在登台目录中添加我最新的“可发布”WAR文件。这是最新的已知的好war文件,因为我不“知道”它是否好,直到它在生产环境中进行了测试(在这种情况下,我的Docker容器在一个“已知的好”框架)

当测试框架时,我可能会使用一个dockerfile,看起来像这样:

从yourorg-docker -dev.jfrog.io /项目/框架:最新维护者you@yourorg.com添加https://yourorg.jfrog.io/yourorg/java-释放——/…/ app - [释放].战争/var/lib/tomcat7/webapps/app.war

这是完全相同的,除了我们使用的是从开发Docker注册表中提取的框架的开发版本,在它被批准之前(因为这是验收测试)和WAR的最后一个已知的良好发布版本。所以我们的推广管道是这样的:

管道

三明治吗?

此提升管道实现了一种夹心测试方法,将应用程序的自顶向下测试和框架的自底向上测试同时结合在一起。通过拥有框架与应用程序的独立测试和生产管道,您不仅有机会重用框架,而且可以将安全更新问题与应用程序开发分离开来。

每当我们想要更新框架时,也就是说,每当有a.)安全修复;或者b)需要更改框架的基础设施组件或其配置。在这种情况下,这意味着无论何时ubuntu:trust更新,或者无论何时我们想要使用新的JDK或Tomcat版本,或者如果我们出于任何原因需要更改dockerfile。当更新的框架镜像发布到Docker注册表时,或者应用程序中的代码发生变化时,我们触发应用程序管道。

有了这些触发器,唯一可以“冻结”CI/CD过程的事情——也就是说,中断开发,这样就需要人工干预,而不是在一个或另一个管道中修复代码,因为它们是交叉依赖的——是如果对基础架构进行了更改,需要进行不向后兼容的代码更改。也就是说,为了适应基础结构的变化而在应用程序级别上进行的代码更改将不会在旧的基础结构上运行,而旧的代码也不会在新的基础结构上运行。我不会说这种情况永远不会发生,但在现代世界中,对于得到良好支持的框架来说,这是一种相当罕见的边缘情况。当它确实发生时,您需要手动将WAR文件或框架构建提升到释放状态,以“启动”这个CI/CD进程(当然也是在您第一次运行时)。

这就是规律。在以后的文章中,我们将讨论更详细的实现使用Jenkins管道来管理Docker注册表之间的镜像流。

你准备好了吗开始使用Artifactory管理您的容器生命周期