我们正在升级FutureStack的注册,仅到4月30日。条款和条件适用。 现在注册

管理New Relic网站服务团队的Karl Matthias也对这篇文章做出了贡献。

所有的媒体码头工人最近,有很多关于理论用例的讨论。但是New Relic已经在现实世界中使用Docker在生产中取得了几个月的成功,用它来解决一个单一的、棘手的问题:部署。这篇文章是基于我们在DockerCon 2014被称为Docker部署:对开发人员来说是强大的,对操作人员来说是无痛的,解释了我们面临的部署问题;我们如何使用Docker、我们的开源Centurion部署工具、其他工具和最佳实践来解决这些问题,以及我们使用的简单策略如何改善了New Relic开发人员和运营人员的生活。

标题幻灯片

我们已经看到其他公司在Docker的基础上建立了“平台即服务”。但是,我们并没有马上着手构建PaaS;我们着手改善开发人员和运维团队的生活。一路上我们遵循着新圣物哲学(沃德·坎宁安提供的)去做“最简单的事情。”以下是我们所做的,以及我们如何到达那里,以及一些我们建造的工具,以指导我们的舰队。

我们的故事从准备3月发布的新Relic洞见的公开测试版.Insights团队的初步调查显示,Docker为他们这样的开发团队提供了潜在的巨大利益。因此,在承诺了早期测试之后,我们努力推动Docker投入生产。

结果证明这是一个非常快速的过程:我们从12月份还没有Docker产品到2月份发布了有史以来最大的新产品。我们现在每个月都要推出几项新服务。

我们的情况

我们从一个相当标准化的应用环境开始,有大约7个两种语言的产品应用。这些都是大型的单片应用,对环境的重大改变很少发生。该系统可以使用我们已经构建的工具进行维护,并且在6年的生产生命周期中,系统的配置也在缓慢发展。我们几乎在硬件或大型虚拟机上运行所有的东西——通常在每个主机上运行多个应用程序或服务。我们在f5层使用了集中式负载平衡。这是一个经典的生产环境,与我们规模和成熟的许多其他公司非常相似。

协调一致的努力使开发团队能够处理他们自己的操作,这很好,但我们不能让这些DevOps人员访问他们需要的所有东西。此外,当站点工程团队(我们)需要更改时,我们发现让开发人员针对我们庞大的Puppet代码库拉出请求是很尴尬的,并且经常对双方都有害。更糟糕的是,因为他们需要访问大量的配置来调试他们的应用程序,许多开发人员有可能访问所有的数据库秘密。

即使对于那些成熟的代码库,当环境需要更改时,部署也经常会中断。在Site Engineering没有花大量时间调试这个问题之前,还不清楚谁应该对此负责。修复任何问题所花费的时间都超过了它应有的时间,而且系统问题很难隔离,因为如此多的应用共享资源,并且相同服务器上的许多应用有冲突的需求。

到2013年底,事情开始迅速发展。我们开始将我们的主应用程序分解成一个带有许多服务的面向服务的体系结构(SOA),所有这些服务都需要新的环境。此外,我们的应用变得越来越多样化。我们至少有4个Ruby版本,3个jvm, 5个数据存储,大量的新数据库实例,以及大量的其他变体。不同的应用程序在不同的时间更新依赖关系。

剩下来处理所有问题的是每个团队中一到两个人,他们知道他们部署配置的神奇之处。更糟糕的是,现有团队中的部署专家并没有扩展到所有新团队。一些团队发现自己没有任何人知道部署。再加上启动Insights会让我们的服务器数量增加50%而且的东西不得不改变。

我们没有

在这一点上,我们有很多途径可以采取了。但是我们想做最简单的事情,以最少的痛苦获得最大的胜利——对于Site Engineering和我们的开发人员来说。

所以我们并没有试图一次性创建一个完整的PaaS框架。虽然这可能是我们的最终目标,但它不会解决立即部署的问题。

我们并没有从数据量最大的应用程序开始Dockerizing我们的应用程序。相反,我们从最简单的内部Web应用程序开始,特别是可以水平伸缩的无状态的东西。我们早期的测试表明,由于Docker网络堆栈的原因,高吞吐量的应用程序对于你的第一次Docker部署并不是一个好的选择。Docker 1.0版带来了可靠的基于主机的网络,这可能改变了这种情况——我们现在正在研究。如果应用程序的每个实例都必须保持很长一段时间,这也不是一个好的首选。

我们没有实现动态扩展或服务发现。我们决定使用端口注册表静态地为每个应用程序分配端口。这让我们可以跨服务器池为应用程序预配置负载均衡器,并让运行状况检查确定其服务的位置。它还允许我们轻松地预配置监控应用程序。

执行:我们所做的

New Relic在Docker上发布的早期项目构建了自己的dockerfile。Insights团队制定了一些其他团队遵循的最佳实践,我们现在已经在我们的基本图像中进行了编码。洞察团队的Unix知识和普遍的决断力促进了整个探索过程。

与此同时,我们的站点工程团队专注于这个故事的部署部分,开发了一个工具,可以让我们保证容器的运行时配置,并使用Docker: Centurion进行自动化部署。我们将在下面对此进行更多讨论。

