Déploiement Grafana/Prometheus

Déploiement Prometheus + Grafana + Exporters - Guide Complet

Date : 28 Novembre 2025
Environnement : AlmaLinux 10, Podman rootless
Infrastructure : VPS OVH avec monitoring complet des services


Table des matières

  1. Architecture finale
  2. Stack de monitoring déployée
  3. Déploiement Prometheus & Grafana
  4. Configuration des exporters
  5. Configuration Nginx reverse proxy
  6. Dashboard Grafana
  7. Problèmes rencontrés et solutions
  8. Commandes de maintenance
  9. Ressources

Architecture finale

┌─────────────────────────────────────────────────────────┐
│                    VPS AlmaLinux 10                     │
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │           Conteneurs Podman (rootless)           │   │
│  │                                                  │   │
│  │  ┌──────────────┐    ┌──────────────┐           │   │
│  │  │  Prometheus  │◄───│   Grafana    │           │   │
│  │  │  :9091       │    │   :3000      │           │   │
│  │  └──────┬───────┘    └──────────────┘           │   │
│  │         │                                        │   │
│  │         ├──► Node Exporter (:9100)               │   │
│  │         └──► Autres conteneurs                   │   │
│  └──────────────────────────────────────────────────┘   │
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │        Services système (hôte)                   │   │
│  │                                                  │   │
│  │  • Podman Exporter (:9882)                       │   │
│  │  • Podman API (socket rootless)                  │   │
│  │  • Nginx reverse proxy                           │   │
│  └──────────────────────────────────────────────────┘   │
│                                                          │
│  ┌──────────────────────────────────────────────────┐   │
│  │             Accès externe HTTPS                  │   │
│  │                                                  │   │
│  │  grafana.sanjy.fr → Nginx → Grafana         │   │
│  └──────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘

Stack de monitoring déployée

Services déployés

Service Type Port Description
Prometheus Conteneur 9091 Collecte et stockage des métriques
Grafana Conteneur 3000 Visualisation et dashboards
Node Exporter Conteneur 9100 Métriques système (CPU, RAM, disque)
Podman Exporter Systemd user 9882 Métriques des conteneurs Podman
Podman API Systemd user Socket API Podman pour l'exporter
Nginx Système 80/443 Reverse proxy HTTPS

Services monitorés


Déploiement Prometheus & Grafana

Structure des fichiers

~/monitoring/
├── docker-compose.yml
├── prometheus/
│   ├── config/
│   │   └── prometheus.yaml
│   └── data/                    # Volume Podman
└── grafana/
    ├── data/                    # Volume Podman
    └── provisioning/
        └── datasources/
            └── prometheus.yml

Création de la structure

mkdir -p ~/monitoring/{prometheus/config,grafana/provisioning/datasources}
cd ~/monitoring

Configuration Prometheus

Fichier prometheus/config/prometheus.yaml :

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  # Prometheus auto-monitoring
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Node Exporter (système)
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['host.containers.internal:9100']

  # Podman Exporter (conteneurs)
  - job_name: 'podman_exporter'
    static_configs:
      - targets: ['host.containers.internal:9882']

  # Nginx Exporter (optionnel)
  - job_name: 'nginx'
    static_configs:
      - targets: ['host.containers.internal:9113']

Points clés :

Configuration datasource Grafana

Fichier grafana/provisioning/datasources/prometheus.yml :

apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: false

Note : Utilisation de prometheus:9090 (résolution DNS interne Docker/Podman entre conteneurs du même réseau).

Docker Compose

Fichier docker-compose.yml :

version: '3.8'

services:
  prometheus:
    image: docker.io/prom/prometheus:latest
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./prometheus/config:/etc/prometheus:Z
      - prometheus_data:/prometheus:Z
    command:
      - '--config.file=/etc/prometheus/prometheus.yaml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'
    ports:
      - "9091:9090"
    networks:
      - monitoring

  grafana:
    image: docker.io/grafana/grafana:latest
    container_name: grafana
    restart: unless-stopped
    user: "472"
    volumes:
      - grafana_data:/var/lib/grafana:Z
      - ./grafana/provisioning:/etc/grafana/provisioning:Z
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD= ******
      - GF_SERVER_ROOT_URL=https://grafana.sanjy.fr
      - GF_SERVER_DOMAIN=grafana.sanjy.fr
    ports:
      - "3000:3000"
    networks:
      - monitoring
    depends_on:
      - prometheus

  node-exporter:
    image: docker.io/prom/node-exporter:latest
    container_name: node-exporter
    restart: unless-stopped
    command:
      - '--path.rootfs=/host'
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
    volumes:
      - /:/host:ro,rslave
    ports:
      - "9100:9100"
    networks:
      - monitoring

volumes:
  prometheus_data:
  grafana_data:

networks:
  monitoring:
    driver: bridge

Points importants :

