使用 MCollective 进行编排
我最初从事系统管理工作是因为我热爱学习计算机知识,并且我认为这是一个总能让我学到新东西的职业。多年后的今天,这个预测被证明是正确的,而且似乎总有新的东西需要学习。特别是,时不时会出现一项新技术,极大地改变了系统管理员的工作方式。例如,在 2012 年 10 月号的 LJ 中,我写了一篇题为“如何部署服务器”的文章,其中我描述了系统管理员部署服务器的演变过程,从手工定制配置,到镜像,到安装后脚本,最终到配置管理。
因此,在本文中,我将扩展这个概念,讨论如何使用编排工具(特别是 MCollective)来管理服务器安装后的编排任务。已经有很多 MCollective 安装指南,所以我在这里不再重复;相反,我的目标是提供一些示例,说明这些工具如何进一步自动化管理任务,并描述我个人如何使用它们。虽然我专门讨论 MCollective,但这些相同的概念可以被改编并应用于任何其他编排工具。
如今,配置管理仍然是系统管理员配置服务器最流行的方式之一,但随着时间的推移,许多管理员开始将这些工具从配置管理推向所谓的编排。编排指的是帮助您以有条不紊、分阶段的方式在您的环境中推送更改(特别是软件安装和更新)的工具。
虽然一些管理员可能可以接受随机推送软件更新,但如果您想要平稳的升级,通常您会希望遵循一种方法,即您可能首先更新一台服务器,然后在成功的情况下,在更新其余服务器之前再更新几台。在更新软件之前,您可能需要通知上游系统,以便它们可以停止发送流量,并且在您更新软件之后,您可能需要重新启动服务。这个过程并不新鲜;只是在过去,管理员会通过手动登录到一台台机器,或者编写自定义脚本来完成这项工作。使用编排工具,您可以从一个中心位置执行这些相同的步骤。
对于像 Puppet 和 Chef 这样的工具,配置管理和编排之间的界限比 SaltStack 或 Ansible 更清晰。虽然 Puppet 和 Chef 可以以无主节点的方式运行,但默认方法是让客户端定期签入主服务器,以查看它们是否符合中心配置,如果不符合,则更改直到符合为止。通常,您会让客户端以某种随机方式签入主节点,或者以其他方式向它们发送触发器以应用更改。
由于像 SaltStack 和 Ansible 这样的工具在 SSH 之上工作,它们已经包含一个编排组件,允许您从中心位置以分阶段的方式触发某些类型的更改。虽然您可以使 Puppet 和 Chef 执行编排,但许多尝试过的管理员最终会感到沮丧,并用其他工具替换它们,而不是意识到这些工具非常有能力完成它们被构建来完成的任务,但只是在编排方面不太强大。
当我试图使用 Puppet 来分阶段进行软件更新时,我个人也遇到了类似的令人沮丧的情况。Puppet 在配置管理方面做得很好,但在我的经验中,它对于编排来说并不理想。我没有抛弃 Puppet,而是简单地用一个非常强大的工具 MCollective 补充了它,MCollective 明确地用于编排,并且与 Puppet 集成良好。
MCollective 允许您发送命令,查询特定 Puppet facts 的值,启动和停止服务,查询和更新软件,甚至启动 Puppet 本身。MCollective 还可以使用 Puppet 使用的 Facter 中的相同 facts 来限制哪些服务器运行命令。因此,例如,您可以发送一个命令,该命令仅在运行特定 Linux 发行版的机器上执行。
虽然存在许多编排工具,但它们中的大多数都采用了“美化后的 SSH for 循环方法”,最终结果是一些中心化的管理主机,该主机在各处都具有 SSH root 访问权限,并且一次在一台服务器上运行命令。MCollective 具有强大的安全模型,您的命令被限制为每个客户端上存在的特定插件,并且当您从管理节点运行命令时,它会使用您用户的本地密钥签名并发送到中央作业队列。每个客户端都会检查该命令是否旨在用于它,如果是,它会从队列中拾取作业,验证签名,并且如果安装了插件,则只会执行该命令。使用这种安全模型,攻击者无法破坏作业队列并注入新作业,因为他们无法对其进行签名,并且如果攻击者破坏了管理节点,他们将被限制为您已启用的任何插件。此外,由于 MCollective 使用作业队列,命令并行运行,因此发送到 50 台服务器的命令应该与发送到一台服务器的命令一样快地返回。
与其描述每个默认的 MCollective 插件及其参数,不如通过演练 MCollective 如何帮助自动化系统管理员这些天经常执行的任务(不幸的是):修补 OpenSSL 中的安全漏洞,来更好地说明 MCollective 作为编排工具。管理员必须在每台服务器上手动执行的基本步骤如下:
-
检查服务器上安装的 OpenSSL 版本。如果不是最新版本,则继续执行其余步骤。
-
更新 OpenSSL。
-
确认 OpenSSL 软件包现在是已修补的版本。
-
重新启动主机上任何使用 OpenSSL 的服务(如 Apache、nginx 或 PostgreSQL),以便它们加载新的库。
虽然您当然可以使用配置管理工具来确保您始终运行最新版本的 OpenSSL,但重新启动任何使用 OpenSSL 的服务的过程可能不是您希望在客户端下次签入时随机发生的事情。以下是如何使用 MCollective 从中央管理主机执行上述步骤。
package
插件允许您查询系统上的软件包,并且此特定命令同时轮询您环境中的所有主机,并返回每个主机拥有的 OpenSSL 软件包的版本
mco package openssl status
您还可以使用 package 插件命令来更新软件包,并且此特定命令将您环境中每台主机上的 OpenSSL 更新到最新版本
mco package openssl update
在输出中,它将返回一个完整统计,显示有多少主机安装了 OpenSSL 以及版本。
service
插件允许 MCollective 启动、停止、重新启动和查询系统上 init 服务的状态。此特定命令同时重新启动您环境中每台主机上的 nginx 服务
mco service nginx restart
任何没有 nginx 服务的主机都将安全地不执行任何操作。您可以将上述命令中的 nginx
替换为您系统上的任何其他 init 服务。
就是这样。通过三个命令,我可以修补 OpenSSL 并重新启动整个环境中的 nginx。如果我只需要修补 bash(例如在 Shellshock 漏洞的时代),我可以使用单个 mco package bash update
命令来完成。
当然,大多数管理员都不希望同时在每台服务器上应用命令(尤其是重新启动命令)。相反,您希望一次对环境的某些部分进行分阶段操作。最简单的方法是使用 -I
参数,该参数允许您将命令应用于特定服务器。因此,例如,您可以像这样仅在 web1.example.com 上重新启动 nginx
mco service nginx restart -I web1.example.com
MCollective 允许您对命令应用非常复杂的过滤器,以便它们仅应用于具有 -W argument
的特定主机组。例如,如果您只想在运行 Debian 8.5 的主机上更新 OpenSSL,您可以键入
mco package openssl update -W "operatingsystem=Debian
↪operatingsystemrelease=8.5"
更重要的是,由于这些过滤器可以基于 Facter facts,因此您不必像在 SSH for 循环脚本的糟糕旧时代那样维护和更新本地服务器类别列表。因此,例如,如果您在 AWS 中启动一台新的 Debian 8.5 服务器,您运行的下一个恰好引用发行版版本的 MCollective 命令将在结果中返回该服务器,而无需您执行任何操作。您甚至可以使用 mco find
命令来返回与特定 fact 匹配的所有服务器的列表
mco find -W "operatingsystem=Debian operatingsystemrelease=8.5"
您可以使用 facter 命令的输出中显示的任何 facts,如果您使用 Puppet,您还可以利用 Puppet 中的任何自定义 facts。因此,例如,我利用这一点的方式是根据主机名中的数字将我的主机分成不同的高可用性组。在我的例子中,当我在 AWS 中创建主机时,我将可用区分为三个组,主机名中的数字反映了这些组之一。因此,例如,主机名中带有 1、4 或 7 的所有主机都将位于一个可用区中;2、5 和 8 将位于另一个可用区中;3、6 和 9 将位于另一个可用区中。然后,我在 Puppet 中设置一个名为 hagroup 的自定义 fact,根据主机属于这三个组中的哪一个,将其设置为 a、b 或 c。因此,如果我想跨所有服务器更新 OpenSSL,但仅以容错方式重新启动 nginx,我可能会这样做
mco package openssl update
mco service nginx restart -W hagroup=c
这样,我只在三分之一的环境中重新启动 nginx。如果出现某种问题,环境的其他三分之二将正常运行。然后我会等待该组中的所有 nginx 主机返回,并为 hagroup=b
然后最终为 hagroup=a
重复 nginx restart
命令。当我更新可能崩溃的软件或在更新后自动重新启动服务的软件包时,我还会将软件包更新命令限制为特定的 hagroup。
MCollective 的优点在于,由于您可以根据在每个系统上自动设置的 facts 来限制它,因此特别容易创建 shell 脚本,这些脚本围绕一组 MCollective 命令,以一致但快速且自动化的方式执行常见的系统管理任务(例如,升级 OpenSSL)。您还可以使用自己相对容易编写的自定义插件来扩展 MCollective。
在我的下一篇文章中,我计划描述我如何包装一系列 MCollective 命令,包括我们内部编写的一些自定义插件,以自动化您通常手动执行的所有步骤,以升级生产系统上的内部软件。