2013-11-21 46 views
0

是的,我知道,我們有一個名爲「spiceweasel」的工具來處理所有這些,但我非常好奇,它是如何以及爲什麼它在主廚中以這種方式工作。如何更新節點的狀態而不是覆蓋它?

廚師帶來了一個很好的想法,有一個你描述的環境的整個存儲庫,這個想法是偉大的,但節點似乎並不像我期望的那樣工作。

所以出現這種情況: 您有廚師服務器/工作站設置,並且您的羣集中已有bootstrapedprovisioned節點。如您所知,每個節點在某個時間間隔運行chef-client,我將定義。因此,每個節點都會按照隨機間隔重新運行食譜,檢查是否沒有機會,如果發生變化 - 它會變回原處。

因此,您的資料庫中有文件夾nodes/。而當你做knife upload /nodes時,所有節點的配置必須是更新了,但現在它完全覆蓋了節點的狀態。那麼爲什麼這是不好的?因爲,假設我編輯了節點配置文件並將其上載到主服務器,則節點狀態將重置,直到下一次chef-client run操作。我有一個駐留在另一個節點上的cookbook /角色,它檢查特定節點(它擁有特定角色)的IP。有一個很大的機會,當chef-client run將在其中一個節點上執行時,它不會找到另一個節點的IP,整個食譜將無法運行!

也許是錯誤的食譜使用節點狀態,但嘿,這是所有的地方..所以現在會是不錯的選擇,只是爲了UPDATE節點狀態,而不是將其覆蓋。

所以問題是:是否有可能更新節點的狀態,而不是銷燬它?

回答

2

您可以編寫一個knife插件,從廚師服務器獲取現有節點對象,使用本地值更新並再次保存。

我現在用this plugin一段時間(最初由Chris Gaffney):

class NodeUpdateFromFile < ::Chef::Knife 
    deps do 
    require "chef/node" 
    require "chef/json_compat" 
    require "chef/knife/core/object_loader" 
    end 

    banner "knife node update from file FILE (options)" 

    def loader 
    @loader ||= ::Chef::Knife::Core::ObjectLoader.new(Chef::Node, ui) 
    end 

    def run 
    update = loader.load_from("nodes", @name_args[0]) 
    begin 
     node = ::Chef::Node.load(update.name) 
    rescue Net::HTTPServerException 
     ui.info("Could not load existing node #{update.name}, assuming new node.") 
     node = ::Chef::Node.new 
     node.name(update.name) 
    end 

    # Replace attributes, run_list, and chef_environment from the new node 
    # definition. 
    node.normal_attrs = update.normal_attrs 
    node.override_attrs = update.override_attrs 
    node.default_attrs = update.default_attrs 

    node.run_list.reset!(update.run_list) 
    node.chef_environment(update.chef_environment) 

    # Expand the run_list in case it has changed 
    node.expand! 
    node.save 

    output(format_for_display(node)) if config[:print_after] 

    ui.info("Updated Node #{update.name}!") 
    end 
end 

只要把它放到你的廚師庫中.chef/plugins/knife/node_update_from_file.rb並使用新的命令

knife node update from file my.node.json 

而不是舊knife node from file my.node.json

+0

這實際上是輝煌!如果沒有任何東西會彈出,我已經接受了你的回答,但我確實對主廚服務器的行爲感興趣。這真的很好,這可以在廚師回購本身! – holms

1

您可以保存和更新節點每個t的所有正常/超馳/自動屬性如果你不介意的話。

  1. 執行knife node show your-node-name --format json -l > nodes/your-node-name.json轉儲所有節點屬性。注意參數-l表示長輸出,包括正常,覆蓋和自動屬性。
  2. 更新它
  3. 執行knife node from file nodes/your-node-name.json

這就意味着你保存和更新所有屬性,所有的時間。

+0

如果角色和食譜沒有任何變化,是否有可能改變節點狀態?如果它不會,那麼這是完美的解決方案:)並且上面的插件可能也是一樣的 – holms

+0

@holms它只是轉儲所有節點屬性,包括正常,覆蓋和自動,所以是的,那就是節點狀態。但是,每個節點通常需要30KB,所以從操作角度來看效率不高。 – shawnzhu

0

霍爾格的答案是不適合我的環境下,用自己的插件許多自動生成的屬性在node.default_attrs = update.default_attrs

被刪除,因此,我的解決問題的方法是疊代的更新節點屬性,並將它們添加到節點廚師服務員。由此產生的代碼是:

class NodeUpdateFromFile < ::Chef::Knife 
    deps do 
    require "chef/node" 
    require "chef/json_compat" 
    require "chef/knife/core/object_loader" 
    end 

    banner "knife node update from file FILE (options)" 

    def loader 
    @loader ||= ::Chef::Knife::Core::ObjectLoader.new(Chef::Node, ui) 
    end 

    def run 
    update = loader.load_from("nodes", @name_args[0]) 
    begin 
     node = ::Chef::Node.load(update.name) 
    rescue Net::HTTPServerException 
     ui.info("Could not load existing node #{update.name}, assuming new node.") 
     node = ::Chef::Node.new 
     node.name(update.name) 
    end 

    # Replace attributes, run_list, and chef_environment from the new node 
    # Note: With this appproach attributes will never be removed from the chefserver 
    update.normal_attrs.each { |key, value| node.normal_attrs[key] = value } 
    update.override_attrs.each { |key, value| node.override_attrs[key] = value } 
    update.default_attrs.each { |key, value| node.default_attrs[key] = value } 

    node.run_list.reset!(update.run_list) 
    node.chef_environment(update.chef_environment) 

    # Expand the run_list in case it has changed 
    node.expand! 
    node.save 

    output(format_for_display(node)) if config[:print_after] 

    ui.info("Updated Node #{update.name}!") 
    end 
end 
相關問題