1000 Ways to Deploy a Full Stack and Bash Ain't One

Daniel Farrell and Marcus Williams
(Red Hat and Intel)
@dfarrell07

ODL's CD Pipeline

ODL'S CD PIPELINE

Three-layer stack

ODL'S CD PIPELINE

Packaging layer

ODL'S CD PIPELINE

RPM, .deb

ODL'S CD PIPELINE

Configuration Management Layer

ODL'S CD PIPELINE

Puppet module, Ansible role

ODL'S CD PIPELINE

Pre-Configured Images Layer

ODL'S CD PIPELINE

Containers, VMs
(Docker, Vagrant base boxes)

PACKAGE LAYER

PACKAGE LAYER

Handles system-level dependencies
(Java...)

PACKAGE LAYER

Lays down the basic files

PACKAGE LAYER

Creates required users/groups

PACKAGE LAYER

Sets permissions

PACKAGE LAYER

Configures systemd

PACKAGE LAYER

RPMs and .debs

RPM

RPM

Automatically package every autorelease build

RPM

Daily latest-snapshot builds

RPM

Test resulting RPMs

RPM

Host on the CentOS Community Build System

RPM

Latest in [5,6]-testing repos

RPM

[opendaylight-6-testing]
name=CentOS CBS OpenDaylight Carbon testing repository
baseurl=http://cbs.centos.org/repos/nfv7-opendaylight-6-testing/$basearch/os/
enabled=1
gpgcheck=0

RPM

Install ODL's repo
[~]$ sudo curl -o /etc/yum.repos.d/opendaylight-6-testing.repo \
                  <URL to repo config>

RPM

Install ODL
[~]$ sudo yum install -y opendaylight
<snip>
Installed:
  opendaylight.noarch 0:6.0.0-0.1.20170405snap4741.el7
Complete!

RPM

Latest branch release/SR in [4,5]-release

RPM

Static releases/SRs in [50,51,52]-release

RPM

Manage service with systemd
[~]$ sudo systemctl start opendaylight
[~]$ sudo systemctl is-active opendaylight
active

RPM

Connect to Karaf shell, install features
$ ssh -p 8101 karaf@localhost
opendaylight-user@root>feature:install ...    

Deb

deb

Parallels RPM pipeline
Mentoring intern (Akshita Ja) to build

CONFIG MANAGEMENT LAYER

CONFIG MANAGEMENT LAYER

Installs ODL via package layer

CONFIG MANAGEMENT LAYER

Edits files to apply configuration
(Karaf features, port mappings, L3, logging, HA, security groups, IPv4 vs V6, VPP config, Java heap, user/pass...)

CONFIG MANAGEMENT LAYER

Manages ODL's systemd service

PUPPET

Puppet

IPR underway to import into ODL-managed repos

Puppet

Puppet Forge

Puppet

Well-developed API
class opendaylight::params {
  $default_features = ['config', 'standard', 'region', 'package', 'kar', 'ssh', 'management']
  $extra_features = []
  $odl_rest_port = '8080'
  $odl_bind_ip = '0.0.0.0'
  $rpm_repo = 'opendaylight-6-testing'
  $deb_repo = 'ppa:odl-team/boron'
  $log_levels = {}
  $enable_ha = false
  $ha_node_ips = []
  $ha_node_index = 0
  $security_group_mode = 'stateful'
  $vpp_routing_node = ''
  $java_opts = '-Djava.net.preferIPv4Stack=true'
  $manage_repositories = true
  $username = 'admin'
  $password = 'admin'
}

Puppet

Good OS Support

Puppet

Well tested

PUPPET

Syntax, rspec-puppet, Puppet linting
desc "Run syntax, lint, and spec tests."
task :test => [
  :syntax,
  :lint,
  :metadata_lint,
  :spec,
]

PUPPET

Coala linting
Executing section git...
Executing section spacing...
Executing section markdown...
Executing section rest...
Executing section yaml...
Executing section json...
Executing section xml...

Puppet

Beaker system testing

Puppet

Deploy against real containers/VMs

Puppet

Verify resulting state

Puppet

Repeat for various configs

Puppet

At a high level...

Puppet

In detail...

Puppet

Bringing machine 'centos-7' up with 'libvirt' provider...

centos-7 12:45:09$ yum install -y puppet

Puppet

centos-7 12:45:46$ puppet apply <test manifest>

Puppet

centos-7 12:49:37$ /bin/sh -c systemctl\ is-active\ opendaylight
active

centos-7 executed in 0.04 seconds
      should be running

Puppet

centos-7 12:49:37$ /bin/sh -c id\ odl
uid=1001(odl) gid=1001(odl) groups=1001(odl)

centos-7 executed in 0.04 seconds
      should exist

Puppet

centos-7 executed in 0.05 seconds
            should match /^featuresBoot=standard,ssh/

Puppet

Finished in 5 minutes 22 seconds (files took 1 minute 10.87 seconds to load)
132 examples, 0 failures

Puppet

Beaker is pretty great

Puppet

Daily tests in ODL CI

Puppet

desc "All tests, use containers for Beaker tests"
task :acceptance_dock => [
  :cent_5rel_dock,
  :ubuntu_5rel_dock,
  :cent_5test_dock,
  :cent_6test_dock,
]

