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íjournalcollectoru (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/logs 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.serviceaprometheus-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 ;-)