用例-使用Docker和Artifactory的不可变基础设施

文摘:

Keith Kreissl, Mac海勒- ogden, Zlatko Sisic, Deep Mistry - Cars.com, 2016年5月:探索不可变基础设施的优势,以及如何通过Artifactory的二进制存储实现这一点,包括码头工人注册表,一个为Alpine Package Manager托管的存储库,以及一个托管的NPM存储库。加入我们的首次旅程,在这条道路上见证我们如何能够重新设计他们的渲染引擎到一个节点应用程序在集装箱码头工人.所有这一切都可以通过由Jenkins和Artifactory组成的构建管道实现。

讨论转录:

(Keith)大家好。你们今天过得怎么样?你们在纳帕玩得开心吗?

(观众)是的。

[Keith]好吧。我叫Keith Kreissl。我是cars.com的主要开发人员。今天和我在一起的有兹拉特科·西西奇,麦克·海勒·奥格登,还有深·密斯特里。所有高级开发人员。在我们开始这个演讲之前,有几件事我们想先说清楚。第一,我们在cars.com不卖车。我们在cars.com上的销售也不提成。最重要的是,我们买车没有折扣。如果这里有人想要这些,很不幸我不能给你。 But we hope you stay and enjoy the talk anyway.

我们在cars。com做什么呢?Cars.com是购车者和车主的主要在线目的地。我们提供可靠和容易理解的信息,以帮助消费者研究,定价,并找到新车和二手车和优质服务和维修供应商。现在我已经完成了我的营销任务,让我们谈谈技术人员在cars.com做什么。

让我们来看看其中的一些指标。我们是一家成立于1998年的公司,处理这些指标的最明显的选择是使用典型的JDE堆栈。HTTP服务器,然后是应用程序服务器,然后是Java,当然,运行在输入名称的任何Linux主机上,然后它都与数据库通信。但是随着时间的推移,正如你所看到的,我们实际上已经达到了一些相当可观的数字。因此,我们必须加强我们的基础设施。这些都可以用这个漂亮的结构图来描述。

现在,我不指望任何人能读懂这个,尤其是前面的人。所以,请相信我的话。您知道,我们有一个呈现层,一个组合层,一个服务层,然后是一个数据存储层。这么多年来,我们有很多——我们有很多建筑决策者来了又走。他们给我们留下了什么,他们给我们留下了两种HTTP服务器,我们有IBM和Oracle。我们有两种类型的应用服务器。我们有WebLogic和WebSphere。我们有两种类型的Java运行时。也就是甲骨文和IBM。和不同版本。 Yes we are still running one-five cause we have an IBM portal. So if anybody wants to talk about that we can still do that. We also are using Java 7 and we’re looking at doing a little of Java 8. And then when you look at the OS we have Oracle Linux and we have Red Hat Linux, and I’m pretty sure some of our Linux engineering have some IBM AIX boxes running out there.

现在你可能会说,这对一种环境来说并不可怕。但是我们有五种环境。我们有一个开发人员、一个未来测试、一个集成、一个性能测试和一个prod。所以把所有这些都乘以5。好吧,还是不算太糟。我们所有的应用程序呢?我们有大约10个网页应用程序和大约100个服务在任何给定的时间运行。真正发生的是,它变成像这样的东西。

所以任何时候你都会想,嘿,问题在哪里。我不知道,因为这是我们必须要做的。因为我们要管理所有的系统,所有的虚拟机。所以,我知道,你会说,嘿,Keith,猜猜主厨来了什么,你为什么不去和他们谈谈,他们有解决方案给你。是的,我们使用Chef。Chef帮了我们很多,非常大的忙,为我们采购了所有的vm。但是,我们得谈谈那些创造奇迹的人,对吧?这是开发人员。这是在座的每一个人;用笔记本电脑写所有的代码。 So now, as you can see, we have laptops which are running either NGINX or Apache. I have an app server that’s going to be either Jetty, Tomcat, Spring Boots, the new one. That’s what everyone’s loving. Then I have different versions of Java. Is it the Oracle? Is it the open JDK? And then let’s not talk about the OS that we’re running on, which is going to be either OSX or Windows.

