Install InfluxDB in HA mode

- Allow to deploy three influxdb_grafana nodes at most
- Add firewall rule to allow traffic between the nodes of the raft
  cluster
- Create a VIP
- Create a file /etc/hiera/plugins/influxdb_grafana.yaml that contains
  information about nodes that belong to the raft cluster and the VIP
- Install and configure HAProxy

Implements: blueprint influxdb-clustering
Change-Id: I0852da40d709563adc8b89bbad240ae89dfa862e
This commit is contained in:
Guillaume Thouvenin 2015-12-14 08:53:58 +01:00
parent 1d2997342f
commit 322fd4a1d1
17 changed files with 316 additions and 21 deletions

View File

@ -38,8 +38,20 @@ firewall {'020 ssh':
action => 'accept',
}
firewall { '113 corosync-input':
port => 5404,
proto => 'udp',
action => 'accept',
}
firewall { '114 corosync-output':
port => 5405,
proto => 'udp',
action => 'accept',
}
firewall { '200 influxdb':
port => [8083, 8086],
port => [8083, 8086, 8088],
proto => 'tcp',
action => 'accept',
}

View File

@ -0,0 +1,49 @@
# Copyright 2016 Mirantis, 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.
$stats_port = '1000'
$influxdb_port = '8086'
$influxdb_nodes = hiera(lma::influxdb::raft_nodes)
openstack::ha::haproxy_service { 'influxdb':
order => '800',
listen_port => $influxdb_port,
balancermember_port => $influxdb_port,
ipaddresses => values($influxdb_nodes),
server_names => keys($influxdb_nodes),
haproxy_config_options => {
'option' => ['httpchk GET /ping HTTP/1.1'],
'http-check' => 'expect status 204',
'balance' => 'roundrobin',
'mode' => 'http',
},
balancermember_options => 'check',
internal => true,
internal_virtual_ip => hiera(lma::influxdb::vip),
public => false,
public_virtual_ip => undef,
}
openstack::ha::haproxy_service { 'stats':
order => '010',
listen_port => $stats_port,
server_names => undef,
internal_virtual_ip => hiera(lma::influxdb::vip),
public_virtual_ip => undef,
haproxy_config_options => {
'stats' => ['enable', 'uri /', 'refresh 5s', 'show-node',
'show-legends', 'hide-version'],
'mode' => 'http',
},
}

View File

