Chef::Lxc
Installation
This library depends on ruby-lxc, a native liblxc binding.
Use standard rubygem way to install chef-lxc
$ gem install chef-lxc
Usage
There are three ways you can use chef-lxc.
- Use the command line tool
- Use the lxc resource/provider from any chef recipe
- Use the Chef::LXCHelper module from any arbitrary ruby script.
CLI examples
- Execute a chef recipe against a running container (like chef-apply)
lxc-create -n test -t ubuntu lxc-start -n test -d chef-lxc test -e 'package "screen"' # via command line
or stream a recipe
echo 'package "vim"' | sudo bundle exec chef-lxc chef -s
or supply a file
chef-lxc test /path/to/recipe.rb
Chef resource/provider examples
- Create & manage containers (inside chef recipes), named
web
require 'chef/lxc' lxc "web"
A more elaborate example,
require 'chef/lxc'
lxc "web" do
template "ubuntu"
recipe do
package "apache2"
service "apache2" do
action [:start, :enable]
end
end
action [:create, :start]
end
Use Chef-Lxc from arbitrary ruby code
-
Install openssh-server package on a vanilla un-privileged ubuntu container and change the default ubuntu user's password
require 'lxc' require 'chef' require 'chef/lxc' include Chef::LXCHelper ct = LXC::Container.new('foo') ct.create('download', nil, {}, 0, %w{-a amd64 -r trusty -d ubuntu}) # reference: http://www.rubydoc.info/gems/ruby-lxc/LXC/Container#create-instance_method ct.start sleep 5 # wait till network is up and DHCP allocates the IP recipe_in_container(ct) do package 'openssh-server' execute 'echo "ubuntu:ubuntu" | chpasswd' end
Automating multi container setup
Chef-LXC provides Chef::LXC.create_fleet
method to build chef managed
multi container system. It offers helper methods to create containers and perform common
chef administrative operations like creating roles, environments, databags etc.
Chef::LXC::Fleet
can be used with chef-zero
and berkshelf to test and prototype chef-solo or chef-client/server
managed infrastructure easily.
Following is an example:
require 'chef/lxc'
require 'chef_zero/server'
require 'tempfile'
require 'berkshelf'
cookbook_path = File.expand_path('/tmp/cookbooks')
# Use berkshelf to venodirze cookbooks
berksfile = Berkshelf::Berksfile.from_file('/path/to/Berksfile')
berksfile.vendor('/tmp/cookbooks')
# Use chef zero as chef server, tell chef-zero to bind on lxcbr interface
server = ChefZero::Server.new(host: '10.0.3.1', port: 8889)
server.start_background
# Generate temporary client key for knife operations
tempfile = Tempfile.new('chef-lxc')
File.open(tempfile.path, 'w') do |f|
f.write(server.gen_key_pair.first)
end
Chef::LXC.create_fleet('memcache') do |fleet|
# Create base container with chef installed in it
fleet.create_container('base') do |ct|
ct.recipe do
execute 'apt-get update -y'
remote_file '/opt/chef_12.2.1-1_amd64.deb' do
source 'http://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/13.04/x86_64/chef_12.2.1-1_amd64.deb'
end
dpkg_package 'chef' do
source '/opt/chef_12.2.1-1_amd64.deb'
end
directory '/etc/chef'
file '/etc/chef/client.pem' do
content ChefZero::Server.new.gen_key_pair.first
end
file '/etc/chef/client.rb' do
content "chef_server_url 'http://10.0.3.1:8889'\n"
end
end
end
# configure chef setting for the chef zero server
fleet.chef_config do |config|
config[:client_key] = tempfile.path
config[:node_name] = 'test'
config[:chef_server_url] = 'http://10.0.3.1:8889'
end
# Upload cookbooks, data bags, create roles
fleet.upload_cookbooks(cookbook_path)
fleet.create_environment('sandbox')
fleet.create_role('memcached', 'recipe[memcached]')
fleet.create_role('db', 'recipe[mysel::server]')
fleet.create_role('web', 'recipe[apache]', 'recipe[php]')
fleet.create_container('memcached', from: 'base') do |ct|
ct.command('chef-client -r role[memcached] -E sandbox')
end
fleet.create_container('db', from: 'base') do |ct|
ct.command('chef-client -r role[mysql] -E sandbox')
end
fleet.create_container('web', from: 'base') do |ct|
ct.command('chef-client -r role[web] -E sandbox')
end
end
tempfile.unlink
server.stop
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request