所以你可以看到这个问题一直在复利。现在我已经成为我们的开发运营团队的领导,我每天听到的最常见的事情是:嘿,在我的机器上可以工作,为什么在X环境中不能工作?这就像让人头脑麻木的沮丧,因为正如你所看到的,我在想,问题出在哪里。

输入不变的基础设施。我们在cars.com正在努力实现我们的应用程序、运行环境和操作系统的终极封装,这样我们就可以有最大的信心,我们在自己的机器上或自动化机器上创建的工件将是经过每个单独环境和在生产环境中运行的相同的工件。

我们希望实现一种可预测、可扩展并具有自动恢复功能的基础设施。我们真的很想推广那件藏物。我不想决定要换哪部分。我想说,这条线在这里,这条线在这里。我还希望能够应对交通流量的增加。我不想去获取更多的vm,我不想去运行所有的Chef命令和运行所有的东西。我希望它能正常工作。当然,如果灾难发生了怎么办?如果某件事不起作用怎么办?我希望能够高效地回滚。 So how am I going to do this, what’s gonna do it for me?

当然是Docker了。对吧?它是万能的。那么,为什么码头工人吗?它给了我们一个很好的状态隔离。我可以把所有的组件放在一个图像中,并确保它在每个环境中都是正常的。我不需要这么做,我可以自己构建它。我可以得到自动部署。我移动这个工件的地方,这个运行这个容器的映像里面有一个应用程序,一个运行时和一个操作系统。确保如果其中任何一个部分发生了变化,这不是什么大问题,对吧? I just rebuild my image and then I can run it in a different environment. I have fast recovery. Right. If something goes wrong, let’s say a container starts going haywire or maybe I don’t like what’s happening in the container, then I just can spin up one — a previous one that was running.

对我们来说最重要的是蓝色/绿色和金丝雀的释放。有了这个,我希望能够尝试新的功能。我想说,嘿,我想让10%的流量看到这个,剩下的90%看到另一个。我怎样才能有效地做到这一点?只需旋转两个容器,将其添加到负载均衡器,然后就可以了。

另外,我不知道你们是否有这个问题,但如果你想改变你的技术,如果你想改变你的语言。如果你用Java运行,你想,嘿,我想知道Node能不能工作。我们花了很多时间来研究这些,来确定,这个是否能和Java一样好。对吧?用这种方法,我们真的不需要那样做。您可以将两个容器旋转起来,并排放置,然后看看哪个性能更好。有了这个,我就把坏掉的那个关了。

最后,它是热的。对吧?它性感。现在到处都是。每个人都想这么做。他们今天早上讨论过这件事。我们刚刚参加了Riot Games的另一场发布会。他们也在这么做。这似乎就是未来。

那么,现在你知道了Docker的所有这些,它有多酷,它将如何帮助我们,我想下一件事是我们真的必须弄清楚我们的用例是什么。你知道的,比如,我们怎么才能做到。所以,我们决定看看我们的渲染引擎。我们的呈现引擎是典型的JDE应用程序。它在运行,很好,很有效。然后我们决定,把它放到Node里。不仅如此,让我们把运行时和环境都放到Docker容器中。这就是我们要做的。我们会拿这个应用,我们会给它一个运行时,我们会把它贴在Docker里面。

但当我们开始做这件事时,我们开始意识到我们还有其他一些新的挑战。为了解释这些新的挑战,以及我们是如何解决这些挑战的,我想邀请兹拉特科上台,给你们更多的背景知识。

[Zlatko]好吧,Keith。谢谢你对我们复杂的基础设施提供了一些见解。我很确定我们不是唯一有这个问题的人。所以,至少,我们正在采取一些步骤来简化它,一次几步,我的意思是,我们目前在这方面做得很好。

