- Configurazione di Elasticsearch
Configurazione di Elasticsearch
Zabbix può archiviare i dati della cronologia in Elasticsearch come alternativa a un database relazionale.
Questa guida illustra la configurazione delle versioni supportate di Elasticsearch.
Il server Zabbix non si avvia se la versione di Elasticsearch è precedente alla versione minima supportata.
Se è più recente della versione massima supportata, il server Zabbix si avvia solo se il parametro AllowUnsupportedDBVersions è impostato su 1.
Elasticsearch può archiviare i seguenti tipi di valore:
| Tipo di valore dell'item | Tabella del database | Tipo Elasticsearch |
|---|---|---|
| Numerico (senza segno) | history_uint | uint |
| Numerico (virgola mobile) | history | dbl |
| Carattere | history_str | str |
| Log | history_log | log |
| Testo | history_text | text |
| Binario | history_bin | non supportato da Zabbix |
| JSON | history_json | json |
Note importanti
- Elasticsearch richiede libcurl. Per i dettagli, vedere requisiti.
- Housekeeper non elimina i dati da Elasticsearch. Per controllare per quanto tempo vengono conservati i dati, vedere Index Lifecycle Management.
- Zabbix non calcola né memorizza i trend in Elasticsearch. Valutare la possibilità di estendere il periodo di conservazione della cronologia per preservare i dati meno recenti.
- Quando viene utilizzato Elasticsearch, le query di intervallo che recuperano i valori dal database sono limitate dal timestamp del periodo di conservazione dei dati.
- Elasticsearch non è supportato per i proxy Zabbix.
- A partire da Elasticsearch 8.0, le funzionalità di sicurezza sono abilitate per impostazione predefinita: Elasticsearch richiede l'autenticazione e utilizza HTTPS per la propria API HTTP, con certificati firmati da una CA generata automaticamente.
Gli esempi in questa pagina utilizzano
http://localhost:9200senza autenticazione. Se la sicurezza è abilitata, utilizzare un URLhttps://e passare il certificato CA e le credenziali nelle richieste (ad esempio,sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic https://localhost:9200; il file del certificato CA può essere letto solo daroote dal gruppoelasticsearch). Per connettere il server Zabbix e il frontend Zabbix a un cluster di questo tipo, vedere Connessione a un cluster protetto.
Se Elasticsearch non è ancora installato, consultare la guida ufficiale all'installazione prima di procedere.
Configurazione di Elasticsearch
Per memorizzare i dati di storico in Elasticsearch, è necessario:
- Creare un indice per ogni tipo di valore che si desidera memorizzare: è qui che Elasticsearch archivia i dati, in modo simile a una tabella in un database relazionale.
- Definire una mappatura per ogni indice: questa definisce la struttura dei dati, in modo simile allo schema di una tabella.
- Configurare una pipeline di ingest per elaborare i valori prima della memorizzazione (necessaria per i valori JSON e per gli indici basati sulla data).
Elasticsearch può memorizzare i dati in un singolo indice per tipo di valore oppure in più indici basati sulla data. Entrambi gli approcci sono descritti di seguito.
Memorizzazione dello storico in un singolo indice
Con questo approccio, tutti i dati dello storico per un determinato tipo di valore vengono scritti in un singolo indice (ad esempio, uint o text).
Per creare un indice per il tipo di valore Numerico (senza segno), inviare la seguente richiesta (con /uint nell'URL) all'istanza Elasticsearch:
curl -X PUT \
http://localhost:9200/uint \
-H 'content-type:application/json' \
-d '{
"settings": {
"index": {
"number_of_replicas": 1,
"number_of_shards": 5
}
},
"mappings": {
"properties": {
"itemid": { "type": "long" },
"clock": { "format": "epoch_second", "type": "date" },
"value": { "type": "long" }
}
}
}'
Elasticsearch risponderà confermando che l'indice è stato creato:
{"acknowledged": true, "shards_acknowledged": true, "index": "uint"}
È necessario inviare richieste simili per ogni tipo di valore che si desidera memorizzare in Elasticsearch, ovvero per ogni tipo elencato nell'opzione value_types della configurazione del server Zabbix.
Le mappature per tutti i tipi di valore sono disponibili nel repository del codice sorgente di Zabbix.
Ad esempio, per creare un indice per il tipo di valore Testo:
curl -X PUT \
http://localhost:9200/text \
-H 'content-type:application/json' \
-d '{
"settings": {
"index": {
"number_of_replicas": 1,
"number_of_shards": 5
}
},
"mappings": {
"properties": {
"itemid": { "type": "long" },
"clock": { "format": "epoch_second", "type": "date" },
"value": {
"fields": {
"analyzed": { "index": true, "type": "text", "analyzer": "standard" }
},
"index": false,
"type": "text"
}
}
}
}'
Tipo di valore JSON
A differenza degli altri tipi di valore, i valori JSON richiedono un'elaborazione aggiuntiva prima dell'archiviazione. L'indice per il tipo di valore JSON memorizza ogni valore in uno dei due campi:
value_parsed—oggetti JSON, memorizzati come campo flattened, in modo che possano essere cercati per chiave e valore;value_raw—tutti gli altri valori JSON (array, stringhe, numeri, valori booleani enull), memorizzati come stringa.
Una ingest pipeline analizza ogni valore come JSON e lo memorizza nel campo corretto. I valori che non sono JSON validi non vengono inviati a Elasticsearch, perché gli item che li ricevono diventano non supportati.
Per prima cosa, creare la ingest pipeline:
curl -X PUT \
http://localhost:9200/_ingest/pipeline/json \
-H 'content-type:application/json' \
-d '{
"processors": [
{
"json": {
"field": "value",
"target_field": "value_parsed",
"ignore_failure": true
}
},
{
"script": {
"source": "if (ctx.value_parsed == null || !(ctx.value_parsed instanceof Map)) { ctx.value_raw = ctx.value; ctx.remove(\"value_parsed\"); }"
}
}
]
}'
Elasticsearch risponderà con una conferma della creazione della ingest pipeline:
{"acknowledged": true}
Quindi, creare un indice per il tipo di valore JSON inviando la seguente richiesta (con /json nell'URL) alla propria istanza Elasticsearch.
L'impostazione default_pipeline fa sì che Elasticsearch elabori ogni valore scritto in questo indice con la ingest pipeline json.
Questa impostazione è necessaria perché Zabbix server non specifica una ingest pipeline quando memorizza la cronologia in un singolo indice.
curl -X PUT \
http://localhost:9200/json \
-H 'content-type:application/json' \
-d '{
"settings": {
"index": {
"number_of_replicas": 1,
"number_of_shards": 5,
"default_pipeline": "json"
}
},
"mappings": {
"dynamic": false,
"properties": {
"itemid": { "type": "long" },
"clock": { "type": "date", "format": "epoch_second" },
"ns": { "type": "long" },
"value_parsed": { "type": "flattened", "ignore_above": 8191 },
"value_raw": { "type": "keyword", "ignore_above": 8191 }
}
}
}'
Elasticsearch non può indicizzare valori keyword e flattened più lunghi di 32766 byte.
Con "ignore_above": 8191, le stringhe più lunghe di 8191 caratteri non vengono indicizzate (e non possono essere cercate), ma vengono comunque memorizzate e restituite integralmente a Zabbix.
Senza questo limite, Elasticsearch rifiuta tali valori, che vengono persi.
Archiviazione della history in indici basati sulla data
Invece di scrivere tutti i dati della history in un unico indice (ad esempio, uint), Elasticsearch può distribuire questi dati su più indici basati sulla data (ad esempio, uint-2026-01-01, uint-2026-01-02).
Questo semplifica la gestione del volume dei dati e della retention nel tempo.
Per abilitarlo, è necessario:
- Creare un index template per ogni tipo di valore che si desidera archiviare: questo indica a Elasticsearch quale mapping applicare quando crea automaticamente un nuovo indice basato sulla data.
- Creare un ingest pipeline per ogni tipo di valore: elabora ogni valore in ingresso e lo indirizza al corretto indice basato sulla data.
Template degli indici
Per creare un template per l'indice text, inviare una richiesta con i seguenti dettagli:
- Utilizzare
_index_template/text_templatenell'URL dell'istanza Elasticsearch. - Utilizzare
"text-*"nel campo"index_patterns"per trovare una corrispondenza con i nomi degli indici basati sulla data. - Nel campo
"template", specificare le impostazioni dell'indice e una mappatura per il tipo di valoretext(vedere le mappature nel repository del codice sorgente di Zabbix).
curl -X PUT \
http://localhost:9200/_index_template/text_template \
-H 'content-type:application/json' \
-d '{
"index_patterns": [ "text-*" ],
"template": {
"settings": {
"index": {
"number_of_replicas": 1,
"number_of_shards": 5
}
},
"mappings": {
"properties": {
"itemid": { "type": "long" },
"clock": { "format": "epoch_second", "type": "date" },
"value": {
"fields": {
"analyzed": { "index": true, "type": "text", "analyzer": "standard" }
},
"index": false,
"type": "text"
}
}
}
}
}'
Creare un template per ogni tipo di valore che si desidera memorizzare, modificando di conseguenza il nome del template, il pattern dell'indice e la mappatura.
Ad esempio, un template per l'indice json (per informazioni dettagliate sui campi value_parsed e value_raw, vedere Tipo di valore JSON):
curl -X PUT \
http://localhost:9200/_index_template/json_template \
-H 'content-type:application/json' \
-d '{
"index_patterns": [ "json-*" ],
"template": {
"settings": {
"number_of_replicas": 1
},
"mappings": {
"dynamic": false,
"properties": {
"itemid": { "type": "long" },
"clock": { "type": "date", "format": "epoch_second" },
"ns": { "type": "long" },
"value_parsed": { "type": "flattened", "ignore_above": 8191 },
"value_raw": { "type": "keyword", "ignore_above": 8191 }
}
}
}
}'
Utilizzare template di indice componibili (_index_template) come mostrato sopra.
I template di indice legacy (_template) sono deprecati ed Elasticsearch rifiuta i template legacy i cui pattern di indice si sovrappongono ai template integrati, ad esempio un template legacy con il pattern log* per l'indice log.
Pipeline di ingestione
Per creare una pipeline di ingestione per l'indice text:
- Utilizzare
_ingest/pipeline/text-pipelinenell'URL della propria istanza Elasticsearch. - Includere un processore
date_index_nameper instradare ogni valore all'indice corretto basato sulla data, in base al relativo timestamp.
curl -X PUT \
http://localhost:9200/_ingest/pipeline/text-pipeline \
-H 'content-type:application/json' \
-d '{
"description": "daily text index naming",
"processors": [
{
"date_index_name": {
"field": "clock",
"date_formats": ["UNIX"],
"index_name_prefix": "text-",
"date_rounding": "d"
}
}
]
}'
Creare una pipeline per ogni tipo di valore che si desidera memorizzare, modificando di conseguenza il nome della pipeline, la descrizione e il valore di "index_name_prefix".
Il nome della pipeline deve essere costituito dal nome dell'indice e dal suffisso -pipeline (ad esempio, uint-pipeline), perché Zabbix server utilizza questo nome quando invia i valori a Elasticsearch.
Per l'indice json, la pipeline deve inoltre analizzare il valore JSON prima di instradarlo all'indice corretto:
curl -X PUT \
http://localhost:9200/_ingest/pipeline/json-pipeline \
-H 'content-type:application/json' \
-d '{
"description": "daily json index naming",
"processors": [
{
"json": {
"field": "value",
"target_field": "value_parsed",
"ignore_failure": true
}
},
{
"script": {
"source": "if (ctx.value_parsed == null || !(ctx.value_parsed instanceof Map)) { ctx.value_raw = ctx.value; ctx.remove(\"value_parsed\"); }"
}
},
{
"date_index_name": {
"field": "clock",
"date_formats": [ "UNIX" ],
"index_name_prefix": "json-",
"date_rounding": "d"
}
}
]
}'
Configurazione del server Zabbix
Nel file di configurazione del server Zabbix (zabbix_server.conf), impostare il parametro HistoryProvider.
Ad esempio, per archiviare in Elasticsearch i valori di tipo Character, Log, Text e JSON (mantenendo i valori Numeric in un database):
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=http://localhost:9200
Se si utilizzano indici basati sulla data, aggiungere date_index=1 al parametro:
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=http://localhost:9200,date_index=1
Se le funzionalità di sicurezza di Elasticsearch sono abilitate, specificare un URL https:// con le credenziali (vedere Connessione a un cluster protetto).
Dopo aver apportato le modifiche, riavviare il server Zabbix:
systemctl restart zabbix-server
Configurazione del frontend di Zabbix
Nel file di configurazione del frontend di Zabbix (zabbix.conf.php), impostare la variabile $HISTORY_PROVIDERS in modo che corrisponda alla configurazione del server:
$HISTORY_PROVIDERS[] = [
'types' => ['str','log','text','json'],
'provider' => 'elasticsearch',
'url' => 'http://localhost:9200'
];
Se le funzionalità di sicurezza di Elasticsearch sono abilitate, specificare lo stesso URL https:// con le credenziali utilizzate nella configurazione del server (vedere Connessione a un cluster protetto).
Connessione a un cluster protetto
Se le funzionalità di sicurezza di Elasticsearch sono abilitate (impostazione predefinita a partire da Elasticsearch 8.0), il server Zabbix e il frontend Zabbix devono considerare attendibile il certificato CA del livello HTTP di Elasticsearch e devono autenticarsi con un nome utente e una password.
- Creare un ruolo e un utente per Zabbix.
Il ruolo seguente consente a Zabbix di recuperare la versione di Elasticsearch (il privilegio del cluster
monitor), creare indici, scrivere e leggere i dati della cronologia ed eliminare i dati della cronologia quando la cronologia dell'item viene cancellata:
sudo curl -X PUT \
--cacert /etc/elasticsearch/certs/http_ca.crt -u elastic \
https://localhost:9200/_security/role/zabbix_history \
-H 'content-type:application/json' \
-d '{
"cluster": [ "monitor" ],
"indices": [
{
"names": [ "uint", "uint-*", "dbl", "dbl-*", "str", "str-*", "log", "log-*", "text", "text-*", "json", "json-*" ],
"privileges": [ "create_index", "index", "read", "delete" ]
}
]
}'
sudo curl -X PUT \
--cacert /etc/elasticsearch/certs/http_ca.crt -u elastic \
https://localhost:9200/_security/user/zabbix \
-H 'content-type:application/json' \
-d '{
"password": "<password>",
"roles": [ "zabbix_history" ]
}'
- Aggiungere il certificato CA di Elasticsearch ai certificati attendibili del sistema operativo sugli host del server Zabbix e del frontend Zabbix.
Se Zabbix viene eseguito su un host diverso da Elasticsearch, copiare prima il certificato CA (
/etc/elasticsearch/certs/http_ca.crt) su tale host. Ad esempio, su Debian/Ubuntu:
sudo cp /etc/elasticsearch/certs/http_ca.crt /usr/local/share/ca-certificates/elasticsearch-http-ca.crt
sudo update-ca-certificates
Il nome dell'host nell'URL deve corrispondere al certificato HTTP di Elasticsearch.
Il certificato generato automaticamente è valido per localhost, il nome dell'host e gli indirizzi IP dell'host Elasticsearch.
- Specificare le credenziali nell'URL, sia nel file di configurazione del server Zabbix sia nel file di configurazione del frontend.
Se la password contiene caratteri speciali, codificarli in percentuale (ad esempio,
@come%40,:come%3Ae,come%2C).
HistoryProvider=elasticsearch;value_types="str,log,text,json",url=https://zabbix:<password>@localhost:9200
$HISTORY_PROVIDERS[] = [
'types' => ['str','log','text','json'],
'provider' => 'elasticsearch',
'url' => 'https://zabbix:<password>@localhost:9200'
];
- Riavviare il server Zabbix e PHP-FPM (oppure il web server, se PHP viene eseguito come modulo del web server).
Risoluzione dei problemi
I seguenti passaggi possono aiutare a risolvere i problemi relativi alla configurazione di Elasticsearch:
- Controllare i log di Elasticsearch o del server Zabbix per individuare eventuali errori. Ad esempio, i seguenti messaggi nei log del server Zabbix indicano problemi di connessione a un cluster protetto (vedere Connessione a un cluster protetto):
cannot query Elasticsearch: SSL certificate problem: self-signed certificate in certificate chain—il certificato CA di Elasticsearch non è considerato attendibile;cannot query Elasticsearch, HTTP error message: The requested URL returned error: 401—le credenziali sono mancanti o errate;cannot query Elasticsearch, HTTP error message: The requested URL returned error: 403—l'utente non dispone dei privilegi richiesti.
Il frontend di Zabbix visualizza errori simili (ad esempio, Elasticsearch error: missing authentication credentials for REST request).
-
Per identificare le query lente, impostare il parametro di configurazione del server Zabbix
LogSlowQueries. Se la lettura della cronologia da Elasticsearch richiede più tempo di quello specificato, il server Zabbix registraslow query: <N> sec, "<query>". Durante l'attesa della risposta di Elasticsearch, il server Zabbix registra inoltrewaiting for Elasticsearch response <N>secogni volta che trascorre il tempo specificato, oppure ogni 10 secondi seLogSlowQueriesè impostato su 0. -
Verificare che Elasticsearch consenta l'accesso dal server Zabbix e dal frontend di Zabbix.
-
Verificare che
auto_create_indexsia abilitato (è abilitato per impostazione predefinita):
curl -X GET \
"http://localhost:9200/_cluster/settings?include_defaults=true&filter_path=**.auto_create_index"
# {"persistent": {"action": {"auto_create_index": "false"} } }
Per abilitarlo, inviare la seguente richiesta:
curl -X PUT \
http://localhost:9200/_cluster/settings \
-H 'content-type:application/json' \
-d '{
"persistent": {
"action.auto_create_index": "true"
}
}'
# {"acknowledged": true, "persistent": {"action": {"auto_create_index": "true"} }, "transient": {} }
- Verificare che mapping, template e pipeline di ingestione siano corretti inviando richieste
GETai rispettivi URL:
curl -X GET "http://localhost:9200/json*"
curl -X GET "http://localhost:9200/_index_template/json*"
curl -X GET "http://localhost:9200/_ingest/pipeline/json*"
È possibile confrontare le risposte ricevute con quelle previste nella documentazione dell'API di Elasticsearch.
-
Verificare se alcuni shard si trovano in uno stato di errore; il riavvio di Elasticsearch potrebbe risolvere il problema. In un cluster a nodo singolo, gli indici con repliche (
"number_of_replicas": 1) hanno lo stato yellow, perché le repliche non possono essere allocate sullo stesso nodo degli shard primari; ciò non influisce su Zabbix. Per evitarlo, impostare"number_of_replicas"su0. -
Eseguire una query su Elasticsearch per verificare se i dati raccolti da Zabbix sono archiviati, ad esempio:
curl "http://localhost:9200/json*/_search" \
-H 'Content-Type: application/json' \
-d '{
"query": {
"term": {
"itemid": 42269
}
}
}'
- Se è necessario reimpostare la configurazione di Elasticsearch e ricominciare da capo, eliminare gli indici, i template degli indici e le pipeline di ingestione creati per Zabbix (questa operazione elimina tutti i dati della cronologia archiviati in Elasticsearch).
Per impostazione predefinita, Elasticsearch non consente di eliminare gli indici utilizzando espressioni jolly; pertanto, per eliminare gli indici basati sulla data, modificare temporaneamente l'impostazione
action.destructive_requires_name. I template degli indici e le pipeline di ingestione devono essere eliminati uno alla volta; le richieste relative a template o pipeline inesistenti restituiscono un errore, che può essere ignorato.
curl -X DELETE "http://localhost:9200/uint,dbl,str,log,text,json?ignore_unavailable=true"
curl -X PUT \
http://localhost:9200/_cluster/settings \
-H 'content-type:application/json' \
-d '{"persistent": {"action.destructive_requires_name": false}}'
curl -X DELETE "http://localhost:9200/uint-*,dbl-*,str-*,log-*,text-*,json-*"
curl -X PUT \
http://localhost:9200/_cluster/settings \
-H 'content-type:application/json' \
-d '{"persistent": {"action.destructive_requires_name": null}}'
for type in uint dbl str log text json; do
curl -X DELETE "http://localhost:9200/_index_template/${type}_template"
curl -X DELETE "http://localhost:9200/_ingest/pipeline/${type}-pipeline"
done
curl -X DELETE "http://localhost:9200/_ingest/pipeline/json"