我们使用Docker将构建与部署分离开来,这一策略与Docker的架构非常吻合:构建作业将内容发送到Docker注册表,部署则从注册表中获取图像并将其执行到服务器上。Docker是一项强大的技术,因此在开始使用它时,有很多东西需要学习。我们不希望团队为了部署而需要对Docker构建和发布图像有深刻的理解。我们的想法是降低标准,我们觉得这可能是一个主要的障碍。但我们也想让团队在需要的时候保留Docker的全部权力。我们编写了一些工具并开发了一个策略来处理这个问题。

降低门槛:想想跳高,而不是地狱边境

通过早期的过程,我们发现了一些图像的最佳实践,并能够利用Docker的图层创建一些易于使用的基础图层,供团队构建。这是简化开发团队工作的第一步。遵循标准,在Docker中很容易打包你的应用程序。它还使软件升级更加容易:我们更新了基本映像,团队可以在下一次部署时使用它。与部署同步更改操作系统依赖是一个巨大的胜利。

在我们使用Centurion正确部署了一些东西之后,我们制作了其他工具来自动配置Dockerfile。这个名为shiright的工具可以让我们在数小时内(而不是数周)启动并运行新项目。团队不需要知道如何编写Dockerfile,他们可以简单地在命令行上指定配置项,基本映像可以使用shiright来构建容器映像。团队通常不需要做任何事情来构建映像,只需要签出他们自己的存储库并运行shiright。shiright和Centurion让我们完全分离了开发人员和运营人员的关注点,清晰地划分了责任,让团队能够非常快速地组建和运行。

我们最近有机会衡量我们的成功,当一个团队将遗留代码分解成一个新服务,让他们的应用在几个小时内运行。如果使用以前的机制,这将是一个真正的挑战。

了解百夫长

回到我们的工具上来!Centurion是一个命令行应用程序它可以让你将Docker集装箱运送到整批机器上,具有可重复配置。它还具有环境意识,这意味着您可以在一个地方为每个环境设置所有应用程序配置。

认识百夫长

Centurion处理端口映射、卷映射和运行时环境变量(如数据库秘密或特定于环境的设置)。它可以选择您要部署到的服务器,以及它们使用的环境。

另一个大的优点是它支持开箱即用的Web应用程序的滚动部署。它利用每个应用程序的健康检查URL(我们使用/check/status)确定地知道新容器何时成功启动并准备好服务。

我们已经在使用Centurion将真正的应用程序部署到生产环境中。但是它灵活的设计让它能够与笔记本电脑上的boot2docker一样小的环境一起工作,所以开发人员可以确保从笔记本电脑到登台和生产的一切都是相同的。

其他新遗迹工具

如果它没有被监控,那么它就不在生产中。我们在New Relic监控一切,Docker也不例外。当然,我们使用New Relic APM,但我们也使用Nagios有关更多系统级健康检查。我们的check_dockerNagios检查确保Docker运行良好也是开源和可用的。

当然,New Relic APM与Docker一起工作,因为它不需要知道它在哪里运行,只需要知道它运行得有多好。

操作环境

我们的部署配置目前位于Git存储库中,由所有应用程序共享。我们正在努力etcd支持。

因为它只是一个命令行工具,百夫长能够放入我们的詹金斯环境和立即允许连续部署。我们有两种作业:基于shipright的作业(用于构建映像)和基于centurion的作业(用于将映像部署到服务器)。

在Docker中创建并运行一个新的应用程序是非常容易的。但是我们为调试构建了一些额外的支持。Centurion可以为您提供一个具有所有相同配置项和相同基本映像的运行控制台。运行时调试可以通过SSH在每个容器中运行,通过集中的日志记录(例如,通过Papertrail),并通过Docker ' logs '命令。我们正在把所有通过syslog的东西都放到日志路由器(Mozilla Heka),进入ElasticSearch / Kibana消费。

在这个新环境中,团队可以随时对他们的依赖项进行迭代。一个团队升级了Ruby和Rails版本,而无需通知我们。安全补丁的运行也更加顺畅。它们可以很容易地应用在下一个容器构建中,彻底地测试,然后推到生产中,而不需要开发团队将依赖项更改与部署同步:从设计上讲,它是同步的。

通过添加Docker服务器可以很容易地增加容量。要做到这一点,我们只需从Cobbler网络引导机器,当新操作系统出现时,Puppet就会安装Docker守护进程。

快乐的开发者,光明的未来

我们的开发团队对Docker非常热情。能够在自己的依赖项上迭代,轻松地启动本地集成环境,并且从不需要接触Capistrano,这些都是巨大的胜利。

开发人员喜欢它

我们大大降低了新工地工程项目的门槛。我们只需要提供一个带有Puppet的数据库,在负载平衡器和DNS中添加一个条目,然后让团队将数据添加到Centurion中(我们仍然告诉他们使用哪个主机)。Site Engineering在Puppet中花更少的时间去挖掘如何支持相互冲突的依赖关系。

还有很多工作要做。但我们对我们的目标和实现目标的下一步有一个清晰的愿景。我们希望很快就能支持etcd服务发现和服务状态。我们还希望从etcd中动态配置负载平衡器和Nagios。最终,我们会回过头来,开始使用docker通过主机网络从Centurion配置大容量的应用程序和数据库。

我们将Docker的成功归功于我们的简单方法。一步一步来,构建简单的工具(或使用我们的!),先做那些以最少的痛苦提供最大的收益的片段,你也可以利用Docker所提供的优势。