Virtualization

for developers

Lyubomir Popov / @lpopov

openfest-logo

Reasons to virtualize

  • Multiple projects depending on different kinds of software
  • Multiple projects depending on different versions of the same software
  • Decreases setup time for a new developer joining the project
  • Increases chances of successful deployments by mirroring production environment
  • Reuse Puppet recipes in production and development environments
  • Isolated environments
  • Legacy applications
  • 'Works on my machine' syndrome

What is VirtualBox?

  • Hypervisor for x86 computers
  • Supports the creation and management of guest virtual machines running versions and derivations of Windows, Linux, BSD, OS/2, Solaris, Haiku, OSx86 and others
  • Software-based virtualization
  • Hardware-assisted virtualization ( Intel's VT-x and AMD's AMD-V )

What is Vagrant?

  • Command line tool written by Mitchell Hashimoto
  • Automates VM creation with VirtualBox, VMware, AWS, Digital Ocean
  • Integrates with provisioning tools like shell scripts, Chef, Puppet and Ansible
  • Runs on Linux, Mac OS X and Windows

Why use Vagrant?

  • You can create VMs quickly and easily
  • You can reproduce exactly the same environment on different systems
  • You need to keep only a small number of text files, to recreate an environment

Vagrant commands


$ vagrant init user/box   # Create Vagrantfile for specified base box
$ vagrant up              # Create a VM if needed and boot
$ vagrant reload          # After every change to Vagrantfile
$ vagrant halt            # Turns off the VM
$ vagrant destroy         # Deletes the VM
$ vagrant suspend         # Suspends the VM
$ vagrant resume          # Resumes the VM
$ vagrant ssh             # Log in using ssh
$ vagrant status          # Status of the VM
                    

Getting up and running

Install Vagrant and VirtualBox

(www.vagrantup.com and www.virtualbox.org)


$ vagrant init puppetlabs/ubuntu-14.04-64-puppet
$ vagrant up 
$ vagrant ssh
                    

Vagrantfile

  • Network configuration
  • Port forwarding
  • Shared folders
  • VM configuration (RAM, CPU, Threads)
  • Provisioner setup

Vagrantfile

Created with 'vagrant init puppetlabs/ubuntu-14.04-64-puppet'


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "puppetlabs/ubuntu-14.04-64-puppet"
end
                        

Vagrantfile

Adding networking


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "puppetlabs/ubuntu-14.04-64-puppet"
  config.vm.network "private_network", ip: "10.0.1.10"
end
                        

Vagrantfile

Port forwarding


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "puppetlabs/ubuntu-14.04-64-puppet"
  config.vm.network "private_network", ip: "10.0.1.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
end
                        

Vagrantfile

Shared folders


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "puppetlabs/ubuntu-14.04-64-puppet"
  config.vm.network "private_network", ip: "10.0.1.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder "./", "/vagrant"
end
                        

Vagrantfile

VM configuration (RAM, CPU, Network)


  ...
  config.vm.box = "puppetlabs/ubuntu-14.04-64-puppet"
  config.vm.network "private_network", ip: "10.0.1.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder "./", "/vagrant"
  config.vm.provider :virtualbox do |vb|
    # vb.customize ["startvm", :id, "--type", "gui"]
    vb.customize ["modifyvm", :id, "--memory", "512"]
    vb.customize ["modifyvm", :id, "--cpus", "1"]
    vb.customize ["modifyvm", :id, "--hwvirtex", "on"]
    vb.customize ["modifyvm", :id, "--audio", "none"]
    vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
    vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
  end
end
                        

Vagrantfile

Provisioner setup


  ...
    vb.customize ["modifyvm", :id, "--audio", "none"]
    vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
    vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
  end
  
  config.vm.provision "puppet" do |puppet|
    #puppet.manifests_path = "puppet/manifests"
    #puppet.module_path = "puppet/modules"
    #puppet.manifest_file  = "site.pp"
    puppet.environment_path = "puppet/environments"
    puppet.environment = "vagrant"
  end
end
                        

What is Puppet?

  • One of the market leaders in configuration management
  • Configuration management system that allows you to define the state of your IT infrastructure, then automatically enforces the correct state
  • Works as well on a single server, as on thousands of physical and virtual machines
  • Automates tasks that sysadmins often do manually
  • Ensures consistency, reliability and stability

Puppet Basics

  • puppet-agent, puppetserver, puppetdb
  • Resources
  • Classes
  • Modules

Puppet Resources

Definition:


                        <TYPE> { '<TITLE>':
                          <ATTRIBUTE> => <VALUE>,
                        }    
                        

Puppet Resources

Special Attributes:

  • ensure: present/absent (may take additional values depending on the resource)
  • before: Applies a resource before the target resource
  • require: Applies a resource after the target resource
  • notify: Applies a resource before the target resource. The target resource refreshes if the notifying resource changes
  • subscribe: Applies a resource after the target resource. The subscribing resource refreshes if the target resource changes

Puppet Resources

Example Part 1:


    file { 'vagrant-vhost.conf':
      path    => "/etc/apache2/sites-available/vagrant-vhost.conf",
      ensure  => file,
      source  => "puppet:///modules/apache/vagrant-vhost.conf",
      require => Package['apache2'],
      notify  => Service['apache2'],
      owner   => 'root',
      mode    => '0644',
    }
                        

Puppet Resources

Example Part 2:


    package { 'apache2':
      ensure => installed,
      before => File['vagrant-vhost.conf'],
    }
    service {'apache2':
      ensure    => running,
      subscribe => File['vagrant-vhost.conf'],
    }    
    
Package['ntp'] -> File['/etc/ntp.conf'] ~> Service['ntpd']

Puppet Classes

   class apache2 (String $version = 'latest') {
        file { 'vagrant-vhost.conf':
          path    => "/etc/apache2/sites-available/vagrant-vhost.conf",
          ensure  => file,
          source  => "puppet:///modules/apache/vagrant-vhost.conf",
          require => Package['apache2'],
          notify  => Service['apache2'],
          owner   => 'root',
          mode    => '0644',
        }
        package { 'apache2':
          ensure => $version,
          before => File['vagrant-vhost.conf'],
        }
        service {'apache2':
          ensure    => running,
          subscribe => File['vagrant-vhost.conf'],
        } 
    }

File structure


$ tree --prune puppet
puppet
└── environments
    └── vagrant
        ├── manifests
        │   └── site.pp
        └── modules
            ├── apache
            │   ├── files
            │   │   └── vagrant-vhost.conf
            │   └── manifests
            │       └── init.pp
            ├── mysql
            │   └── manifests
            │       └── init.pp
            └── php
                ├── files
                │   └── php.ini
                └── manifests
                    └── init.pp

12 directories, 6 files
                        

USB drive directory structure


.
├── boxes
└── packages
    ├── linux
    │   ├── packer
    │   ├── vagrant
    │   └── virtualbox
    ├── osx
    │   ├── packer
    │   ├── vagrant
    │   └── virtualbox
    └── windows
        ├── packer
        ├── vagrant
        └── virtualbox
                    

Hands-on time

  • Take a usb drive, copy and install appropriate versions of Vagrant and VirtualBox
  • Copy 'puppetlabs-ubuntu-14.04-64-puppet.box' box file
  • Run:

$ vagrant box add puppetlabs/ubuntu-14.04-64-puppet puppetlabs-ubuntu-14.04-64-puppet.box
$ git clone https://github.com/lpopov/virtualization-for-developers-workshop.git
$ cd virtualization-for-developers-workshop
$ vagrant up
                    

Links (Part 1)

Links (Part 2)

Links (Part 3)

Thank you