2013-11-21 2 views
0

예,이 모든 것을 처리하기 위해 "spiceweasel"이라는 도구가 있지만 정말 궁금합니다. 어떻게 그리고 왜 셰프에서 그렇게 작동하는지 궁금합니다.노드의 상태를 덮어 쓰지 않고 어떻게 업데이트 할 수 있습니까?

셰프는 설명 된 환경의 전체 저장소를 갖기에 좋은 아이디어를 제공하지만,이 아이디어는 훌륭하지만 예상대로 노드가 작동하지 않는 것 같습니다.

여기 상황은 다음과 같습니다. 클러스터에 bootstrapedprovisioned 노드가 이미 있습니다. 아시다시피, 각 노드는 내가 정의 할 어떤 간격으로 chef-client을 실행합니다. 그래서 각 노드는 무작위 간격으로 조리법을 다시 실행하여 아무런 변화가 없는지 확인하고 변경 사항이 있으면 다시 변경합니다.

따라서 nodes/ 폴더가 저장소에 있습니다. knife upload /nodes을 수행 할 때 모든 노드 구성이 으로 업데이트되어야합니다.이지만 이제 은 노드 상태를 완전히 덮어 씁니다. 왜 이것이 나쁜가? 왜냐하면, 내가 노드 구성 파일을 편집하고 chef-server에 업로드 한 다음 노드 상태가 다음 chef-client run 작업까지 리셋한다고 가정 해 보겠습니다. 나는 다른 노드에있는 cookbook/role을 가지고 있으며 특정 노드를 소유하고있다. 노드 중 하나에서 chef-client run이 수행 될 때 다른 노드의 IP를 찾지 못하고 전체 요리 책이 실행되지 않을 큰 기회가 있습니다!

요리 책에 노드 상태를 사용하는 것이 좋겠지 만, 어딘가에 있습니다 ... 이제는 업데이트 노드 상태로 덮어 쓰지 말고 옵션을 사용하는 것이 좋습니다.

그래서 질문입니다 : 노드의 상태를 파괴하는 대신 업데이트 할 수 있습니까?

답변

2

요리사 서버에서 기존 노드 객체를 가져 와서 로컬 값으로 업데이트하고 다시 저장하는 칼 플러그인을 작성할 수 있습니다.

나는 (원래 Chris Gaffney에 의해) 지금 몇 시간 동안 this plugin를 사용

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 

그냥 오래된 knife node from file my.node.json 대신 새 명령

knife node update from file my.node.json 

.chef/plugins/knife/node_update_from_file.rb에서 요리사 저장소에 넣고 사용

+0

이것은 실제로 훌륭합니다 !!! 팝업창이 나타나지 않으면 답변을 수락했습니다. 저는 실제로 chef-server가 그런 식으로 행동해야하는 이유에 관심이 있습니다. 이것이 요리사 repo 자체에있을 수있는 것은 정말로 멋지다! !! – holms

1

노드의 모든 정상/무시/자동 속성을 저장하고 업데이트 할 수 있습니다. 너라면 상관 없어.

  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 
관련 문제