Docker是一种在Linux容器里运行应用的开源工具,一种轻量级的虚拟机。除了运行应用,Docker还提供了 一些工具,借助Docker Index或自己托管的Docker注册表对进行了集装箱化处理的应用进行分发,从而简化复 杂应用的部署过程。
我将在本文介绍如今在部署复杂系统时公司所面临的挑战,Docker怎样有效地解决这个问题,以及Docker 的其他用例。
部署的挑战
服务器应用的部署已经越来越复杂了。把几个Perl脚本拷贝到正确目录就完成服务器应用的安装,这种时 代已经一去不复返了。如今的软件有很多类型的需求:
对已安装软件和库的依赖(“Python版本高于2.6.3,使用Django 1.2”)
依赖于正在运行的服务(“需要一个MySQL 5.5数据库和一个RabbitMQ队列”)
依赖于特定的操作系统(“在64位的Ubuntu Linux 12.04上构建、测试”)
资源需求:
最小的可用内存(“需要1GB的可用内存”)
能绑定特定的端口(“绑定80和443端口”)
我们来看一个相对简单的应用的部署:Wordpress。Wordpress的安装通常要求:
Apache 2
PHP 5
MySQL
Wordpress源码
一个Wordpress MySQL数据库,配置Wordpress使用该数据库
Apache的配置:
加载PHP模块
支持URL重写和.htaccess文件
指向WordPress源码的DocumentRoot
在服务器上部署、运行这样一个系统,我们可能会遇到下面的问题和挑战:
隔离性:如果我们已经在这个服务器上部署了不同的网站,已有的网站只能在nginx上运行,而Wordpress 依赖于Apache,这时我们就会有麻烦:它们都监听80端口。同时运行两个网站是可以的,但需要调整配置(修 改监听端口),设置反向代理等。库级别也会出现类似的冲突,如果还要运行一个仍然依赖PHP4的老应用就会 出问题,因为Wordpress不再支持PHP4,同时运行PHP4和PHP5则非常困难。运行在同一个服务器上的应用没有 互相隔离(在文件系统级别和网络级别),所以它们可能会互相冲突。
安全性:Wordpress的安全记录并不是非常好。所以还是给它创建个沙箱,至少黑客入侵时不会影响其他运 行的应用。
升级、降级:升级应用一般会覆盖现有文件。升级过程中会发生什么?系统要关闭么?如果升级失败,或 者不对该怎么办?我们怎样快速回退到先前的版本?
快照、备份:一旦所有的内容都设置好,就给系统创建一个“快照”,以便能备份快照,甚至 能移到另一个服务器上再次启动,或者拷贝到多个服务器上以备不时之需。
重复性:系统出新版本之后,比较好的做法是先在测试基础设施上自动部署并测试,然后再发布到生产系 统。通常会利用诸如Chef、Puppet等工具在服务器上自动安装一堆包,等一切内容都就绪后,再在生产系统上 运行相同的部署脚本。这在百分之九十九的情况下都没有问题。但有百分之一的例外,在部署到测试环境和生 产环境之间的时间跨度里,你依赖的包在包仓库里有了更新,而新版本并不兼容。结果生产环境的设置和测试 环境不同,还有可能破坏生产系统。假如没有控制部署的每一个方面(例如托管自己的APT或YUM仓库),持续 在多个阶段(比如测试、预演、生产环境)重复搭建出完全相同的系统就很困难。
资源限制:如果我们的Wordpress耗费CPU资源,并占用了所有的CPU周期,导致其他应用无法做任何事情怎 么办?如果它用尽了全部可用的内存呢?或者疯狂写日志阻塞磁盘呢?要是能限制应用的可用资源,比如CPU 、内存和磁盘空间,就会非常方便。
易于安装:也许有Debian或CentOS包,抑或是能自动执行所有复杂步骤并安装Wordpress的Chef菜谱。但这 些菜谱很难稳定下来,因为它们需要考虑目标系统上可能的系统配置。很多情况下,这些菜谱只能在干净的系 统上运行。因此,你不太可能更换成自己的包或Chef菜谱。这样的话,安装就是个复杂的系统工程,而不是午 休期间就能搞定的事情。
易于移除:软件应该能轻松、干净地移除,不留痕迹。但部署应用通常要调整已有的配置文件、设置状态 (MySQL数据库的数据,日志),完全移除应用也变得不那么容易。
那我们应该如何解决这些问题呢?
虚拟机!