【问题标题】:Manage conflicting roles in chef管理厨师中的冲突角色
【发布时间】:2012-11-13 18:46:35
【问题描述】:

我对厨师比较陌生,所以我可能会遗漏一些非常基本的东西。经过大量搜索,我没有找到我需要的东西,所以这里是:

在 Chef 中,我的角色相互冲突。我需要某种类型的所有服务器都具有角色 A,但具有角色 B 的服务器除外。

我能想到的最好的描述方式是举个例子:

系统日志1,系统日志2

web1、web2、web3

db1、db2

邮件1,邮件2

这个环境中的每台服务器(几十个)都有一个叫syslog_client的角色,除了syslog1和syslog2,它们需要有syslog_server这个角色。

syslog-server 和 syslog-client 角色会发生冲突,因为它们以不同的方式配置相同的软件。

这些是角色而不是配方,因为它们实际上包含多个配方。

我想过做这样的事情:

角色/base.rb:

name "base"
description "base configuration"
override_attributes(
)
default_attributes(
)
run_list(
  "recipe[one]",
  "recipe[two]",
  "recipe[three]",
  "role[uno]"
)

unless node[:roles].include?('syslog_server')
  run_list('role[syslog_client]')
end

问题是此时节点对象不存在。我曾考虑将其移入食谱中,但我也想不出一个好的方法来做这件事。我能够在基本配方中使用它:

unless node[:roles].include?('syslog_server')
  node[:roles]+=['syslog_client']
end

这会将 syslog_client 添加到角色属性(或不正确),但它从未真正运行 syslog_client 角色。

我考虑过将 syslog_client 移动到一个独立的配方而不是一个角色中,并将角色属性移动到环境中。这会起作用,因为这样我就可以打电话给include_recipe "syslog::client"。问题是我们几乎所有的食谱都是从角色分配的(而不是从其他食谱中分配的),我担心做出这种改变会造成一次性的难以跟踪。除此之外,正如我已经提到的,这些实际上是几个食谱,因此将它们作为一个食谱添加并不理想。

在我目前工作的环境中,我们有许多不同的服务器类型/角色,向它们添加角色[syslog_client] 是可行的,但并不理想。由于有多个人致力于此,似乎有人会忘记将配方添加到新角色。

在理想的世界中,像我的第一个解决方案这样的解决方案是可能的,因为这使我们能够尽可能保持环境的一致性。不过,我对其他选择持开放态度。

最后,我想我需要有人告诉我如何:

  1. 使第一个解决方案起作用。仅当另一个角色不存在时才将角色添加到运行列表中
  2. 如果我不能获得第一名,我想就使用我列出的方式或其他我没有想到的想法来实现这一目标的最佳方式提出意见

如果我遗漏了有关我们厨师设置的任何有用的详细信息,请告诉我。

免责声明:上面的示例实际上是我实际尝试实现的非常简化的版本。我什至没有使用 syslog,但它所服务的公司非常注重安全,并且不会对公开发布他们的环境细节感到满意。如果我遗漏了任何内容并且需要添加更多信息,我会尽可能详细。

【问题讨论】:

  • 嘿,本,也许我对你的设置感到困惑,但为什么你没有一个单独的服务器角色应用于这两个不调用 syslog_client 的节点?如果您有单独的客户端和服务器角色,您可以从指定 syslog 角色开始,然后指定其余所需的配方。我想我不明白你是如何产生冲突的,除非你试图把东西归为一个角色。
  • 这正是问题所在。此角色是应用于所有服务器的“基本”角色。它配置用户、服务器上的一些基本环境等。通过将 syslog_client 添加到基本角色,我们能够确保每个服务器都获得 syslog_client。但我希望能够告诉 syslog_server 角色否定 syslog_client 角色。
  • 基本角色中是否还有其他服务器和客户端共有的内容?我想我只会为你需要的任何东西设置一个基本角色,然后再调用一个服务器或客户端角色。本质上是在基本配置和任何特定于节点的配置之间添加另一个角色级别。抱歉,如果我遗漏了您所做的区分。
  • 是的,基本角色包含许多配置项,每个服务器都会获得。这是一个设计决策(不是我做出的),已经在多个数据中心的多个生产集群中使用,并且很难改变。这里的想法是将 syslog_client 角色包含在基本角色中(因为它将在所有服务器上运行,但只有 1% 的服务器),然后如果 syslog_server 角色在 run_list 中,则否定 syslog_client 角色。我意识到还有其他设计选择,但保持基本设计对公司很重要。
  • 如果在 syslog_client 角色后添加 syslog_server 角色到 run_list 中,那么 syslog_server 将覆盖 syslog_client 提供的配置。

标签: conflict roles chef-infra


【解决方案1】:

扩展上面所说的创建两个角色的问题。一个客户端和一个服务器

客户端角色包括基础角色和客户端功能。它将通过在所有其他角色中用此角色替换对“base”的引用来应用于所有服务器。这意味着这些角色仍然会获得基础,但也会获得客户。

服务器是一个独立角色,仅适用于那些服务器,具有基础角色,然后是服务器角色?

这样,客户端和服务器都可以将基本角色应用到它们身上,而无需复制基本角色的定义。您仍然可以根据需要管理该基本角色,但在创建角色时使用聚合?

创建新角色时,用户不会从添加 base 开始,而是添加 syslog_client 角色,这也为他们提供了 base。

对我来说,这感觉就像 Chef 在推动您创建角色的方式。我们拥有的是适用于所有服务器的 1 个角色,其中一些适用于 1 个服务器子类型,但不适用于其他服务器。这样一来,我们应用的叶子角色实际上由 4 或 5 个其他角色组成。以无需逻辑即可共享的方式对共同点进行建模?

另一种选择是将客户端配方添加到每个节点,并且第一个执行步骤是检查节点角色,如果它说服务器基本上只是跳过配方执行?哪个与您要用于添加配方的逻辑相同,但它会存在于配方中并控制执行?

unless node[:roles].include?('syslog_server')
   #Do your client install
end

【讨论】:

  • 这基本上就是我所做的:unless node[:roles].include?('syslog_server')我对这个解决方案不满意,它已经导致了混乱,但我不得不从这个问题上继续前进,这是我能做到的最好的在规定的时间内做。我已经接受了你的回答,因为我自己再也没有回来发布它。感谢您的建议
猜你喜欢
  • 1970-01-01
  • 2013-11-03
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多