正文
Docker不仅在开发过程中有用,也可以简化打包代码部署生产环境的过程。这是因为Docker使得生产环境和测试环境更为对称。这是开发/生产均势12要素(https://12factor.net/dev-prod-parity)中的一点。
对于不同的语言,我们已经有了非常棒的管理工具,例如rbenv(Ruby version management)和nvm(Node Version Manager)。这些工具使的我们从繁杂的运营时版本匹配的工作中解放出来。如果你的代码基于一些晦涩的原生二进制代码或者是某个特定的文件系统结构,那这些工具会更有用。
容器会在此基础上更进一步。容器使的我们可以把我们的应用程序与所需的运行环境完美的打包在一起。
这种可移植性也在混合云的构建过程中非常有效。这一点从我们的云迁移过程可以有更深入的理解。
当时,我们对于云服务商的不稳定性非常不满。我们决定迁移到“IaaS之王”——AWS亚马逊云服务。
我们预感到这次迁移早晚都要进行。所以,到那时我们会需要把我们的应用迁移到Docker上运行几个月。等到我们彻底告别我们原有的云的时候,整个迁移过程就可以在短短几天内完成。
如此大规模的迁移可以认为是小概率事件。但是我从未觉得增加灵活性有什么问题。
如果所做的事情与app无关,就完全没有意义。AWS等云服务商提供的已经投产的解决方案(https://aws.amazon.com/cn/cloudwatch/)或许可以解决监控、日志等在迁移过程中的割切问题。但是这些可以用容器化的开源解决方案实现,更加易于部署,而且可以让你避免“云监狱(http://t.cn/Rcdulfj)”的窘境。
你需要还是不需要编排系统,并不是正确的问题。需要面对的问题是,你是否想让编排系统自管理、还是靠人工在凌晨3点修复系统崩溃的问题。
这个比喻所指的事情,涉及到很多迁移的部分。软件系统变得更加复杂,而且在运行时切割得更厉害。当网络分区的时候,软件系统会变的脆弱。
现在,容器本身并不能解决这个问题。恰恰相反,容器的短暂性使得你的系统变得无比动态化。这导致部署的时候难以保证运行时的依赖关系。
当系统规模需要扩展到集群时,情况更糟糕。使用集群,你永远无法精准确认你的进程可能在那个环节退出运行。这使得定位和为进程编址更加困难。但是从单一主机部署方案过渡到集群部署所必须要面对的情况。
我们尝试了几种集群系统,包括Google的Kubernetes、Mesosphere的Marathon和Hashicorp的Nomad。
我们最终使用了Docker自带的Docker Swarm集群管理工具来管理我们大部分的部署。我们使用的是简单的"Docker for AWS CloudFormation"模板(https://docs.docker.com/docker-for-aws/)。
首先,针对你的系统应该运行的服务,明确地描述所期待的系统状态。这样Swarm会持续地监控容器的实际状态。当某个节点失败时,Swarm会通过将工作负载重新编排到其他节点,使得服务达到预期的状态。如果某个节点无法恢复,Swarm也会通过重新部署新服务器的方式自行修复集群。