Automatización de un sistema de monitoreo basado en Icinga2 y Puppet

Automatización de un sistema de monitoreo basado en Icinga2 y Puppet


Hablemos un poco sobre ... Infraestructura como código (IaC).


En Habré hay algunos artículos muy buenos sobre Icinga2, también hay excelentes artículos sobre Puppet:

Icinga2 es una opción fácil
Elevamos la micromonitorización en icinga2 con los gastos mínimos
Configurar un servidor Puppet moderno desde cero

Sin embargo, el tema de la automatización y la integración de estos dos sistemas sorprendentes no se revela en absoluto.
En esta guía, mostraré en un ejemplo "vivo" cómo puede combinar estos dos
sistemas, obtenga una herramienta poderosa para monitorear su infraestructura con todas las funciones necesarias. Este artículo es una especie de guía de acción para instalar el paquete "todo en una botella". Después de completar esta guía, tendrá disponible una solución de monitoreo completamente operativa, que puede "terminar" por su cuenta. ¡Intentémoslo!

Entonces


Criamos un nuevo anfitrión. Y necesitamos:


1. Para que su monitoreo aparezca automáticamente en Icinga2, y se creen verificaciones básicas:


Cheques
Instantáneas
Explicaciones
Anfitrión



A una frecuencia dada, verificamos con el comando ping que el host está "en vivo".
Uso del disco



Compruebe que tenemos suficiente espacio libre en disco.
Carga media



Monitoreamos la carga en el servidor dinámicamente. Se tiene en cuenta la cantidad de procesadores que contiene.
Memoria libre



Verificamos que tenemos suficiente memoria libre en el servidor.
Puertos abiertos



Escaneamos los puertos en el servidor y creamos un mapa de puertos abiertos. Controlamos que no teníamos nuevos puertos abiertos o cerrados.
Actualizaciones críticas



Monitoreamos la presencia de actualizaciones críticas en el servidor.


2. Agregue cheques personalizados para varios servicios de una manera conveniente y comprensible. ¡Qué le mostraría al director qué buenos compañeros somos y obtendríamos un premio!


Algunos ejemplos:
Servicio
Código de verificación YAML
Host virtual
Verifique el host "en vivo" o no.




'%{::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
Verifique que podamos conectarnos a la base de datos PostgreSQL.




  '%{::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 

Estado de Nginx
Monitoreamos el estado de Nginx a través de 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. Que todo estaba ordenado, confiable y hermoso. Y lo más importante, no pase más de 30 minutos preocupados con la configuración inicial.


Debe tener experiencia con Docker y, por lo tanto, con Linux, por sí mismo.

Esta configuración se describe en Debian / Ubuntu. Y, aunque no veo ninguna razón para que no trabaje en otros sistemas similares a Unix, yo mismo no puedo dar tales garantías. Tengo un par de máquinas con CentOS, funciona allí, pero la mayoría, sin embargo, son Debian / Ubuntu.

Empecemos


Diré de inmediato, es conveniente para mí cuando toda la configuración del host es servicios, configuraciones, software, cuentas, etc. - están descritos por un archivo yaml, esto en realidad evita documentar la infraestructura y proporciona una configuración clara. Abrió el proyecto correspondiente en el repositorio de git, donde los nombres de los archivos corresponden al nombre del host, luego abrió la configuración del host deseado. Y puede ver de inmediato qué servicios hay en el host, qué se respalda de esto, qué se supervisa, etc.

Así es como se ve la estructura del proyecto en el repositorio:

 project_1/hostname1.com.yaml project_2/hostname2.com.yaml project_3/hostname3.com.yaml 

Utilizo aquí una plantilla de este tipo, que describe la configuración de cualquiera de nuestros servidores:

Plantilla completa
 #============================|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: "%{lookup('puppet_ca')}" puppet::puppetmaster: "%{lookup('puppet_master')}" #=========================================================================# #============================|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: "%{lookup('my_ssh_port')}" 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: - "%{alias('admins_ssh_keys')}" #--------------------------------------------|SUDO|-----------------------# #---//Appointment permissions for users.//--------------------------------# sudo::config_file_replace: false sudo::configs: user: content: "user ALL=(ALL) NOPASSWD: ALL" #--------------------------------------------|SSH|------------------------# #--------//Settings for ssh server.//-------------------------------------# ssh::storeconfigs_enabled: true ssh::server_options: Protocol: '2' Port: "%{lookup('my_ssh_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: "%{lookup('host_address')}" 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: "%{lookup('host_address')}" 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: "%{lookup('host1_ip')}" ports: 6432 options: check hostname2: listening_service: postgres server_names: hostname2 ipaddresses: "%{lookup('host2_ip')}" 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: "upstreamName": ensure: present members: - "localhost:9999" #---------------------------------------------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: "/etc/letsencrypt/live/hostname/fullchain.pem" ssl_key: "/etc/letsencrypt/live/hostname/privkey.pem" ssl_trusted_cert: "/etc/letsencrypt/live/hostname/chain.pem" ssl_redirect: false ssl_port: 443 error_pages: '403': /usa-restrict.html #---------------------------------------------nginx-|HTTPAUTH|------------# httpauth: 'admin': file: "/etc/nginx/htaccess" 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: "ciao" auth_basic_user_file: "/etc/nginx/htaccess www_root: /var/www/html ssl: true 'hostname.zz/~* \.(?:ico|css|js|html|map|gif|jpg|png|svg|ttf|woff|appcache|pdf)$': location: '~* \.(?:ico|css|js|html|map|gif|jpg|png|svg|ttf|woff|appcache|pdf)$' www_root: '/home/hostname/hostname-client-release/current/dist' expires: max raw_append: - "add_header Pragma public;" - 'add_header Cache-Control "public, must-revalidate, proxy-revalidate";' #---------------------------------------------------|NGINS STATUS|--------# #----------------------------|LETSENCRYPT|--------------------------------# #---//Let's Encrypt is a certificate authority that provides #---//free X.509 certificates for Transport Layer Security (TLS)//--------# #---//encryption via an automated process designed to eliminate//---------# #---//the hitherto complex process of manual creation, validation,//------# #---//signing, installation, and renewal of certificates//----------------# #---//for secure websites.//----------------------------------------------# letsencrypt::email: client@mail.com letsencrypt_certonly: hostname: manage_cron: true domains: - hostname plugin: webroot webroot_paths: - '/var/www/html' #----------------------------|FILE SERVERS|-------------------------------# #-----------------------------------------|FILES|-------------------------# #---//Creating files & folders on the server.//---------------------------# file: "/home/hostname/hostname-release/shared/ecosystem.config.js": ensure: present owner: hostname content: | module.exports = { /** * Application configuration section * http://pm2.keymetrics.io/docs/usage/application-declaration/ */ apps : [ // First application { name : 'api', script : '/home/hostname/hostname-release/current/dist/index.js', cwd : '/home/hostname/hostname-release/current/dist/', watch : false, ignore_watch : ["logs"], "log_type": "format", env: { COMMON_VARIABLE: 'true' }, env_production : { NODE_ENV: 'production', PORT: 9999, DEBUG : '*' }, env_development : { NODE_ENV: 'development', PORT: 9999, DEBUG : '*' } }, // Second application { name : 'WEB', script : 'web.js' } ], /** * Deployment section * http://pm2.keymetrics.io/docs/usage/deployment/ */ deploy : { production : { user : 'node', host : '0.0.0.0', ref : 'origin/master', repo : 'name@name.com:repo.git', path : '/var/www/production', 'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production' }, dev : { user : 'node', host : '0.0.0.0', ref : 'origin/master', repo : 'name@name.com:repo.git', path : '/var/www/development', 'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env dev', env : { NODE_ENV: 'dev' } } } }; #-----------------------------------------|FTP|----------------------------# #---//Very Secure FTP Daemon is an FTP server for Unix-like systems.//-----# vsftpd::ftpd_banner: 'ASCII FTP Server' vsftpd::anonymous_enable: 'NO' vsftpd::write_enable: 'YES' vsftpd::chroot_local_user: 'YES' vsftpd::allow_writeable_chroot: 'YES' vsftpd::userlist_enable: 'YES' vsftpd::userlist_deny: 'NO' #-----------------------------------------|NFS|---------------------------# #---//Network File System is a distributed file system protocol,//--------# #---//allowing a user on a client computer to access files over//---------# #---//a computer network much like local storage is accessed.//-----------# nfs::server_enabled: true nfs::client_enabled : false nfs::nfs_v4: true nfs::nfs_v4_idmap_domain: "%{::domain}" nfs::nfs_v4_export_root: '/share' nfs::nfs_v4_export_root_clients: "%{lookup('host_address')}/32(rw,fsid=root,insecure,no_subtree_check,async,no_root_squash)" nfs::nfs_exports_global: /var/www: {} /var/smb: {} #----------------------------|PACKAGES|-----------------------------------# #---//Install of packages to server.//------------------------------------# packages: namePackage: ensure: installed #-------------------------------------|APT|-------------------------------# #---//Management of repository of packages.//---# apt::sources: 'debian_unstable': comment: 'This is the iWeb Debian unstable mirror' location: 'http://debian.mirror.iweb.ca/debian/' release: 'unstable' repos: 'main contrib non-free' pin: '-10' key: id: 'IDIDIDIDIDIDIDIDIDIDIDIDIDIDIDID' server: 'subkeys.pgp.net' include: src: true deb: true 'puppetlabs': location: 'http://apt.puppetlabs.com' repos: 'main' key: id: 'IDIDIDIDIDIDIDIDIDIDIDIDIDIDIDID' server: 'pgp.mit.edu' #-------------------------------------|PHP|-------------------------------# php_pool: myadmin: listen: 'xxxx:x' #-------------------------------------|RVM|-------------------------------# #---//Ruby Version Manager is a unix-like software platform designed//---# #---//to manage multiple installations of Ruby on the same device.//------# rvm_ruby: user1_rvm: user: user1 version: ruby-2.5.1 white_label_platform: default #-------------------------------------|PYTHON|----------------------------# python::version: system python::dev: present python::virtualenv: true #----------------------------|NODEJS|-------------------------------------# #-----------------------------------|NVM|---------------------------------# #---//Node Version Manager for Node.js//----------------------------------# #---//Node.js lets developers use JavaScript to write Command Line//------# #---//tools and for server-side scripting—running scripts server-side//---# #---//to produce dynamic web page content before the page is sent//-------# #---//to the user's web browser.//----------------------------------------# nodejs::repo_url_suffix: '8.x' nvm::user: name nvm::install_node: 8.10.0 #----------------------------|DOCKER|-------------------------------------# #---//Docker's management//-----------------------------------------------# docker::run_instance::instance: nats: image: 'nats' extra_parameters: '-p 8222:8222 -p 4222:4222 -p 6222:6222 --name nats --network admin_default' docker::compose::ensure: present docker_compose: /etc/admin/gitlab/docker-compose.yaml: ensure: present docker::iptables: false docker::tcp_bind: tcp://0.0.0.0:2375 docker::compose::ensure: present docker_swarm: 'agent': ensure: present join: true advertise_addr: '%{::ipaddress_enp2s0}' listen_addr: '%{::ipaddress_enp2s0}' manager_ip: '%{lookup("host_address")}' token: '' docker_registry: 'host.com:5000': username: '' password: '' email: 'mail@mail.com' #=========================================================================# #============================|BACKUPS UPDATES|============================# #--------------------------------------------|UPDATES|--------------------# #---//Unattended upgrades is the linux-like mechanism//-------------------# #---//automatic updates.//------------------------------------------------# unattended_upgrades::origins: - "o=Debian,n=${distro_codename}" - "o=Debian,n=${distro_codename}-security" - "o=Debian,n=${distro_codename}-updates" - "o=Debian,n=${distro_codename}-proposed" - "o=Debian,n=${distro_codename}-backports" - "o=debian icinga,n=icinga-${distro_codename}" - "o=Zabbix,n=${distro_codename}" #--------------------------------------------|BACKUPS|--------------------# #---//The backups are processed by gembackup.//---------------------------# backup_jobs: #Creates full backup type_files: types: ['archive'] add: - '/path' storage_type: 'ftp' storage_host: "%{lookup('my_ftp_hostname')}" path: '/files/' storage_username: "%{lookup('my_backup_ftp_username')}" storage_password: "%{lookup('my_backup_ftp_password')}" compressor: "%{lookup('my_backup_compressor')}" keep: 7 weekday: [1-7] hour: 0 minute: 0 #--------------------------------------------|MOUNT|----------------------# #---//ontrol the mounting of remote & local mount points.//--------------# mount: #Mount folder from other server to keep backups "/tmp/mediastagetv_netbynet": device: "%{lookup('host_address')}:/" ensure: mounted fstype: nfs4 options: defaults atboot: false #--------------------------------------------|S3 AMAZON|------------------# #---//Simple Storage Service is a cloud computing web service.//----------# hostname1-archives: '/home/hostname1/hostname1/shared/log_amazon' hostname2-archives: '/home/hostname2/hostname2/shared/log_amazon' yas3fs::mounts: #=========================================================================# #============================|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: "%{lookup('host_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: "redis" vars: redis_hostname: localhost redis_port: 6379 redis_perfvars: '*' #=========================================================================# #============================|MAIL & LOGS|================================# #----------------------------------------|MAIL|---------------------------# #---------------------------------------------|POSTFIX|-------------------# #---//Management of mail-server Postfix.//--------------------------------# postfix::manage_conffiles: false postfix_config: relayhost: ensure: present value: "%{lookup('host_address')}" virtual_maps: value: hash:/etc/postfix/virtual ensure: present sender_canonical_map: value: hash:/etc/postfix/canonical_sender ensure: present postfix_hash: '/etc/postfix/virtual': ensure: present content: | root %{lookup('hostname_admin_emails')} rails %{lookup('hostname_emails')} '/etc/postfix/canonical_sender': ensure: present content: | name@%{lookup('my_domain')} name@my_domain.com root@%{lookup('my_domain')} root@my_domain.com #----------------------------------------|LOGS|---------------------------# #---------------------------------------------|RSYSLOG|-------------------# #---//Rsyslog is a software utility for forwarding log messages//---------# #---//in an IP network. It implements the basic syslog protocol,//--------# #---//extends it with content-based filtering, rich filtering//-----------# #---//capabilities, flexible configuration options and adds features//----# #---//such as using TCP for transport.//----------------------------------# rsyslog::client: log_local: true my_rsyslog_snippet: 99_everything: content: "*.*;auth,authpriv.none /var/log/syslog\n" 01_mail: content: "mail.* -/var/log/mail.log\n& stop" 02_auth: content: "auth,authpriv.* /var/log/auth\n& stop" 03_puppetagent: content: ":programname,contains,\"puppet-agent\" /var/log/puppetlabs/puppet/puppet-agent.log\n& stop" 04_iptables: content: ":msg,contains,\"IPTABLES INPUT\" /var/log/iptables/iptables.log\n& stop" 05_pam_unix: content: ":msg,regex,\".*session opened for.*(uid=0)\" /var/log/admin/auth.log\n& stop" 06_sshd: content: ":msg,regex,\".*publickey for username.*0.0.0.0\" /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: "ooy5ieneePahnei" mysql::server::manage_config_file: true mysql::server::service_name: 'mysql' # required for puppet module mysql::server::override_options: 'mysqld': 'bind-address': '*' "userName": "", "password": "", "databaseName": "", mysql::server::db: "hostname": user: "" password: "" host: "%" grant: - "ALL" #-------------------------------------|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: - "%{lookup('host')}" #-------------------------------------|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: "%{lookup('')}" dest_db: recommender auth_user: recommender pool_size: 200 auth_pass: - source_db: master host: "%{lookup('')}" dest_db: recommender auth_user: recommender pool_size: 50 auth_pass: - source_db: slave host: "%{lookup('')}" dest_db: recommender auth_user: recommender pool_size: 200 auth_pass: #=========================================================================# #==============================|APPLICATION SERVICES|=====================# #---------------------------------------------------|CONFLUENCE|----------# #---------------------------------------------------|JENKINS|-------------# #=========================================================================# 



