Automatisierung eines Überwachungssystems basierend auf Icinga2 und Puppet
Lassen Sie uns ein wenig über ... Infrastruktur als Code (IaC) sprechen.
Auf Habré gibt es einige sehr gute Artikel über Icinga2, es gibt auch ausgezeichnete Artikel über Puppet:
Icinga2 ist eine einfache OptionWir erhöhen das Mikromonitoring auf icinga2 mit minimalen KostenEinrichten eines modernen Puppet-Servers von Grund auf neuDas Thema Automatisierung und Integration dieser beiden erstaunlichen Systeme wird jedoch überhaupt nicht offenbart.
In diesem Handbuch werde ich in einem "lebenden" Beispiel zeigen, wie Sie diese beiden kombinieren können
Erhalten Sie ein leistungsstarkes Tool zur Überwachung Ihrer Infrastruktur mit allen erforderlichen Funktionen. Dieser Artikel ist eine Art Leitfaden für die Installation des Pakets "Alles in einer Flasche". Nach dem Ausfüllen dieses Handbuchs steht Ihnen eine voll funktionsfähige Überwachungslösung zur Verfügung, die für Sie weiter angepasst werden kann. Lass es uns versuchen!
Also:
Wir haben einen neuen Gastgeber großgezogen. Und wir brauchen:
1. Damit die Überwachung automatisch in Icinga2 angezeigt wird und grundlegende Überprüfungen erstellt werden:
Schecks
| Schnappschüsse
| Erklärungen
|
Host
| 
| Bei einer bestimmten Häufigkeit überprüfen wir mit dem Ping-Befehl, ob der Host "live" ist.
|
Festplattennutzung
| 
| Überprüfen Sie, ob genügend freier Speicherplatz vorhanden ist. |
Durchschnitt laden
| 
| Wir überwachen die Belastung des Servers dynamisch. Die Anzahl der Prozessoren wird berücksichtigt. |
Freier Speicher
| 
| Wir überprüfen, ob auf dem Server genügend freier Speicher vorhanden ist. |
Ports öffnen
| 
| Wir scannen die Ports auf dem Server und erstellen eine Karte der offenen Ports. Wir überwachen, dass wir keine neuen offenen oder geschlossenen Ports hatten. |
Kritische Updates
| 
| Wir überwachen das Vorhandensein kritischer Updates auf dem Server. |
2. Fügen Sie auf bequeme und verständliche Weise benutzerdefinierte Überprüfungen für verschiedene Dienste hinzu. Was würde dann dem Regisseur zeigen, was für gute Leute wir sind und einen Preis bekommen!
Einige Beispiele:
Service
| YAML-Bestätigungscode
|
---|
Virtueller HostÜberprüfen Sie den "Live" -Host oder nicht.

| '%{::fqdn} virtual host' : target: /etc/icinga2/zones.d/master/%{::fqdn}.conf apply: true assign: [ 'host.name == %{::fqdn}' ] display_name: '%{::fqdn} virtualhost' check_command: 'http' vars: http_uri: / http_ssl: true http_vhost: 'hostname' http_address: "%{lookup('host_address')}"
|
PostgreSQLÜberprüfen Sie, ob wir eine Verbindung zur PostgreSQL-Datenbank herstellen können.

| '%{::fqdn} PostgreSQL': target: /etc/icinga2/zones.d/master/%{::fqdn}.conf apply: true assign: [ 'host.name == %{::fqdn}' ] display_name: 'PostgreSQL' command_endpoint: '%{::fqdn}' check_command: "postgres" vars: postgres_host: "localhost" postgres_action: "connection" phone_notifications: true
|
Nginx-StatusWir überwachen den Status von Nginx über stub_status.

