Puppet module to deploy HAProxy bundle for HA
authorDamien Ciabrini <dciabrin@redhat.com>
Fri, 21 Apr 2017 13:09:31 +0000 (15:09 +0200)
committerMichele Baldessari <michele@acksyn.org>
Thu, 25 May 2017 12:37:17 +0000 (14:37 +0200)
This module is used by tripleo-heat-templates to configure and deploy
Kolla-based haproxy containers managed by pacemaker.

We use short-lived containers that call pcs via puppet to create
the needed pacemaker resources, properties and constraints.

Co-Authored-By: Michele Baldesari <michele@acksyn.org>
Partial-Bug: #1692908

Depends-On: I44fbd7f89ab22b72e8d3fc0a0e3fe54a9418a60f
Depends-On: Ie9b7e7d2a3cec4b121915a17c1e809e4ec950e7f

Change-Id: Ifcf890a88ef003d3ab754cb677cbf34ba8db9312

manifests/pacemaker/haproxy_with_vip.pp
manifests/profile/pacemaker/haproxy_bundle.pp [new file with mode: 0644]

index 1fc3ff7..606ac26 100644 (file)
@@ -69,6 +69,12 @@ define tripleo::pacemaker::haproxy_with_vip(
       $ipv6_addrlabel = ''
     }
 