现在我们得到了什么?我们有一个用Node编写的新的渲染引擎,我们想要Dockerize它,并尽快将它部署到生产环境中。基本上,我们是这样开始的,我们有一个开发团队,他们在开发新的代码行。他们正在简化应用程序、重构、构建、创建新节点和NPM模块。所以他们必须把它-或者说我们必须用Docker发布它。

因此,我们首先从简单的官方Node图像开始。使用它们,把它们拉下来,添加我们要部署的应用程序,一切都运行得很好。但我们注意到的问题是在虚拟机上运行。把这些图像从一个点移到另一个点要花很多时间。从我们的存储库到一个新的虚拟机。从存储库到开发人员的机器。所以我们需要坐下来再看一看看能否重构这些图像。如果我们能创造出别的东西,让一切变得更流畅,更快。不仅是更快,我们还在寻找其他的开发团队。我的意思是,我们有JavaScript开发人员,Java开发人员,我们也有数据开发人员,他们想把他们的脚本——[…]脚本——转移到生产环境,所以有不同的团队,不同的需求,我们在想我们应该怎么做。 Do we provide runtimes and images for every one of those themes or do we really want to provide a base image that provides a certain set of utilities. So that any developer can take that image, pull it down and be familiar with the environment. That’s what we basically — that is the route that we wanted to take. So we evaluated to different major Linux distributions. They’re all kind of big in size but they all still work.

我们注意到,从bash脚本到tar zip等一系列非常基础的工具。我们注意到,默认情况下,我们使用的每个发行版都缺少这些工具。所以不管我们用的是哪一种,我们都需要对它进行一些调整以使它符合我们的环境和需求。所以最后,我们真的想要一个非常轻量级,功能非常强大,所有团队都可以重复使用的东西。

因此,经过评估和一些POCs,我们认为Alpine Linux是我们的最佳选择。因此,Alpine Linux提供了一些开箱即用的实用程序。这是非常小的。大约有5兆字节。您可以使用Alpine包管理器来安装其他库,这些库也是由APK存储库提供的。所以我们的基本图像大约有12兆字节。然后我们用它来安装额外的-来层出额外的基础映像并创建不同的运行时。

现在我们有了一个Java运行时。我们有不同版本的Node运行时。我们有Tomcat实例。我们有不同的网络服务器,如果我们需要,以防万一。而且它们都非常非常,我是说,非常小。你可以看到其中一些,比如Tomcat从357兆下降到181兆。在Node上,你有两种不同类型的图像,最新的和苗条的。我的意思是,它从300兆增加到55兆。我们的整个图像,加上这个应用程序,大约有80mb的大小。

那么我们是怎么做到的呢?我的意思是,我们用了其他人都在用的最佳实践。你可以在网上找到,它是整合命令,基本上把它们链接在一起。安装应用程序,从源代码安装二进制文件,删除那些二进制文件,清理所有临时文件。我们还做的一件事是为了增强这些图像的安全性我们降低了运行时的实际用户权限。所以我们不想以根用户的身份运行它们。是的,很多人会说,你为什么不以根用户运行它,它只是一个容器。有一些额外的特权可以在安全漏洞的情况下使用。如果我们降低它的权限-我的意思是,如果我们降低特权,以特定用户的身份运行它,我们还必须确保这些用户能够执行运行时所以我们必须改变那些二进制文件中的权限。我们还注意到,通过仔细地重新排列命令,改变到用户,然后提取二进制文件等等,我们能够进一步缩小这些图像的大小。