| '%{::fqdn} nginx status' : target: /etc/icinga2/zones.d/master/%{::fqdn}.conf apply: true assign: [ 'host.name == %{::fqdn}' ] command_endpoint: '%{::fqdn}' display_name: 'nginx status' check_command: 'nginx_status' vars: nginx_status_host_address: localhost nginx_status_servername: server.com nginx_status_critical: '1600,60,30' nginx_status_warn: '1500,55,25'
|
3. Dass alles ordentlich, zuverlässig und schön war. Und am wichtigsten ist, dass Sie nicht mehr als 30 Minuten mit der Ersteinrichtung verbringen.
Sie müssen Erfahrung mit Docker und damit mit Linux haben - für sich.
Dieses Setup wird unter Debian / Ubuntu beschrieben. Und obwohl ich keinen Grund sehe, nicht an anderen Unix-ähnlichen Systemen zu arbeiten, kann ich selbst keine solchen Garantien geben. Ich habe ein paar Maschinen mit CentOS, es funktioniert dort, aber die meisten sind trotzdem Debian / Ubuntu.
Fangen wir an
Ich sage sofort, es ist praktisch für mich, wenn die gesamte Hostkonfiguration aus Diensten, Konfigurationen, Software, Konten usw. besteht. - Sie werden durch eine Yaml-Datei beschrieben. Dies vermeidet die Dokumentation der Infrastruktur und gibt eine klare Konfiguration. Er öffnete das entsprechende Projekt im Git-Repository, wobei die Dateinamen dem Hostnamen entsprechen, und öffnete dann die Konfiguration des gewünschten Hosts. Und Sie können sofort sehen, welche Dienste auf dem Host vorhanden sind, was von diesem gesichert wird, was überwacht wird usw.
So sieht die Projektstruktur im Repository aus: project_1/hostname1.com.yaml project_2/hostname2.com.yaml project_3/hostname3.com.yaml
Ich verwende hier eine solche Vorlage, die die Konfiguration eines unserer Server beschreibt:
Vollständige Vorlage #============================|INPUT DATA|=================================# #---------------------------------------|VARS|----------------------------# #---//Information about variables, keys & contacts//----------------------# host_address: xxxx my_company: my_mail_domain: my_ssh_port: #---------------------------------------|CLASSES|-------------------------# #---//Classes are modules installed on the server.//----------------------# #---//These modules process the arguments typed below.//------------------# #---//Without classes nothing will work.//--------------------------------# #---//Class default_role is mandatory. This class will install//----------# #---//etckeeper, some required perl modules and manages all the logics.//-# classes: - default_role #---------------------------------------|TIMEZONE|------------------------# #---//Set timezone, which will be used on the host.//---------------------# timezone::timezone: Europe/Moscow #---------------------------------------|FACTS|---------------------------# #---//Facts are variables which puppet agent uses.//----------------------# facter::facts_hash: role: value: 'name' company: value: 'name of company' file: 'location.txt' #=========================================================================# #============================|PUPPET|=====================================# #---//Settings for puppet agent.//----------------------------------------# puppet::runmode: cron puppet::ca_server: puppet::puppetmaster: #=========================================================================# #============================|CRON TASKS|=================================# cron_tasks: Name: command: user: minute: '' hour: '' #=========================================================================# #============================|SUPERVISOR|=================================# #---//Supervisor is a process manager//-----------------------------------# supervisord::install_pip: false supervisord::install_init: false supervisord::service_name: supervisor supervisord::package_provider: apt supervisord::executable: /usr/bin/supervisord supervisord::executable_ctl: /usr/bin/supervisorctl supervisord::config_file: /etc/supervisor/supervisord.conf supervisord::programs: 'name': ensure: present command: 'su - rails -c "/home/name/s2"' autostart: no autorestart: 'false' directory: /home/name/domainName/current #=========================================================================# #============================|SECURITY|===================================# #-------------------------------------|FIREWALL|--------------------------# #---//Iptables rules//----------------------------------------------------# firewall: 096 Allow inbound SSH: dport: proto: tcp action: accept #-------------------------------------|FAIL2BAN|--------------------------# #-------------------------------------|ACCESS|----------------------------# #--------------------------------------------|ACCOUNTS|-------------------# #---//Discription of accounts which will be created on server.//----------# accounts: user: shell: '/bin/bash' password: '' locked: false purge_sshkeys: true groups: - docker sshkeys: - #--------------------------------------------|SUDO|-----------------------# #---//Appointment permissions for users.//--------------------------------# sudo::config_file_replace: false sudo::configs: user: content: #--------------------------------------------|SSH|------------------------# #--------//Settings for ssh server.//-------------------------------------# ssh::storeconfigs_enabled: true ssh::server_options: Protocol: '2' Port: PasswordAuthentication: 'yes' PermitRootLogin: 'without-password' SyslogFacility: 'AUTHPRIV' UsePAM: 'yes' X11Forwarding: 'no' #--------------------------------------------|VPN|------------------------# #---//Settings for vpn server.//------------------------------------------# openvpn::servers: 'namehost': country: '' province: '' city: '' organization: '' email: '' server: 'xxxx 255.255.255.0' dev: tun local: openvpn::client_defaults: server: 'namehost' openvpn::clients: # Firstname Lastname 'user': {} openvpn::client_specific_configs: 'user': server: 'namehost' redirect_gateway: true route: - xxxx 255.255.255.255 #=========================================================================# #============================|OPERATING SYSTEM|===========================# #---------------------------------------------|SYSCTL|--------------------# #---//set sysctl parameters//---------------------------------------------# sysctl::base::values: fs.file-max: value: '2097152000' net.netfilter.nf_conntrack_max: value: '1048576' net.nf_conntrack_max: value: '1048576' net.ipv6.conf.all.disable_ipv6: value: '1' vm.oom_kill_allocating_task: value: '1' net.ipv4.ip_forward: value: '0' net.ipv4.tcp_keepalive_time: value: '3' net.ipv4.tcp_keepalive_intvl: value: '60' net.ipv4.tcp_keepalive_probes: value: '9' #---------------------------------------------|RCS|-----------------------# #---//Managment of RC scenario//------------------------------------------# rcs::tmptime: '-1' #---------------------------------------------|WEB SERVERS|---------------# #---------------------------------------------------------|HAPROXY|-------# #---//HAProxy is software that provides a high availability load//--------# #---//balancer and proxy server for TCP and HTTP-based applications//-----# #---// that spreads requests across multiple servers.//-------------------# haproxy::merge_options: true haproxy::defaults_options: log: global maxconn: 20000 option: [ 'tcplog', 'redispatch', 'dontlognull' ] retries: 3 stats: enable timeout: [ 'http-request 10s', 'queue 1m', 'check 10s', 'connect 300000000ms', 'client 300000000ms', 'server 300000000ms' ] haproxy_server: stats: ipaddress: ports: '9090' options: mode: 'http' stats: [ 'uri /', 'auth puppet:123123123' ] postgres: collect_exported: false ipaddress: '0.0.0.0' ports: '5432' options: option: - tcplog balance: roundrobin haproxy_balancemember: hostname1: listening_service: postgres server_names: hostname1 ipaddresses: ports: 6432 options: check hostname2: listening_service: postgres server_names: hostname2 ipaddresses: ports: 6432 options: - check - backup #---------------------------------------------|NGINX|---------------------# #---//Nginx is a web server which can also be used as a reverse proxy,//--# #---//load balancer, mail proxy and HTTP cache//--------------------------# nginx::nginx_cfg_prepend: 'load_module': - modules/ngx_http_geoip_module.so nginx::http_raw_append: - 'real_ip_header X-Forwarded-For;' - 'geoip_country /usr/share/GeoIP/GeoIP.dat;' - 'set_real_ip_from 0.0.0.0/0;' nginx::worker_rlimit_nofile: 16384 nginx::confd: true nginx::server_purrge: true nginx::server::maintenance: true #---------------------------------------------nginx-|MAPS|----------------# nginx::string_mappings: allowed_country: ensure: present string: '$geoip_country_code' mappings: - key: 'default' value: 'yes' - key: 'US' value: 'no' #---------------------------------------------nginx-|UPSTREAMS|-----------# nginx::nginx_upstreams: : ensure: present members: - #---------------------------------------------nginx-|VHOSTS|--------------# nginx::nginx_servers: 'hostname': proxy: 'http://' location_raw_append: - 'if ($allowed_country = no) {return 403;}' try_files: - '' - /index.html - =404 ssl: true ssl_cert: ssl_key: ssl_trusted_cert: ssl_redirect: false ssl_port: 443 error_pages: '403': /usa-restrict.html #---------------------------------------------nginx-|HTTPAUTH|------------# httpauth: 'admin': file: password: '' realm: realm mechanism: basic ensure: present #---------------------------------------------nginx-|LOCATIONS|-----------# nginx::nginx_locations: 'domain1.com/usa-restricted': location: /usa-restrict.html www_root: /home/clientName1/clientName1-client-release/current/dist server: domain1.com ssl: true '^~ domain2.com/resources/upload/': location: '^~ /resources/upload/' server: domain2.com location_alias: '/home/clientName2/upload/' raw_append: - 'if ($allowed_country = no) {return 403;}' '/nginx_status-domain3.com': location: /nginx_status stub_status: on raw_append: - access_log off; - allow 127.0.0.1; - deny all; #---------------------------------------------nginx-|WELL-KNOWN|----------# #---//These locations are needed for SSL certificates generating//--------# #---//with Letsencrypt.//-------------------------------------------------# 'x.hostname.zz/.well-known': location: '/.well-known' server: x.hostname.zz proxy: 'http://kibana' auth_basic: auth_basic_user_file: add_header Pragma public;public, must-revalidate, proxy-revalidate/home/hostname/hostname-release/shared/ecosystem.config.jslogslog_typeformat%{::domain}%{lookup('host_address')}/32(rw,fsid=root,insecure,no_subtree_check,async,no_root_squash)host_addresso=Debian,n=${distro_codename}o=Debian,n=${distro_codename}-securityo=Debian,n=${distro_codename}-updateso=Debian,n=${distro_codename}-proposedo=Debian,n=${distro_codename}-backportso=debian icinga,n=icinga-${distro_codename}o=Zabbix,n=${distro_codename}%{lookup('my_ftp_hostname')}%{lookup('my_backup_ftp_username')}%{lookup('my_backup_ftp_password')}%{lookup('my_backup_compressor')}/tmp/mediastagetv_netbynet%{lookup('host_address')}:/%{lookup('host_address')}redis%{lookup('host_address')}*.*;auth,authpriv.none /var/log/syslog\nmail.* -/var/log/mail.log\n& stopauth,authpriv.* /var/log/auth\n& stop:programname,contains,\ /var/log/puppetlabs/puppet/puppet-agent.log\n& stop:msg,contains,\ /var/log/iptables/iptables.log\n& stop:msg,regex,\ /var/log/admin/auth.log\n& stop:msg,regex,\ /var/log/admin/auth.log\n& stop #---------------------------------------------|LOGWATCH|------------------# #---//Logwatch is a log-analysator for create short reports.//------------# logwatch::format: text logwatch::service: # Ignore this servie - -http - -iptables #---------------------------------------------|LOGROTATE|-----------------# #---//Management of rotation of log files.//------------------------------# my_rclogs_path: '/home/hostname/hostname/shared/log' my_rclogs_amazon_path: '/home/hostname1/hostname1/shared/log_amazon' my_ttlogs_path: '/home/hostname2/hostname2/shared/log' my_ttlogs_amazon_path: '/home/hostname/hostname/shared/log_amazon' logrotate::ensure: latest logrotate::config: dateext: true compress: true logrotate::rules: booking-logs: path: '%{lookup("my_rclogs_path")}/booking_com.log' size: 2500M rotate: 20 copytruncate: true delaycompress: true dateext: true dateformat: -%Y%m%d-%s compress: true postrotate: mv %{lookup('my_rclogs_path')}/booking_com.log*.gz %{lookup('my_rclogs_amazon_path')}/ #---------------------------------------------|ATOP|----------------------# #---//ATOP service displays a new information about CPU//-----------------# #---//and memory utilization.//-------------------------------------------# atop::service: true atop::interval: 30 #----------------------------------------|DNS|----------------------------# #---//Management of file /etc/resolv.conf//-------------------------------# resolv_conf::nameservers: - 0.0.0.0 - 0.0.0.0 #=========================================================================# #============================|DATABASES|==================================# #--------------------------------------|MYSQL|----------------------------# #---//MySQL is a relational database management system.//-----------------# mysql::server::package_ensure: 'installed' #· mysql::server::root_password: mysql::server::manage_config_file: true mysql::server::service_name: 'mysql' # required for puppet module mysql::server::override_options: 'mysqld': 'bind-address': '*' : , : , : , mysql::server::db: : user: password: host: grant: - #-------------------------------------|ELASTICSEARCH|---------------------# #---//Elasticsearch is a search engine based on Lucene.//-----------------# #---//It provides a distributed, multitenant-capable full-text search//---# #---//engine with an HTTP web interface and schema-free JSON documents.//-# elasticsearch::version: 5.5.1 elasticsearch::manage_repo: true elasticsearch::repo_version: 5.x elasticsearch::java_install: false elasticsearch::restart_on_change: true elasticsearch_instance: 'es-01': ensure: 'present' #-------------------------------------|REDIS|-----------------------------# #---//Redis is an in-memory database project implementing//---------------# #---//a distributed, in-memory key-value store with//---------------------# #---//optional durability.//----------------------------------------------# redis::bind: 0.0.0.0 #-------------------------------------|ZOOKEPER|--------------------------# #---//Zooker is a centralized service for distributed systems//-----------# #---//to a hierarchical key-value store, which is used to provide//-------# #---//a distributed configuration service, synchronization service,//-----# #---//and naming registry for large distributed systems.//----------------# zookeeper::init_limit: '1000' zookeeper::id: '1' zookeeper::purge_interval: '1' zookeeper::servers: - #-------------------------------------|POSTGRES|--------------------------# #---//Postgres, is an object-relational database management system//------# #---//with an emphasis on extensibility and standards compliance.//-------# #---//As a database server, its primary functions are to store data//----# #---//securely and return that data in response to requests from other//--# #---//software applications.//--------------------------------------------# postgresql::server::postgres_password: postgresql::server::ip_mask_allow_all_users: '0.0.0.0/0' postgresql::postgresql::server: ip_mask_allow_all_users: '0.0.0.0/32' postgres_db: master: user: password: confluence: user: password: postgres_config: 'max_connections': value: 300 postgres_hba: 'Allow locals without password': order: 1 description: 'locals postgres no password' type: 'host' address: '127.0.0.1/32' database: 'all' user: 'all' auth_method: 'trust' #----------------------------------------------|PGBOUNCER|----------------# #---//PgBouncer is a connection pooler for PostgreSQL//-------------------# pgbouncer::group: postgres pgbouncer::user: postgres pgbouncer::userlist: - user: password: pgbouncer::databases: - source_db: recommender host: dest_db: recommender auth_user: recommender pool_size: 200 auth_pass: - source_db: master host: dest_db: recommender auth_user: recommender pool_size: 50 auth_pass: - source_db: slave host: dest_db: recommender auth_user: recommender pool_size: 200 auth_pass: #=========================================================================# #==============================|APPLICATION SERVICES|=====================# #---------------------------------------------------|CONFLUENCE|----------# #---------------------------------------------------|JENKINS|-------------# #=========================================================================#
Beispiel für einen Überwachungsabschnitt:
#============================|MONITORING|=================================# #---------------------------------------|ICINGA SERVICES|-----------------# #---//Managment of monitoring system.//-----------------------------------# icinga2_service: '%{::fqdn} virtual host' : target: /etc/icinga2/zones.d/master/%{::fqdn}.conf apply: true assign: [ 'host.name == %{::fqdn}' ] display_name: '%{::fqdn} virtualhost' check_command: 'http' vars: http_uri: / http_ssl: true http_vhost: 'hostname' http_address: '%{::fqdn} nginx status' : target: /etc/icinga2/zones.d/master/%{::fqdn}.conf apply: true assign: [ 'host.name == %{::fqdn}' ] command_endpoint: '%{::fqdn}' display_name: 'nginx status' check_command: 'nginx_status' vars: nginx_status_host_address: localhost nginx_status_servername: server.com nginx_status_critical: '1600,60,30' nginx_status_warn: '1500,55,25' '%{::fqdn} redis': target: /etc/icinga2/zones.d/master/%{::fqdn}.conf apply: true assign: [ 'host.name == %{::fqdn}' ] display_name: 'Redis' command_endpoint: '%{::fqdn}' check_command: vars: redis_hostname: localhost redis_port: 6379 redis_perfvars: '*' #=========================================================================#
Das allgemeine Funktionsschema eines solchen Schemas besteht nur aus zwei einfachen Aktionen:
- Wir starten Puppet auf dem Host - der Host sieht die dazugehörigen Schecks und exportiert sie in PuppetDB.
- Führen Sie Puppet im Icinga2-Container aus - Checks von Puppetdb werden zu echten Icinga2-Konfigurationen.
Hier werden viele sagen:
"Warum muss ich das alles möglich machen, wenn ich das übliche Icinga2 erhöhen und Schecks mit meinen Händen oder über die Weboberfläche hinzufügen kann?"In der Tat macht es keinen Sinn, einen Garten einzäunen, wenn Sie ein Dutzend Hosts mit Hunderten von Diensten überwachen müssen und eine ziemlich nette Person mit gutem Gedächtnis sind (nicht in der Natur zu finden). Ganz anders ist es, wenn Sie über eine ziemlich große Infrastruktur verfügen und das Gefühl haben, irgendwo etwas vergessen zu haben. In solchen Momenten hilft die Automatisierung sehr, weil hilft, alles in die Regale zu stellen und in vielerlei Hinsicht den menschlichen Faktor zu vermeiden.
Bezeichnen Sie die Hauptvorteile:
Schauen wir uns diese Vorlage an: icinga2_service: '%{::fqdn} disk service': target: /etc/icinga2/zones.d/master/%{::fqdn}.conf apply: true assign: [ 'host.name == %{::fqdn}' ] display_name: 'Disk usage' command_endpoint: '%{::fqdn}' check_command: 'disk' vars: #All disks disk_all: true disk_exclude_type: - aufs - tmpfs disk_ignore_ereg_path: - /run/docker
+ 1. Hiera — .. . Icinga2, , . , , , .
+ 2. , . — .
+ 3. , .. , Icinga2 , puppet Icinga2.
+ 4. puppetDB , .
,
1. puppet.
docker docker-compose.
, :
Docker...Docker-compose...2. :
git clone http://git.comgress64.com/external/puppet-icinga2-how-to.git
3. docker-compose.yaml .
, — PuppetServer, PuppetDb, PostgreSQL PuppetBoard. volumes . , . - PostgreSQL , - — . — . , :
4. Puppet, Postgres, Puppetdb Graphite
, PostgreSQL. , — , . - . Ctrl+C, .
5. puppet master:
docker run --net puppeticinga2howto_default --link puppet:puppet puppet/puppet-agent
6. , :
Notice: Applied catalog in 0.03 seconds Changes: Total: 1 Events: Success: 1 Total: 1 Resources: Changed: 1 Out of sync: 1 Total: 8 Time: Schedule: 0.00 File: 0.00 Transaction evaluation: 0.01 Catalog application: 0.03 Convert catalog: 0.04 Config retrieval: 0.45 Node retrieval: 1.38 Last run: 1532605377 Fact generation: 2.24 Plugin sync: 4.50 Filebucket: 0.00 Total: 8.65 Version: Config: 1532605376 Puppet: 5.5.1
c Icinga2.
7. Dockerfile, :
docker-compose build icinga
8. , Icinga2.
docker-compose up -d icinga
9. . icinga2 Puppet , :
10. Icinga, Icingaweb2 Apache.
Icinga2 !
Icingaweb2
1. , .
, :
http://ip___:8081/icingaweb2
Icinga c :
icingaadmin/icinga .
:
, :
:
- Icinga2, Icinga, .
2.
icinga2 — Icinga. .
, :
puppet:
. hostname , : docker run --hostname example.com --rm -t --link puppet:puppet --net puppeticinga2howto_default -i phusion/baseimage:latest /sbin/my_init -- bash -l
puppet : apt-get update && apt-get install -y ruby make gcc perl-modules && gem install --no-ri --no-rdoc puppet
puppet: puppet agent --server puppet --waitforcert 60 --test
icinga2 puppetDB. , puppet icinga2: docker-compose exec icinga puppet agent --server puppet --waitforcert 60 --test
, :
.5 :
. , production .
, , , . , , .
Vielen Dank für Ihre Aufmerksamkeit!
Confluence:/ ./docs.comgress64.com/...:https://github.com/Icinga/puppet-icinga2https://forge.puppet.com/icinga/icingaweb2https://docs.docker.com/https://docs.puppet.com/https://docs.puppet.com/hiera/