Fix SELinux

# Appliquer les contextes SELinux
sudo chcon -R -t container_file_t ~/monitoring/

# Ou permanent
sudo semanage fcontext -a -t container_file_t "$HOME/monitoring(/.*)?"
sudo restorecon -Rv ~/monitoring/

Démarrage

cd ~/monitoring
podman-compose up -d

# Vérifier les logs
podman-compose logs -f

# Vérifier que tout tourne
podman ps

Accès


Configuration des exporters

Node Exporter (conteneur)

Déjà inclus dans docker-compose.yml.

Test :

curl http://localhost:9100/metrics | grep node_

Podman Exporter (service systemd user)

Pourquoi en service systemd et pas en conteneur ?

La vérité vraie: j'ai juste pas réussi à faire marcher l'image prometheus-podman-exporter :D Si quelqu'un a déjà réussi à la faire marcher qu'il me dise comment svp.

Installation

# Installer depuis les dépôts AlmaLinux
sudo dnf install -y prometheus-podman-exporter

Service Podman API (prérequis)

Créer le service pour exposer l'API Podman :

mkdir -p ~/.config/systemd/user/

cat > ~/.config/systemd/user/podman-api.service << 'EOF'
[Unit]
Description=Podman API Service
Documentation=man:podman-system-service(1)
After=network.target

[Service]
Type=exec
KillMode=process
ExecStart=/usr/bin/podman system service --time=0

[Install]
WantedBy=default.target
EOF

# Activer et démarrer
systemctl --user daemon-reload
systemctl --user enable --now podman-api

# Vérifier
systemctl --user status podman-api

# Vérifier que le socket existe
ls -lah /run/user/$(id -u)/podman/podman.sock

Service Podman Exporter

cat > ~/.config/systemd/user/prometheus-podman-exporter.service << EOF
[Unit]
Description=Prometheus Podman Exporter
After=podman-api.service
Requires=podman-api.service

[Service]
Type=simple
Environment="CONTAINER_HOST=unix:///run/user/$(id -u)/podman/podman.sock"
ExecStart=/usr/bin/prometheus-podman-exporter
Restart=always
RestartSec=5

[Install]
WantedBy=default.target
EOF

# Activer et démarrer
systemctl --user daemon-reload
systemctl --user enable --now prometheus-podman-exporter

# Vérifier
systemctl --user status prometheus-podman-exporter

Test

# Métriques disponibles
curl http://localhost:9882/metrics | grep podman_container

# Vérifier dans Prometheus
curl -G http://localhost:9091/api/v1/query \
  --data-urlencode 'query=podman_container_info' | jq

Configuration Nginx reverse proxy

DNS OVH

Ajouter l'enregistrement A :

Type    Nom       Valeur          TTL
A       grafana   <IP_VPS>        3600

Certificat Let's Encrypt

Étendre le certificat existant :

sudo certbot certonly --nginx \
  -d sanjy.fr \
  -d www.sanjy.fr \
  -d vault.sanjy.fr \
  -d grafana.sanjy.fr \
  --expand

Configuration Nginx

Fichier /etc/nginx/conf.d/grafana.conf :

server {
    listen 80;
    server_name grafana.sanjy.fr;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name grafana.sanjy.fr;

    # SSL
    ssl_certificate /etc/letsencrypt/live/sanjy.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sanjy.fr/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Headers sécurité
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Logs
    access_log /var/log/nginx/grafana-access.log;
    error_log /var/log/nginx/grafana-error.log;

    # Proxy vers Grafana
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

Test et activation

# Tester la configuration
sudo nginx -t

# Recharger Nginx
sudo systemctl reload nginx

# Fix SELinux si nécessaire
sudo setsebool -P httpd_can_network_connect 1

# Vérifier
curl -I https://grafana.sanjy.fr

Accès final

https://grafana.sanjy.fr

Dashboard Grafana

Connexion

Dashboard "Services Status" (custom)

Création manuelle :

  1. Menu → Dashboards → New Dashboard
  2. Add visualization
  3. Select Prometheus datasource

Query :

podman_container_info{name=~"jenkins|vault|bookstack"} * on(id) group_left(name) podman_container_state

Configuration :

Value mappings :

Résultat : Briques vertes/rouges indiquant l'état de chaque service.

Dashboards communautaires (tentative)

IDs testés mais non fonctionnels :

Raison : Les dashboards communautaires attendent des labels ou métriques spécifiques qui ne correspondent pas exactement à la configuration.

Solution : Création de dashboards custom adaptés aux métriques disponibles.


Conclusion

Infrastructure monitoring complète déployée avec succès.

Points clés :

Stack complètement opérationnelle et prête pour la production.

Prochaines étapes possibles :


Revision #3
Created 2025-11-29 00:19:47 UTC by Admin
Updated 2025-11-29 18:00:20 UTC by Admin