有了运行时,有了应用程序创建的实际图像,我们必须找出存储它们的位置。我们有应用程序,我们有所有不同的Node模块,我们有Docker映像。另一方面,我们有Java开发人员构建新的应用程序。Jar文件,var文件。我们也有一些静态文件。另外,我们的一些Linux管理员,我的意思是,正如Keith已经提到的,我们使用不同风格的Linux。每个人都使用-每个人都使用不同的包管理器。所以我们想要巩固这一切。我们想弄清楚我们真正能用的是什么而不是五六个不同的应用程序。维护他们。 Is there anything we can use as a single solution? And Artifactory came to the rescue. It really turned out to be a one-stop shop for us. It really provided everything that we need.

我们能够保存Docker映像。我们能够使用NPM存储库。Maven存储库。它和詹金斯的结合非常好。它——一个非常伟大的特性是——真正伟大的特性是能够定义多个存储库并将它们组合起来。就像我们在这里做的是为我们所有的工件创建本地仓库。无论是快照还是发布,都可以将其分离出来。我们还创建了远程存储库,缓存我们从互联网上获取的所有外部工件。然后能够为那种类型的工件创建虚拟存储库。我们可以将这些本地和远程存储库组合或分层,这样当我们可以配置,例如,我们的Java - Docker映像,或本地Maven实例,或Java,我的意思是Java环境时。 All we have to do is point to Artifactory and let the Artifactory make the decision where the artifact is going to be written from.

另外,我们利用元数据支持。我们标记图像,然后在构建过程中使用它,并利用REST API检索它们。有了这些基本的方法,现在我想请Mac告诉我们更多关于我们首先开发的自定义脚本的内容。

[麦克]谢谢Z解释我们是如何设置这些内容的。

有了这些背景,我们面临的下一个大问题是如何处理我们的一些构建和部署。我们有了所有这些工件,我们已经知道了在哪里存储它们,我们已经优化了它们,这很好,现在我们到底要如何使用它们。我认为这是每个人都在关注的问题。现在有很多解决方案。但它们都处于发展的早期阶段。这就是我们所面临的问题,当我们看到这种情况时,你可以在这些网站的主页上看到免责声明,比如,Docker的论坛有一个声明,说初始开发还没有解决。比如,期待大的变化。对吧?我们研究的每一个解决方案也只解决了问题的一部分。

我们真正需要的是能够满足我们当前需求的东西,而不是将我们锁定在一个特定的工具上。能给我们争取点时间的东西。对吧?很简单的事情。因为我们没有太多的需求来推出这个初始的Node应用程序。我们有一个应用程序,我们想要集装箱化,向组织证明我们可以做到这一点。对吧?我们需要做什么?我们需要能够处理一些扩展需求,用端口做一些动态的事情,我们需要能够处理滚动部署。作为开始,这可能已经足够了。 Also, we’re really trying to achieve immutable infrastructure so it’s all well and good that containers can, you know, encapsulate application state but we really want immutability in the thing that’s handling the builds and handling the deployments too. Like, at least to some degree we want that to be the same thing running on local developer machines that’s also running on the machines that handle the builds and handle the deployments. All right.

最后,如果我们能有一个提供非常简单的声明性语法的工具,那就太好了。我可以与应用程序源一起存储的一些配置文件与工件一起构建,因此所有构建逻辑或运行时逻辑实际上都随映像一起发送。

所有这些都会很好,所以我想,什么样的工具可以帮助我满足这些基本的需求。我回想起过去,我碰巧记得有一个小工具,最初的构建工具,叫做Make。我看了看,你知道吗,这应该是一个Make文件。每个人都知道这一点。这对现在来说已经足够了。我们现在需要填补空白,而Make就是那个人。

所以,你知道,我只是坐了几个小时,写了一个Make文件。我不指望你们能读懂所有的东西。我必须把它缩小到4号字体。这实际上是一个更老的版本。信不信由你,它现在是现在的两倍。这是我们要解决的问题。但是看着这个Make文件,我在想,你知道,我希望这个在本地开发人员的机器上,我希望这个在将要处理构建和部署的机器上。我希望到处都是这样。但是把它散布到任何地方,肯定是个问题。它太大了,你会飘的。 And it’s — that’s the opposite of mutability, right.

