Unité 5.1 : Observabilité et débogage
Introduction
Vous avez déployé TaskBoard sur Managed Kubernetes dans le module 3 et l'avez connecté à PostgreSQL, Redis, Object Storage et Kafka dans le module 4. Il est maintenant en production, et à un moment donné, il présentera des dysfonctionnements : des pics de latence de l'API, un pod en boucle de redémarrage, une connexion à la base de données qui expir silencieusement, ou un trafic qui cesse d'atteindre une couche sans que personne ne sache pourquoi. Sans observabilité intégrée, vous déboguez à l'aveugle.
Cette unité vous montre comment instrumenter et déboguer TaskBoard de manière programmatique sur IONOS CLOUD. Vous enverrez des métriques au Monitoring Service, transmettez des journaux au Logging Service, auditez les modifications d'infrastructure via Activity Logs et capturez le trafic réseau avec Flow Logs. Chaque outil couvre une couche différente de la pile, et l'unité se conclut par un workflow de débogage Kubernetes reproductible qui les relie. Il est essentiel de noter que vous apprendrez également la contrainte IONOS CLOUD qui piège la plupart des équipes : les événements du plan de contrôle Kubernetes ne transitent pas automatiquement par le Logging Service, vous devez donc vous-même transmettre les journaux du cluster.
1. Métriques avec le Monitoring Service
Le Monitoring Service ingère les métriques via un pipeline que vous créez à l'aide de l'API REST. Chaque pipeline expose un point de terminaison de poussée HTTP qui accepte les métriques au format Prometheus (Counter, Gauge, Histogram, Summary), et la visualisation se fait dans une instance Grafana gérée, provisionnée par contrat et par région. Le format d'ingestion alternatif est le JSON, qui doit être compressé à l'aide de Snappy.
Vous créez un pipeline en POST à /pipelines sur le point de terminaison régional. Le point de terminaison suit le modèle https://monitoring.<region-slug>.ionos.com, par exemple https://monitoring.de-txl.ionos.com/pipelines pour Berlin ou https://monitoring.de-fra.ionos.com/pipelines pour Francfort. Les agents de poussée pris en charge sont Prometheus, Grafana Agent, OpenTelemetry et Fluent Bit.
1.1 Création d'un pipeline de métriques
Créez le pipeline avec un jeton Bearer. La réponse renvoie la clé d'ingestion propre à chaque pipeline dans metadata.key, mais uniquement lors de la création. Pour des raisons de sécurité, la clé n'est jamais renvoyée dans les réponses ultérieures, il est donc essentiel de la capturer immédiatement et de la stocker dans votre gestionnaire de secrets.
curl -s -X POST "https://monitoring.de-txl.ionos.com/pipelines" \
-H "Authorization: Bearer $IONOS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"name": "taskboard-prod"
}
}'
Sortie attendue (tronquée) :
{
"id": "a1b2c3d4-...",
"metadata": {
"key": " exporter-api-key-shown-once ",
"grafanaEndpoint": "https://a1b2c3d4-...grafana.de-txl.ionos.com"
},
"properties": { "name": "taskboard-prod", "status": "PROVISIONING" }
}
Le motif d'hôte d'ingestion est <id>-metrics.<id>.monitoring.<region>.ionos.com, et le chemin de poussée est /api/v1/push sur le port sortant 443. Le motif d'URL de poussée complet est <httpEndpoint>/api/v1/push.
1.2 Poussée des métriques depuis TaskBoard
Configurez votre agent pour pousser vers le point d'accès du pipeline. Grafana Agent, Prometheus et OpenTelemetry s'authentifient tous en définissant l'en-tête APIKEY: <key>. L'exemple Fluent Bit utilise à la place Authorization: Bearer <apiKey>. L'intervalle de poussée par défaut est de 1 minute et est configurable.
# grafana-agent.yaml - remote_write block for TaskBoard API pods
metrics:
configs:
- name: taskboard
remote_write:
- url: https://a1b2c3d4-metrics.a1b2c3d4.monitoring.de-txl.ionos.com/api/v1/push
headers:
APIKEY: ${MONITORING_PIPELINE_KEY}
scrape_configs:
- job_name: taskboard-api
static_configs:
- targets: ["taskboard-api:8080"]
Une fois les données réceptionnées, créez des tableaux de bord et des alertes dans l'instance Grafana managée située à l'adresse grafanaEndpoint, telle que renvoyée dans la réponse de création. Vous définissez les conditions d'alerte, les seuils et les préférences de notification directement dans Grafana, par exemple une alerte lorsque la latence p95 des requêtes de l'API TaskBoard dépasse un seuil sur une fenêtre de 5 minutes. L'accès au Monitoring Service est contrôlé par le privilège IAM nommé Access and manage Monitoring.
2. Journaux centralisés avec le Logging Service
Le Logging Service collecte les journaux via son propre pipeline, créé avec POST /pipelines sur le point d'accès régional https://logging.<region-slug>.ionos.com. Un nouveau pipeline renvoie le statut PROVISIONING et devient utilisable une fois qu'il est Ready. Les sources de journaux prises en charge sont Kubernetes, Docker, Linux Systemd, HTTP (API REST JSON) et Générique. La rétention par défaut est de 30 jours, et les valeurs de rétention autorisées sont 7, 14, 30 ou illimitée. Chaque pipeline autorise jusqu'à 5 flux de journaux.
curl -s -X POST "https://logging.de-txl.ionos.com/pipelines" \
-H "Authorization: Bearer $IONOS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"name": "taskboard-logs",
"logs": [
{"source": "kubernetes", "tag": "taskboard", "protocol": "tcp", "retentionInDays": 30}
]
}
}'
Les journaux sont interrogeables dans Grafana du Logging Service sur une fenêtre de requête de 30 jours. L'accès nécessite le privilège IAM Access and manage Logging Service.
2.1 Transfert des journaux avec Fluent Bit
Fluent Bit est l'agent de journaux pris en charge. Chaque source de journaux nécessite le point de terminaison du pipeline et une clé, tous deux obtenus à partir de la réponse de l'API REST. Pour Kubernetes, installez le paquet Fluent Bit correspondant à votre distribution, puis orientez sa sortie de transfert vers le tcpAddress du pipeline avec la clé partagée.
# fluent-bit.conf - forward TaskBoard pod logs to the Logging Service
[OUTPUT]
Name forward
Match *
Host <tcpAddress-host>
Port 9000
Tag taskboard
tls on
SharedKey ${LOGGING_PIPELINE_KEY}
Notez que la source HTTP REST n'accepte que des journaux au format JSON. Structurez donc les journaux de votre application en JSON lorsque vous utilisez le chemin HTTP au lieu du protocole forward.
2.2 La contrainte du plan de contrôle Kubernetes
Il s'agit d'un piège spécifique à IONOS CLOUD. Les événements du plan de contrôle Kubernetes ne transitent PAS automatiquement par le Logging Service d'IONOS CLOUD. Le déploiement d'une charge de travail sur Managed Kubernetes ne vous offre pas la transmission des journaux du cluster gratuitement. Vous devez configurer la transmission des journaux au niveau du cluster séparément, ce qui signifie en pratique d'exécuter Fluent Bit en tant que DaemonSet dans votre cluster afin d'acheminer les journaux des nœuds et des pods vers votre pipeline.
# Excerpt: Fluent Bit DaemonSet output for an MKS cluster
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluent-bit
namespace: logging
spec:
template:
spec:
containers:
- name: fluent-bit
image: fluent/fluent-bit:latest
env:
- name: LOGGING_PIPELINE_KEY
valueFrom:
secretKeyRef:
name: logging-pipeline
key: shared-key
Pour une prise en charge intégrée sans que chaque produit n'exécute sa propre pile d'ingestion, le Logging Service propose également le Central Logging, une fonctionnalité au niveau du contrat et par région, activée avec PUT /central (corps {"properties":{"enabled":true}}). Seuls les administrateurs de contrat, les propriétaires et les utilisateurs disposant du privilège Access and manage Logging Service peuvent l'activer ou la désactiver.
3. Audit des modifications avec Activity Logs
Lorsqu'un incident remonte à une modification de configuration, Activity Logs permettent de déterminer qui a modifié quoi et à quel moment. L'URL de base de l'API est https://api.ionos.com/activitylog/v1, et le service est en lecture seule par conception : chaque appel est une GET. Il enregistre les connexions des utilisateurs, le provisionnement des ressources, les modifications de configuration, l'accès aux données, la récupération des ressources, les modifications des ressources et les suppressions de ressources. Chaque entrée suit également la source d'une action, les ressources affectées et la chronologie des événements. Les réponses sont au format JSON, et l'authentification accepte l'authentification de base ou un jeton Bearer.
3.1 Interrogation du journal d'activité
Filtrez par une plage de début et de fin date pour définir la fenêtre d'investigation. La pagination est contrôlée par une limite qui plafonne le nombre d'éléments de réponse par page et un décalage pour parcourir les pages suivantes.
# Find all changes during the incident window
curl -s "https://api.ionos.com/activitylog/v1/contracts/${CONTRACT_NUMBER}?startDate=2026-06-04&endDate=2026-06-05&limit=50" \
-H "Authorization: Bearer $IONOS_TOKEN"
(replacez ${CONTRACT_NUMBER} par votre numéro de contrat ; le chemin de base /activitylog/v1 sans segment /contracts/{contractNumber} ne renvoie que les informations de version de l'API, et non les entrées de journal.)
import requests
def find_changes(token, contract_number, start, end):
url = f"https://api.ionos.com/activitylog/v1/contracts/{contract_number}"
headers = {"Authorization": f"Bearer {token}"}
offset, limit = 0, 100
while True:
params = {"startDate": start, "endDate": end, "limit": limit, "offset": offset}
items = requests.get(url, headers=headers, params=params, timeout=30).json()["hits"]["hits"]
if not items:
break
for entry in items:
yield entry["_source"]
offset += limit
La période de conservation des Activity Logs est de 35 jours. Pour tout ce dont vous avez besoin au-delà de cette durée, téléchargez les données et stockez-les ailleurs. IONOS Cloud Object Storage est la cible explicitement recommandée pour la persistance à long terme, de sorte qu'un travail d'exportation planifié vers un bucket vous fournit une piste d'audit qui dépasse la fenêtre intégrée.
4. Dépannage réseau avec Flow Logs
Lorsque la connectivité est interrompue entre les niveaux de TaskBoard et que les journaux de l'application sont silencieux, le problème se situe généralement au niveau de la couche réseau : une règle de pare-feu, une lacune de routage ou une carte réseau mal configurée. Flow Logs capturent le trafic afin que vous puissiez voir exactement ce qui est accepté et rejeté. Les ressources prises en charge sont la carte réseau de la VM, le Managed Network Load Balancer, le Managed Application Load Balancer et le Managed NAT Gateway. Les actions de capture sont Rejected, Accepted ou Any, et les directions de capture sont Ingress, Egress ou Bidirectional. Les adresses IPv4 et IPv6 sont toutes deux prises en charge.
Flow Logs publie dans un bucket IONOS Cloud Object Storage au format .log.gz (texte compressé gzip), avec une rotation toutes les 10 minutes. Deux contraintes sont importantes pour l'automatisation : la configuration est immuable après la création, et il n'y a qu'un seul journal de flux par ressource. Pour modifier un paramètre, vous devez supprimer et recréer le journal. La création de journaux de flux nécessite le privilège de groupe DCD Create Flow logs.
4.1 Lecture des enregistrements Flow Log
Chaque enregistrement est au format fixe et immuable (version 2). Les champs les plus utiles pour le dépannage sont srcaddr, dstaddr, srcport, dstport, protocol et action, où action est ACCEPT (autorisé par le pare-feu) ou REJECT (bloqué par le pare-feu). Une série d'entrées REJECT sur le port utilisé par votre application indique directement une règle NSG.
import boto3, gzip
# Flow logs land in an Object Storage bucket as .log.gz objects
s3 = boto3.client("s3",
endpoint_url="https://s3-eu-central-1.ionoscloud.com",
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY)
obj = s3.get_object(Bucket="taskboard-flowlogs", Key="2026/06/05/flow-0001.log.gz")
for line in gzip.decompress(obj["Body"].read()).decode().splitlines():
f = line.split()
# version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
if f and f[-2] == "REJECT":
print("BLOCKED:", f[3], "->", f[4], "port", f[6])
Le champ log-status est OK pour un intervalle normal ou SKIPDATA lorsque des enregistrements ont été ignorés pendant l'intervalle. Voir SKIPDATA signifie que vous n'obtenez pas l'image complète pour cette fenêtre.
5. Le flux de travail de débogage Kubernetes
La plupart des incidents de production de TaskBoard apparaissent d'abord dans Kubernetes. Traitez les couches dans l'ordre plutôt que de passer directement aux outils de plateforme, car le signal le moins coûteux est le plus proche du pod.
5.1 Chemin d'escalade
Commencez par kubectl et n'escaladez vers l'observabilité de la plateforme que lorsque le signal intra-cluster vient à manquer :
# 1. What is the pod actually doing?
kubectl get pods -n taskboard
kubectl logs -n taskboard deploy/taskboard-api --tail=100
# 2. Why won't it start or stay healthy?
kubectl describe pod -n taskboard <pod-name>
kubectl get events -n taskboard --sort-by=.lastTimestamp
# 3. Is it a resource or latency problem? -> Monitoring Service metrics in Grafana
# 4. Need historical/aggregated logs across pods? -> Logging Service search
Rappel de la contrainte de la section 2 : kubectl logs vous affiche la sortie en direct du conteneur, mais elle n'est pas persistée et les événements du plan de contrôle n'atteignent pas le Logging Service de manière autonome. La recherche dans le Logging Service n'est utile que si votre DaemonSet Fluent Bit effectue déjà la transmission. Intégrez l'observabilité avant l'incident, pas pendant.
5.2 Vérifications d'état
Les sondes de vivacité et de disponibilité constituent votre première ligne de défense pour la récupération automatisée. Une sonde de disponibilité qui échoue retire le pod des points de terminaison du Service, ce qui arrête le flux de trafic vers une instance défaillante, tandis qu'une sonde de vivacité redémarre un conteneur bloqué.
# TaskBoard API deployment probes
livenessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet: { path: /readyz, port: 8080 }
initialDelaySeconds: 5
periodSeconds: 10
Étant donné que Managed Application Load Balancer est provisionné séparément de vos manifests K8s, configurez sa vérification d'état pour qu'elle corresponde au même chemin /readyz afin que l'ALB et Kubernetes soient en accord quant aux backends considérés comme sains.
Fiche de référence rapide de l'API
Principales fins de point pour le sujet de cette unité :
| Méthode | Fin de point | Description |
|---|---|---|
POST |
https://monitoring.<region>.ionos.com/pipelines |
Créer un pipeline de métriques (clé dans metadata.key, une seule fois) |
POST |
<httpEndpoint>/api/v1/push |
Envoyer des métriques au format Prometheus (en-tête APIKEY) |
POST |
https://logging.<region>.ionos.com/pipelines |
Créer un pipeline de journaux (renvoie PROVISIONING) |
PUT |
https://logging.<region>.ionos.com/central |
Activer/désactiver Central Logging pour la région |
GET |
https://api.ionos.com/activitylog/v1/contracts/{contractNumber} |
Interroger l'activité d'audit (filtres de date, limite/décalage) |
URL de base (CloudAPI) : https://api.ionos.com/cloudapi/v6
Authentification : Authorization: Bearer <token> (l'envoi de métriques utilise APIKEY: <key>)
Atelier de code
Objectif : Mettre en place la surveillance des métriques et la journalisation centralisée pour TaskBoard, puis diagnostiquer une panne de connectivité simulée à l'aide d'Activity Logs et de Flow Logs.
Prérequis :
- Compte IONOS CLOUD avec jeton API (
IONOS_TOKENexporté) - TaskBoard en cours d'exécution sur Managed Kubernetes (Unité 3.2)
kubectlconfiguré pour votre cluster MKS- Un seau Object Storage et une Access Key + Secret Key pour Flow Logs
Étape 1 : Créer le pipeline de surveillance
curl -s -X POST "https://monitoring.de-txl.ionos.com/pipelines" \
-H "Authorization: Bearer $IONOS_TOKEN" -H "Content-Type: application/json" \
-d '{"properties":{"name":"taskboard-prod"}}' | tee pipeline.json
Sortie attendue :
{"id":"...","metadata":{"key":"...","grafanaEndpoint":"https://...grafana.de-txl.ionos.com"},...}
Étape 2 : Capturer la clé d'ingestion
export MON_KEY=$(python3 -c "import json;print(json.load(open('pipeline.json'))['metadata']['key'])")
echo "Stored key length: ${#MON_KEY}"
Sortie attendue :
Stored key length: 44
Étape 3 : Créer le pipeline de journalisation
curl -s -X POST "https://logging.de-txl.ionos.com/pipelines" \
-H "Authorization: Bearer $IONOS_TOKEN" -H "Content-Type: application/json" \
-d '{"properties":{"name":"taskboard-logs","logs":[{"source":"kubernetes","tag":"taskboard","protocol":"tcp","retentionInDays":30}]}}'
Sortie attendue :
{"id":"...","properties":{"name":"taskboard-logs","status":"PROVISIONING"}}
Étape 4 : Déployer le DaemonSet Fluent Bit pour transférer les journaux du cluster (les journaux du plan de contrôle ne parviendront pas autrement)
kubectl create namespace logging
kubectl create secret generic logging-pipeline -n logging --from-literal=shared-key="$LOGGING_PIPELINE_KEY"
kubectl apply -f fluent-bit-daemonset.yaml
Sortie attendue :
daemonset.apps/fluent-bit created
Étape 5 : Simuler une interruption en ajoutant une règle NSG qui bloque le port de la couche d'application, puis observer l'échec du trafic
kubectl get pods -n taskboard # pods Running, but requests time out
Étape 6 : Trouver la modification dans Activity Logs
curl -s "https://api.ionos.com/activitylog/v1/contracts/${CONTRACT_NUMBER}?startDate=2026-06-05&endDate=2026-06-05&limit=20" \
-H "Authorization: Bearer $IONOS_TOKEN"
Sortie attendue :
{"hits":{"total":1,"hits":[{"_source":{"action":"configuration changes","resource":"firewallrule/...","user":"...","time":"..."}}]}}
Étape 7 : Confirmer au niveau du réseau avec Flow Logs
python3 read_flowlogs.py | grep BLOCKED
Sortie attendue :
BLOCKED: 10.0.2.5 -> 10.0.3.7 port 8080
Liste de contrôle de validation :
- [ ] Pipeline de surveillance créé et clé capturée avant tout second appel API
- [ ] Pipeline de journalisation atteint
Readyet le DaemonSet Fluent Bit est en cours d'exécution - [ ] La requête Activity Logs renvoie la modification de configuration en cause
- [ ] Les Flow Logs affichent des enregistrements
REJECTsur le port bloqué
Nettoyage :
curl -s -X DELETE "https://monitoring.de-txl.ionos.com/pipelines/$MON_ID" -H "Authorization: Bearer $IONOS_TOKEN"
curl -s -X DELETE "https://logging.de-txl.ionos.com/pipelines/$LOG_ID" -H "Authorization: Bearer $IONOS_TOKEN"
kubectl delete namespace logging
Erreurs courantes
Erreurs de développement à éviter lors de l'observabilité sur IONOS CLOUD :
-
S'attendre à des journaux Kubernetes sans transfert
- Problème : Vous ouvrez Grafana du Logging Service après un déploiement sur MKS et vous ne voyez aucun journal de cluster ou de plan de contrôle.
- Pourquoi cela se produit : Les événements du plan de contrôle Kubernetes ne transitent pas automatiquement par le Logging Service d'IONOS CLOUD. La plateforme ne les transfère pas à votre place.
- Solution : Exécutez Fluent Bit en tant que DaemonSet (ou configurez le Central Logging) et pointez-le vers le
tcpAddressde votre pipeline de journalisation avec la clé partagée avant d'avoir besoin des journaux.
-
Perte de la clé du pipeline de métriques
- Problème : Votre agent reçoit
401/403lors de l'envoi et vous ne trouvez pas la clé pour corriger le problème. - Pourquoi cela se produit : La clé d'ingestion n'est retournée qu'une seule fois, dans
metadata.keylors de la création du pipeline, et n'apparaît jamais dans les réponses ultérieures pour des raisons de sécurité. - Solution : Enregistrez la clé dans votre magasin de secrets lors de la création. Si elle est perdue, vous ne pouvez pas la récupérer ; provisionnez un nouveau pipeline ou faites pivoter la clé.
- Problème : Votre agent reçoit
-
Tentative de modification d'un Flow Log sur place
- Problème : Vous mettez à jour la direction de capture d'un Flow Log via l'API et la modification n'a pas d'effet.
- Pourquoi cela se produit : La configuration d'un Flow Log est immuable après sa création, et il existe un seul journal de flux par ressource.
- Solution : Supprimez le journal de flux existant et créez-en un nouveau avec les paramètres souhaités. Intégrez ce modèle de suppression puis de création dans votre Terraform/automatisation plutôt que de vous attendre à une mise à jour sur place.
Résumé
Vous pouvez désormais instrumenter TaskBoard de bout en bout sur IONOS CLOUD. Les métriques sont acheminées vers un pipeline de Monitoring Service et affichées dans Grafana managé avec des alertes ; les journaux sont acheminés vers un pipeline de Logging Service via Fluent Bit ; les modifications d'infrastructure sont auditées via l'API Activity Logs en lecture seule ; et les pannes au niveau réseau sont visibles dans les Flow Logs écrits dans Object Storage. Avec des sondes et des vérifications d'état ALB correspondantes en place, les instances défaillantes sont retirées automatiquement de la rotation. Surtout, vous connaissez la contrainte d'IONOS CLOUD qui affecte les équipes en production : les journaux du cluster et les événements du plan de contrôle doivent être transférés par vous, et non par la plateforme.
Points clés :
- Les pipelines de surveillance acceptent les métriques au format Prometheus sur
/api/v1/push; la clé d'ingestion n'est affichée qu'une seule fois lors de la création - Les pipelines de journalisation prennent en charge les sources Kubernetes, Docker, Systemd, HTTP et génériques, avec une rétention de 7/14/30 jours ou illimitée ; Fluent Bit est l'agent pris en charge
- Les événements du plan de contrôle Kubernetes ne sont PAS acheminés automatiquement via le Logging Service ; transférez-les vous-même avec un DaemonSet Fluent Bit ou le Central Logging
- Activity Logs est en lecture seule (
GETuniquement), filtrable par date, avec une rétention de 35 jours ; exportez vers Object Storage pour des pistes d'audit plus longues - Les Flow Logs capturent
ACCEPT/REJECTpar interface réseau, NLB, ALB et passerelle NAT dans des objets.log.gz; la configuration est immuable et limitée à une par ressource
Terminologie importante :
- Pipeline de métriques : Une instance de Monitoring Service créée via
POST /pipelinesqui expose un point de terminaison HTTP push pour les métriques au format Prometheus. - Clé d'ingestion : L'identifiant par pipeline renvoyé une seule fois dans
metadata.key; les agents l'envoient en tant qu'en-têteAPIKEY(ou Bearer pour Fluent Bit). - Central Logging : Une bascule au niveau du contrat et par région (
PUT /central) qui permet aux produits intégrés de transférer les journaux vers le Logging Service sans que chacun n'exécute sa propre ingestion. - Activity Logs : L'API d'audit en lecture seule sur
/activitylog/v1qui enregistre qui a modifié quelle ressource et quand, conservée pendant 35 jours. - Flow Logs : Captures réseau immuables, par ressource, publiées au format texte gzip dans Object Storage, utilisées pour visualiser le trafic accepté et rejeté.
Prochaines étapes
Continuer à apprendre : Unité 5.2 : Sécurité automatisée
Sujets connexes :