+    $haproxy_in_container = hiera('haproxy_docker', false)
+    $constraint_target_name = $haproxy_in_container ? {
+      true => 'haproxy-bundle',
+      default => 'haproxy-clone'
+    }
+
     pacemaker::resource::ip { "${vip_name}_vip":
       ip_address     => $ip_address,
       cidr_netmask   => $netmask,
@@ -77,9 +83,10 @@ define tripleo::pacemaker::haproxy_with_vip(
       location_rule  => $location_rule,
       tries          => $pcs_tries,
     }
+
     pacemaker::constraint::order { "${vip_name}_vip-then-haproxy":
       first_resource    => "ip-${ip_address}",
-      second_resource   => 'haproxy-clone',
+      second_resource   => $constraint_target_name,
       first_action      => 'start',
       second_action     => 'start',
       constraint_params => 'kind=Optional',
@@ -87,13 +94,18 @@ define tripleo::pacemaker::haproxy_with_vip(
     }
     pacemaker::constraint::colocation { "${vip_name}_vip-with-haproxy":
       source => "ip-${ip_address}",
-      target => 'haproxy-clone',
+      target => $constraint_target_name,
       score  => 'INFINITY',
       tries  => $pcs_tries,
     }
 
+    $service_resource = $haproxy_in_container ? {
+      true => Pacemaker::Resource::Bundle['haproxy-bundle'],
+      default => Pacemaker::Resource::Service['haproxy']
+    }
+
     Pacemaker::Resource::Ip["${vip_name}_vip"] ->
-      Pacemaker::Resource::Service['haproxy'] ->
+      $service_resource ->
         Pacemaker::Constraint::Order["${vip_name}_vip-then-haproxy"] ->
           Pacemaker::Constraint::Colocation["${vip_name}_vip-with-haproxy"]
   }
diff --git a/manifests/profile/pacemaker/haproxy_bundle.pp b/manifests/profile/pacemaker/haproxy_bundle.pp
new file mode 100644 (file)
index 0000000..3e7b7dd
--- /dev/null
@@ -0,0 +1,196 @@
+# Copyright 2016 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+# == Class: tripleo::profile::pacemaker::haproxy
+#
+# HAproxy with Pacemaker HA profile for tripleo
+#
+# === Parameters
+#
+# [*haproxy_docker_image*]
+#   (Optional) The docker image to use for creating the pacemaker bundle
+#   Defaults to hiera('tripleo::profile::pacemaker::haproxy::haproxy_docker_image', undef)
+#
+# [*bootstrap_node*]
+#   (Optional) The hostname of the node responsible for bootstrapping tasks
+#   Defaults to hiera('haproxy_short_bootstrap_node_name')
+#
+# [*enable_load_balancer*]
+#   (Optional) Whether load balancing is enabled for this cluster
+#   Defaults to hiera('enable_load_balancer', true)
+#
+# [*step*]
+#   (Optional) The current step in deployment. See tripleo-heat-templates
+#   for more details.
+#   Defaults to hiera('step')
+#
+# [*pcs_tries*]
+#   (Optional) The number of times pcs commands should be retried.
+#   Defaults to hiera('pcs_tries', 20)
+#
+class tripleo::profile::pacemaker::haproxy_bundle (
+  $haproxy_docker_image = hiera('tripleo::profile::pacemaker::haproxy::haproxy_docker_image', undef),
+  $bootstrap_node       = hiera('haproxy_short_bootstrap_node_name'),
+  $enable_load_balancer = hiera('enable_load_balancer', true),
+  $step                 = hiera('step'),
+  $pcs_tries            = hiera('pcs_tries', 20),
+) {
+  include ::tripleo::profile::base::haproxy
+
+  if $::hostname == downcase($bootstrap_node) {
+    $pacemaker_master = true
+  } else {
+    $pacemaker_master = false
+  }
+
+  if $step >= 1 and $pacemaker_master and hiera('stack_action') == 'UPDATE' and $enable_load_balancer {
+    tripleo::pacemaker::resource_restart_flag { 'haproxy-clone':
+      subscribe => Concat['/etc/haproxy/haproxy.cfg'],
+    }
+  }
+
+  if $step >= 2 and $enable_load_balancer {
+    if $pacemaker_master {
+      $haproxy_short_node_names = hiera('haproxy_short_node_names')
+      $haproxy_short_node_names.each |String $node_name| {
+        pacemaker::property { "haproxy-role-${node_name}":
+          property => 'haproxy-role',
+          value    => true,
+          tries    => $pcs_tries,
+          node     => $node_name,
+          before   => Pacemaker::Resource::Bundle['haproxy-bundle'],
+        }
+      }
+      $haproxy_location_rule = {
+        resource_discovery => 'exclusive',
+        score              => 0,
+        expression         => ['haproxy-role eq true'],
+      }
+      # FIXME: we should not have to access tripleo::haproxy class
+      # parameters here to configure pacemaker VIPs. The configuration
+      # of pacemaker VIPs could move into puppet-tripleo or we should
+      # make use of less specific hiera parameters here for the settings.
+      $haproxy_nodes = hiera('haproxy_short_node_names')
+      $haproxy_nodes_count = count($haproxy_nodes)
+
+      pacemaker::resource::bundle { 'haproxy-bundle':
+        image             => $haproxy_docker_image,
+        replicas          => $haproxy_nodes_count,
+        container_options => 'network=host',
+        options           => '--user=root --log-driver=journald -e KOLLA_CONFIG_STRATEGY=COPY_ALWAYS',
+        run_command       => '/bin/bash /usr/local/bin/kolla_start',
+        storage_maps      => {
+          'haproxy-cfg-files'               => {
+            'source-dir' => '/var/lib/kolla/config_files/haproxy.json',
+            'target-dir' => '/var/lib/kolla/config_files/config.json',
+            'options'    => 'ro',
+          },
+          'haproxy-cfg-data'                => {
+            'source-dir' => '/var/lib/config-data/haproxy/etc',
+            'target-dir' => '/etc',
+            'options'    => 'ro',
+          },
+          'haproxy-hosts'                   => {
+            'source-dir' => '/etc/hosts',
+            'target-dir' => '/etc/hosts',
+            'options'    => 'ro',
+          },
+          'haproxy-localtime'               => {
+            'source-dir' => '/etc/localtime',
+            'target-dir' => '/etc/localtime',
+            'options'    => 'ro',
+          },
+          'haproxy-pki-extracted'           => {
+            'source-dir' => '/etc/pki/ca-trust/extracted',
+            'target-dir' => '/etc/pki/ca-trust/extracted',
+            'options'    => 'ro',
+          },
+          'haproxy-pki-ca-bundle-crt'       => {
+            'source-dir' => '/etc/pki/tls/certs/ca-bundle.crt',
+            'target-dir' => '/etc/pki/tls/certs/ca-bundle.crt',
+            'options'    => 'ro',
+          },
+          'haproxy-pki-ca-bundle-trust-crt' => {
+            'source-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt',
+            'target-dir' => '/etc/pki/tls/certs/ca-bundle.trust.crt',
+            'options'    => 'ro',
+          },
+          'haproxy-pki-cert'                => {
+            'source-dir' => '/etc/pki/tls/cert.pem',
+            'target-dir' => '/etc/pki/tls/cert.pem',
+            'options'    => 'ro',
+          },
+          'haproxy-dev-log'                 => {
+            'source-dir' => '/dev/log',
+            'target-dir' => '/dev/log',
+            'options'    => 'rw',
+          },
+        },
+      }
+      $control_vip = hiera('controller_virtual_ip')
+      tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_control_vip':
+        vip_name      => 'control',
+        ip_address    => $control_vip,
+        location_rule => $haproxy_location_rule,
+        pcs_tries     => $pcs_tries,
+      }
+
+      $public_vip = hiera('public_virtual_ip')
+      tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_public_vip':
+        ensure        => $public_vip and $public_vip != $control_vip,
+        vip_name      => 'public',
+        ip_address    => $public_vip,
+        location_rule => $haproxy_location_rule,
+        pcs_tries     => $pcs_tries,
+      }
+
+      $redis_vip = hiera('redis_vip')
+      tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_redis_vip':
+        ensure        => $redis_vip and $redis_vip != $control_vip,
+        vip_name      => 'redis',
+        ip_address    => $redis_vip,
+        location_rule => $haproxy_location_rule,
+        pcs_tries     => $pcs_tries,
+      }
+
+      $internal_api_vip = hiera('internal_api_virtual_ip')
+      tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_internal_api_vip':
+        ensure        => $internal_api_vip and $internal_api_vip != $control_vip,
+        vip_name      => 'internal_api',
+        ip_address    => $internal_api_vip,
+        location_rule => $haproxy_location_rule,
+        pcs_tries     => $pcs_tries,
+      }
+
+      $storage_vip = hiera('storage_virtual_ip')
+      tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_storage_vip':
+        ensure        => $storage_vip and $storage_vip != $control_vip,
+        vip_name      => 'storage',
+        ip_address    => $storage_vip,
+        location_rule => $haproxy_location_rule,
+        pcs_tries     => $pcs_tries,
+      }
+
+      $storage_mgmt_vip = hiera('storage_mgmt_virtual_ip')
+      tripleo::pacemaker::haproxy_with_vip { 'haproxy_and_storage_mgmt_vip':
+        ensure        => $storage_mgmt_vip and $storage_mgmt_vip != $control_vip,
+        vip_name      => 'storage_mgmt',
+        ip_address    => $storage_mgmt_vip,
+        location_rule => $haproxy_location_rule,
+        pcs_tries     => $pcs_tries,
+      }
+    }
+  }
+
+}