所以我们找到了一种方法,把它包裹在一个简单的小入口里,把它分布得更干净一点。现在,应用程序源代码中的文件看起来更像这样。这是一个非常简单的例子,但它给出了我所说的声明性配置。看似简单。它只有一个名字。那是我们在注册表参数上设置的工件存储库。一些端口绑定。它有自己的端口绑定语法。如果你使用Docker运行端口绑定,它可能看起来不熟悉但是一些环境变量,一些卷。我们用来渲染引擎的那个要复杂一点,但也不是很复杂。 It’s pretty basic, right.

这个文件叫做动力系统。mkfile,它位于你的项目根目录中。

我将给你们一个非常非常高层次的了解这个工具的CLI是什么样子的。这将为你们提供一些背景知识为我们一会儿要做的演示提供一些背景知识。所以有一个动力系统建造指令。现在,这个命令,以及其他命令,你会注意到你没有指定任何标志或者任何关于你正在运行的信息因为这些都在配置中。这就是整个事情的重点,动力总成构建只是做一个构建,但那些参数将从配置文件中填写。

有一个powertrain publish命令它会继续用那个文件中的信息给你的图像打上标签然后它也会把那个推入注册表。

最后是deploy命令,它将做一些事情。这是一个复合任务它会到Docker主机上移除所有退出的容器,确保我们能够,在Docker群集的例子中,按我们想要的方式分配端口。它会拉下那个图像因为你假设你把图像建立在不同的盒子上而不是部署在不同的盒子上。因此,图像需要从注册表中提取。它会运行那个图像。然后它会去停止之前在那里的所有容器。它还可以在命令行上参数化,指定需要的实例数量。如果你想的话,还有很多其他选项可以放在那里。既然你已经对我们为构建和部署而创建的这个临时工具有了一些了解,我将邀请Deep Mistry在这里更多地谈谈我们的CI/CD管道以及我们如何在Jenkins中使用它。

(深)。谢谢Mac介绍我们是如何构建和部署这些新的应用程序的。

让我来告诉你我们将如何将它部署到生产中。

谈谈CI/CD,我们使用的一些工具。因此,当涉及到CI/CD时,我们显然使用通常的怀疑对象。我们使用Jenkins作为CI服务器,我们使用Bitbucket作为源代码控制,我们使用Artifactory,正如你之前听到Z提到的,它是我们所有注册表需求的一站式商店,所以我们使用Docker注册表,我们使用Alpine APK,还有我们所有的Maven和Gradle工件。我们也在CI/CD中使用Docker不仅仅是运行我们的应用程序容器我们还在CI/CD管道中使用Docker容器进行无限的测试。你在上面看不到的是主厨。我们用Chef来代替Jenkins的奴隶。还有Docker自己托管。

谈论持续集成工作流。所以这是典型的,你知道,一个开发人员会对代码库做一个更改,他们会提交代码,然后把它推到我们的源代码控制。一旦代码被推送到比特桶上,就会触发詹金斯的网页链接,然后就会启动一个构建任务。构建作业要做的是从Bitbucket中拉下回购,正如Mac之前在幻灯片中展示的,源代码不-显然它控制源代码-它也有Docker文件以及我们的动力总成配置文件。现在Jenkins要在CI服务器上使用相同的动力系统构建命令。如你所见,它可以做动力总成构建,这将构建我们的Docker形象。

使用powertrain,您还可以覆盖配置文件中指定的一些变量。在这种情况下,在我们的CI服务器上,我们实际上使用了一个版本变量,这只是给它一个不同于源文件中的版本。这样我们就可以在Artifactory中跟踪那个版本。我们使用Jenkins的构建号和触发提交的git哈希值的组合。这触发了这个构建。詹金斯构建了这个图像,对吧,一旦图像构建好,它就会使实际的容器旋转起来。应用程序的容器。这是一个web应用它会将那个web应用旋转到Docker主机上然后它还会旋转一个测试容器。对该应用程序运行一些自动测试,以确保一切正常。我们所做的改变并没有破坏一些核心功能。 So once this test it completes, and if it’s successful, we go ahead and push this image onto the Artifactory, right.

