Zabbix 5 in alta disponibilità. Una soluzione più semplice

Per chi non lo conoscesse in dettaglio, Zabbix è formato, per la parte server, da tre componenti: il server vero e proprio (il software che esegue i controlli e i calcoli, scritto in C); il database, nel quale vengono salvati sia i dati di configurazione che quelli di monitoraggio (può essere MySQL/MariaDB o Postgres, più raramente Oracle) e il frontend, la parte grafica che permette l’accesso per la visualizzazione (scritta in PHP su webserver Apache o Nginx)
Se all’inizio le tre componenti possono stare su una singola macchina, fisica o virtuale, al crescere delle infrastrutture da monitorare è necessario separarle per migliorare le performance.
Il primo componente che di solito viene separato è il database, mantenendo frontend e server su una singola macchina. Resta inteso che, in situazioni di particolare grandezza o complessità, le tre componenti possono stare anche ognuna su un server differente.
La separazione dei componenti è spesso l’occasione per rendere più resistente l’infrastruttura creandone una in alta disponibilità.
A questo proposito esiste un bell’articolo di Edmund Vesmanis sul blog di Zabbix, tratto da una sua presentazione allo Zabbix Summit 2019. Lo potete trovare qua. https://blog.zabbix.com/zabbix-ha-cluster-setups/8264/
La soluzione descritta nell’articolo presenta, due punti a mio avviso rivedibili:
L’infrastruttura è esageratamente ridondante, prevedendo i tre componenti separati e, per ognuno di essi, tre VM, per un totale di nove server;
La replica tra i DB viene effettuata in maniera asincrona, quando usando MariaDB e Galera (software di clustering nativo) è possibile farla in maniera sincrona.
Ho quindi pensato di procedere alla realizzazione di un cluster di soli quattro nodi, due per server e frontend (assieme) e due per il DB con MariaDB/Galera.

Ogni gruppo di server avrà tre IP: due fisici, assegnati alle vm che compongono il cluster e un VIP gestito dal software di alta disponibilità.
I sistemi sono tutti Ubuntu Bionic (18.04)

Cluster Zabbix server-frontend:
Nodo 1: 10.32.2.55
Nodo 2: 10.32.2.49
VIP: 10.32.2.52

Cluster DB
Nodo 1: 10.32.4.17
Nodo 2: 10.32.4.20
VIP: 10.32.4.18

Prima di tutto editiamo i file /etc/hosts dei singoli nodi, inserendo nome e IP dei due nodi che compongono il cluster, ad esempio come in questo esempio:

10.32.4.13 zabbix-db-p01
10.32.4.14 zabbix-db-p02

Iniziamo dall’installazione del DB.
Aggiungiamo la chiave del repository:

apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'

Poi il repository vero e proprio e aggiorniamo:

add-apt-repository 'deb [arch=amd64,arm64,ppc64el] https://mirror.mva-n.net/mariadb/repo/10.5/ubuntu bionic main'

apt update -y

Ora installiamo MariaDB e Galera

apt-get install mariadb-server rsync -y

Securizziamo l’installazione:

mysql_secure_installation

Cambiare la password e rispondere “Y” a tutte le altre risposte.

Ripetere i passi appena fatti sul nodo 2

Ora configuriamo Galera:

nano /etc/mysql/conf.d/galera.cnf

Inserire queste righe sul primo nodo:

[mysqld]
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0
# Galera Provider Configuration
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
# Galera Cluster Configuration
wsrep_cluster_name="galera_cluster"
wsrep_cluster_address="gcomm://10.32.4.17,10.32.4.20"

# Galera Synchronization Configuration
wsrep_sst_method=rsync

# Galera Node Configuration
wsrep_node_address="10.32.4.17"
wsrep_node_name="zabbix-db-p01"

Ripetere le operazioni analogamente sul secondo nodo, cambiando le ultime due voci in fondo in accordo con i parametri della macchina (quelle che iniziano con “wsrep”).

Avviamo il cluster: per fare questo è necessario che MariaDB sia spento su tutti i nodi:

systemctl stop mysql 

Andiamo sul nodo 1 e avviamo il cluster:

galera_new_cluster

Verifichiamo se il cluster funziona correttamente:

mysql -u root -p -e "show status like 'wsrep_cluster_size'"

Un output come questo denota il corretto funzionamento:

+———————–+——-+
| Variable_name        | Value |
+———————–+——-+
| wsrep_cluster_size | 1         |
+————————+——+