@ -0,0 +1,52 @@
# Copyright 2016 Mirantis, 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.
$hiera_dir = '/etc/hiera/plugins'
$plugin_name = 'influxdb_grafana'
$plugin_yaml = "${plugin_name}.yaml"
$vip_name = 'influxdb'
$network_metadata = hiera_hash('network_metadata')
if ! $network_metadata['vips'][$vip_name] {
fail('InfluxDB VIP is not defined')
}
$influxdb_nodes = get_nodes_hash_by_roles($network_metadata, [$plugin_name])
$influxdb_address_map = get_node_to_ipaddr_map_by_network_role($influxdb_nodes, 'influxdb_vip')
$influxdb_vip = $network_metadata['vips'][$vip_name]['ipaddr']
$corosync_roles = [$plugin_name]
###################
$calculated_content = inline_template('
lma::influxdb::raft_nodes:
<% @influxdb_address_map.keys.sort.each do |k| -%>
<%= k %>: <%= @influxdb_address_map[k] %>
<% end -%>
lma::influxdb::vip: <%= @influxdb_vip %>
corosync_roles:
<% @corosync_roles.sort.each do |crole| -%>
- <%= crole %>
<% end -%>
')
file { "${hiera_dir}/${plugin_yaml}":
ensure => file,
content => "${calculated_content}\n",
}

View File

@ -14,6 +14,7 @@
#
$influxdb_grafana = hiera('influxdb_grafana')
$directory = $influxdb_grafana['data_dir']
$raft_nodes = hiera(lma::influxdb::raft_nodes)
user { 'influxdb':
ensure => present,
@ -35,6 +36,8 @@ if $influxdb_grafana['retention_period'] == 0 {
$retention_period = sprintf('%dd', $influxdb_grafana['retention_period'])
}
# We cannot mix IP addresses and hostnames otherwise the Raft cluster won't
# start. We decide to stick with hostnames because they are more meaningful.
class { 'lma_monitoring_analytics::influxdb':
influxdb_rootpass => $influxdb_grafana['influxdb_rootpass'],
influxdb_dbname => $influxdb_grafana['influxdb_dbname'],
@ -44,4 +47,6 @@ class { 'lma_monitoring_analytics::influxdb':
retention_period => $retention_period,
replication_factor => $influxdb_grafana['replication_factor'],
require => File[$directory],
raft_hostname => hiera('node_name'),
raft_nodes => keys($raft_nodes),
}

View File

@ -15,13 +15,18 @@
# == Class: influxdb
class influxdb (
$data_dir = $influxdb::params::data_dir,
$hh_dir = $influxdb::params::hh_dir,
$meta_dir = $influxdb::params::meta_dir,
$wal_dir = $influxdb::params::wal_dir,
$data_dir = $influxdb::params::data_dir,
$hh_dir = $influxdb::params::hh_dir,
$meta_dir = $influxdb::params::meta_dir,
$wal_dir = $influxdb::params::wal_dir,
$raft_hostname = undef,
$raft_nodes = undef,
) inherits influxdb::params {
class {'influxdb::install': }
class {'influxdb::install':
raft_hostname => $raft_hostname,
raft_nodes => $raft_nodes,
}
class {'influxdb::service':
require => Class['influxdb::install'],

View File

@ -14,10 +14,22 @@
#
# == Class: influxdb::install
class influxdb::install {
class influxdb::install (
$raft_hostname = undef,
$raft_nodes = undef,
) {
package { 'influxdb':
ensure => installed,
}
if $raft_hostname and $raft_nodes {
file { '/etc/default/influxdb':
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
content => template('influxdb/influxdb_variables.erb')
}
}
}

View File

@ -0,0 +1,30 @@
# Copyright 2016 Mirantis, 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.
require 'spec_helper'
describe 'influxdb::configure' do
let(:facts) do
{:kernel => 'Linux', :operatingsystem => 'Ubuntu',
:osfamily => 'Debian'}
end
describe 'with defaults' do
it { is_expected.to compile }
it { is_expected.to contain_ini_setting('http_auth_enabled') }
it { is_expected.to contain_ini_setting('data_dir') }
it { is_expected.to contain_ini_setting('wal_dir') }
it { is_expected.to contain_ini_setting('hh_dir') }
it { is_expected.to contain_ini_setting('meta_dir') }
end
end

View File

@ -0,0 +1,35 @@
# Copyright 2016 Mirantis, 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.
require 'spec_helper'
describe 'influxdb::install' do
let(:facts) do
{:kernel => 'Linux', :operatingsystem => 'Ubuntu',
:osfamily => 'Debian'}
end
describe 'with defaults' do
it { is_expected.to contain_package('influxdb').with_ensure('installed') }
it { is_expected.to have_file_count(0) }
end
describe 'with params' do
let(:params) do
{:raft_hostname => 'node-1',
:raft_nodes => ['node-1', 'node-2']}
end
it { is_expected.to contain_package('influxdb').with_ensure('installed') }
it { is_expected.to contain_file('/etc/default/influxdb') }
end
end

View File

@ -0,0 +1,29 @@
# Copyright 2016 Mirantis, 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.
require 'spec_helper'
describe 'influxdb::service' do
let(:facts) do
{:kernel => 'Linux', :operatingsystem => 'Ubuntu',
:osfamily => 'Debian'}
end
describe 'with defaults' do
it { is_expected.to contain_service('influxdb').with(
'ensure' => 'running',
'enable' => 'true',
'hasrestart' => 'true'
) }
end
end

View File

@ -21,6 +21,10 @@ describe 'influxdb' do
describe 'with defaults' do
it { is_expected.to compile }
it { is_expected.to contain_class('influxdb::install') }
it { is_expected.to contain_class('influxdb::service') }
it { is_expected.to contain_class('influxdb::configure') }
end
end

View File

@ -0,0 +1 @@
INFLUXD_OPTS="-hostname <%= @raft_hostname %> -join <%= @raft_nodes.sort.collect{|x| "#{x}:8088"}.join(',') %>"

View File

@ -22,6 +22,8 @@ class lma_monitoring_analytics::influxdb (
$influxdb_dir = $lma_monitoring_analytics::params::influxdb_dir,
$retention_period = $lma_monitoring_analytics::params::influxdb_retention_period,
$replication_factor = $lma_monitoring_analytics::params::influxdb_replication_factor,
$raft_hostname = undef,
$raft_nodes = undef,
) inherits lma_monitoring_analytics::params {
$configure_influxdb = $lma_monitoring_analytics::params::influxdb_script
@ -31,11 +33,15 @@ class lma_monitoring_analytics::influxdb (
$real_retention_period = $retention_period
}
validate_array($raft_nodes)
class { '::influxdb':
data_dir => "${influxdb_dir}/data",
meta_dir => "${influxdb_dir}/meta",
hh_dir => "${influxdb_dir}/hh",
wal_dir => "${influxdb_dir}/wal",
data_dir => "${influxdb_dir}/data",
meta_dir => "${influxdb_dir}/meta",
hh_dir => "${influxdb_dir}/hh",
wal_dir => "${influxdb_dir}/wal",
raft_hostname => $raft_hostname,
raft_nodes => $raft_nodes,
}
file { $configure_influxdb:

View File

@ -2,13 +2,56 @@
type: group
role: [influxdb_grafana]
tasks:
- fuel_pkgs
- hiera
- globals
- tools
- logging
- netconfig
- hosts
- cluster
- cluster-haproxy
required_for: [deploy_end]
requires: [deploy_start]
parameters:
strategy:
type: parallel
- id: influxdb-firewall
type: puppet
groups: [influxdb_grafana]
required_for: [cluster]
requires: [netconfig]
parameters:
puppet_manifest: "puppet/manifests/firewall.pp"
puppet_modules: "/etc/puppet/modules"
timeout: 360
- id: influxdb-vip
type: puppet
groups: [influxdb_grafana]
requires: [cluster]
parameters:
puppet_manifest: "/etc/puppet/modules/osnailyfacter/modular/virtual_ips/virtual_ips.pp"
puppet_modules: "/etc/puppet/modules"
timeout: 3600
- id: influxdb-haproxy
type: puppet
groups: [influxdb_grafana]
required_for: [deploy_end]
requires: [cluster-haproxy, influxdb-vip]
parameters:
puppet_manifest: "puppet/manifests/haproxy.pp"
puppet_modules: "/etc/puppet/modules"
timeout: 3600
- id: influxdb-hiera-override
type: puppet
groups: [influxdb_grafana]
requires: [globals]
required_for: [logging]
parameters:
puppet_manifest: "puppet/manifests/hiera-override.pp"
puppet_modules: "/etc/puppet/modules"
timeout: 120

View File

@ -11,13 +11,13 @@ attributes:
error: "You must provide a number"
replication_factor:
value: '1'
value: '3'
label: 'Replication factor'
description: 'The number of replicas'
weight: 6
type: "text"
regex: *number_validation
# Don't expose the replication factor until clustering is supported
# Don't expose the replication factor while clustering is alpha
restrictions:
- condition: "true"
action: hide

18
network_roles.yaml Normal file
View File

@ -0,0 +1,18 @@
# Unique network role name
- id: "influxdb_vip"
# Role mapping to network
default_mapping: "management"
properties:
# Should be true if network role requires subnet being set
subnet: true
# Should be true if network role requires gateway being set
gateway: false
# List of VIPs to be allocated
vip:
# Unique VIP name
- name: "influxdb"
# Optional linux namespace for VIP
namespace: "haproxy"
alias: "influxdb"
node_roles:
- "influxdb_grafana"

View File

@ -5,7 +5,8 @@ influxdb_grafana:
public_ip_required: false
weight: 100
limits:
max: 1
max: 3
recommended: 3
conflicts:
- controller
- compute

View File

@ -1,13 +1,6 @@
# The following tasks are executed in the order they are declared
# Priorities are important, this ensure that this plugin is deployed before
# LMA Collector (priority 8200).
- role: [influxdb_grafana]
stage: post_deployment/8100
type: puppet
parameters:
puppet_manifest: puppet/manifests/firewall.pp
puppet_modules: /etc/puppet/modules
timeout: 300
- role: [influxdb_grafana]
stage: post_deployment/8100