使用容器还是使用类似Chef、Puppet这类的配置管理工具?

jopen 8年前

容器会取代你对配置管理的需求吗?或者说两者可以共存吗?它们应该如何共存?本文主要对比了传统的配置管理和现在比较火的容器管理之间的差别,并对两者分别进行了概括,可以让读者初步了解两者之间的区别,并感受到容器技术的力量。

每一个开发和运营团队都有着或多或少相同的目标,编写干净的、可维护的和高性能的代码,尽可能在不宕机的情况下部署代码,并为用户带来极速和愉悦的体验。增加部署次数,但却要求不宕机,这谈何容易?我想实现这个目标的方法少说也有几百个,我们需要建立一个托管平台,这个平台上要有大量系统管理员过去通常手工操纵的东西。

现在『平台』这个术语有些被过度使用了,在这里,平台是指运行代码的计算机以及运行的方式,具体到实际环境,平台可能是你机柜里的一台服务器,一些Shell脚本,也可能是一个公有的PaaS平台,也可能是牛逼哄哄的AWS或者其它。

配置管理回顾

大约一年之前,理论上最好的方法是使用配置管理工具来自动化服务器基础设施以及部署工作流,一些比较流行的工具包括:

使用配置管理工具,你需要编写代码来描述你希望如何安装和配置系统的一些组件。当你在服务器上执行代码的时候,它应该在理想状态下结束运行。使用这种工具的好处是你可以抽象掉一些各种不同的操作系统在处理类似包管理这样的功能时所带来的不同

例如,你可以写一个bash脚本用来在Ubuntu或Debian上安装libxml2:
#!/bin/bash  apt-get install -y libxml2

但是,当你在CentOS或者Fedora上使用这个脚本的时候会发生什么呢?它可能无法正常运行,因为这些发行版使用的是不同的包管理器。

取而代之,你可以用Chef写一个代码块,它可以抽象掉不同的发行版之间的差异。你可以在libxml2包存在的任何地方执行这个相同的Chef代码,它都会正常运行。
package “libxml2” do  action :install  done

用以部署的配置管理

因为我对Chef非常熟悉并且在脑海中仍然记忆犹新,所以我将讨论一下它的配置资源和我在使用时碰到的一些陷阱。Chef的配置资源基于Capsitrano,Capsitrano被视为代码部署的最好选择,所以我这里所写并非是要唠叨它。

在你的Chef recipe代码中,配置资源的语法其最简单的形式看起来像这样:
deploy 'private_repo' do  repo 'git@github.com:acctname/private-repo.git'  user 'ubuntu'  deploy_to '/tmp/private_code'  ssh_wrapper '/tmp/private_code/wrap-ssh4git.sh'  action :deploy  end

chef-client通过某种方式的循环保持单一运行时,在同一个服务器上部署多个项目的现象并不少见。

一个这样的简单示例如下:
%w(project1 project2).each do |project|  deploy ‘#{project}’ do      repo 'git@github.com:acctname/#{project}-repo.git'      user 'ubuntu'      deploy_to '/var/www'      ssh_wrapper '/tmp/private_code/wrap-ssh4git.sh'      action :deploy  end  done

对于这种方式如何结束运行,存在一些问题:
  1. 如果项目1由于某种原因部署失败,比如Git的仓库权限问题,而你并没有处理这样的错误,接下来会导致后续的部署接连失败。
  2. 如果你必须通过bundler、npm或者类似的工具构建部署模块,势必运行会非常缓慢,在某些情况下可能会花费几分钟甚至更长。如果模块构建失败,Chef会崩溃,除非你非常明智地提前考虑到这种情况。
  3. 通常情况下,从Git拉取很慢。
  4. 如果GitHub崩了,你就无法部署。如果你正在新服务器的引导过程中自动扩展和部署代码,碰到这种情况是非常糟糕的。

围绕这些问题有很多解决办法,比如提前构建模块并将其存储在向s3这样的对象存储库中,将你的recipe拉到本地解压而不是在云端构建他们。还有一些人将他们的GitHub仓库映射到一个本地服务器,然后从本地服务器拉取。总体来说,我的观点是,使用配置管理工具是非常的复杂并且很容易出错

容器回顾

容器是时下的新宠,但它绝不是一项新技术。从2.6.24版本开始,由于加入了cgroup的支持,Linux内核已经支持容器。谷歌已经使用了十几年来支持他们巨大的全球性基础设施。在过去的两年里,像Docker这种初创公司以及一些大型企业如红帽、亚马逊、谷歌和IBM在他们的主机产品中增加了对容器的支持,这已经使得容器在开发者和运维工程师中成为了最流行的话题。通过使用Linux中现有的工具如cgroups和 namespace,并且使得它们对于普通用户来说更加简单和方便,Docker产生了巨大影响。