现在,这也是一个管道。一旦构建完成,它将触发我们的部署任务到我们的环境中默认情况下,我们将每个提交部署到我们的开发环境中。部署作业基本上,它做的是,它实际上,我们在Jenkins中使用的是我们把所有Docker主机配置到Jenkins主机上作为SSH从机。部署任务做的是SSH到Docker主机上运行你可以在本地笔记本电脑上运行的动力系统脚本到Docker主机上。

就像你看到的,它可以用相同的版本来做动力系统部署,用相同的版本来构建图像。对吧?关于动力传动系统,我们能做的最酷的事情之一是,我们可以从图像本身,从构建图像中提取配置。对吧?记住,当詹金斯在建立图像时,它拉下了回购协议,所以我已经知道我的动力总成配置是什么样的以及我的动力总成文件是什么。但在Docker主机上,我们没有任何源。我们只有图像。我们能做的就是使用powertrain的extract config命令它会提取所有我们为powertrain存储的配置文件。然后你可以提供你想用哪个配置文件运行或者你想用哪个运行配置启动你的容器。对吧? So this is pretty powerful. With this, what it can do is you can pretty much run your container in any run configuration from whatever you want to, right. You can do this from your local environment and you can do this on multiple environments, right.

这就是我们如何部署到不同的环境中。就像Keith之前提到的如果我们有5个不同的环境这就是我们如何在跨环境移动时实现应用的不变性。

我们会试着向你们展示,管道是什么样子的。我们会-麦克会帮我向你们展示一点。

[Mac]所以我要在这个回购上放一个提交,以便开始构建。这是原始回购。我要在自述文件中添加一行然后添加,提交。我们所有的……当然,我们所有的开发人员都必须有一个[…]ID。我想我得把它也放进去。

[深度]好了,这个推送应该会继续下去,启动我们的一个构建工作。

[麦克]这是推杆,现在我们可以继续了。打开浏览器,我在管道页面进行渲染,我们会刷新。把它搬开。

所以,是的,它实际上在执行和你们之前在幻灯片中看到的相同的动力系统指令。它正在构建应用程序映像。需要注意的一点是当我们实际构建图像时。熟悉Docker的人,我们实际上是在构建应用程序并在Docker文件中为应用程序运行单元测试。我的意思是,Docker文件中的Docker指令。因此,作为Docker构建过程的一部分,我们实际上是在构建应用程序并进行单元测试。我们这样做的原因是我们想确保应用程序是在最终要运行的环境中构建和测试的。这是相同的图像,它会在Docker主机的容器中运行,我们应该在相同的图像上构建和测试。这就是它现在所做的。

因此,当这些正在构建的时候,我们可以去Artifactory看一眼我们的Docker注册表。哦。正如我们之前提到的我们之前创建了一些基础图像。我们所有的应用图像都可以在Artifactory中找到。这是慢一点的WiFi。所以。好了。我们——我们——几乎存储了每个提交负载,所以正如你在CI工作流中看到的,每个提交都被构建到Docker映像中。我们可以回到Bitbucket服务器,查看提交历史,看看哪个提交,哪个构建与那个提交相关。如果您想要回滚,您可以快速地到Artifactory,将映像拉下来并部署它。

Artifactory的一个很酷的功能是Docker信息标签。所以早些时候,当我们开始构建应用程序时,我们从可用的基础包开始,比如Ubuntu或Debian。它们的体型显然要大一些。我们看到了如何在Artifactory中看到每一层,我们可以看到该层利用了多少空间。这真的帮助我们解决问题,改善我们的Docker文件,减少我们的一些基本图像大小。