Andiamo sul nodo 2 e avviamo MariaDB:

systemctl start mysql

Verifichiamo che il secondo nodo sia inserito nel cluster:

mysql -u root -p -e "show status like 'wsrep_cluster_size'"

Un output come questo denota il corretto funzionamento:

+———————–+——-+
| Variable_name        | Value |
+———————–+——-+
| wsrep_cluster_size | 2         |
+————————+——+

Infine testiamo la replica del DB. Entriamo su MariaDB e creiamo un database:

mysql -u root -p

MariaDB [(none)]> create database test_db; 

MariaDB [(none)]> show databases;

+——————–+
| Database               |
+——————–+
| test_db                  |
+——————–+

Accediamo al secondo nodo e verifichiamo:

mysql -u root -p 

MariaDB [(none)]> show databases;

+——————–+
| Database               |
+——————–+
| test_db                  |
+——————–+

La replica funziona correttamente.

Passiamo ora alla realizzazione del cluster HA per il database.

Installiamo i pacchetti:

apt install -y pcs corosync

Creiamo l’utente per il cluster e impostiamo la password

useradd hacluster
passwd <CLUSTER_PASSWORD>

Autentichiamo i nodi del cluster

pcs cluster auth NODI

username: hacluster

password: <CLUSTER_PASSWORD>

zabbix-ha-db1: Authorized
zabbix-ha-db2: Authorized

Creiamo il cluster

pcs cluster setup --name zabbix_db_cluster zabbix-db-p01 zabbix-db-p02 --force

Creiamo la risorsa IP

pcs resource create virtual_ip ocf:heartbeat:IPaddr2 \
ip=10.32.4.18 op monitor interval=5s −−group zabbix_db_cluster

Stoppiamo il cluster e facciamolo ripartire. Poi verifichiamo lo stato

pcs cluster stop −−all && pcs cluster start −−all
pcs status

Impostiamo il blocco dello spostamento delle risorse dopo un ripristino. Poi disabilitiamo STONHIT

pcs resource defaults resource−stickiness=100
pcs property set stonith−enabled=false

A questo punto il cluster dei due nodi condivide l’IP inserito, che è quello che dovrà essere utilizzato per contattare il Database, composto di due nodi replicati tra di loro in maniera sincrona tramite Galera.

Passiamo ora al cluster dei due nodi con server e frontend

Prima di tutto inseriamo nel file /etc/hosts le seguenti righe

10.32.2.55 zabbix-mon-p01
10.32.2.49 zabbix-mon-p02

Passiamo ora alla realizzazione del cluster HA per il server/frontend.

Installiamo i pacchetti:

apt install -y pcs corosync

Creiamo l’utente per il cluster e impostiamo la password

useradd hacluster

passwd <CLUSTER_PASSWORD>

Autentichiamo i nodi del cluster

pcs cluster auth NODI

username: hacluster

password: <CLUSTER_PASSWORD>

zabbix-ha-db1: Authorized
zabbix-ha-db2: Authorized

Creiamo il cluster

pcs cluster setup --name zabbix_server_cluster zabbix-mon-p01 zabbix-mon-p02 --force

Installiamo lo zabbix serve rsu entrambi i nodi:

yum install −y zabbix−server

Editiamo il file di configurazione (/etc/zabbix/zabbix_server.conf) modificando come segue le righe:

SourceIP=10.32.2.52 (IP del VIP)

DBHost=10.32.4.18 (VIP del cluster DB)
DBName=zabbix
DBUser=zabbix
DBPassword=<DB_ZABBIX_PASS>

Impostiamo il blocco dello spostamento delle risorse dopo un ripristino. Poi disabilitiamo STONHIT

pcs resource defaults resource−stickiness=100
pcs property set stonith−enabled=false

Riavviamo il cluster e controlliamo

pcs cluster stop −−all && pcs cluster start −−all

pcs status

Ora passiamo alle risorse, iniziando dal VIP

pcs resource create virtual_ip_server ocf:heartbeat:IPaddr2 ip=10.32.2.52 op monitor interval=5s −−group zabbix_server_cluster

Poi lo Zabbix Server

pcs resource create ZabbixServer systemd:zabbix−server op monitor interval=10s −−group zabbix_server_cluster

Ultimi settaggi, per essere certi che il server Zabbix sia attivo su un solo nodo alla volta

pcs constraint colocation add virtual_ip_server ZabbixServer INFINITY −-force

Facciamo in modo che il server Zabbix parta sempre dopo il VIP

