- PVSM.RU - https://www.pvsm.ru -

Автоматический мониторинг средствами Nagios и Puppet

Добрый день.
Хочу написать о проблеме с которой я столкнулся около года назад. Для нашего проекта выделели аккаунт на AWS и было решено перевести процесс разработки в облако. Все удобно, виртуальные сервера разворачиваются и настраиваются шустро, но чем дальше мы двигались в production тем острее акцентировался вопрос о мониторинге. Новые сервера добавлялись каждый день, а в продакшне еще планировался автоскейлинг.

На всякий случай, кототкое описание:

Nagios — программа мониторинга компьютерных систем и сетей с открытым кодом. Предназначена для наблюдения, контроля состояния вычислительных узлов и служб, оповещает администратора в том случае, если какие-то из служб прекращают (или возобновляют) свою работу.
Puppet — кроссплатформенное клиент-серверное приложение, которое позволяет централизованно управлять конфигурацией операционных систем и программ, установленных на нескольких компьютерах. Puppet написан на языке программирования Ruby.

Тогда уже были написаны большинство puppet манифестов для компонентов проекта, и текущий способ добавления новых нод был узким местом в этой системе. И к большому моему удивлению я обнаружил что puppet начал поддерживать такие ресурсы как nagios_host, nagios_contact, etc.
puppet type reference [1]

В итоге, есть puppet-server, nagios-servers(dev/stage/production), и куча нод. Нужно было как то сказать nagios серверу что у нас появилась новая нода.
Алгоритм такой:
Bootstrap новой ноды => Запуск Puppet агента на ноде => Запуск Puppet агента на ноде с нагиосом(каждые 30 минут по умолчанию).
Puppet умеет отлично хранить экспортируемые ресурсы нод в базе данных (puppetdb/mysql/postgress/etc?). Экспортируемые ресурсы помогают извлечь из ноды facter переменные, такие как fqdn, ip_address, etc… Это мне и было нужно.

Перейдем к установке puppetdb,
На самом деле все просто
Добавляем репозиторий Puppetlabs Puppet Labs Package Repositories [2]

Для меня работает этот способ

wget apt.puppetlabs.com/puppetlabs-release-precise.deb [3]
sudo dpkg -i puppetlabs-release-precise.deb
sudo apt-get update
sudo puppet resource package puppetdb ensure=latest
sudo puppet resource service puppetdb ensure=running enable=true

/etc/puppet/puppet.conf

[master]
storeconfigs = true
storeconfigs_backend = puppetdb

/etc/puppet/puppetdb.conf

[main]
server = puppet # dns name
port = 8081

Как установить mysql или postgresql вместо puppetdb подробно описано тут [4]

Пример

Для примера использования exported resources. Возьмем 2 класса

class test {

file { "/tmp/1":
ensure => present,
content => "$::ipaddress",
}

}

class test {

@@file { "/tmp/1":
ensure => present,
content => "$::ipaddress",
}

}

В первом случае, когда нода применяет манифест test, копируется в файл /tmp/1 содержимое переменной $::ipaddress из facter. Во втором случае файлик на ноде не создается а ресурс @@file сохраняется в puppetdb для последующего вызова.
Вызвать его можно с помощью конструкции

class export_test {

File <<| |>> {
}

}

она объявляется в классе и говорит: Дай мне все экспортные ресурсы в вида File.

site.pp

node 'firstnode' {
include test
}
node 'secondnode' {
include exporttest
}

В итоге на secondnode скопируются ресурсы из fistnode.
Тоже самое делаем и с nagios ресурсами

Конфиг из нагиоса

define host {
address 23.253.222.185
alias magnetodb-1
host_name magnetodb-1
use linux-server
hostgroups dev
}

define service {
service_description SSH
use local-service
check_command check_ssh
servicegroups GENERIC_GROUP
host_name magnetodb-1
}

define service {
service_description PING
use nagios-graph-service
check_command check_ping!100.0,20%!500.0,60%
servicegroups GENERIC_GROUP
host_name magnetodb-1
}

