使用 Puppet 实现多站点高可用性的选项

使用 Puppet 实现多站点高可用性的选项

我维护着两个数据中心,随着我们越来越多的重要基础设施开始通过 Puppet 进行控制,如果我们的主站点出现故障,那么在第二个站点上的 Puppet Master 工作就变得非常重要。

更好的方法是采用一种主动/主动设置,这样第二个站点的服务器就不会通过 WAN 进行轮询。

有没有实现多站点 Puppet 高可用性的标准方法?

答案1

Puppet 实际上非常适合多主机环境,但也有注意事项。主要注意事项是什么? Puppet 的很多部分喜欢集中化。 证书颁发机构、库存和仪表板/报告服务、文件存储和存储的配置 - 它们都处于最佳状态(或只是需要)在一个只有一个地方供它们对话的设置中。

不过,如果您在失去主站点时不介意部分功能正常丧失,那么在多主环境中让许多移动部件正常工作是相当可行的。


让我们从基本功能开始,让节点向主节点报告:

模块和清单

这部分很简单。对它们进行版本控制。如果是分布式版本控制系统,则只需集中和同步,并根据需要在故障转移站点中更改推送/拉取流程。如果是 Subversion,那么您可能希望将svnsync存储库转移到故障转移站点。

证书颁发机构

这里的一个选项是简单地在主服务器之间同步证书颁发机构文件,这样所有主服务器都共享相同的根证书并能够签署证书。这一直让我感到“做错了”;

  • 一个主服务器是否真的应该认为在客户端身份验证中为来自另一个主服务器的传入连接提供的自己的证书是有效的?
  • 这能可靠地用于库存服务、仪表板等吗?
  • 如何在以后添加其他有效的 DNS 替代名称?

我不能诚实地说我已经彻底测试过此选项,因为它看起来很糟糕。但是,根据说明,Puppet Labs 似乎并不鼓励使用此选项这里

因此,剩下的就是拥有一个中央 CA 主控。当 CA 停机时,所有信任关系仍可继续工作,因为所有客户端和其他主控都会缓存 CA 证书和 CRL(尽管它们不会像应有的那样频繁刷新 CRL),但您将无法签署新证书,直到主站点恢复或从故障转移站点的备份中恢复 CA 主控。

您将选择一个主服务器作为 CA,并让所有其他主服务器禁用它:

[main]
    ca_server = puppet-ca.example.com
[master]
    ca = false

然后,您需要让中央系统获取所有与证书相关的流量。有几种方法可以实现此目的;

  1. 使用 3.0 中的新SRV记录支持将所有代理节点指向 CA 的正确位置 -_x-puppet-ca._tcp.example.com
  2. ca_serverpuppet.conf所有代理中设置配置选项
  3. 将代理发出的所有与 CA 相关的请求流量代理到正确的主服务器。例如,如果您通过 Passenger 在 Apache 中运行所有主服务器,则在非 CA 上进行以下配置:

    SSLProxyEngine On
    # Proxy on to the CA.
    ProxyPassMatch ^/([^/]+/certificate.*)$ https://puppet-ca.example.com:8140/$1
    # Caveat: /certificate_revocation_list requires authentication by default,
    # which will be lost when proxying. You'll want to alter your CA's auth.conf
    # to allow those requests from any device; the CRL isn't sensitive.
    

这样就行了。


在我们继续讨论辅助服务之前,先来说明一下;

主证书的 DNS 名称

我认为这是升级到 3.0 的最有力理由。假设您想将一个节点指向“任何旧的工作主节点”。

在 2.7 下,您需要一个通用 DNS 名称,例如puppet.example.com,并且所有主服务器都需要在其证书中使用此名称。这意味着dns_alt_names在他们的配置中进行设置,重新颁发他们在配置为主服务器之前拥有的证书,当您需要将新的 DNS 名称添加到列表中时再次重新颁发证书(例如,如果您希望多个 DNS 名称让代理在其站点中优先选择主服务器)。。太丑了。

使用 3.0,您可以使用SRV记录。向所有客户提供此信息;

[main]
    use_srv_records = true
    srv_domain = example.com