容器使应用程序的跨平台可移植性比以往任何时候都更容易,它解决了开发环境与生产环境差异的老问题。作为曾经的运维工程师,我不记得已经听到过多少次这种声音,“生产环境出问题了…代码在本地运行的很好”。这就造成了开发人员编写代码和运维团队部署代码出现分歧而不是相互协作的现状。

容器的优势

相比配置管理系统来说,特别是谈到部署的时候,容器有着明显的优势。
  • 所有原本在你的cookbook、playbook、manifest等文件中的逻辑现在都写在Dockerfile中,Dockerfile直接依附于应用的仓库,它被设计用来构建。这就意味着,事情会更加条理并且管理Git仓库的人也可以修改和测试应用程序的自动化。
  • 对于开发者来说,容器或是Docker比他们绞尽脑汁去折腾本地部署要容易的多,它消除了整个团队要理解如何使用你所选择的、与Vagrant紧密联系的配置管理系统的需求。
  • 所有应用程序的依赖关系都与容器捆绑,这就意味着在部署的时候没有必要在云端的每台服务器上去构建。这会使得部署和回滚更加迅速。
  • 由于无需每次部署都从Git上拉取,这就消除了GitHub中断的风险并且使你避免了无法部署。当然,如果你依赖 DockerHub 或其他托管镜像注册表,还是会有可能碰到这个问题。
  • 容器促成标准化,这使得像集中式日志记录,监测和指标这样的系统,无论容器中运行的是什么,都能够轻松地卡入到位。总的来说,这将对部署时的问题监测以及轻松地推行这类监控解决方案的能力产生巨大影响。

但是,仍然有些不足,对吗?嗯…是的。
  • Dockerfile不会给你同配置文件一样的控制权,因为你的应用程序在各个环境如dev、staging、production之间切换。你会遇到这种情况,你的Dockerfile必须根据环境变量调用外部脚本来编辑云端中Docker镜像里的配置文件。在某些情况下,你甚至可能需要针对每个环境编写不同的Dockerfile,如果你的应用程序没有遵循“十二要素应用宣言”的最佳实践,这通常会是一个问题。
  • 关于 Docker的安全模式,有很多负面的说法,即使在运行过程中孵化出一个竞争性的容器。虽然最近有可能在容器内确认各个层的校验和,但是从长期来看,这是不可能的。一些掌控中间层的人可能毫不费力就能污染下层容器。

配置管理和容器可以兼容吗?

当然可以。

即使不是全部的也有相当大的一部分流行的配置管理系统拥有针对Docker集成的hook。Chef有一种集成方案,允许你使用Chef cookbook和recipe构建Docker镜像以及管理如何把你的容器部署到服务器上。Ansible也有完成类似目标的集成。

有些情况下,我会说:“是的,可以同时使用两者”:

你已经使用了其中一种配置管理系统并且你想尝试使用容器。

这将是很容易的尝试,你可以得到一些即时的反馈,看看是否要继续深入到更加复杂或全部功能的主机平台。对于你的基础设施,所有需要你真正改变的是增加Docker并将它作为应用程序的包装,你会继续以同样的方式将它们部署到同一服务器。虽然这样有些不妥,但因为使用了群集托管平台,便可以显著提高资源利用率,并能为你节省很多资金。

你在部署无法轻易在容器内运行的东西。

有一些确实比较古老的软件有时需要你去运行和管理,其中有一些不能很好地与容器兼容,使得它们自动安装和管理的唯一方法是使用配置管理。如果你遇到了使用容器时不会遇到的严重的合规性要求或者要求你在特权模式下运行它们,这也会是一个潜在的问题。

你应该同时使用两者吗?

理想状况下,答案是No。随着全栈容器管理系统的发布,在2015年,你大可不必担心要同时使用两者才能够完全自动化你的基础设施。当然,一些容器管理系统确实需要配置管理来自动化它的配置…我猜测他们可能思考地不够透彻。

一般来说,如果你要同时使用两者:
  • 配置管理将只用于安装Docker,业务流程系统,配置PAM/ SSH身份验证和调整OS的sysctl值。基本上不涉及应用程序的部署。
  • Docker和你选择的业务流程系统用来运行应用程序和特定的软件包。

最好选用单一的标准来自动化托管环境,这使得团队的新成员能够更加容易的加快进度,同时也使得公司内部更多的团队加入进来,并共同出力来修改和改进整个基础设施。

你对此有何感想?欢迎在评论中分享你的看法!

原文链接:Containers Vs. Config Management (翻译:李加庆来自:http://dockone.io/article/717