因此正如前面提到的Z所示,应用程序映像只有88兆字节。之前的一张不同的基本图像几乎有500兆字节。由于我们实际上是在为每次提交创建一个图像并发布,如果您可以进一步减小大小,这将非常有帮助。所以,是的,我们可以从Artifactory中使用一个非常好的工具。

所以我们要回到我们的管道。希望构建现在已经完成了。

(Mac)

你只需要刷新它。哦,它还在运行。这也需要很多时间因为正如我之前提到的,它也要做一些测试。使用它进行自动测试。它使测试容器旋转,并运行针对它的所有自动测试。这显然会触发部署到开发所以每次构建都会自动触发我们的部署到开发环境。从那里开始,如果你想部署到未来的测试环境中,我们有一个按钮部署规则,qa将不得不继续,如果他们想测试一个特定的构建,只要点击那里的按钮,就可以将该构建移动到[…]环境中。

[麦克]詹金斯的工作现在可能有替补了。我们有7万[……]。

(深)。

(Mac)

(深)是的。希望。所以- - -

[麦克]你要我按按钮吗?

你可以按一下,没关系。

基本上,这个想法就像你构建你的应用程序映像,你知道,你是在本地系统上构建它还是在CI服务器上构建它。你应该能够移动图像到任何你想要的环境和动力系统,你真的可以做到这一点。因为您可以用各种运行配置来运行该容器。因此,开发人员可能需要一些其他的服务依赖关系或其他数据库依赖关系,所以你不应该仅仅因为想要不同的环境依赖关系而更改应用程序。所以,是的。我想总结一下,这就是我们如何在应用中实现不可变性。就- - -

(Mac)

你想要,你想要看构建队列。好像我不知道它有多大似的。好了。

[Mac]是啊,构建队列被备份了。

(深)是的。

是的。就像Mac提到的,有开发者一直在投入,所以这是我们所关注的一件事:就像扩展Jenkins本身。我们现在只有一个师傅。我们正在考虑使用多个主节点和集群。

最后,我想请Keith回来谈谈Docker在cars.com的未来,以及我们想如何推进它。

[Keith]是的,似乎我们要把电子邮件放在CI/CD管道中,以便开发者在我们做演示时不要碰它。

好吧,不管怎样。所以现在你看到我们有了这个全新的工具,我们有了这个不可变的基础设施的伟大概念,当然还有Docker和这种对学习和真正扩展它的渴望。我们正在采取更小的步骤。我们真的在尝试迭代这个过程。在这个领域,很多事情都在发生变化,所以我们只是想确保在我们跳上下一个技术之前,看看那里有什么。然而,当我们发现我们需要某种新功能时,我们就会把它添加回整个CI/CD管道中。

好吧,让我们谈谈Docker在cars.com的未来。当我开始这个演讲时,我说过我们有10个web应用程序和大约100个服务都是用Java编写的。我们当然希望能够将所有这些移动到Docker容器中,并拥有一个完整的Docker生态系统,让我们所有的应用程序能够相互通信。

但我想更进一步。我真的很想采纳这个想法,你知道,容器里面运行的是什么并不重要,对吧?如果你有这样的想法,你的容器可以接受一个web请求,然后相应地响应,那么里面有什么就不重要了。我想放什么就放什么。它为你提供了更多的工具你可以用它们来解决任何问题。也许你想做Node。也许你想做Scala。也许[……]是你选择的语言。应该允许您使用它们,而不受现有基础设施的限制。如果你从这个角度开始构建你的容器和你的图像,那么你应该没有问题旋转一些东西,拆除它和尝试新的东西。 Which is real exciting for all of us, especially as technologists, to see where this can take us.

所以到最后,我们得出结论,你知道,我们真的感谢大家在这里听我们,希望你们学到的知识,或者,你知道,采取了一些东西远离我们所做的或如果您有任何指针对我们我们很想听到,所以从这个角度我想打开的问题,我可以把每个人都在这里,然后我们就可以把它从那里。

快速释放,否则死亡