Yanis Guenane 183b99c0d2 loadbalancer: Implementing a proper failover based on the router state
Due to the fact that two HAProxy can not listen on the same vip at the
same time, the management of the HAProxy service has been delegated to
the keepalived process. With this patch, the keepalived process
starts/stops the HAProxy daemon based on the state is is entering.

If it enters MASTER mode then it starts the HAProxy daemon.
If it enters BACKUP mode then it stops the HAProxy daemon.

close #25
2014-01-22 00:21:05 +01:00

286 lines
8.6 KiB
Puppet

#
# Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
#
# 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.
#
# HAproxy nodes
#
class cloud::loadbalancer(
$ceilometer_api = true,
$cinder_api = true,
$glance_api = true,
$neutron_api = true,
$heat_api = true,
$heat_cfn_api = true,
$heat_cloudwatch_api = true,
$nova_api = true,
$ec2_api = true,
$metadata_api = true,
$swift_api = true,
$keystone_api_admin = true,
$keystone_api = true,
$horizon = true,
$spice = true,
$haproxy_auth = $os_params::haproxy_auth,
$keepalived_state = 'BACKUP',
$keepalived_interface = $os_params::keepalived_interface,
$keepalived_ipvs = [ $os_params::openstack_vip, $os_params::mysql_vip ],
$keepalived_localhost_ip = $os_params::keepalived_localhost_ip,
$ks_cinder_public_port = $os_params::ks_cinder_public_port,
$ks_ceilometer_public_port = $os_params::ks_ceilometer_public_port,
$ks_ec2_public_port = $os_params::ks_ec2_public_port,
$ks_glance_public_port = $os_params::ks_glance_public_port,
$ks_heat_public_port = $os_params::ks_heat_public_port,
$ks_heat_cfn_public_port = $os_params::ks_heat_cfn_public_port,
$ks_heat_cloudwatch_public_port = $os_params::ks_heat_cloudwatch_public_port,
$ks_keystone_admin_port = $os_params::ks_keystone_admin_port,
$ks_keystone_public_port = $os_params::ks_keystone_public_port,
$ks_metadata_public_port = $os_params::ks_metadata_public_port,
$ks_neutron_public_port = $os_params::ks_neutron_public_port,
$ks_nova_public_port = $os_params::ks_nova_public_port,
$ks_swift_public_port = $os_params::ks_swift_public_port,
$horizon_port = $os_params::horizon_port,
$spice_port = $os_params::spice_port,
$openstack_vip = $os_params::openstack_vip,
$mysql_vip = $os_params::mysql_vip
){
class { 'haproxy':
manage_service => false,
}
class { 'keepalived': }
keepalived::vrrp_script { 'haproxy':
name_is_process => true
}
keepalived::instance { '1':
interface => $keepalived_interface,
virtual_ips => split(join(flatten([$keepalived_ipvs, ['']]), " dev ${keepalived_interface},"), ','),
state => $keepalived_state,
track_script => ['haproxy'],
priority => 50,
notify_master => '"/etc/init.d/haproxy start"',
notify_backup => '"/etc/init.d/haproxy stop"',
}
$monitors_data = inline_template('
<%- if @swift_api -%>
acl swift_api_dead nbsrv(swift_api_cluster) lt 1
monitor fail if swift_api_dead
<%- end -%>
<%- if @keystone_api -%>
acl keystone_api_dead nbsrv(keystone_api_cluster) lt 1
monitor fail if keystone_api_dead
<% end -%>
<%- if @galera -%>
acl galera_dead nbsrv(galera_cluster) lt 1
monitor fail if galera_dead
<%- end -%>
<%- if @neutron_api -%>
acl neutron_api_dead nbsrv(neutron_api_cluster) lt 1
monitor fail if neutron_api_dead
<%- end -%>
<%- if @cinder_api -%>
acl cinder_api_dead nbsrv(cinder_api_cluster) lt 1
monitor fail if cinder_api_dead
<%- end -%>
<%- if @nova_api -%>
acl nova_api_dead nbsrv(nova_api_cluster) lt 1
monitor fail if nova_api_dead
<%- end -%>
<%- if @nova_ec2 -%>
acl nova_ec2_dead nbsrv(nova_ec2_cluster) lt 1
monitor fail if nova_ec2_dead
<%- end -%>
<%- if @nova_metadata -%>
acl nova_metadata_dead nbsrv(nova_metadata_cluster) lt 1
monitor fail if nova_metadata_dead
<%- end -%>
<%- if @spice -%>
acl spice_dead nbsrv(spice_cluster) lt 1
monitor fail if spice_dead
<%- end -%>
<%- if @glance_api -%>
acl nova_api_dead nbsrv(glance_api_cluster) lt 1
monitor fail if nova_api_dead
<%- end -%>
<%- if @ceilometer_api -%>
acl ceilometer_api_dead nbsrv(ceilometer_api_cluster) lt 1
monitor fail if ceilometer_api_dead
<%- end -%>
<%- if @heat_api -%>
acl heat_api_dead nbsrv(heat_api_cluster) lt 1
monitor fail if heat_api_dead
<%- end -%>
<%- if @heat_cfn_api -%>
acl heat_api_cfn_dead nbsrv(heat_api_cfn_cluster) lt 1
monitor fail if heat_api_cfn_dead
<%- end -%>
<%- if @heat_cloudwatch_api -%>
acl heat_api_cloudwatch_dead nbsrv(heat_api_cloudwatch_cluster) lt 1
monitor fail if heat_api_cloudwatch_dead
<%- end -%>
<%- if @horizon -%>
acl horizon_dead nbsrv(horizon_cluster) lt 1
monitor fail if horizon_dead
<%- end -%>
')
file{'/etc/logrotate.d/haproxy':
content => "
/var/log/haproxy.log
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
postrotate
endscript
}
"
}
haproxy::listen { 'monitor':
ipaddress => $openstack_vip,
ports => '9300',
options => {
'mode' => 'http',
'monitor-uri' => '/status',
'stats' => ['enable','uri /admin','realm Haproxy\ Statistics',"auth ${haproxy_auth}", 'refresh 5s' ],
'' => $monitors_data,
}
}
if $keystone_api {
cloud::loadbalancer::listen_http {
'keystone_api_cluster':
ports => $ks_keystone_public_port,
listen_ip => $openstack_vip;
'keystone_api_admin_cluster':
ports => $ks_keystone_admin_port,
listen_ip => $openstack_vip;
}
}
if $swift_api {
cloud::loadbalancer::listen_http{
'swift_api_cluster':
ports => $ks_swift_public_port,
httpchk => 'httpchk /healthcheck',
listen_ip => $openstack_vip;
}
}
if $nova_api {
cloud::loadbalancer::listen_http{
'nova_api_cluster':
ports => $ks_nova_public_port,
listen_ip => $openstack_vip;
}
}
if $ec2_api {
cloud::loadbalancer::listen_http{
'ec2_api_cluster':
ports => $ks_ec2_public_port,
listen_ip => $openstack_vip;
}
}
if $metadata_api {
cloud::loadbalancer::listen_http{
'metadata_api_cluster':
ports => $ks_metadata_public_port,
listen_ip => $openstack_vip;
}
}
if $spice {
cloud::loadbalancer::listen_http{
'spice_cluster':
ports => $spice_port,
listen_ip => $openstack_vip,
httpchk => 'httpchk GET /';
}
}
if $glance_api {
cloud::loadbalancer::listen_http{
'glance_api_cluster':
ports => $ks_glance_public_port,
listen_ip => $openstack_vip;
}
}
if $neutron_api {
cloud::loadbalancer::listen_http{
'neutron_api_cluster':
ports => $ks_neutron_public_port,
listen_ip => $openstack_vip;
}
}
if $cinder_api {
cloud::loadbalancer::listen_http{
'cinder_api_cluster':
ports => $ks_cinder_public_port,
listen_ip => $openstack_vip;
}
}
if $ceilometer_api {
cloud::loadbalancer::listen_http{
'ceilometer_api_cluster':
ports => $ks_ceilometer_public_port,
listen_ip => $openstack_vip;
}
}
if $heat_api {
cloud::loadbalancer::listen_http{
'heat_api_cluster':
ports => $ks_heat_public_port,
listen_ip => $openstack_vip;
}
}
if $heat_cfn_api {
cloud::loadbalancer::listen_http{
'heat_api_cfn_cluster':
ports => $ks_heat_cfn_public_port,
listen_ip => $openstack_vip;
}
}
if $heat_cloudwatch_api {
cloud::loadbalancer::listen_http{
'heat_api_cloudwatch_cluster':
ports => $ks_heat_cloudwatch_public_port,
listen_ip => $openstack_vip;
}
}
if $horizon {
cloud::loadbalancer::listen_http{
'horizon_cluster':
ports => $horizon_port,
listen_ip => $openstack_vip;
}
}
haproxy::listen { 'galera_cluster':
ipaddress => $mysql_vip,
ports => 3306,
options => {
'mode' => 'tcp',
'balance' => 'roundrobin',
'option' => ['tcpka', 'tcplog'],
'timeout client' => '400s',
'timeout server' => '400s',
}
}
}