有什么方法可以在主厨节点中实现互斥吗?
Is there any method to get mutual exclusion in a chef node?
例如,如果进程在 chef-client 为 运行 时更新节点,则 chef-client 将覆盖节点数据:
- chef-client 获取节点数据(状态 1)
- 进程A获取节点数据(状态1)
- 进程A在本地更新节点数据(状态2)
- 这个过程保存节点数据(状态2)
- chef-client 在本地更新节点数据(状态 2*)
- chef-client保存节点数据,这个节点数据不包含进程A(状态2)的变化。 Chef-client 覆盖节点数据。 (状态 2*)
同样的问题,如果我们有两个进程同时保存节点数据
编辑
我们需要外部修改,因为我们有一个很好的 UI Chef 服务器来远程管理很多计算机,显示像树(类似于 LDAP)。管理员可以从这里更新配方的值。这个项目是开源的:https://github.com/gecos-team/
虽然我们有一个信号量系统,但我们发现如果同时有两个或更多请求,我们可能会遇到并发问题:
- 常规情况是系统works
- 但有时系统does not work
编辑 2
I have added a document with a lot of information about our problem.
在生产中发现了这个,并得出结论,没有安全的方法直接编辑节点属性。留给厨师客户:-)
好消息是还有其他更可靠的方法来设置节点属性。 Chef 角色和环境都可以在客户端 运行ning 期间安全地编辑,并且仅在下一位 Chef 运行 期间生效。此外 node attribute precedence rules 确保您所做的任何设置覆盖可能由配方所做的设置。
抛出我会为这个案例做些什么作为答案:
- 有一个像这样的分布式锁机制
This
我自己并没有使用它,只是为了想法
- 构建一个 start/report/error 处理程序,它将
- 开始时获取对 1 中 DLM 中节点名称的锁定。
- 如果它不能中止 运行 或等到锁释放
- 最后(报错)释放锁。
- 修改外部系统以执行与上述处理程序相同的操作,在修改前获取锁并在完成后释放。
- 注意锁的生命周期!!!它应该比你的 Chef 运行 加上边距长,并且 UI 应该确保它的锁在写入之前仍然存在,如果没有则中止。
摆脱处理程序的一种方法(但您仍然需要 UI 的锁)是利用 reporting api(Chef 12 的高级功能,在 25 个节点下免费, 向上需要许可证)
这个有点绕,需要节点做报告(所以chef-server url应该以organizations/结尾,客户端版本应该在11.16或use the backport以上)
然后你可以问一下runs for a node,看看这个节点有没有started状态,等到结束了。
Chef 没有实现交易功能,默认情况下它也不会自动重新聚合更新的节点。它对竞争条件开放,您可以尝试通过 chef-client 运行 中更新的节点属性来减少竞争条件(就在您执行关键操作之前),但您永远不会以可靠的工作设置结束。
收敛时间越长 运行s,差距和腐败风险就越大。
Chef 的节点属性仅对 chef-client 运行ning 在节点本身上的调试或修改有用,在高度 concurrent/dynamic 的环境中几乎没有用。
我会使用 Consul.io 实时协调信号量和 key/value 配置数据。使用 consul 提供的各种接口之一(http、DNS、...),使用厨师食谱或 LWRP 访问它。
您可以向 运行 厨师客户端执行一个非常简单的推送任务(恕我直言,比厨师 "push jobs" 功能更简单、更强大,但未集成到厨师的 ACL/user 管理),这也是受保护的 by a distributed semaphore or using the "Leader Election" 功能。当然,您也必须将此逻辑添加到您的节点更新脚本中。
然后 Chef-client 将在开始时检索一个锁并阻止您在收敛时操作数据,反之亦然。
我建议避免从您的外部应用程序更新 Chef 节点数据,并将所需的节点配置移至 Chef 数据包。
所以节点会读取Chef节点数据和配置数据包,只写入节点数据。而您的外部应用程序读取两者但只写入数据包。
如果您想避免依赖其他外部服务,也许您可以使用某种时间片。
粗略地说:节点仅在奇数分钟启动 chef-client。 Api 仅在偶数分钟更新厨师数据(如果您有多个队列,则分配这些偶数分钟)。
例如,如果进程在 chef-client 为 运行 时更新节点,则 chef-client 将覆盖节点数据:
- chef-client 获取节点数据(状态 1)
- 进程A获取节点数据(状态1)
- 进程A在本地更新节点数据(状态2)
- 这个过程保存节点数据(状态2)
- chef-client 在本地更新节点数据(状态 2*)
- chef-client保存节点数据,这个节点数据不包含进程A(状态2)的变化。 Chef-client 覆盖节点数据。 (状态 2*)
同样的问题,如果我们有两个进程同时保存节点数据
编辑
我们需要外部修改,因为我们有一个很好的 UI Chef 服务器来远程管理很多计算机,显示像树(类似于 LDAP)。管理员可以从这里更新配方的值。这个项目是开源的:https://github.com/gecos-team/
虽然我们有一个信号量系统,但我们发现如果同时有两个或更多请求,我们可能会遇到并发问题:
- 常规情况是系统works
- 但有时系统does not work
编辑 2
I have added a document with a lot of information about our problem.
在生产中发现了这个,并得出结论,没有安全的方法直接编辑节点属性。留给厨师客户:-)
好消息是还有其他更可靠的方法来设置节点属性。 Chef 角色和环境都可以在客户端 运行ning 期间安全地编辑,并且仅在下一位 Chef 运行 期间生效。此外 node attribute precedence rules 确保您所做的任何设置覆盖可能由配方所做的设置。
抛出我会为这个案例做些什么作为答案:
- 有一个像这样的分布式锁机制 This 我自己并没有使用它,只是为了想法
- 构建一个 start/report/error 处理程序,它将
- 开始时获取对 1 中 DLM 中节点名称的锁定。
- 如果它不能中止 运行 或等到锁释放
- 最后(报错)释放锁。
- 开始时获取对 1 中 DLM 中节点名称的锁定。
- 修改外部系统以执行与上述处理程序相同的操作,在修改前获取锁并在完成后释放。
- 注意锁的生命周期!!!它应该比你的 Chef 运行 加上边距长,并且 UI 应该确保它的锁在写入之前仍然存在,如果没有则中止。
摆脱处理程序的一种方法(但您仍然需要 UI 的锁)是利用 reporting api(Chef 12 的高级功能,在 25 个节点下免费, 向上需要许可证)
这个有点绕,需要节点做报告(所以chef-server url应该以organizations/结尾,客户端版本应该在11.16或use the backport以上)
然后你可以问一下runs for a node,看看这个节点有没有started状态,等到结束了。
Chef 没有实现交易功能,默认情况下它也不会自动重新聚合更新的节点。它对竞争条件开放,您可以尝试通过 chef-client 运行 中更新的节点属性来减少竞争条件(就在您执行关键操作之前),但您永远不会以可靠的工作设置结束。
收敛时间越长 运行s,差距和腐败风险就越大。
Chef 的节点属性仅对 chef-client 运行ning 在节点本身上的调试或修改有用,在高度 concurrent/dynamic 的环境中几乎没有用。
我会使用 Consul.io 实时协调信号量和 key/value 配置数据。使用 consul 提供的各种接口之一(http、DNS、...),使用厨师食谱或 LWRP 访问它。
您可以向 运行 厨师客户端执行一个非常简单的推送任务(恕我直言,比厨师 "push jobs" 功能更简单、更强大,但未集成到厨师的 ACL/user 管理),这也是受保护的 by a distributed semaphore or using the "Leader Election" 功能。当然,您也必须将此逻辑添加到您的节点更新脚本中。
然后 Chef-client 将在开始时检索一个锁并阻止您在收敛时操作数据,反之亦然。
我建议避免从您的外部应用程序更新 Chef 节点数据,并将所需的节点配置移至 Chef 数据包。
所以节点会读取Chef节点数据和配置数据包,只写入节点数据。而您的外部应用程序读取两者但只写入数据包。
如果您想避免依赖其他外部服务,也许您可以使用某种时间片。
粗略地说:节点仅在奇数分钟启动 chef-client。 Api 仅在偶数分钟更新厨师数据(如果您有多个队列,则分配这些偶数分钟)。