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>:3100, takže např.: http://10.66.0.81:3100. Výchozí login je admin / admin.
Dashboard
Mnou vyrobené dashboardy ke stažení:
- Linux node - Monitoring Linuxového operačního systému.
- Download: Linux node-1759688247003.json
- Screenshot:

- nginx - Monitoring webového serveru nginx s použitím GeoIP Lite databází od maxmind.
- Download: nginx-1762203222824.json
- Screenshot:
🔥Jak na konfiguraci GeoIP se dozvíš na stránce konfigurace-geoip-s-maxmind-databazemi
- Cisco - Monitoring Cisco zařízení pomocí
SNMParsyslogu.- Download: Cisco-1761595211367.json
- Screenshot:
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 datasource
# 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 datasource
# Configuration file version
apiVersion: 1
# Localhost loki datasource
datasources:
- name: Loki
type: loki
access: proxy
url: http://localhost:3100
jsonData:
timeout: 60
maxLines: 5000
Authentication
Entra ID
🗒️ Oficiální návod je k dispozici ZDE
Jak nastavíme přihlášení pomocí vlastní Entra ID ?
-
EntraID
- Vytvořit App registration.
Authentication=>[ + Add a platform ]=>Web=> NastavitRedirect URInahttps://grafana.example.com/login/azuread+https://<grafana.example.comCertificates & secrets[ + New client secret ]=> < Pojmenovat si klíč a nastavit platnost (volil bych nejdelší - 24 měsíců) > =>[Add]. Zkopírovat HODNOTU (Value), nikoliv Secret ID a uložit si jej někam (později jej budeme potřebovat)[ + New federated credential ]:- Federated credential scenario: Other issuer
- Issuer: https://login.microsoftonline.com/<TENANT-ID>/v2.0
- Name: Nějak si to pojmenovat 🤷♂️
- Description: třeba: "Grafana OAuth."
- Audience:
api://AzureADTokenExchange
API permissions[ + Add a permission ]=>Microsoft Graph=>Delegated permissions=> Nyní máme dvě možnosti jak nastavit oprávnění ke čtení uživatelského profilu. Buď pomocí vybrání jednotlivých oprávnění nebo obecnéhoUser.Read(Sign in and read user profile).- OpenId permissions
🗒️
User.Read=> Allows users to sign-in to the app, and allows the app to read the profile of signed-in users. It also allows the app to read basic company information of signed-in users.
GroupMember.Read.All=> Allows the app to list groups, read basic group properties and read membership of all groups the signed-in user has access to.- email (Může být použito
User.Read) - openid (Může být použito
User.Read) - profile (Může být použito
User.Read)
- email (Může být použito
- =>
[ Add permissions ]
- OpenId permissions
-
Grafana
Client Id=><Application (client) ID>Client secret=> Zde vyplnit Value z client secret vytvořeného v Entra IdScopes=>openid,email,profileFIC managed identity client Id=> Zde vyplnit<Application (client) ID>FIC audience=>api://AzureADTokenExchange
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" } }
rsyslog
Tento nástroj používáme pro odchytávání logů pomocí syslogu ze zařízení jako jsou switche.
rsyslog má konfiguraci v /etc/rsyslog.conf a /etc/rsyslog.d.
-
Nainstalovat:
apt -yq install rsyslog -
V
/etc/rsyslog.dsi vytvořit konfigurační soubor:- pro "nastartování vysílače" / serveru který bude zachytávat logy které do něj budeme posílat,
01-remote_server.conf:# Enable imudp, UDP Syslog Input Module # https://www.rsyslog.com/doc/configuration/modules/imudp.html module(load="imudp") input(type="imudp" port="514") # Enable imutcp, TCP Syslog Input Module # https://www.rsyslog.com/doc/configuration/modules/imtcp.html module(load="imtcp") input(type="imtcp" port="601") # Allow receiving from localhost and local network #$AllowedSender UDP, 127.0.0.1, 10.0.0.0/8 #$AllowedSender TCP, 127.0.0.1, 10.0.0.0/8💡 Dle poznámky lze omezit z jakých adres/subnetů budeme přijímat komunikaci.
- pro logování například Cisco switche si nastavím
10-cisco_switch.confkterý bude ukládat logy do speciální podsložky a bude zde řadit klienty z určitých adres či logy obsahující určité zprávy:template(name="Cisco_Switch" type="string" string="/var/log/remote/cisco/%HOSTNAME%.log") :fromhost-ip, regex, "^10\.39\.\7.\.*" -?Cisco_Switch :msg, contains, " sw-a1269-hardcore.net.cvut.it:" -?Cisco_Switch
- pro "nastartování vysílače" / serveru který bude zachytávat logy které do něj budeme posílat,
-
Povolit provoz na UDP a TCP porty v nftables (v mém případě do interních sítí):
ip saddr 10.0.0.0/8 tcp dport 601 accept comment "Allow rsyslog on internal sites (TCP/601) - IN" ip saddr 10.0.0.0/8 udp dport 514 accept comment "Allow rsyslog on internal sites (UDP/514) - 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
Konfiguraci 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 ;-)




No comments to display
No comments to display