Préambule
Les travaux pratiques s'effectuent sur deux plateformes distinces.
La première est un Prometheus déjà installé sur un cluster Kubernetes qui permet d'effectuer des requêtes PromQL afin de se concentrer sur l'apprentissage du langage.
La seconde est un ensemble de machines individuelles sur lesquelles chacun d'entre vous pourra se connecter afin de procéder à l'installation et au paramétrage de Prometheus et de différents exporteurs.
L'accès aux différentes plateformes est protégé par une gateway 0 trust sur laquelle il faudra s'enregistrer au préalable en utilisant les liens individuels fournis en séance.
Accès au sujet de TP
https://sqli-prom-activities.ext-gw.datailor.fr/
Passerelle 0 trust
Plateforme #1 : Cluster Kubernetes
Prometheus
https://sqli-training-prometheus.ext-gw.datailor.fr/graph
Plateforme #2 : Serveurs personnels
Machine : prom01
- Utilisateur : sqli-prom01
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.61
- Accès shell
- Accès aux applications
Machine : prom02
- Utilisateur : sqli-prom02
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.62
- Accès shell
- Accès aux applications
Machine : prom03
- Utilisateur : sqli-prom03
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.63
- Accès shell
- Accès aux applications
Machine : prom04
- Utilisateur : sqli-prom04
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.64
- Accès shell
- Accès aux applications
Machine : prom05
- Utilisateur : sqli-prom05
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.65
- Accès shell
- Accès aux applications
Machine : prom06
- Utilisateur : sqli-prom06
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.66
- Accès shell
- Accès aux applications
Machine : prom07
- Utilisateur : sqli-prom07
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.67
- Accès shell
- Accès aux applications
Machine : prom08
- Utilisateur : sqli-prom08
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.68
- Accès shell
- Accès aux applications
Machine : prom09
- Utilisateur : sqli-prom09
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.69
- Accès shell
- Accès aux applications
Machine : prom10
- Utilisateur : sqli-prom10
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.70
- Accès shell
- Accès aux applications
Machine : prom11
- Utilisateur : sqli-prom11
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.71
- Accès shell
- Accès aux applications
Machine : prom12
- Utilisateur : sqli-prom12
- IP Interne à utiliser dans les fichiers de configuration : 10.102.28.72
- Accès shell
- Accès aux applications
Exercices - Partie 1 le PromQL
Exercices à effectuer sur le cluster Kubernetes
Exercice 1
Sujet
Trouver la charge CPU par instance, par CPU sur l'ensemble du cluster
Métrique : node_cpu_seconds_total
Modes à prendre en compte :
- user
- system
- nice
- irq
- iowait
- softirq
- steal
Mode à ne pas prendre en compte :
- idle
Solution
sum(node_cpu_seconds_total{mode!="idle"}) by (instance,cpu)
sum by (instance,cpu) (node_cpu_seconds_total{mode!="idle"})
sum(node_cpu_seconds_total{mode=~"user|system|nice|irq|iowait|softirq|steal"}) by (instance,cpu)
node_cpu_seconds_total{mode="user"}
+ ignoring(mode) node_cpu_seconds_total{mode="system"}
+ ignoring(mode) node_cpu_seconds_total{mode="nice"}
+ ignoring(mode) node_cpu_seconds_total{mode="irq"}
+ ignoring(mode) node_cpu_seconds_total{mode="iowait"}
+ ignoring(mode) node_cpu_seconds_total{mode="softirq"}
+ ignoring(mode) node_cpu_seconds_total{mode="steal"}
Exercice 1bis
Sujet
Afficher maintenant uniquement les modes user et system :
Solution
sum by (instance,cpu) (node_cpu_seconds_total{mode=~"user|system"})
Exercice 2
Sujet
Identifier l'espace disque disponible restant sur chacune des instances du cluster sur la partition racine.
Métrique : node_filesystem_free_bytes
Solution
node_filesystem_free_bytes{mountpoint="/"}
sum by (instance) (node_filesystem_free_bytes{mountpoint="/"})
ATTENTION: node_filesystem_free_bytes correspond à l'espace disque restant prenant en compte la marge de 5% de linux, pour avoir la quantité d'espace disque utilisable utiliser node_filesystem_avail_bytes
Exercice 3
Sujet
Identifier le pourcentage d´espace disque disponible restant sur chacune des instances du cluster sur la partition racine.
Métriques :
- node_filesystem_free_bytes <-- Quantité d´espace disque disponible
- node_filesystem_size_bytes <-- Quantité d´espace disque total
Solution
node_filesystem_free_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100
node_filesystem_free_bytes{mountpoint="/"} / node_filesystem_size_bytes
Exercice 4
Sujet
Sur la base de la requête précédente, identifier la tendance d'évolution de l'espace disque disponible restant sur la partition racine sur les 4 dernières heures (ou 5 dernières minutes si vous êtes sur ADSL).
Fonctions possibles :
derivrateirate
Solution
deriv(node_filesystem_avail_bytes[4h])
NOTE: rate et irate sont inapplicables et donnent des résultats qui peuvent porter à confusion car la métrique est une jauge et non un compteur
Exercice 4bis
Sujet
Utiliser la fonction rate sur la métrique node_cpu_seconds_totalsur un période de 5m puis sur une période de 2m
Quelle observation faites-vous du résultat obtenu ?
Solution
rate(node_cpu_seconds_total[5m])
rate(node_cpu_seconds_total[2m])
Le rate sur 5m est plus lissé que le rate sur 2m. Pour obtenir un graphe de consommation CPU au plus juste on priviligégie la période de 2m ou encore un irate
Exercice 5
Sujet
Pondérer le résultat de la requête précédente avec la tendance d'évolution de la charge CPU sur les 12 dernières heures
Solution
# a * rate2m + b * rate12h
# a + b = 1
# 0 < a < 1
# 0 < b < 1
0.1 * rate(node_cpu_seconds_total{mode="idle"}[2m]) + 0.9 * rate(node_cpu_seconds_total{mode="idle"}[12h])
Exercice 6
Sujet
Sur la base des requêtes précédentes, prédire la quantité d'espace disque disponible restant sur la partition racine.
Solution
predict_linear(node_filesystem_free_bytes{mountpoint="/"}[1h], 4 * 3600)
Exercice 7
Sujet
Utiliser la fonction holt_winters sur la métrique node_filesystem_free_bytes pour construire un graphe pertinent de l'évolution de l'espace disque disponible restant sur la partition racine, jouez sur les paramètres sfet tfpour voir leur impact et identifier des cycles
Solution
holt_winters(node_filesystem_free_bytes{mountpoint="/"}[4h], 0.1, 0.93)
Exercice 8
Sujet
Sur la base de la requête de l'exercice 1, calculer la tendance d'évolution de la charge CPU par instance, par CPU sur l'ensemble du cluster sur les 4 dernières heures (ou 5 dernières minutes si vous êtes sur ADSL)
Solution
deriv(irate(node_cpu_seconds_total{mode="idle"}[2m])[4h])
NOTE: Impossible car on ne peut appliquer un range sur le résultat d'un calcul
sum (rate (node_cpu_seconds_total{mode!="idle"}[4h])) by (instance,cpu)
Exercice 9
Sujet
Soustraire la métrique scrape_samples_scraped à la valeur du compte des métriques
- Commencer par compter le nombre de métriques (Utiliser
__name__)
Solution
count({__name__!=""}) - sum(scrape_samples_scraped)
Exercice 10
Sujet
Écrire une requête basée sur le compteur node_cpu_seconds_total pour connaître le pourcentage d'utilisation CPU par instance
Solution
sum by (instance) (irate(node_cpu_seconds_total{mode!="idle"}[2m]))
/ on (instance)
count by (instance) (node_cpu_seconds_total{mode="idle"})
* 100
Ou
sum by (instance) (irate(node_cpu_seconds_total{mode!="idle"}[2m]))
/ on (instance)
sum by (instance) (irate(node_cpu_seconds_total[2m]))
* 100
Exercice 11
Sujet
Écrire une requête basée sur le compteur prometheus_http_requests_total pour connaître l'évolution des requêtes sur 5m
Solution
rate(prometheus_http_requests_total[5m])
Exercice 12
Sujet
Identifier le ratio de requêtes http en erreur 400 par rapport aux requêtes http ok (status 200). Utiliser la métrique prometheus_http_requests_total
Solution
sum(increase(prometheus_http_requests_total{code="400"}[2m])) / sum(increase(prometheus_http_requests_total{code="200"}[2m]))
Exercice 13
Sujet
Identifier le ratio de requêtes http en erreurs (quel que soit le code) par rapport aux requêtes http ok (i.e. valides). Utiliser la métrique prometheus_http_requests_total
Solution
sum(increase(prometheus_http_requests_total{code=~"4[0-9][0-9]|5[0-9][0-9]"}[2m]))
/
sum(increase(prometheus_http_requests_total{code=~"1[0-9][0-9]|2[0-9][0-9]"}[2m]))
Exercice 14
Sujet
Identifier le 90e percentile de la durée des requêtes http. Utiliser la métrique prometheus_http_request_duration_seconds_bucket
90e percentile = 0.9 quantile
Solution
histogram_quantile(0.9, prometheus_http_request_duration_seconds_bucket)
Exercice 14bis
Sujet
Écrire la requête du calcul de l'apdex :
Étant données les SLA suivantes :
- Satisfaisant : req <= 0.2s
- Tolérable : req <= 1s > 0.2s
- Frustrante : req > 1s
Et la formule suivante :
\[ Apdex = \left( \frac{ Sat \times 1 + Tol \times 0.5 + Fru \times 0 }{ Nb_{req} } \right) \]
Solution
APDEX Long terme par handler
(
# Requêtes satisfaisantes
prometheus_http_request_duration_seconds_bucket{le="0.2"}
+ ignoring(le)
(
(
# Requêtes tolérables
prometheus_http_request_duration_seconds_bucket{le="1"}
- ignoring(le)
prometheus_http_request_duration_seconds_bucket{le="0.2"}
)
*
0.5
)
)
/ ignoring(le)
# Nombre total de requêtes
prometheus_http_request_duration_seconds_bucket{le="+Inf"}
APDEX Long terme
(
# Requêtes satisfaisantes
sum(prometheus_http_request_duration_seconds_bucket{le="0.2"})
+
(
(
# Requêtes tolérables
sum(prometheus_http_request_duration_seconds_bucket{le="1"})
-
sum(prometheus_http_request_duration_seconds_bucket{le="0.2"})
)
*
0.5
)
)
/
# Nombre total de requêtes
sum(prometheus_http_request_duration_seconds_bucket{le="+Inf"})
APDEX Court terme
(
# Requêtes satisfaisantes
sum(increase(prometheus_http_request_duration_seconds_bucket{le="0.2"}[2m]))
+
(
(
# Requêtes tolérables
sum(increase(prometheus_http_request_duration_seconds_bucket{le="1"}[2m]))
-
sum(increase(prometheus_http_request_duration_seconds_bucket{le="0.2"}[2m]))
)
*
0.5
)
)
/
# Nombre total de requêtes
sum(increase(prometheus_http_request_duration_seconds_bucket{le="+Inf"}[2m]))
Exercices - Partie 2 l'installation et le paramétrage
Exercices à effectuer sur votre serveur personnel
Exercice 15
Mise en place des dossiers et configuration docker-compose :
apt update
mkdir -p /opt/prometheus/data
mkdir -p /opt/prometheus/config
touch /opt/prometheus/docker-compose.yml
touch /opt/prometheus/config/prometheus.yml
echo "autocmd FileType yaml setlocal ts=2 sts=2 sw=2 expandtab" >> ~/.vimrc
echo "set listchars=tab:▸\ ,trail:·,precedes:·,extends:·,eol:$,space:·" >> ~/.vimrc
echo "set list" >> ~/.vimrc
vim /opt/prometheus/config/prometheus.yml
Contenu du fichier prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
Lancement de Prometheus (version simple)
Sur le serveur personnel
cd /opt/prometheus
apt install -y docker-compose
vim /opt/prometheus/docker-compose.yml
Contenu du fichier docker-compose.yml :
version: '3.5'
services:
prometheus:
image: prom/prometheus
ports:
- 9090:9090
volumes:
- "/opt/prometheus/config/:/etc/prometheus/"
command: --config.file=/etc/prometheus/prometheus.yml --log.level=debug # Uniquement pour mettre prometheus en mode debug
node-exporter:
image: quay.io/prometheus/node-exporter
volumes:
- "/:/host:ro,rslave"
ports:
- 9100:9100
command: --path.rootfs=/host
Démarrage du node-exporter et du serveur Prometheus
docker-compose up -d && docker-compose logs -f
Exercice 16
Sujet
Est-ce que les métriques du node-exporter sont disponibles dans le serveur prometheus
Solution
Non
Exercice 17
Sujet
Rajouter la configuration dans scrape_configs pour récupérer les métriques du node-exporter avec une static_config
Utiliser la documentation suivante : https://prometheus.io/docs/prometheus/latest/configuration/configuration/
docker-compose restart prometheus # Redémarrer prometheus
docker-compose logs prometheus # Lire les logs du serveur prometheus
Solution
#file: /opt/prometheus/config/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: node-exporter
static_configs:
- targets:
- 10.102.28.XX:9100
labels:
node: promXX
Exercice 18
Sujet
Rajouter la configuration dans scrape_configs pour récupérer les métriques du prometheus
Solution
#file: /opt/prometheus/config/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: node-exporter
static_configs:
- targets:
- 10.102.28.XX:9100 # node exporter
labels:
node: promXX
- job_name: prometheus
static_configs:
- targets:
- 10.102.28.XX:9090 # prometheus
labels:
node: promXX
Exercice 19
Sujet
- Chercher la documention du scraper sur https://prometheus.io/
- Transformer la configuration de scraping du
node-exporteren file discovery et redémarrer le serveur prometheus - Ajouter le node exporter
10.102.28.72:9100sans redémarrer le serveur prometheus
Solution
#file: /opt/prometheus/config/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- 10.102.28.XX:9090 # prometheus
labels:
node: promXX
- job_name: node-exporter
file_sd_configs:
- files:
- ./node-exporters.yml
refresh_interval: "15s"
#file: /opt/prometheus/config/node-exporters.yml
- targets:
- 10.102.28.XX:9100 # node exporter
- 10.102.28.72:9100
labels:
node: promXX
Exemple plus complet et dynamique :
#file: /opt/prometheus/config/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- 10.102.28.XX:9090 # prometheus
labels:
node: promXX
- job_name: node-exporter
file_sd_configs:
- files:
- ./targets/node-exporters/*.yml
refresh_interval: "15s"
#file: /opt/prometheus/config/targets/node-exporters01.yml
- targets:
- 10.102.28.XX:9100 # node exporter
labels:
node: promXX
Exercice 20
Sujet
Installer un nouvel exporter (MySQL, Docker avec cAdvisor) et l'intégrer dans votre instance prometheus
Installation de MySQL
Installer et configurer MySQL
apt install -y mysql-server
sed -i -e 's/127.0.0.1/0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
rm -rf /var/lib/mysql
mkdir /var/lib/mysql
chown -R mysql:mysql /var/lib/mysql
mysqld --initialize-insecure --console
service mysql stop
service mysql start
mysql -uroot -h localhost
mysql> create user 'prometheus' identified by 'prometheus';
mysql> grant all on *.* to 'prometheus'@'%';
mysql> create database bdd;
mysql> grant all on *.* to 'prometheus'@'%';
mysql> use bdd;
mysql> create table test_table (id int primary key, test varchar(100));
Ajouter au docker-compose.yml:
mysqld-exporter:
image: prom/mysqld-exporter
ports:
- 9104:9104
environment:
- DATA_SOURCE_NAME=prometheus:prometheus@(<IP>:3306)/bdd
Pour lancer le mysqld-exporter, il suffit de faire :
docker-compose up -d
Pour lire les logs :
docker-compose logs mysqld-exporter
Sujet
Scraper les données de votre mysqld-exporter puis trouver la métrique qui permet de savoir que le serveur mysql tourne bien :
Solution
#file: /opt/prometheus/targets/mysqld-exporters01.yml
- targets:
- 10.102.28.XX:9104
labels:
node: promXX
#file: /opt/prometheus/config/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- 10.102.28.XX:9090 # prometheus
labels:
node: promXX
- job_name: node-exporter
file_sd_configs:
- files:
- ./targets/node-exporters/*.yml
refresh_interval: "15s"
- job_name: mysqld-exporter
file_sd_configs:
- files:
- ./targets/mysqld-exporters/*.yml
refresh_interval: "15s"
Sujet
Trouver la métrique qui permet de savoir si Mysql est bien up & running.
Solution
mysql_up
Exercice 21 - cAdvisor
Ajouter au docker-compose.yml:
cadvisor:
image: google/cadvisor:latest
ports:
- 8080:8080
volumes:
- "/:/rootfs:ro"
- "/var/run:/var/run:ro"
- "/sys:/sys:ro"
- "/var/lib/docker/:/var/lib/docker:ro"
- "/dev/disk/:/dev/disk:ro"
privileged: true
Exécuter docker-compose up -d dans le dossier /opt/prometheus
Sujet
Scraper les métriques de cAdvisor
Solution
#file: /opt/prometheus/config/cadvisors01.yml
#file: /opt/prometheus/config/prometheus.yml
Sujet
Lister les conteneurs qui ont été vus pour la dernière fois il y a moins d'une minute :
Solution
(time() - container_last_seen) < 60
Sujet
Superviser la consommotion CPU, mémoire et réseau de Prometheus et lancer en parallèle la requête promql {__name__=~".+"}
Solution
Consommation CPU des containers
sum by (id) (irate(container_cpu_usage_seconds_total{id=~"/docker/.*"}[2m]))
Consommation RAM des containers
container_memory_usage_bytes{id=~"/docker/.*"}
Capacité RAM occupée en %
container_memory_usage_bytes{id=~"/docker/.*"} / ignoring (id, instance, job) group_left node_memory_MemTotal_bytes * 100
container_memory_usage_bytes{id=~"/docker/.*"} / container_spec_memory_reservation_limit_bytes
container_memory_usage_bytes{id=~"/docker/.*"} / (container_spec_memory_reservation_limit_bytes != 0)
container_memory_usage_bytes{id=~"/docker/.*"} / container_spec_memory_limit_bytes
container_memory_usage_bytes{id=~"/docker/.*"} / (container_spec_memory_limit_bytes != 0)
Quantité réseau utilisée en réception
irate(container_network_receive_bytes_total[2m])
Quantité réseau utilisée en émission
irate(container_network_transmit_bytes_total[2m])
Exercice 22
Déployer le blackbox exporter
mkdir /opt/prometheus/blackbox
wget https://raw.githubusercontent.com/prometheus/blackbox_exporter/master/example.yml -O /opt/prometheus/blackbox/blackbox.yml
Ajouter au docker-compose.yml:
blackbox:
image: prom/blackbox-exporter:master
ports:
- 9115:9115
command: "--config.file=/config/blackbox.yml"
volumes:
- "/opt/prometheus/blackbox:/config"
Sujet
Configurer prometheus pour qu'il scrape les métriques des probe du blackbox exporter pour le site orange.fr
Attention, bien utiliser le module http_2xx_example à la place de http_2xx
Solution
# file:prometheus.yml
- job_name: blackbox
file_sd_configs:
- files:
- ./targets/blackbox/*.yml
refresh_interval: "15s"
metrics_path: /probe
params:
module: [http_2xx_orange_fr]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 10.102.28.71:9115
# file:./targets/blackbox/orange-targets.yml
- targets:
- orange.fr
labels:
node: promXX
Suite à la modification dans le docker-compose.yml effectuer :
docker-compose up -d
Note: Pour redémarrer le blackbox exporter :
docker-compose restart blackbox
Sujet
Trouver le code retour HTTP du site orange.fr tel que récupéré depuis le blackbox exporter
Solutions
probe_http_status_code{instance="orange.fr"}
Sujet
Résoudre le soucis en modifiant les headers HTTP dans la configuration du blackbox exporter
Solutions
#file: /opt/prometheus/blackbox/blackbox.yml
modules:
http_2xx_orange_fr:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
valid_status_codes: [] # Defaults to 2xx
method: GET
headers:
Host: orange.fr
Accept-Language: en-US
Origin: orange.fr
follow_redirects: true
fail_if_ssl: false
fail_if_not_ssl: false
fail_if_body_matches_regexp:
- "Could not connect to database"
fail_if_body_not_matches_regexp:
- "[Oo]range"
fail_if_header_matches: [] # Verifies that no cookies are set
fail_if_header_not_matches:
- header: Set-Cookie
allow_missing: true
regexp: '.*'
tls_config:
insecure_skip_verify: false
preferred_ip_protocol: "ip4" # defaults to "ip6"
ip_protocol_fallback: false # no fallback to "ip6"
Sujet
Trouver le temps de réponse global d'orange.fr
Solution
probe_duration_seconds{instance="orange.fr"}
sum by (instance) (probe_http_duration_seconds{instance="orange.fr"})
Exercice 23
Sujet
Rajouter à votre supervision un cluster Kubernetes (URL et token ci-dessous) en utilisant kubernetes_sd_configs
api_server: https://rancher.k8s.datailor.fr/k8s/clusters/c-mdmxl
role: ingress
authorization:
credentials: kubeconfig-u-crd2h8kh77:mgs57kl5z54l76qnqvj8dwvnlsqn5bw6cm68dp2277hm6hc4vvw7wt
Rajouter les role: ingress à votre scrape config du blackbox exporter.
Liste des ingress présentes dans le cluster :
NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE
cattle-prometheus prometheus-ingress <none> prometheus.formation.public.datailor.fr 10.102.28.13,10.102.28.14 80, 443 2d21h
cattle-prometheus prometheus-ingress <none> grafana.formation.public.datailor.fr 10.102.28.13,10.102.28.14 80, 443 2d21h
Solution
#file:prometheus.yml
- job_name: blackbox_kubernetes
kubernetes_sd_configs:
- role: ingress
api_server: https://rancher.k8s.datailor.fr/k8s/clusters/c-mdmxl
authorization:
credentials: kubeconfig-u-crd2h8kh77:mgs57kl5z54l76qnqvj8dwvnlsqn5bw6cm68dp2277hm6hc4vvw7wt
metrics_path: /probe
params:
module: [http_2xx]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 10.102.28.XX:9115
#file: /opt/prometheus/blackbox/blackbox.yml
modules:
http_2xx:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
valid_status_codes: [] # Defaults to 2xx
method: GET
headers: {}
follow_redirects: true
fail_if_ssl: false
fail_if_not_ssl: false
fail_if_body_matches_regexp: []
fail_if_body_not_matches_regexp: []
fail_if_header_matches: [] # Verifies that no cookies are set
fail_if_header_not_matches: []
tls_config:
insecure_skip_verify: false
preferred_ip_protocol: "ip4" # defaults to "ip6"
ip_protocol_fallback: false # no fallback to "ip6"
Exercice 24
Dans docker-compose.yml rajouter :
grafana:
image: grafana/grafana
ports:
- 3000:3000
volumes:
- grafana-config:/etc/grafana
- grafana-data:/var/lib/grafana
- grafana-logs:/var/log/grafana
volumes:
grafana-config:
grafana-data:
grafana-logs:
Pour prendre en compte la modification
docker-compose up -d && docker-compose logs -f grafana
Mot de passe par défaut admin:admin
- Créer la datasource Prometheus
- Importer le tableau de bord 1860 (node exporter)
- D'analyser les requêtes qui sont faites pour ressortir la charge CPU
- Trouver et importer un tableau de bord pour MySQL, analyser sa cohérence
- Trouver et importer un tableau de bord pour le blackbox exporter, analyser sa cohérence
https://grafana.com/grafana/dashboards/
Exercice 25
Créer le dossier $ mkdir /opt/prometheus/config/rules et ajouter dans /opt/prometheus/config/prometheus.yml :
rule_files:
- rules/*.rules.yml
Exécuter docker-compose restart prometheus && docker-compose logs -f prometheus
Exercice 26
https://awesome-prometheus-alerts.grep.to/rules.html
Créer le fichier /opt/prometheus/config/rules/basic.rules.yml et ajouter :
groups:
- name: example
rules:
- alert: (PXX) Instance down
expr: count(up == 0) >= 1
for: 1m
labels:
severity: page
annotations:
summary: (PXX) Instance down
description: >
(PXX) Instance down {{ range query "up == 0" }}
- {{ .Labels.instance }} - {{ .Labels.job }}
{{ end }}
Exercice 27
Ajouter au docker-compose.yml :
alertmanager:
image: prom/alertmanager
ports:
- 9093:9093
volumes:
- "/opt/prometheus/alertmanager/config/:/prometheus"
- "/opt/prometheus/alertmanager/data/:/data"
command: --config.file=/prometheus/alertmanager.yml --storage.path=/data
Exécuter :
mkdir -p /opt/prometheus/alertmanager/config/
mkdir -p /opt/prometheus/alertmanager/data/
chmod 777 -R /opt/prometheus/alertmanager/data/
Ajouter dans /opt/prometheus/alertmanager/config/alertmanager.yml :
global:
#
route:
receiver: 'mattermost'
repeat_interval: 10s
group_interval: 10s
group_wait: 10s
receivers:
- name: mattermost
slack_configs:
- api_url: "https://chat.datailor.fr/hooks/am7kpp6f8pnq8xat37pap8usqa"
send_resolved: true
title: "(AXX){{ range .Alerts }}{{ .Annotations.summary }}\\n{{ end }}"
text: "(AXX){{ range .Alerts }}{{ .Annotations.description }}\\n{{ end }}"
Exécuter docker-compose up -d && docker-compose logs -f
Ajouter dans /opt/prometheus/config/prometheus.yml :
alerting:
alertmanagers:
- scheme: http
static_configs:
- targets:
- "<IP>:9093"
Exécuter docker-compose restart prometheus && docker-compose logs -f prometheus
Exercice 28
Écrire plusieurs alertes et les router différement selon leurs labels dans les receivers suivants :
- prom-pager
- prom-info
- prom-ticket
Solution
#basic.rules:
groups:
- name: example
rules:
- alert: (PXX) Instance down
expr: count(up == 0) >= 1
for: 5s
labels:
severity: page
annotations:
summary: (PXX) Instance down
description: >
(PXX) Instance down {{ range query "up == 0" }}
- {{ .Labels.instance }} - {{ .Labels.job }}
{{ end }}
- alert: (PXX) Instance down
expr: count(up == 0) >= 1
for: 5s
labels:
severity: pager
annotations:
summary: (P11) Instance down
description: >
(PXX) Instance down {{ range query "up == 0" }}
- {{ .Labels.instance }} - {{ .Labels.job }}
{{ end }}
#alertmanager.yml:
global:
#
route:
receiver: 'mattermost'
repeat_interval: 10s
group_interval: 10s
group_wait: 10s
routes:
- match:
severity: ticket
receiver: mattermost-ticket
- match:
severity: info
receiver: mattermost-info
- match:
severity: pager
receiver: mattermost-pager
receivers:
- name: mattermost
slack_configs:
- api_url: "https://chat.datailor.fr/hooks/am7kpp6f8pnq8xat37pap8usqa"
send_resolved: true
title: "(AXX){{ range .Alerts }}{{ .Annotations.summary }}\\n{{ end }}"
text: "(AXX){{ range .Alerts }}{{ .Annotations.description }}\\n{{ end }}"
- name: mattermost-pager
slack_configs:
- api_url: "https://chat.datailor.fr/hooks/bfyy41uny3y39pjmet46hnnijh"
send_resolved: true
title: "(AXX){{ range .Alerts }}{{ .Annotations.summary }}\\n{{ end }}"
text: "(AXX){{ range .Alerts }}{{ .Annotations.description }}\\n{{ end }}"
- name: mattermost-ticket
slack_configs:
- api_url: "https://chat.datailor.fr/hooks/n73mdxdtq3fpd8r4x5zkmauaiy"
send_resolved: true
title: "(AXX){{ range .Alerts }}{{ .Annotations.summary }}\\n{{ end }}"
text: "(AXX){{ range .Alerts }}{{ .Annotations.description }}\\n{{ end }}"
- name: mattermost-info
slack_configs:
- api_url: "https://chat.datailor.fr/hooks/otwsdx3a33df5ctc915hbn5xmc"
send_resolved: true
title: "(AXX){{ range .Alerts }}{{ .Annotations.summary }}\\n{{ end }}"
text: "(AXX){{ range .Alerts }}{{ .Annotations.description }}\\n{{ end }}"
Exercice 29
Sujet
Écrire une recording rule correspondant à la somme des requêtes http de prometheus sur 5 minutes.
Solution
- name: recordings
rules:
- record: any:prometheus_http_requests:sum5m
expr: sum(increase(prometheus_http_requests_total[5m]))
Exercice 30
Sujet
Écrire 2 recording rules, l'une pour calculer la moyenne sur 12h et l'autre l'écart type sur 12h de la recording rule précédente
Solution
- name: recordings
rules:
- record: any:prometheus_http_requests:sum5m
expr: sum(increase(prometheus_http_requests_total[5m]))
- record: any:avg_prometheus_http_requests:12h
expr: avg_over_time(any:prometheus_http_requests:sum5m[12h])
- record: any:stddev_prometheus_http_requests:12h
expr: stddev_over_time(any:prometheus_http_requests:sum5m[12h])
Exercice 31
Sujet
Écrire la recording rule du z-score du nombre de requêtes http sur le serveur prometheus grâce à la formule suivante :
Z-score = (Métrique observée - moyenne de la métrique) / écart-type de la métrique
Solution
- name: recordings
rules:
- record: any:prometheus_http_requests:sum5m
expr: sum(increase(prometheus_http_requests_total[5m]))
- record: any:avg_prometheus_http_requests:12h
expr: avg_over_time(any:prometheus_http_requests:sum5m[12h])
- record: any:stddev_prometheus_http_requests:12h
expr: stddev_over_time(any:prometheus_http_requests:sum5m[12h])
- record: any:zscore_prometheus_https_requests:12h
expr: >
(
any:prometheus_http_requests:sum5m
-
any:avg_prometheus_http_requests:12h
)
/
any:stddev_prometheus_http_requests:12h
Exercice 32
Construire une fédération entre vos Prometheus
- job_name: federation
static_configs:
- targets:
- 10.102.28.XX:9090
- 10.102.28.72:9090
metrics_path: /federate
honor_labels: true
honor_timestamps: true
params:
'match[]':
- '{__name__=~"node_cpu_.*", instance=~"10.102.28.XX.*"}'
- '{__name__=~"node_cpu_.*", instance=~"10.102.28.72.*"}'
Exercice 33
Sujet
Lire l'article de Gitlab sur la détection d'anomalies avec Prometheus (https://about.gitlab.com/blog/2019/07/23/anomaly-detection-using-prometheus/) et améliorer notre requête précédente.
Références utiles
- Principe de Heartbeat (Deadman's switch) https://jpweber.io/blog/taking-advantage-of-deadmans-switch-in-prometheus/ pour les petites infrastructures
- Liste d'alertes communes : https://awesome-prometheus-alerts.grep.to/rules.html
- Stockage long terme à surveiller : https://thanos.io/
- Outils connexes : https://openapm.io/
- Exemples de requêtes :
- https://github.com/infinityworks/prometheus-example-queries
- https://coralogix.com/blog/promql-tutorial-5-tricks-to-become-a-prometheus-god/
- https://timber.io/blog/promql-for-humans/
- https://archive.fosdem.org/2017/schedule/event/alerting_with_time_series/attachments/slides/1736/export/events/attachments/alerting_with_time_series/slides/1736/FOSDEM__Alerting_with_Time_Series.pdf
- https://towardsdatascience.com/practical-monitoring-with-prometheus-grafana-part-iii-81f019ecee19
- https://about.gitlab.com/blog/2019/07/23/anomaly-detection-using-prometheus/
- https://rancher.com/docs/rancher/v2.x/en/monitoring-alerting/v2.0.x-v2.4.x/cluster-monitoring/expression/