Пишем класс для клиента который будет добавлять хост и 2 чека в puppetdb

class nagios::host::generic {

@@nagios_host { "$nagios_hostname":
ensure => present,
alias => $nagios_hostname,
host_name => "$nagios_hostname",
address => $ipaddress,
hostgroups => $env,
use => 'linux-server',
target => "$nagios::params::nagios_base/hosts/${env}_${nagios_hostname}.cfg", # местонахождение ресурса на ноде где он будет экспортирован
tag => $::deployment_id,
notify => Service[«nagios»],
require => File[$nagios::params::nagios_dirs],
}

@@nagios_service { «ssh $ipaddress»:
ensure => present,
check_command => 'check_ssh',
host_name => $nagios_hostname,
servicegroups => 'GENERIC_GROUP',
service_description => 'SSH',
use => 'local-service',
target => "$nagios::params::nagios_base/hosts/services/${env}_${nagios_hostname}.cfg",
tag => $::deployment_id,
notify => Service[«nagios»],
require => File[$nagios::params::nagios_dirs]
}

@@nagios_service { «ping $ipaddress»:
ensure => present,
check_command => 'check_ping!100.0,20%!500.0,60%',
host_name => $nagios_hostname,
servicegroups => 'GENERIC_GROUP',
service_description => 'PING',
use => 'nagios-graph-service',
target => "$nagios::params::nagios_base/hosts/services/${env}_${nagios_hostname}.cfg",
tag => $::deployment_id,
notify => Service[«nagios»],
}

}

Заголовки экспортируемых ресурсов должны быть уникальными для каждой ноды, в противном случае получим ошибку о duplicate parameter in exported resources. Для этого добавляем уникальное $ipaddress или $fqdn.

Класс для сервера

class nagios_server {
Nagios_host <<| tag == $::deployment_id |>> {
}
Nagios_service <<| tag == $::deployment_id |>> {
}

# tag == $::deployment_id значит что мы выбираем из базы все ресурсы с конекретным тегом, это удобно когда у нас несколько нагиосов которые должны проверять разные хосты.
# переменную $deployment_id нужно будет предварительно объявить в site.pp

}

site.pp

$deployment_id = «dev»
$env = «dev»

node «nagios-1» {
$nagios_hostname = "${hostname}"
class {'nagios::server':
}
}

node «nagios-client-1» {
$nagios_hostname = "$hostname_$ipaddress"
class {'nagios::hosts::generic':}

}

Для того что бы вычистить все ресурсы ноды из puppetdb

puppet node clean «node_certname»

В свое время данный метод помог мне сохранить кучу времени в обслуживании 100 нод в AWS.
Надеюсь данная статья кому-то поможет. Спасибо за внимание

Ссылки:

docs.puppetlabs.com/puppetdb/1/connect_puppet_master.html [5]
projects.puppetlabs.com/projects/1/wiki/using_stored_configuration [4]
docs.puppetlabs.com/guides/exported_resources.html [6]

Автор: Spitekh

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/sistemnoe-administrirovanie/58900

Ссылки в тексте:

[1] puppet type reference: http://docs.puppetlabs.com/references/latest/type.html

[2] Puppet Labs Package Repositories: http://docs.puppetlabs.com/guides/puppetlabs_package_repositories.html#open-source-repositories

[3] apt.puppetlabs.com/puppetlabs-release-precise.deb: https://apt.puppetlabs.com/puppetlabs-release-precise.deb

[4] тут: http://projects.puppetlabs.com/projects/1/wiki/using_stored_configuration

[5] docs.puppetlabs.com/puppetdb/1/connect_puppet_master.html: http://docs.puppetlabs.com/puppetdb/1/connect_puppet_master.html

[6] docs.puppetlabs.com/guides/exported_resources.html: http://docs.puppetlabs.com/guides/exported_resources.html

[7] Источник: http://habrahabr.ru/post/219249/