Monitoring pomocí Grafana + Loki + Prometheus
Instalace
Server (ten, který sbírá data)
Prometheus
V případě Debianu a jemu podobných stačí nainstalovat balíček prometheus:
apt -y update
apt -y install prometheus
Nastavení se nachází na dvou místech:
-
/etc/default/prometheus=> Nastavení jak se má server spouštět. Já doARGSdoplnil--storage.tsdb.retention.time=90d, aby se mi uchovávalo "pouze"90dní dat. -
/etc/prometheus/prometheus.yml=> Nastavení collectoru, sběrače dat. Zde nastavujeme odkud chceme tahat metriky a jaké.
prometheus.yml
V základu používám node_exporter na Linux a Windows s touto konfigurací. Data sbírám každou minutu, monitoruji i sám sebe a to každou minutu. Každou minutu také zpracovávám pravidla (které tady žádné nemám), alertmanager vystavuji na portu 9093 a adresy serverů ukládám do labelu instance.
# Sample config for Prometheus.
global:
scrape_interval: 1m # Set the scrape interval. Default is every 1 minute.
evaluation_interval: 1m # Evaluate rules every x seconds. The default is every 1 minute.
scrape_timeout: 30s # scrape_timeout. Global default is (10s).
# Attach these labels to any time series or alerts when communicating with
# external systems (federation, remote storage, Alertmanager).
external_labels:
monitor: 'promgraf'
# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
- job_name: 'linux_nodes'
metrics_path: /metrics
static_configs:
- targets:
- localhost:9100
- mujlinux.bali.cz
relabel_configs:
- source_labels: [__address__]
regex: (.*):(9100)
target_label: instance
replacement: '${1}'
- job_name: 'windows_nodes'
metrics_path: /metrics
static_configs:
- targets:
- mojewidle.bali.cz:9100
relabel_configs:
- source_labels: [__address__]
regex: (.*):(9100)
target_label: instance
replacement: '${1}'
No.. a aby nám to celé fungovalo tak ještě potřebuji aby se Prometheus dostal ke klientům. nftables pravidlo vypadá takto:
#!/usr/sbin/nft -f
table inet filter {
chain OUTPUT {
tcp dport 9100 accept comment "Allow connection to prometheus exporter targets - OUT"
}
}
Grafana + Loki
Grafanu a Lokiho instalujeme z repozitářů grafany dle našeho systému.
Pro Debian Linux potřebuji přidat repozitář s gpg klíčem a poté mohu instalovat:
echo 'deb https://apt.grafana.com stable main' | sudo tee /etc/apt/sources.list.d/grafana-oss.list
curl https://apt.grafana.com/gpg.key | gpg --dearmor > /etc/apt/trusted.gpg.d/grafana.gpg
apt -y update
apt -y install grafana loki
Grafana
Grafana má konfiguraci v /etc/grafana. Přistupujeme na <adresu serveru>:3001, takže např.: http://10.66.0.81:3100. Výchozí login je admin / admin.
Provisioned datasources
Grafaně dokážeme přednastavit zdroje dat pomocí yaml konfiguračních souborů. V následujících ukázkových souborech nastavuji Prometheus a Loki jako zdroje dat běžící na stejném serveru jako Grafana (localhost).
Prometheus
# Configuration file version
apiVersion: 1
# Localhost loki datasource
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://localhost:9090
isDefault: true
jsonData:
timeInterval: 60s
timeout: 60
Loki
# Configuration file version
apiVersion: 1
# Localhost loki datasource
datasources:
- name: Loki
type: loki
access: proxy
url: http://localhost:3100
jsonData:
timeout: 60
maxLines: 5000
Loki
Loki má konfiguraci v /etc/loki/config.yml. Má základní konfigurace:
- Poslouchá na portu
3100 - Ukládá data do
/var/lib/loki - Odstraňuje data starší
90 dníauth_enabled: false server: http_listen_port: 3100 grpc_listen_port: 9096 log_level: warn grpc_server_max_concurrent_streams: 2000 common: instance_addr: 127.0.0.1 path_prefix: /var/lib/loki storage: filesystem: chunks_directory: /var/lib/loki/chunks rules_directory: /var/lib/loki/rules replication_factor: 1 ring: kvstore: store: inmemory query_range: results_cache: cache: embedded_cache: enabled: true max_size_mb: 2048 limits_config: metric_aggregation_enabled: true max_query_lookback: 2160h #90d retention_period: 2160h #90d compactor: working_directory: /tmp/loki/retention retention_enabled: true retention_delete_delay: 24h delete_request_store: filesystem schema_config: configs: - from: 2020-10-24 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h pattern_ingester: enabled: true metric_aggregation: loki_address: localhost:3100 ruler: alertmanager_url: http://localhost:9093 frontend: encoding: protobuf
⚠️ Před Lokiho je potřeba přidat proxy s autentizací protože sám Loki tuto vrstvu nemá (viz Grafana docs). Základní zabezpečení pomocí
nginxje popsáno zde. Mimo jiné je možné si jej alespoň v rámci interní sítě omezit pomocí firewallu:#!/usr/sbin/nft -f table inet filter { chain INPUT { ip saddr 10.66.0.0/24 tcp dport 3100 accept comment "Allow Loki target from my services subnet - IN" } }
Klient (monitorovaný server)
Prometheus
Balíčky Promethea jsou u Debianu a z něj vycházejících distribucí většinou přímo v repozitářích. Základem je node_exporter který nám exportuje základní údaje o stavu operačního systému (packages.debian.org)
apt -y update
apt -y install prometheus-node-exporter
V případě používání nftables je potřeba vytvořit příchozí pravidlo pro port 9100 aby si mohl Prometheus vyzvedávat metriky.
Příklad, ve kterém je 10.66.0.81 náš Prometheus collector (server který sbírá data a jmenuje se promgraf dle komentáře pravidla).
#!/usr/sbin/nft -f
table inet filter {
chain INPUT {
ip saddr 10.66.0.81 tcp dport 9100 accept comment "Allow Prometheus metrics access from promgraf - IN"
}
💡 Prometheus lze nastavit, aby sbíral textové soubory jako metriky, které ale musí být v kompatibilním formátu.
(např.:nfsd_cc{hostname="pc666-105.domena",ip="10.66.6.105",path="/srv/linux/debian/shared"} 1jako soubornfsd_cc.prom). Do tohoto souboru zapisujeme řádky pomocíspongez balíčku moreutils./etc/default/prometheus:
# Set the command-line arguments to pass to the server. # Due to shell escaping, to pass backslashes for regexes, you need to double # them (\\d for \d). If running under systemd, you need to double them again # (\\\\d to mean \d), and escape newlines too. ARGS="" # To collect text files in this directory, add the line to ARGS variable. # There might be APT or some other metrics already. # --collector.textfile.directory="/var/lib/prometheus/node-exporter"
Alloy
Linux
TBDKonfiguraci ;Alloy bych doporučil rozložit do souborů a nastavit, aby služba brala konfiguraci ze složky místo výchozího /etc/default/config.alloy.
Nastavení se provede přidáním cesty do proměnné CUSTOM_ARGS jako posledního parametru (pokud zde mají být i jiné přepínače, cesta musí být poslední). Následně ostraním výchozí konfiguraci v /etc/alloy/config.alloy, protože zde budu dávat vlastní configy.
/etc/default/alloy:
## Path:
## Description: Grafana Alloy settings
## Type: string
## Default: ""
## ServiceRestart: alloy
#
# Command line options for Alloy.
#
# The configuration file holding the Alloy config.
#CONFIG_FILE="/etc/alloy/config.alloy"
# User-defined arguments to pass to the run command.
# Specified <PATH_NAME> to include directory: https://grafana.com/docs/alloy/latest/reference/cli/run/
CUSTOM_ARGS="/etc/alloy"
# Restart on system upgrade. Defaults to true.
RESTART_ON_UPGRADE=true
/etc/alloy
00-config.alloy -) výchozí obecná nastavení
// For a full configuration reference, see https://grafana.com/docs/alloy
// Log only warnings and more
logging {
level = "warn"
}
01-endpoint.alloy - nastavení endpointu => Loki serveru na který se budou posílat data. více informací
Zde se vyplňuje adresa ve tvaru: <http(s)>/<FQDN>/<Ingest endpoint>. Jako příklad uvedu svou konfiguraci:
// Data will be sent to this loki instance
loki.write "endpoint" {
endpoint {
url = "http://promgraf.in.cvut.it:3100/loki/api/v1/push"
// basic_auth {
// username = "admin"
// password = "admin"
// }
}
}
09-journal-relabel.alloy - Základní nastavení journal collectoru (sbírání logů z systemd systémových služeb).
// Setup journal relabel rules
loki.relabel "journal" {
forward_to = []
rule {
target_label = "instance"
replacement = constants.hostname
}
rule {
source_labels = ["__journal__systemd_unit"]
target_label = "unit"
}
}
10-varlog-collector.alloy - Nastavení sběru všech logů z /var/log s příponou souboru (suffixem) .log
// Setup varlogs job with labels
discovery.relabel "varlogs" {
// Read .log files from /var/log, recursively
targets = [{
__address__ = "localhost",
__path__ = "/var/log/**/*.log",
service_name = "varlogs",
}]
rule {
target_label = "instance"
replacement = constants.hostname
}
}
// Match files defined in relabel target
local.file_match "varlogs" {
path_targets = discovery.relabel.varlogs.output
}
// Send files to loki endpoint
loki.source.file "varlogs" {
targets = local.file_match.varlogs.targets
forward_to = [loki.write.endpoint.receiver]
}
50-journal-ssh.alloy - Odesílání logů systemd jednotky (unit) ssh.service.
loki.source.journal "ssh" {
matches = "_SYSTEMD_UNIT=ssh.service _SYSTEMD_UNIT=sshguard.service"
format_as_json = true
relabel_rules = loki.relabel.journal.rules
forward_to = [loki.write.endpoint.receiver]
}
51-journal-monitoring.alloy - Odesílání logů systemd jednotek (units) alloy.service a prometheus-node-exporter.service. Sledujeme tímto stav služeb které nám mají za úkol poskytovat metriky a logy.
loki.source.journal "alloy" {
matches = "_SYSTEMD_UNIT=alloy.service"
format_as_json = true
relabel_rules = loki.relabel.journal.rules
forward_to = [loki.write.endpoint.receiver]
}
loki.source.journal "prometheus_node_exporter" {
matches = "_SYSTEMD_UNIT=prometheus-node-exporter.service"
format_as_json = true
relabel_rules = loki.relabel.journal.rules
forward_to = [loki.write.endpoint.receiver]
}
/etc/alloy/52-journal-journal.alloy/ - Odesílání logů systemd jednotky (unit) systemd-journald.service.
loki.source.journal "systemd_journald" {
matches = "_SYSTEMD_UNIT=systemd-journald.service"
format_as_json = true
relabel_rules = loki.relabel.journal.rules
forward_to = [loki.write.endpoint.receiver]
}
Windows
TBD ;-)