Ejemplo de sección de monitoreo:


 #============================|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: "%{lookup('host_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: "redis" vars: redis_hostname: localhost redis_port: 6379 redis_perfvars: '*' #=========================================================================# 


El esquema general de operación de dicho esquema consta de solo dos acciones simples:


  1. Iniciamos puppet en el host: el host ve los controles que le pertenecen y los exporta a puppetDB.

  2. Ejecute puppet en el contenedor icinga2: las comprobaciones de puppetdb se convierten en configuraciones reales de Icinga2.


Aquí, muchos dirán: "¿Por qué tengo que hacer que todo esto suceda, si puedo subir el icinga2 habitual y agregar cheques con mis manos o a través de la interfaz web?"

De hecho, si necesita monitorear una docena de hosts con cientos de servicios, y es una persona bastante ordenada con buena memoria (no se encuentra en la naturaleza), entonces no tiene sentido cercar un jardín. Es una cuestión completamente diferente si tiene una infraestructura bastante grande y existe la sensación de que puede haber olvidado algo en alguna parte. En esos momentos, la automatización ayuda mucho, porque ayuda a poner todo en los estantes y evitar, de muchas maneras, el factor humano.

Denote las principales ventajas:


Veamos esta plantilla:

 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/* - /sys/* - /var/lib/docker* - /var/lib/ureadahead/debugfs/* - /run/user/* 

+ 1. Hiera — .. . Icinga2, , . , , , .

+ 2. , . — .

+ 3. , .. , Icinga2 , puppet Icinga2.

+ 4. Entonces, todas las comprobaciones que hemos almacenado en una sola base de datos puppetDB podemos crear scripts bastante potentes para una mayor automatización, en la que utilizaremos esta información.


Así que vamos


1. Configurar la marioneta.


Espero que hayas configurado docker y docker-compose.
Si no, entonces necesita instalarlos:
Instalando Docker ...
Instalando Docker-compose ...

2. Clonamos el repositorio en nuestro servidor:


 git clone http://git.comgress64.com/external/puppet-icinga2-how-to.git 

3. Abra docker-compose.yaml con su editor favorito y mírelo.


Vemos que en este paquete tenemos varios contenedores aumentando a la vez: PuppetServer, PuppetDb, servidor PostgreSQL y PuppetBoard. También montó volúmenes del directorio actual. Esta configuración no es óptima para todos, así que considere su infraestructura. Alguien ya tiene un servidor PostgreSQL, alguien quiere almacenar código en otra sección: aquí hay libertad para la creatividad. En esta etapa, sugiero que deje la plantilla predeterminada; siempre puede volver a ella más tarde. Recojamos nuestro paquete de contenedores y veamos qué sucedió:

4. Inicie el contenedor Puppet, Postgres, Puppetdb y Graphite.


 #  Puppet, Postgres  Puppetdb #  Puppet, Postgres, Puppetdb  Graphite cd puppet-icinga2-how-to docker-compose up -d puppet puppetdb-postgres puppetdb graphite && docker-compose logs -f 

Ahora hemos cargado varias imágenes y lanzado contenedores, creado bases de datos en PostgreSQL. Esperemos hasta que se inicien todos los servidores: los errores se pueden ignorar, ya que deberían estabilizarse después de un tiempo. Presione Ctrl + C para salir del modo de vista de registro.

5. Comprueba el trabajo de nuestro titiritero:


 docker run --net puppeticinga2howto_default --link puppet:puppet puppet/puppet-agent 

6. Si todo está bien, verá esta conclusión:


 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 

Configure el servidor Icinga2.

7. Haga la imagen desde el Dockerfile haciendo:


 docker-compose build icinga 

8. Ejecute el contenedor en el que vivirá el servidor Icinga2.


 docker-compose up -d icinga 

9. Hasta ahora, nuestro contenedor está vacío. Configuremos el servidor icinga2 usando nuestro servidor Puppet haciendo:


 #   puppet  librarian-puppet   puppet docker-compose exec puppet bash -c 'cd /etc/puppetlabs/code && gem install librarian-puppet && librarian-puppet install --verbose' # Puppet   Icinga     docker-compose exec icinga puppet agent --server puppet --waitforcert 60 --test 

10. Instale y configure Icinga, Icingaweb2 y Apache.


¡Su servidor Icinga2 está listo!


Icingaweb2


1. Veamos que tenemos.


Es conveniente observar el estado del sistema de monitoreo en el navegador, hacer:
Abrir en el navegador http://ip___:8081/icingaweb2y acceder a Icinga con el inicio de sesión predeterminado: icingaadmin / icinga .

Vemos esta imagen:



después de unos minutos, vemos que todas las comprobaciones funcionaron para nosotros: los



gráficos también funcionan:



tenemos un entorno web funcional para Icinga2, pero todavía no hay hosts conectados a Icinga, conectemos nuestro primer host.

2. Conecte el nuevo host al sistema de monitoreo.


Ahora solo tenemos un host conectado a icinga2: el propio Icinga. Vamos a conectar otro.
Estoy mostrando un ejemplo en una ventana acoplable, pero de todos modos funcionará en metal desnudo:

primero debe preparar una plantilla y proporcionar información sobre el host para títeres:

 #    cd puppet-icinga2-how-to/code/environments/production/hieradata/nodes #    (   ) cp template.yaml example.com.yaml #       : host_address: 172.18.0.7 my_company: COMGRESS64 my_package_manager: apt my_ssh_port: 22 #    

. 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 

Miramos a través del navegador lo que obtuvimos:



se han agregado cheques y están a la espera de completarse.
Después de 5 minutos: de



la misma manera, todos los demás hosts se agregan al sistema. Quiero llamar su atención sobre el hecho de que esta guía es una prueba de concepto y no se puede utilizar en un entorno de producción sin modificaciones.

Si el artículo parece interesante, la próxima vez le mostraré cómo puede agregar todo tipo de comprobaciones personalizadas interesantes, compartir secretos y contar todo tipo de sutilezas. Además, si hay un deseo, contaré con más detalle acerca de cómo funciona todo esto desde adentro.

Gracias por su atencion!



Confluence:
/ ./
docs.comgress64.com/...

:
https://github.com/Icinga/puppet-icinga2
https://forge.puppet.com/icinga/icingaweb2
https://docs.docker.com/
https://docs.puppet.com/
https://docs.puppet.com/hiera/

Source: https://habr.com/ru/post/es420199/


All Articles