然后,主服务器不需要特殊证书 - 只需将新记录添加到您的SRVRR 即可_x-puppet._tcp.example.com,它是组中的实时主服务器。更好的是,您可以通过为不同的站点设置不同的记录集,轻松地使主服务器选择逻辑更加复杂;“任何旧的工作主服务器,但更喜欢您站点中的主服务器” SRV;不需要dns_alt_names


报告/仪表板

这个方法最适用于集中式,但如果主站点宕机时您可以不用它,那就没问题了。只需将所有主站点配置为放置报告的正确位置即可。

[master]
    reports = http
    reporturl = https://puppetdash.example.com/reports/upload

..一切就绪。无法上传报告不会对配置运行造成严重影响;如果仪表板服务器出现故障,报告将会丢失。

事实清单

另一个值得粘在仪表板上的好东西是库存服务。按照文档中的建议facts_terminus进行设置,当中央库存服务关闭时,这实际上会中断配置运行。这里的技巧是在非中央主服务器上使用终端,这样可以实现优雅的故障。restinventory_service

facts_terminus = inventory_service
inventory_server = puppet-ca.example.com
inventory_port = 8140

将您的中央库存服务器设置为通过 ActiveRecord 或 PuppetDB 存储库存数据,并且只要服务可用,它就应该保持最新状态。


所以 - 如果你可以接受一个相当基本的配置管理环境,在这种环境中,你甚至不能使用 CA 签署新节点的证书,直到它恢复,那么这就可以正常工作 - 虽然如果其中一些组件是对分布式更加友好

答案2

Ladadadada 描述的“无主傀儡”方法是我最熟悉的(这基本上就是我们在公司使用 radmind 的方法)。我想更准确地说,它是“由外部进程同步的多个主服务器”,其中任何给定的服务器(理论上)都可以在紧急情况下为整个宇宙提供服务。

在我们的案例中,由于 radmind 的性质,我们只需将rsync记录和数据文件从已批准的主服务器发送到每个远程站点的 radmind 服务器,然后客户端从具有短主机名的服务器提取更新radmind(通过这个神奇的resolv.conf评估结果radmind.[sitename].mycompany.com- 始终是本地 radmind 服务器。如果本地服务器关闭,则很容易覆盖并指向任何其他站点的服务器)。

这种 rsync 过程可能也适用于您的情况,但与基于版本控制的解决方案相比,它可能不是最优的。


对于 puppet 或 chef,基于版本控制的系统比简单的 rsync 更有意义,原因有几个 - 最大的原因是您控制的是 puppet 脚本的版本(而不是像使用 radmind 那样控制整个操作系统映像)。基于版本控制的
管理的额外好处是,您可以让多个人同时在存储库上工作(并行性的巨大优势),您可以免费获得修订历史记录,如果有人破坏了 Puppet 环境,您可以轻松回滚(假设您正在使用,git您也拥有git blame它,它按照说明书上说的做)。
创造性的分支和合并甚至可以让您在版本控制框架内处理重大操作系统升级或其他转换 - 一旦正确完成,只需切换到新分支,(希望)生产推送就可以正常工作。

如果我在这里实现这个,我可能会利用 git 中的预提交和后提交钩子来确保提交的 puppet 配置是合理的(客户端预提交),如果是的话,则将它们推送到宇宙的其余部分(服务器端发布 - 如果您的部署策略允许这种行为,可能还会触发环境更新)。

在每个站点启动新的 puppetmaster 服务器方面,您可以简单地将 puppet 环境检出到每个远程 puppetmaster,然后使用我上面描述的 resolv.conf/hostname 技巧或重定向到本地系统的任播服务 IP,就像 Michuelnik 建议的那样(如果您想在一个站点的 puppetmaster 崩溃时自动进行故障转移,后者很方便)来确保每个站点都能看到“正确的”puppetmaster,并且不会阻塞您的 WAN 链接以尝试获取更新。


Brain Tree Payments 的员工显然已经结合了版本控制和 rsync 解决方案以及一些自定义的 Capistrano 任务 - 他们的解决方案似乎还不成熟,因为它仍然依赖于手动工作流元素,但它可以进行调整和自动化,而不需要太多工作。
我内心的偏执强迫测试人员对他们的健全性检查步骤情有独钟noop- 我内心的手动流程的憎恨者希望它周围有一定程度的自动化......

相关内容