Berkshelf提供的含糊厨师忽略了环境版本



我们目前的设置是,我们希望重用服务器管理员提供的厨师食谱来提供我们的开发环境。问题是,我们不能更改原始食谱,也不想使用确切的食谱(因为有些部分不需要)。

与实时基础设施相比,我们将使用Vagrant管理的虚拟机,尽可能靠近实时基础设施。因此,我们的计划是在我们这边创建一本简单的食谱,要求我们的服务器提供商提供原始的服务器食谱,并调用所需的recipies。

这一切都已经很好了,食谱是从github(私人回购)下载的,作为Berkshelf的依赖项,我们的自定义食谱只是调用我们想要运行的食谱。

相应的Vagrantfile就这么简单:

Vagrant.configure(2) do |config|
config.vm.box = "bento/centos-6.7"
config.omnibus.chef_version = :latest
config.berkshelf.enabled = true
config.vm.provision :chef_zero do |chef|
chef.cookbooks_path = ['site-cookbooks']
chef.data_bags_path = "data_bags"
chef.nodes_path = "nodes"
chef.roles_path = "roles"
chef.environments_path = "environments"
chef.add_role "cms"
chef.environment = "development"
end
end

而我们的Berksfile只是:

source 'https://supermarket.chef.io'
cookbook '1000-server', git: 'git@github.com:somewhere/1000-server.git'
cookbook 'main', path: './site-cookbooks/main'

总体项目结构如下:

Root
│   Berksfile
│   Berksfile.lock
│   Vagrantfile
│
├───environments
│       .gitkeep
│       development.json
│
├───nodes
│       .gitkeep
│       vagrant-caa3c589.json
│
├───roles
│       .gitkeep
│       cms.rb
│
└───site-cookbooks
│   .gitkeep
│
└───main
│   Berksfile
│   metadata.rb
│
├───attributes
├───files
│   └───default
├───libraries
├───providers
├───recipes
│       cms.rb
│       default.rb
│       _automatic_updates.rb
│       _common_packages.rb
│       _motd.rb
│
├───resources
└───templates
└───default
motd.erb

现在的诀窍是,1000-server食谱的metadata.rb中的所有依赖项都不受版本约束。这取决于环境。

metadata.rb狙击:

depends 'apt'
depends 'automatic_updates'

development.json(来自main食谱)狙击

"cookbook_versions": {
"apt": "= 2.9.2",
"automatic_updates": "= 0.2.0",
....
}

当然,其他环境可能使用不同的版本。这种方法在与普通厨师一起部署的现场环境中非常有效。

对于使用Vagrant的开发部分,我们遇到了一些问题。在Vagrant的供应阶段,特定于环境的版本似乎被忽视了。只有当chef-zero在机器本身上运行时,环境才会请求提供的不同版本。

这一点在apt食谱中变得显而易见。在流浪者供应期间,将出售版本4.0.0(最新版本)。然而,当开发角色趋同时,会出现版本冲突,因为此环境需要版本2.9.2.

vagrant up的(部分截断的)日志为:

$ vagrant up
Bringing machine 'default' up with 'vmware_workstation' provider...
default: The Berkshelf shelf is at "C:/Users/fge/.berkshelf/vagrant-berkshelf/shelves/berkshelf20160614-11060-184lksc-default"
==> default: Sharing cookbooks with VM
==> default: Cloning VMware VM: 'bento/centos-6.7'. This can take some time...
==> default: Checking if box 'bento/centos-6.7' is up to date...
==> default: Verifying vmnet devices are healthy...
==> default: Updating Vagrant's Berkshelf...
==> default: Resolving cookbook dependencies...
==> default: Fetching 'main' from source at site-cookbooks/main
==> default: Using 1000-server (1.0.19) from git@github.com:***.git (at master)
==> default: Using apt (4.0.0)
** snip ** 
==> default: Vendoring apt (4.0.0) to C:/Users/fge/.berkshelf/vagrant-berkshelf/shelves/berkshelf20160614-11060-184lksc-default/apt
==> default: Auto-generating node name for Chef...
==> default: Preparing network adapters...
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Starting the VMware VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 192.168.218.131:22
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Forwarding ports...
default: -- 22 => 2200
==> default: Configuring network adapters within the VM...
==> default: Waiting for HGFS kernel module to load...
==> default: Enabling and configuring shared folders...
default: -- C:/Users/fge/Documents/Projects/chef-playground: /vagrant
default: -- C:/Users/fge/Documents/Projects/chef-playground/roles: /tmp/vagrant-chef/c7b0e759b945769c9873959f131fb7b0/roles
default: -- C:/Users/fge/Documents/Projects/chef-playground/nodes: /tmp/vagrant-chef/8e970870f311a0ae043f0f7907363289/nodes
default: -- C:/Users/fge/.berkshelf/vagrant-berkshelf/shelves/berkshelf20160614-11060-184lksc-default: /tmp/vagrant-chef/3bc7c75ac04521a146fc361c5902825a/cookbooks
default: -- C:/Users/fge/Documents/Projects/chef-playground/data_bags: /tmp/vagrant-chef/d6e666738afcd2f3bf01b2db89232370/data_bags
default: -- C:/Users/fge/Documents/Projects/chef-playground/environments: /tmp/vagrant-chef/d1bb590869371296e6ed41178f8b3a2c/environments
==> default: Installing Chef 12.11.18 Omnibus package...
** snip **
==> default: Thank you for installing Chef!
==> default: Running provisioner: chef_zero...
==> default: Detected Chef (latest) is already installed
==> default: Generating chef JSON and uploading...
==> default: Running chef-client (local-mode)...
==> default: [2016-06-14T09:16:29+00:00] INFO: Started chef-zero at chefzero://localhost:8889 with repository at /tmp/vagrant-chef/3bc7c75ac04521a146fc361c5902825a
==> default:   One version per cookbook
==> default:   data_bags at /tmp/vagrant-chef/d6e666738afcd2f3bf01b2db89232370/data_bags
==> default:   environments at /tmp/vagrant-chef/d1bb590869371296e6ed41178f8b3a2c/environments
==> default:   roles at /tmp/vagrant-chef/c7b0e759b945769c9873959f131fb7b0/roles
==> default:   nodes at /tmp/vagrant-chef/8e970870f311a0ae043f0f7907363289/nodes
==> default:
==> default: [2016-06-14T09:16:29+00:00] INFO: Forking chef instance to converge...
==> default: Starting Chef Client, version 12.11.18
==> default: [2016-06-14T09:16:29+00:00] INFO: *** Chef 12.11.18 ***
==> default: [2016-06-14T09:16:29+00:00] INFO: Platform: x86_64-linux
==> default: [2016-06-14T09:16:29+00:00] INFO: Chef-client pid: 4479
==> default: [2016-06-14T09:16:31+00:00] INFO: GET /organizations/chef/nodes/vagrant-caa3c589
==> default: [2016-06-14T09:16:31+00:00] INFO: #<ChefZero::RestErrorResponse: 404: Object not found: chefzero://localhost:8889/nodes/vagrant-caa3c589>
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/rest_base.rb:91:in `rescue in get_data'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/rest_base.rb:83:in `get_data'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/endpoints/rest_object_endpoint.rb:18:in `get'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/rest_base.rb:62:in `call'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/rest_router.rb:24:in `call'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/server.rb:664:in `block in app'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/server.rb:336:in `call'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/server.rb:336:in `handle_socketless_request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/socketless_server_map.rb:87:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/socketless_server_map.rb:33:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http/socketless_chef_zero_client.rb:154:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:305:in `block in send_http_request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:336:in `block in retrying_http_errors'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:334:in `loop'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:334:in `retrying_http_errors'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:299:in `send_http_request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:144:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:111:in `get'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/node.rb:604:in `load'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/node.rb:588:in `find_or_create'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/policy_builder/dynamic.rb:72:in `load_node'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/client.rb:467:in `load_node'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/client.rb:269:in `run'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:286:in `block in fork_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:274:in `fork'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:274:in `fork_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:239:in `block in run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/local_mode.rb:44:in `with_server_connectivity'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:227:in `run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:456:in `sleep_then_run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:443:in `block in interval_run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:442:in `loop'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:442:in `interval_run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:426:in `run_application'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:59:in `run'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/bin/chef-client:26:in `<top (required)>'
==> default: /usr/bin/chef-client:52:in `load'
==> default: /usr/bin/chef-client:52:in `<main>'
==> default: [2016-06-14T09:16:31+00:00] INFO: HTTP Request Returned 404 Not Found: Object not found: chefzero://localhost:8889/nodes/vagrant-caa3c589
==> default: [2016-06-14T09:16:31+00:00] INFO: POST /organizations/chef/nodes
==> default: --- POST BODY ---
==> default: {"name":"vagrant-caa3c589","chef_environment":"development","json_class":"Chef::Node","automatic":{},"normal":{},"chef_type":"node","default":{},"override":{},"run_list":[]}
==> default: --- END POST BODY ---
==> default: [2016-06-14T09:16:31+00:00] INFO: Setting the run_list to ["role[cms]"] from CLI options
==> default: [2016-06-14T09:16:31+00:00] INFO: GET /organizations/chef/roles/cms
==> default: [2016-06-14T09:16:31+00:00] INFO: GET /organizations/chef/environments/development
==> default: [2016-06-14T09:16:31+00:00] INFO: Run List is [role[cms]]
==> default: [2016-06-14T09:16:31+00:00] INFO: Run List expands to [main::cms]
==> default: [2016-06-14T09:16:31+00:00] INFO: Starting Chef Run for vagrant-caa3c589
==> default: [2016-06-14T09:16:31+00:00] INFO: Running start handlers
==> default: [2016-06-14T09:16:31+00:00] INFO: Start handlers complete.
==> default: resolving cookbooks for run list: ["main::cms"]
==> default: [2016-06-14T09:16:31+00:00] INFO: POST /organizations/chef/environments/development/cookbook_versions
==> default: --- POST BODY ---
==> default: {"run_list":["main::cms"]}
==> default: --- END POST BODY ---
==> default: [2016-06-14T09:16:59+00:00] INFO: #<ChefZero::RestErrorResponse: 412: Could not satisfy version constraints for: apt>
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/endpoints/environment_cookbook_versions_endpoint.rb:42:in `post'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/rest_base.rb:62:in `call'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/rest_router.rb:24:in `call'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/server.rb:664:in `block in app'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/server.rb:336:in `call'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/server.rb:336:in `handle_socketless_request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/socketless_server_map.rb:87:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-zero-4.6.2/lib/chef_zero/socketless_server_map.rb:33:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http/socketless_chef_zero_client.rb:154:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:305:in `block in send_http_request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:336:in `block in retrying_http_errors'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:334:in `loop'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:334:in `retrying_http_errors'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:299:in `send_http_request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:144:in `request'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/http.rb:127:in `post'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/policy_builder/expand_node_object.rb:204:in `sync_cookbooks'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/policy_builder/expand_node_object.rb:83:in `setup_run_context'
==> default: /opt/chef/embedded/lib/ruby/2.1.0/forwardable.rb:183:in `setup_run_context'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/client.rb:510:in `setup_run_context'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/client.rb:280:in `run'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:286:in `block in fork_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:274:in `fork'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:274:in `fork_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:239:in `block in run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/local_mode.rb:44:in `with_server_connectivity'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:227:in `run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:456:in `sleep_then_run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:443:in `block in interval_run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:442:in `loop'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:442:in `interval_run_chef_client'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application/client.rb:426:in `run_application'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/lib/chef/application.rb:59:in `run'
==> default: /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/chef-12.11.18/bin/chef-client:26:in `<top (required)>'
==> default: /usr/bin/chef-client:52:in `load'
==> default: /usr/bin/chef-client:52:in `<main>'
==> default: [2016-06-14T09:16:59+00:00] INFO: HTTP Request Returned 412 Precondition Failed: Could not satisfy version constraints for: apt
==> default:
==> default: ================================================================================
==> default: Error Resolving Cookbooks for Run List:
==> default: ================================================================================
==> default:
==> default:
==> default: Missing Cookbooks:
==> default: ------------------
==> default: Could not satisfy version constraints for: apt
==> default:
==> default:
==> default: Expanded Run List:
==> default: ------------------
==> default: * main::cms
==> default:
==> default:
==> default: Platform:
==> default: ---------
==> default: x86_64-linux
==> default:
==> default:
==> default:
==> default: Running handlers:
==> default: [2016-06-14T09:16:59+00:00] ERROR: Running exception handlers
==> default: Running handlers complete
==> default:
==> default: [2016-06-14T09:16:59+00:00] ERROR: Exception handlers complete
==> default: Chef Client failed. 0 resources updated in 29 seconds
==> default: [2016-06-14T09:16:59+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
==> default: [2016-06-14T09:16:59+00:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
==> default: [2016-06-14T09:16:59+00:00] ERROR: 412 "Precondition Failed"
==> default: [2016-06-14T09:16:59+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
Chef never successfully completed! Any errors should be visible in the
output above. Please fix your recipes so that they properly complete.

我当然可以将这些依赖项固定在我们的metadata.rb主文件中,但我想这会破坏这里的目的,不允许我们切换到不同的环境(例如生产),也不允许我们总是使用与1000-server食谱(或1000-server食谱的不同版本)相同的版本

我看到这个家伙在kitchen上也有同样的问题,但我想这对Vagrant来说不起作用。关于如何在环境中解决这个问题,有什么想法吗?

关于如何解决这个问题,有什么想法吗?或者这是我们

Chef Zero中的版本约束求解器故意非常简单,没有真正的Chef Server那样功能齐全。环境级别的约束通常用于生产覆盖等,而给定食谱实际需要的内容属于相关的metadata.rb文件。您可能还需要查看berks apply命令,以便在另一个方向上运行同步。

最新更新