Chef infra 如何使用chef协调服务器依赖关系?

Chef infra 如何使用chef协调服务器依赖关系?,chef-infra,configuration-management,knife,Chef Infra,Configuration Management,Knife,我们一直在使用chef进行部署,它非常适用于简单的场景。然而,我们现在想要在我们的VM基础设施上编写一个冗余的体系结构。几个框聚集在一起,但是过早地运行chef脚本将导致它们失败。例如,我们希望提供一个Windows群集。服务器1可以配置故障转移群集功能,然后尝试组成群集,但由于服务器2尚未配置,因此运行将失败 如何做到这一点?以下是我们提出的一些想法: 设计chef运行,知道它们将失败,但在不断重新运行时最终会通过。 从自动化的角度来看,这并不理想,因为反馈将变得模棱两可。运行是以预期的方式

我们一直在使用chef进行部署,它非常适用于简单的场景。然而,我们现在想要在我们的VM基础设施上编写一个冗余的体系结构。几个框聚集在一起,但是过早地运行chef脚本将导致它们失败。例如,我们希望提供一个Windows群集。服务器1可以配置故障转移群集功能,然后尝试组成群集,但由于服务器2尚未配置,因此运行将失败

如何做到这一点?以下是我们提出的一些想法:

  • 设计chef运行,知道它们将失败,但在不断重新运行时最终会通过。
    • 从自动化的角度来看,这并不理想,因为反馈将变得模棱两可。运行是以预期的方式失败,还是由于未知原因失败?这可能需要一个人来安装。

  • 当配方在服务器1上运行时,从自定义配方调用“刀子ssh”到配置服务器2。例如:

    windows_feature "FailoverClusters" do
        action: install
    end
    
    # ensure server 2 has the cluster feature enabled 
    # (this would likely be implemented as a LWRP using the  the Knife::Chef::Ssh class rather than the execute LWRP)
    execute 'knife ssh "name:Server2" "recipe[windows_cluster::secondary]"'
        action :run
    end
    
    # join the second server to this cluster (semi-pseudo code)
    windows_cluster 'server2' do
        action :join
    end
    
  • 或者,可以编写一个协调器脚本,使其调用“刀” ssh“的正确顺序。脚本将从生成计算机或开发人员框中运行:

    # ensure the failover cluster feature is enabled on the secondary server
    execute 'knife ssh "name:Server2" "recipe[windows_cluster::secondary]"'
        action :run
    end
    
    # install the failover cluster feature on the primary box and have it configure the cluster
    execute 'knife ssh "name:Server1" "recipe[windows_cluster::primary]"'
        action :run
    end
    
  • 为了解决这个问题,已经开发了不同的框架或技术

  • 在这些解决方案中,我们正朝着3(或4,如果存在的话)的方向前进。一般来说,这似乎是组织部署的最干净的方法,因为意图将存在于更高的抽象层


    处理这些场景的最佳实践或常用方法是什么?

    我建议使用Chef Search。这是逻辑工作流程

  • 在第一台服务器上运行Chef,允许cookbook在其Chef节点属性中将其设置为“master”
  • 在所有其他服务器上运行Chef,允许它们查看“主服务器”
  • 我称之为高级节点部署。首先部署一台服务器,然后部署所有其他服务器

    cookbook将具有搜索属性、根据结果查找或设置属性的代码。见下文:

    myclusternodes = search(:node, "cluster_name:clusterb")
    
    if myclusternodes != nil
      master = myclusternodes.count == 0 ? node[:ipaddress] : myclusternodes[0].ipaddress
    end
    
    node.set[:clusterb][:master] = master