desc "All tests, use VMs for Beaker tests"
task :acceptance_vm => [
  :cent_5rel_vm,
  :ubuntu_5rel_vm,
  :cent_5test_vm,
  :cent_6test_vm,
]

ANSIBLE

Ansible

IPR underway to import into ODL-managed repos

Ansible

Ansible Galaxy

Ansible

Good OS support
(CentOS, Fedora, Ubuntu 16.04)

Ansible

Daily tests in ODL CI

Ansible

Example: Vagrant provisioner

Ansible

At a high level...

Ansible

  # Box that installs ODL via its Ansible role on CentOS 7
  config.vm.define "cent7_ansible" do |cent7_ansible|
    # Build Vagrant box based on CentOS 7
    cent7_ansible.vm.box = "centos/7"

    # Install ODL using the Ansible provisioner
    cent7_ansible.vm.provision "ansible" do |ansible|
      # Path to Ansible playbook that installs ODL using ODL's Ansible role
      ansible.playbook = "provisioning/playbook.yml"
    end
  end

Ansible

In detail...

Ansible

      ansible.playbook = "provisioning/playbook.yml"

Ansible

[~/vagrant-opendaylight]$ cat provisioning/playbook.yml
---
- hosts: all
  sudo: yes
  roles:
    - opendaylight

ansible

Provision the box

Ansible

[~/vagrant-opendaylight]$ vagrant up cent7_ansible

ansible

At a high level...

Ansible

In detail...

Ansible

TASK: [opendaylight | Add ODL yum repo] ********************************** 
changed: [cent7_ansible]
TASK: [opendaylight | Install ODL via RPM repo] **************************
changed: [cent7_ansible]

Ansible

TASK: [opendaylight | Check if FirewallD service is running] ************* 
ok: [cent7_ansible]
TASK: [opendaylight | Open ODL NB REST port via FirewallD] *************** 
skipping: [cent7_ansible]  

Ansible

TASK: [opendaylight | Start ODL systemd service] ************************* 
changed: [cent7_ansible]

Ansible

Explore

Ansible

[~/vagrant-opendaylight]$ vagrant ssh cent7_ansible
[vagrant@localhost ~]$

Ansible

[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active

Ansible

Example: Config change

Ansible

[~/vagrant-opendaylight]$ cat provisioning/playbook.yml
---
- hosts: all
  sudo: yes
  roles:
    - role: opendaylight
      extra_features: ['odl-netvirt-openstack']

Ansible

[~/vagrant-opendaylight]$ vagrant provision cent7_ansible

ansible

At a high level...

Ansible

In detail...

Ansible

TASK: [opendaylight | Configure ODL Karaf features] ********************** 
changed: [cent7_ansible]

Ansible

NOTIFIED: [opendaylight | Stop ODL] ************************************** 
changed: [cent7_ansible]

NOTIFIED: [opendaylight | Cleanup Karaf] ********************************* 
changed: [cent7_ansible]

NOTIFIED: [opendaylight | Start ODL] ************************************* 
changed: [cent7_ansible]

Ansible

Explore

Ansible

[~/vagrant-opendaylight]$ vagrant ssh cent7_ansible

Ansible

[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active

Ansible

[vagrant@localhost ~]$ ssh -p 8101 karaf@localhost
# password "karaf"


Ansible


Ansible

opendaylight-user@root>feature:list | grep odl-netvirt-openstack
odl-netvirt-openstack | 0.3.0-Boron | x | <snip>

PRE-CONFIGURED IMAGES

PRE-CONFIGURED IMAGES

Environment with ODL installed and configured

PRE-CONFIGURED IMAGES

Built using config management layer

PRE-CONFIGURED IMAGES

VM images
(Vagrant base boxes)

PRE-CONFIGURED IMAGES

Containers
(Docker)

PRE-CONFIGURED IMAGES

Built with Packer

PACKER

Packer

Creates ODL's Vagrant base box + Docker image

Packer

Everything's in VCS

Packer

Common Ansible path
(powerful config, free updates)

CONTAINERS

Containers

Example: One-liner Karaf shell

Containers

$ docker run -ti opendaylight/odl /opt/opendaylight/bin/karaf

Containers

$ docker ps
CONTACONTAINER ID   IMAGE                  COMMAND
b2869594fab3        opendaylight/odl:latest   "/opt/opendaylight/bin/karaf"

CONTAINERS

Available on DockerHub

VAGRANT BASE BOXes

Vagrant Base Boxes

Example

Vagrant Base Boxes

[~/sandbox]$ vagrant init -m opendaylight/odl
[~/sandbox]$ cat Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "opendaylight/odl"
end

Vagrant Base Boxes

[~/sandbox]$ vagrant up

Vagrant Base Boxes

    default: URL: https://atlas.hashicorp.com/opendaylight/odl
==> default: Adding box 'opendaylight/odl' (v5.0.0)

Vagrant Base Boxes

[~/sandbox]$ vagrant status
Current machine states:

default                   running (libvirt)

Vagrant Base Boxes

[~/sandbox]$ vagrant ssh

Vagrant Base Boxes

[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active

VAGRANT BASE BOXES

Available on Atlas

1000 Ways to Deploy a Full Stack and Bash Ain't One

By Daniel Farrell

1000 Ways to Deploy a Full Stack and Bash Ain't One

Talk given at ONS 2017 with Marcus Williams

  • 1,990