Docker所使用的底层容器技术已经存在了很多年,甚至早于[dotCloud](https://www.dotcloud.com/)这家平台即服务(PaaS)创业公司,即后来我们所熟知的Docker。在dotCloud之前,许多知名的公司(如[Heroku](https://www.heroku.com/)和[Iron.io](http://www.iron.io/))已经在生产环境中运行大型容器集群,以获取额外的超越虚拟机的性能优势。与虚拟机相比,在容器中运行软件赋予了这些公司秒级而非分钟级的实例启动与停止的能力,同时能使用更少的机器运行更多实例。 既然这项技术并不新鲜,为什么Docker能获得如此巨大的成功呢?主要是因为它的易用性。Docker创造了一种统一的方式,通过简便的命令行及HTTP API工具来打包、运行和维护容器。这种简化降低了将应用程序及其运行时环境打包成一个自包含镜像的入门门槛,使之变得可行且有趣,而不需要类似Chef、Puppet及Capistrano之类的配置管理和发布系统。 Docker提供了一种统一手段,将应用程序及其运行时环境打包到一个简单的Dockerfile里,这从根本上改变了开发人员与DevOps团队之间的交互界面。从而极大简化了开发团队与DevOps之间的沟通需求与责任边界。 在Docker出现之前,各个公司的开发与运维团队之间经常会爆发史诗般的战争。开发团队想要快速前进,整合最新版的软件及依赖,以及持续部署。运维团队则以保证稳定为己任,他们负责把关可以运行于生产环境中的内容。如果运维团队对新的依赖或需求感到不适,他们通常会站在保守的立场上,要求开发人员使用旧版软件以确保糟糕的代码不会搞垮整台服务器。 Docker一下子改变了DevOps的决策思维,从“基本上说不”变成了“好的,只要运行在Docker中就可以”,因为糟糕的代码只会让容器崩溃,而不会影响到同一服务器上的其他服务。在这种泛型中,DevOps有效地负责为开发人员提供PaaS,而开发人员负责保证其代码能正常运行。如今,很多团队将开发人员加入到PagerDuty中,以监控他们在生产环境中的代码,让DevOps和运维人员专注于平台的稳定运行及安全。 ### 开发环境与生产环境 对大多数团队而言,采用Docker是受开发人员更快的迭代和发布周期需求推动的。这对于开发环境是非常有益的,但对于生产环境,在单台宿主机上运行多个Docker容器可能会导致安全漏洞,这一点我们将在第6章“安全”中讲述。事实上,几乎所有关于在生产环境中运行Docker的话题都是围绕着将开发环境与生产环境区分开的两个关注点进行的:一是编排,二是安全。 有些团队试图让开发环境和生产环境尽可能保持一致。这种方法看起来很好,但是限于开发环境这样做所需定制工具的数量又或者说模拟云服务(如AWS)的复杂度,这种方法并不实际。 为了简化这本书的范畴,我们将介绍一些部署代码的用例,但判定最佳开发环境设置的实践机会将留给读者。作为基本原则之一,尽量保持生产环境和开发环境的相似性,并使用一个持续集成/持续交付(CI/CD)系统以获取最佳结果。