pcs constraint order virtual_ip_server then ZabbixServer

Impostiamo alcuni timeout

pcs resource op add ZabbixServer start interval=0s timeout=60s
pcs resource op add ZabbixServer stop interval=0s timeout=120s

Riavviamo di nuovo e controlliamo

pcs cluster stop −−all && pcs cluster start −−all

pcs status

A questo punto il server Zabbix è attivo sul cluster, su un nodo alla volta, connesso al cluster del DB MariaDB/Galera e utilizza il VIP come IP

Passiamo ora al front end, che condivide le stesse VM dello Zabbix server. Ovviamente sarebbe possibile (come fatto nell’articolo di Edmund) separare anche questa funzionalità e dedicare ad essa un paio di VM in un cluster dedicato, ma abbiamo preferito tenere basso il numero dei server coinvolti e accorparla con lo Zabbix server.

Iniziamo con l’installare il front end di Zabbix (Apache e PHP necessari per il funzionamento saranno installati automaticamente dal gestore di pacchetti)

apt install zabbix-web-mysql

Andiamo ad editare il file di configurazione del front end:

$DB['TYPE'] = 'MYSQL';
$DB['SERVER'] = '10.32.4.18';  <-- IP DEL CLUSTER MYSQL
$DB['PORT'] = '0';
$DB['DATABASE'] = 'zabbix';
$DB['USER'] = 'zabbix';
$DB['PASSWORD'] = '<DB_ZABBIX_PASS>';  <-- PASSWORD DELL'UTENTE  ZABBIX SUL DB
...
$ZBX_SERVER = '10.32.2.52';
$ZBX_SERVER_PORT = '10051';
$ZBX_SERVER_NAME = 'ZABBIX-HA';

Per controllare lo stato di Apache creiamo un virtualhost che ci mostri la pagina server-status.

Abilitiamo il modulo:

a2enmod server-status

Poi creiamo nella directory sites available un file denominato serverstatus.conf:

Listen 8080
<VirtualHost *:8080>
DocumentRoot "/var/www/html"
#ServerName localhost
<IfModule mod_status.c>
<Location /server-status>
SetHandler server-status
Order deny,allow
Allow from all
</Location>
</IfModule>
<Directory "/var/www/html">
#allow from all
#Options None
#Require all granted
AllowOverride All
DirectoryIndex index.html
</Directory>
</VirtualHost>

Forziamo Apache a rispondere sull’IP  del VIP. Editiamo il file /etc/apache2/ports.conf con questa modifica:

Listen 10.32.2.52:80

Poiché il frontend condividele risorse con lo Zabbix server sarà sufficiente aggiungere una risorsa al cluster esistente:

pcs resource create zabbix_fe ocf:heartbeat:apache configfile=/etc/apache2/apache2.conf \

statusurl="http://localhost:8080/server-status" op monitor interval=30s --group zabbix_server_cluster

Forziamo il frontend a stare sull ostesso nodo del VIP

pcs constraint colocation add virtual_ip_server zabbix-fe INFINITY --force

Il front end deve partire dopo lo Zabbix Server:

 pcs constraint order virtual_ip_server then zabbix-fe

Infine due timeout:

pcs resource op add zabbix_fe start interval=0s timeout=60s
pcs resource op add zabbix_fe stop interval=0s timeout=120s

Ora anche il frontend è gestito dal cluster in HA

Attenzione: i servizi gestiti dal cluster vanno disabilitati da systemd  (sysctl disable apache2 zabbix-server) perché deve essere il cluster a gestirne l’avvio.

L’ultima cosa che rimane da fare è la sincronizzazione di alcuni file (script e files di configurazione) tra i due nodi. Per risolvere il problema ho fatto uno script che tramite rsync e ssh copia dal nodo 1 al 2 questi oggetti:

  • directory /usr/lib/zabbix (che contiene gli script per l’alerting e gli external check)
  • directory /var/lib/zabbix (che contiene altre configurazioni aggiuntive)
  • file /etc/zabbix/zabbix_server.conf

Lo script gira con cron ogni 8 ore con l’utente root (previo scambio delle chiavi SSH tra il nodo 1 e il 2)

Il sistema di alta disponibilità ha anche un’interfaccia grafica, raggiungibile all’indirizzo <IP_DEL_NODO:2224> con utente hacluster e password <CLUSTER_PASSWORD>

 

© 2021 Catfish Blog | Tema: Storto di CrestaProject WordPress Themes.