我一直听说Docker是一个很酷的新事物,但直到我遇到一个真正的问题时我才感兴趣:通过Docker部署Scout会更容易吗?下面我分三个部分来解释。哇,模拟生产环境的有效方法真实生产环境中有16台服务器。如果我尝试用虚拟机进行模拟,每个VirtualBox实例最多可以有512MB的内存。这样的内存需求是我笔记本电脑内存的两倍。此外,VirtualBox有很多局限性,例如使用单独的系统内核和文件系统。但这些限制对Docker来说都不是问题。Docker的容器共享一台宿主机的系统,甚至可能是同一个程序和库。在一台Docker主机上运行数百个容器不是问题。老办法,我实在无法在本地模拟一个完全真实的环境,我们只需要看看启动一个虚拟机所需要的时间:$timevagrantupBringingmachine'default'upwith'virtualbox'provider...[default]Importingbasebox'squeeze64-ruby193'...[default]BootingVM...[default]WaitingforVMtoboot.Thiscantakeafewminutes....real1m32.052s花费了超过一分半钟来启动映像。那么单纯的修改配置怎么办呢?那我想验证一下可行性,是不是还要重启?再过一分半钟。这分明是一种残忍的惩罚。Docker有多轻量级?当您在Docker容器中运行进程时,您甚至可能会忘记该进程并非直接在主机上运行。在下面的示例中,我在Docker容器中运行一个名为“rails”的图像,它是一个Rails应用程序(Dockerfile):root@precise64:~#dockerrunrails2013-08-2620:21:14,600CRITSupervisorrunningasroot(nouserinconfigfile)2013-08-2620:21:14,603WARNIncludedextrafile"/srv/docker-rails/Supervisorfile"duringparsing2013-08-2620:21:14,736INFORPCinterface'supervisor'initialized2013-08-2620:21:14,740CRITServer'unix_http_server'running-withoutanyHTTPauthentication20:8-2016:14,754INFOsupervisordstartedwithpid12013-08-2620:21:15,783INFOspawned:'rails'withpid102013-08-2620:21:16,841INFOsuccess:railsenteredRUNNINGstate,processhasstayedupfor>than1seconds(startsecs)这负责启动Rails容器只用了2秒。总之,Docker绝对有能力在你的开发电脑上虚拟出一个完整的生产环境,而且速度非常快。既然这么简单,我们开始吧:我将彻底测试构建图像是多么容易和快速——缓存万岁!旧方法如果你想将构建过程从一个空图像编写成一个功能图像(例如:如何在UbuntuARails堆栈上安装),如果你不这样做,让所有的流都正确绝对是一件痛苦的事它很多。看一下为Ruby安装依赖项:$timeapt-getinstall-y-qruby1.9.1ruby1.9.1-devrubygems1.9.1irb1.9.1build-essentiallibopenssl-ruby1.9.1libssl-devzlib1g-devReadingpackagelists...Buildingdependencytree...The将安装以下额外包:....Settinguplibalgorithm-merge-perl(0.08-2)...Processingtriggersforlibc-bin...ldconfigdeferredprocessingnowtakingplacereal1m22.470s然后,你想安装NodeJS依赖项,但忘记将源添加到apt:$apt-getinstall-ynodejs...E:Unabletolocatepackagenodejs解决了源的问题之后,你得确认你的脚本在新镜像中会不会有问题。然后你需要重新安装Ruby,嗯,又浪费了82秒。这是上帝的麻烦。使用Docker在Docker中,您将构建映像的步骤放入Dockerfile中。Dockerfile非常容易阅读,因为您根本不需要学习DSL——它只是在您键入时记录的基本命令。第一次安装Ruby会有点麻烦,但让我们看看通过Dockerfile构建镜像的其余部分时会发生什么:FROMubuntu:12.04RUNapt-getupdate##MYSQLRUNapt-getinstall-y-qmysql-clientlibmysqlclient-dev##RUBYRUNapt-getinstall-y-qruby1.9.1ruby1.9.1-devrubygems1.9.1irb1.9.1build-essentiallibopenssl-ruby1.9.1libssl-devzlib1g-devroot@precise64:/#timedockerbuild-t="dlite/appserver".Uploadingcontext92160bytesStep1:FROMub04untu:12--->8dbd9e392a96Step2:RUNapt-getupdate--->Usingcache--->b55e9ee7b959Step3:RUNapt-getinstall-y-qmysql-clientlibmysqlclient-dev--->Usingcache--->dc92be6158b0Step4:RUNapt-getinstall-y-qruby1。9.1ruby1.9.1-devrubygems1.9.1irb1.9.1build-essentiallibopenssl-ruby1.9.1libssl-devzlib1g-dev--->Usingcache--->7038022227c0Successfullybuilt7038022227c0real0m0.848s#p#部署镜像像许多其他基本环境一样更新与部署一样,Scout也使用长期运行的虚拟机。我们使用Puppet来更新基础环境,然而,这往往比我们想象的更痛苦:如果我们要更新堆栈,Puppet将运行虚拟机然后更新。这将花费很长时间——即使只有一小部分堆栈需要更新,Puppet仍会检查所有这些。在部署过程中也可能会出现问题。如果我们在安装Memcached的时候突然网络中断了一段时间,那么apt-getinstallmemcached命令可能会失效。回滚重大更改,这通常不像预期的那样顺利(比如更新Ruby版本)。这些都是Puppet的缺点——像Puppet或Chef这样的工具非常重要,尤其是当你有一些长期运行的虚拟机时,这些虚拟机会随着时间的推移变得不一致,所以这些工具就更加重要了。使用Docker部署映像-无需修改现有虚拟机。您可以100%确定本地运行的将在相应的生产环境中运行。但是镜像很大,对吧?不是整个Docker的东西——记住容器不在自己的操作系统上运行,我们使用的是联合文件系统。当我们对图像进行更改时,我们只是在顶部添加新层。比如我们在应用服务器上安装Memcached。我们树立新形象。我将标记为asdlite/appserver-memcached,dlite是我的index.docker.io用户名,它基于dite/appserver图像。root@precise64:/#timedockerbuild-t="dlite/appserver-memcached".Uploadingcontext92160bytesStep1:FROMappserver--->8dbd9e392a96Step2:RUNapt-getupdate--->Usingcache--->b55e9ee7b959Step3:RUNapt-getinstall-y-qmemcached--->Runningin2a2a689daee3Readingpackagelists...Buildingdependencytree......Startingmemcached:memcached.Processingtriggersforlibc-bin...ldconfigdeferredprocessingnowtakingplace--->2a2a689daee3Successfullybuilt2a2a689daee3real0m13.289suser0m0.132s只要13秒就能安装好Memcached,这是因为之前的Dockerfile被缓存Yes,Ilovethefeelingofspeed.我会上传和提交这些:root@precise64:/#timedockerpushdlite/appserver-memcachedThepushreferstoarepository[dlite/appserver-memcached](len:1)ProcessingchecksumsSendingimagelistPushingrepositorydlite/appserver-memcached(1tags)Pushing8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1cImage8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1calreadypushed,skipping...Pushingtagsforrev[ad8f8a3809afcf0e2cff1af93a8c29275a847609b05b20f7b6d2a5cbd32ff0d8]on{https://registry-1.docker.io/v1/repositories/dlite/appserver-memcached/tags/latest}real0m28.710s在生产环境的机器上,我下载了镜像:root@prod:/#timedockerpulldlite/appserver-memcachedPullingrepositorydlite/appserver-memcachedPullingimagead8f8a3809afcf0e2cff1af93a8c29275a847609b05b20f7b6d2a5cbd32ff0d8(latest)fromdlite/appserver-memcachedreal0m15.serverapp只用了-15秒就得到imagedlitem。请注意,图像只有10MB大小,使用应用服务器图像作为基础图像:root@precise64:~#dockerimagesREPOSITORYTAGIDCREATEDSIZEappserverlatest7038022227c03daysago78.66MB(virtual427.9MB)appserver-memcachedlatest77dc850dcccc16minutesago10.19MB(virtual438'1MB)从cachedem下载整个图像)只需将Memcached镜像中的更改添加到dlite/appserver镜像中。大多数时候,我们所做的更改会小得多。所以下载一个新的镜像会更快。这些将产生很大的不同:启动新的Docker容器是非常快速的上传+下载新的Docker图像是轻量级的并且不改变当前运行的虚拟机,我们只是启动新容器并停止旧容器。确实令人震惊!这意味着我不需要担心一致性问题——我们不修改正在运行的虚拟机,只是启动新的容器。这意味着轻松回滚!内存缓存失败?停止运行dlite/appserver-memcached的容器,并启动一个运行dlite/appserver镜像的新容器。缺点使用临时容器会导致一系列新问题-分布式配置/协调和服务发现:当新的应用服务器容器启动时,我们如何更新HAProxy配置?当一个新的数据库容器启动后,应用服务器应该如何与数据容器通信?它们如何跨Docker主机进行通信?即将发布的使用etcd的Flynn.io版本将有所帮助。不过在小规模部署的时候就不用担心这个了。总结一下:Docker部署Git进行开发开发应用程序时,开发者可以利用Git的性能和灵活性。Git鼓励实验,不会因为错误而惩罚你:开始在一个分支上进行实验,如果失败了,只需gitrebase或gitreset来恢复。开始一个分支很容易,上传很快。Docker鼓励对操作进行试验。容器启动非常快。构建一个镜像很简单,使用另一个镜像作为基础镜像也很容易。部署整个图像非常快。***,回滚轻而易举。快速+灵活=部署即将成为一种乐趣。原文链接:http://www.oschina.net/translate/docker-git-for-deployment翻译链接:http://www.oschina.net/translate/docker-git-for-deployment
