Добрый день.
Хочу написать о проблеме с которой я столкнулся около года назад. Для нашего проекта выделели аккаунт на AWS и было решено перевести процесс разработки в облако. Все удобно, виртуальные сервера разворачиваются и настраиваются шустро, но чем дальше мы двигались в production тем острее акцентировался вопрос о мониторинге. Новые сервера добавлялись каждый день, а в продакшне еще планировался автоскейлинг.
На всякий случай, кототкое описание:
Nagios — программа мониторинга компьютерных систем и сетей с открытым кодом. Предназначена для наблюдения, контроля состояния вычислительных узлов и служб, оповещает администратора в том случае, если какие-то из служб прекращают (или возобновляют) свою работу.
Puppet — кроссплатформенное клиент-серверное приложение, которое позволяет централизованно управлять конфигурацией операционных систем и программ, установленных на нескольких компьютерах. Puppet написан на языке программирования Ruby.
Тогда уже были написаны большинство puppet манифестов для компонентов проекта, и текущий способ добавления новых нод был узким местом в этой системе. И к большому моему удивлению я обнаружил что puppet начал поддерживать такие ресурсы как nagios_host, nagios_contact, etc.
puppet type reference
В итоге, есть 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
Для меня работает этот способ
wget apt.puppetlabs.com/puppetlabs-release-precise.deb
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 подробно описано тут
Пример
Для примера использования 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
projects.puppetlabs.com/projects/1/wiki/using_stored_configuration
docs.puppetlabs.com/guides/exported_resources.html
Автор: Spitekh