Aller au contenu
Conteneurs & Orchestration medium

etcd : la base clé/valeur du control plane Kubernetes

29 min de lecture

logo etcd

Votre API server Kubernetes répond lentement ? Les pods mettent du temps à démarrer ? Le problème vient peut-être d’etcd, la base de données qui stocke l’intégralité de l’état de votre cluster. Ce guide vous apprend à diagnostiquer, sauvegarder et maintenir etcd pour éviter les pannes et garantir la résilience de votre infrastructure.

Vous apprendrez à :

  • Vérifier la santé d’un cluster etcd en 2 minutes
  • Créer et restaurer des snapshots (procédure complète)
  • Gérer les alarmes NOSPACE et la maintenance day-2
  • Monitorer etcd avec Prometheus

À la fin de ce guide, tu sauras :

  • Expliquer ce que Kubernetes attend d’etcd (cohérence, latence, sécurité)
  • Diagnostiquer rapidement un etcd lent/instable (health, status, quorum, disque)
  • Mettre en place une stratégie backup/restore fiable (et testée)
  • Faire la maintenance day-2 : compaction, defrag, quota, alarmes NOSPACE
  • Surveiller etcd via métriques (Prometheus) et interpréter les signaux

etcd est la source de vérité unique de votre cluster Kubernetes. Tout ce que l’API server connaît — pods, services, secrets, configmaps, RBAC — est stocké dans etcd.

Ce qu’etcd stockeExemple
État désiré”Je veux 3 réplicas de nginx
État actuel”2 pods running, 1 pending”
ConfigurationSecrets, ConfigMaps, ServiceAccounts
MétadonnéesLabels, annotations, finalizers
LeasesLeader election des controllers

Conséquence directe : si etcd est lent, l’API server est lent. Si etcd est down, l’API server ne peut plus persister l’état : les workloads existants continuent de tourner, mais aucune modification n’est possible (créations, suppressions, mises à jour). Selon la durée de l’indisponibilité, même la lecture via API peut se dégrader.

Ce n’est pas une page “historique” d’etcd. L’objectif est 100% opérationnel : des commandes à copier-coller et des runbooks pour résoudre les problèmes courants.


etcd utilise l’algorithme Raft pour garantir la cohérence des données entre tous les membres. Voici comment ça fonctionne :

┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ LEADER │────▶│ FOLLOWER │────▶│ FOLLOWER │
│ (écritures)│ │ (réplique) │ │ (réplique) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└───────────────────┴───────────────────┘
QUORUM = 2/3

Règle d’or : sans quorum (majorité des membres disponibles), aucune écriture n’est possible.

Nombre de membresQuorum requisTolérance aux pannes
110 (aucune)
321 membre
532 membres
743 membres

MVCC, révisions, compaction : pourquoi la base grossit

Section intitulée « MVCC, révisions, compaction : pourquoi la base grossit »

etcd utilise MVCC (Multi-Version Concurrency Control) : chaque modification crée une nouvelle révision sans supprimer l’ancienne. C’est ce qui permet les watches (notifications en temps réel).

Problème : sans maintenance, l’historique s’accumule indéfiniment.

Révision 1: pod-a créé
Révision 2: pod-a modifié (labels)
Révision 3: pod-a modifié (replicas)
Révision 4: pod-a supprimé
Toutes ces révisions sont conservées !

Solutions :

  • Compaction : supprime les anciennes révisions (garde la plus récente)
  • Défragmentation : récupère l’espace disque après compaction

etcd offre trois primitives que Kubernetes exploite massivement :

PrimitiveUsage Kubernetes
TransactionsMises à jour atomiques (create-or-update)
WatchesControllers qui réagissent aux changements
LeasesLeader election, heartbeats

À retenir : etcd est “simple” (clé/valeur) mais exigeant sur la qualité du stockage et du réseau.


C’est la topologie par défaut avec kubeadm, k3s, RKE2 et la plupart des distributions.

┌───────────────────────────────────────────────────────────┐
│ Control Plane Node 1 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ API Server │ │ Controller │ │ Scheduler │ │
│ └──────┬──────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ etcd │◀───────────────────────────────────────┐ │
│ └─────────────┘ │ │
└─────────────────────────────────────────────────────────┼─┘
┌─────────────────────────────────────────────────────────┼─┐
│ Control Plane Node 2 │ │
│ ┌─────────────┐ │ │
│ │ etcd │◀───────────────────────────────────────┼─┤
│ └─────────────┘ │ │
└─────────────────────────────────────────────────────────┼─┘
┌─────────────────────────────────────────────────────────┼─┐
│ Control Plane Node 3 │ │
│ ┌─────────────┐ │ │
│ │ etcd │◀───────────────────────────────────────┘ │
│ └─────────────┘ │
└───────────────────────────────────────────────────────────┘

Avantages : simplicité, moins de machines à gérer.

Inconvénients : si un control plane tombe, vous perdez un membre etcd.

Pour les environnements critiques, etcd peut tourner sur des machines dédiées.

Quand c’est pertinent :

  • Isolation des ressources (CPU/RAM/disque dédiés)
  • Politique de backup différente
  • Cluster etcd partagé entre plusieurs clusters K8s
  • Exigences de latence strictes

Impacts opérationnels : certificats supplémentaires, endpoints à configurer, procédures de maintenance séparées.


  1. Créer le fichier de configuration

    kind-etcd-lab.yaml
    kind: Cluster
    apiVersion: kind.x-k8s.io/v1alpha4
    nodes:
    - role: control-plane
    - role: control-plane
    - role: control-plane
  2. Créer le cluster

    Fenêtre de terminal
    kind create cluster --name etcd-lab --config kind-etcd-lab.yaml

    Sortie attendue :

    Creating cluster "etcd-lab" ...
    ✓ Ensuring node image (kindest/node:v1.31.2) 🖼
    ✓ Preparing nodes 📦 📦 📦
    ✓ Configuring the external load balancer ⚖️
    ✓ Writing configuration 📜
    ✓ Starting control-plane 🕹️
    ✓ Installing CNI 🔌
    ✓ Installing StorageClass 💾
    ✓ Joining more control-plane nodes 🎮
    Set kubectl context to "kind-etcd-lab"
  3. Vérifier les pods etcd

    Fenêtre de terminal
    kubectl get pods -n kube-system -l component=etcd -o wide

    Sortie attendue :

    NAME READY STATUS RESTARTS AGE IP NODE
    etcd-etcd-lab-control-plane 1/1 Running 0 46s 172.19.0.5 etcd-lab-control-plane
    etcd-etcd-lab-control-plane2 1/1 Running 0 40s 172.19.0.4 etcd-lab-control-plane2
    etcd-etcd-lab-control-plane3 1/1 Running 0 33s 172.19.0.3 etcd-lab-control-plane3

etcd exige une authentification mTLS (mutual TLS). Voici le pattern recommandé pour exécuter des commandes etcdctl :

Fenêtre de terminal
kubectl exec -n kube-system etcd-etcd-lab-control-plane -- sh -c '
export ETCDCTL_API=3
etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--endpoints=https://127.0.0.1:2379 \
<COMMANDE>
'
Fenêtre de terminal
kubectl exec -n kube-system etcd-etcd-lab-control-plane -- sh -c '
export ETCDCTL_API=3
etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--endpoints=https://127.0.0.1:2379 \
endpoint health
'

Sortie attendue :

https://127.0.0.1:2379 is healthy: successfully committed proposal: took = 3.837182ms

Utilisez --cluster pour interroger automatiquement tous les membres (plus robuste que de lister les IPs manuellement) :

Fenêtre de terminal
kubectl exec -n kube-system etcd-etcd-lab-control-plane -- sh -c '
export ETCDCTL_API=3
etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--endpoints=https://127.0.0.1:2379 \
endpoint status --cluster --write-out=table
'

Sortie attendue :

+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://172.19.0.5:2379 | 4c95f7dc5897214a | 3.5.15 | 1.6 MB | true | false | 2 | 812 | 812 | |
| https://172.19.0.4:2379 | 66fb782b14ae096a | 3.5.15 | 1.6 MB | false | false | 2 | 812 | 812 | |
| https://172.19.0.3:2379 | ee098f6d097e6ce5 | 3.5.15 | 1.6 MB | false | false | 2 | 812 | 812 | |
+-------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

Ce qu’il faut vérifier :

ColonneCe que ça signifieValeur attendue
IS LEADERUn seul membre doit être leaderExactement 1 true
DB SIZETaille de la baseSimilaire sur tous les membres
RAFT INDEXIndex de réplicationIdentique sur tous les membres
ERRORSAlarmes activesVide
Fenêtre de terminal
kubectl exec -n kube-system etcd-etcd-lab-control-plane -- sh -c '
export ETCDCTL_API=3
etcdctl \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--endpoints=https://127.0.0.1:2379 \
member list --write-out=table
'

Sortie attendue :

+------------------+---------+-------------------------+-------------------------+-------------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+-------------------------+-------------------------+-------------------------+------------+
| 4c95f7dc5897214a | started | etcd-lab-control-plane | https://172.19.0.5:2380 | https://172.19.0.5:2379 | false |
| 66fb782b14ae096a | started | etcd-lab-control-plane2 | https://172.19.0.4:2380 | https://172.19.0.4:2379 | false |
| ee098f6d097e6ce5 | started | etcd-lab-control-plane3 | https://172.19.0.3:2380 | https://172.19.0.3:2379 | false |
+------------------+---------+-------------------------+-------------------------+-------------------------+------------+

Voici la séquence de diagnostic à exécuter en cas de problème. Toujours exporter ETCDCTL_API=3 avant d’exécuter ces commandes.

  1. Vérifier que tous les membres répondent

    Fenêtre de terminal
    etcdctl --endpoints=https://127.0.0.1:2379 endpoint health --cluster

    ✅ Tous les endpoints doivent être healthy

  2. Identifier le leader

    Fenêtre de terminal
    etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --cluster --write-out=table

    ✅ Un seul membre doit avoir IS LEADER = true

  3. Vérifier la cohérence des index

    Dans la sortie précédente, RAFT INDEX et RAFT APPLIED INDEX doivent être identiques sur tous les membres. Un décalage indique un problème de réplication.

  4. Vérifier les alarmes

    Fenêtre de terminal
    etcdctl --endpoints=https://127.0.0.1:2379 alarm list

    ✅ La sortie doit être vide (aucune alarme)

SymptômeCause probableDiagnosticAction
Requêtes kubectl lentesetcd surchargé ou disque lentendpoint status : latence élevéeVérifier I/O disque, considérer des SSD
context deadline exceededRéseau instable entre API server et etcdLogs etcd : slow requestVérifier latence réseau, MTU
Pods pending longtempsetcd en mode alarmalarm listRésoudre l’alarme (voir runbook)
Fenêtre de terminal
# Compter les changements de leader dans les logs
kubectl logs -n kube-system etcd-etcd-lab-control-plane | grep -c "elected leader"
CauseSolution
Latence réseau > 10msAméliorer réseau ou rapprocher les nœuds
CPU insuffisantAugmenter les resources du pod/VM
Disque trop lentMigrer vers SSD NVMe

Quand etcd est lent, il faut identifier se situe la latence :

  1. Vérifier la latence disque (métrique etcd_disk_backend_commit_duration_seconds)

    Fenêtre de terminal
    # Sur le nœud etcd
    iostat -x 1 5

    ⚠️ await > 10ms = disque trop lent → migrer vers SSD NVMe

  2. Vérifier la latence réseau entre peers (métrique etcd_network_peer_round_trip_time_seconds)

    Fenêtre de terminal
    # Depuis un nœud etcd vers les autres
    ping -c 10 <IP_PEER>

    ⚠️ > 10ms = réseau instable → vérifier MTU, congestion

  3. Corréler avec les logs etcd

    Fenêtre de terminal
    kubectl logs -n kube-system etcd-xxx --tail=200 | grep -E "took too long|slow"

    Les messages indiquent le type d’opération lente (apply, commit, etc.)

Fenêtre de terminal
kubectl logs -n kube-system etcd-etcd-lab-control-plane --tail=100 | grep -E "slow|compact|alarm|leader"

Ce qu’il faut chercher :

  • took too long : requêtes lentes (I/O ou réseau)
  • compaction : compaction en cours
  • alarm : quota atteint
  • elected leader : changement de leader

ÉlémentRecommandation
FréquenceToutes les heures minimum, toutes les 15 min pour clusters critiques
Rétention7 jours minimum, 30 jours recommandé
StockageHors du cluster (S3, GCS, NFS externe)
ChiffrementGPG ou autre avant upload
TestRestauration mensuelle sur cluster de test
  1. Exécuter la sauvegarde

    Fenêtre de terminal
    kubectl exec -n kube-system etcd-etcd-lab-control-plane -- sh -c '
    export ETCDCTL_API=3
    etcdctl \
    --cacert=/etc/kubernetes/pki/etcd/ca.crt \
    --cert=/etc/kubernetes/pki/etcd/server.crt \
    --key=/etc/kubernetes/pki/etcd/server.key \
    --endpoints=https://127.0.0.1:2379 \
    snapshot save /tmp/etcd-snapshot.db
    '

    Sortie attendue :

    {"level":"info","ts":"2026-02-02T09:24:53.263527Z","caller":"snapshot/v3_snapshot.go:97","msg":"saved","path":"/tmp/etcd-snapshot.db"}
    Snapshot saved at /tmp/etcd-snapshot.db
  2. Vérifier l’intégrité du snapshot (utilisez etcdutl — compatible 3.5/3.6)

    Fenêtre de terminal
    kubectl exec -n kube-system etcd-etcd-lab-control-plane -- \
    etcdutl snapshot status /tmp/etcd-snapshot.db --write-out=table

    Sortie attendue :

    +----------+----------+------------+------------+
    | HASH | REVISION | TOTAL KEYS | TOTAL SIZE |
    +----------+----------+------------+------------+
    | 8213414f | 822 | 835 | 1.7 MB |
    +----------+----------+------------+------------+
  3. Copier le snapshot hors du conteneur

    Fenêtre de terminal
    kubectl cp kube-system/etcd-etcd-lab-control-plane:/tmp/etcd-snapshot.db ./etcd-snapshot-$(date +%Y%m%d-%H%M%S).db

La procédure complète de restauration dépend de votre distribution :

  1. Arrêter le kubelet sur tous les control planes

    Fenêtre de terminal
    systemctl stop kubelet
  2. Sauvegarder le répertoire etcd actuel

    Fenêtre de terminal
    mv /var/lib/etcd /var/lib/etcd.backup-$(date +%Y%m%d)
  3. Restaurer le snapshot sur chaque membre (avec etcdutl)

    Fenêtre de terminal
    etcdutl snapshot restore /path/to/snapshot.db \
    --name etcd-member-1 \
    --initial-cluster etcd-member-1=https://10.0.0.1:2380,etcd-member-2=https://10.0.0.2:2380,etcd-member-3=https://10.0.0.3:2380 \
    --initial-cluster-token etcd-cluster-1 \
    --initial-advertise-peer-urls https://10.0.0.1:2380 \
    --data-dir /var/lib/etcd

    Répétez sur chaque nœud en adaptant --name et --initial-advertise-peer-urls.

  4. Redémarrer le kubelet

    Fenêtre de terminal
    systemctl start kubelet
  5. Vérifier la santé

    Fenêtre de terminal
    etcdctl --endpoints=https://127.0.0.1:2379 endpoint health --cluster
etcd-backup.sh
#!/bin/bash
set -euo pipefail
# Configuration
export ETCDCTL_API=3
BACKUP_DIR="/backup/etcd"
RETENTION_DAYS=7
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
SNAPSHOT_FILE="${BACKUP_DIR}/etcd-snapshot-${TIMESTAMP}.db"
# Certificats (kubeadm - adapter selon votre distribution)
CACERT="/etc/kubernetes/pki/etcd/ca.crt"
CERT="/etc/kubernetes/pki/etcd/healthcheck-client.crt"
KEY="/etc/kubernetes/pki/etcd/healthcheck-client.key"
ENDPOINTS="https://127.0.0.1:2379"
# Créer le répertoire de backup
mkdir -p "${BACKUP_DIR}"
# Créer le snapshot
etcdctl snapshot save "${SNAPSHOT_FILE}" \
--cacert="${CACERT}" \
--cert="${CERT}" \
--key="${KEY}" \
--endpoints="${ENDPOINTS}"
# Vérifier l'intégrité (etcdutl pour compatibilité 3.5/3.6)
etcdutl snapshot status "${SNAPSHOT_FILE}" --write-out=table
# Supprimer les vieux backups
find "${BACKUP_DIR}" -name "etcd-snapshot-*.db" -mtime +${RETENTION_DAYS} -delete
echo "✅ Backup terminé : ${SNAPSHOT_FILE}"

La compaction supprime les anciennes révisions pour limiter la croissance de la base.

  1. Récupérer la révision actuelle

    Fenêtre de terminal
    REV=$(etcdctl endpoint status -w json | grep -o '"revision":[0-9]*' | head -1 | cut -d: -f2)
    echo "Révision actuelle: $REV"

    Sortie attendue :

    Révision actuelle: 911
  2. Compacter jusqu’à cette révision

    Fenêtre de terminal
    etcdctl compact $REV

    Sortie attendue :

    compacted revision 911

La compaction marque les données comme supprimées, mais ne libère pas l’espace disque. La défragmentation récupère cet espace.

Fenêtre de terminal
# Défragmenter un seul membre (etcd doit tourner)
etcdctl defrag --endpoints=https://127.0.0.1:2379

Sortie attendue :

Finished defragmenting etcd member[https://127.0.0.1:2379]

Procédure recommandée (online) :

  1. Défragmenter un follower
  2. Vérifier sa santé (endpoint health)
  3. Défragmenter le follower suivant
  4. Défragmenter le leader en dernier

Par défaut, etcd a un quota de 2 GB. Quand il est atteint :

  1. etcd déclenche l’alarme NOSPACE
  2. Seules les lectures et suppressions sont autorisées
  3. Le cluster Kubernetes est bloqué

Runbook de résolution :

  1. Vérifier l’alarme

    Fenêtre de terminal
    etcdctl --endpoints=https://127.0.0.1:2379 alarm list
    memberID:4c95f7dc5897214a alarm:NOSPACE
  2. Compacter la base

    Fenêtre de terminal
    # Récupérer la révision actuelle (parsing JSON robuste si jq disponible)
    REV=$(etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --write-out=json | \
    grep -o '"revision":[0-9]*' | head -1 | cut -d: -f2)
    echo "Compaction jusqu'à la révision: $REV"
    etcdctl --endpoints=https://127.0.0.1:2379 compact $REV
  3. Défragmenter tous les membres (un par un, en commençant par les followers)

    Fenêtre de terminal
    # Récupérer la liste des endpoints
    etcdctl --endpoints=https://127.0.0.1:2379 member list --write-out=table
    # Défragmenter chaque membre individuellement
    etcdctl defrag --endpoints=https://<IP_FOLLOWER_1>:2379
    etcdctl defrag --endpoints=https://<IP_FOLLOWER_2>:2379
    etcdctl defrag --endpoints=https://<IP_LEADER>:2379 # En dernier
  4. Désarmer l’alarme

    Fenêtre de terminal
    etcdctl --endpoints=https://127.0.0.1:2379 alarm disarm
  5. Vérifier que l’alarme est levée

    Fenêtre de terminal
    etcdctl --endpoints=https://127.0.0.1:2379 alarm list
    # (sortie vide = OK)

Sécurité : TLS d’abord, contrôle d’accès ensuite

Section intitulée « Sécurité : TLS d’abord, contrôle d’accès ensuite »

etcd ne doit jamais être exposé sans TLS. Toutes les communications doivent être chiffrées :

CommunicationPortsCertificats requis
Client → etcd2379ca.crt, server.crt, server.key
etcd → etcd (peers)2380peer.crt, peer.key

Pour les clusters etcd externes ou partagés, vous pouvez activer l’authentification :

Fenêtre de terminal
# Activer l'authentification
etcdctl auth enable
# Créer un utilisateur
etcdctl user add admin --new-user-password="***"
# Créer un rôle
etcdctl role add readwrite
etcdctl role grant-permission readwrite readwrite /
# Assigner le rôle à l'utilisateur
etcdctl user grant-role admin readwrite

etcd expose ses métriques sur /metrics (port 2379 avec TLS). Les métriques clés à surveiller :

MétriqueDescriptionSeuil initialNotes
etcd_server_has_leaderPrésence d’un leader!= 1Critique — action immédiate
etcd_server_leader_changes_seen_totalChangements de leader> 3/heureAjuster si réseau instable
etcd_disk_backend_commit_duration_secondsLatence d’écriture disquep99 > 25msSur SSD NVMe, attendez < 10ms
etcd_network_peer_round_trip_time_secondsLatence réseau entre peersp99 > 50msDépend de la distance entre nœuds
etcd_mvcc_db_total_size_in_bytesTaille de la base> 80% du quotaWarning à 80%, critique à 95%
etcd_server_proposals_failed_totalPropositions Raft échouées> 0Tout échec = investigation
etcd-alerts.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: etcd-alerts
namespace: monitoring
spec:
groups:
- name: etcd
rules:
- alert: EtcdNoLeader
expr: etcd_server_has_leader == 0
for: 1m
labels:
severity: critical
annotations:
summary: "etcd n'a pas de leader"
- alert: EtcdHighDiskLatency
expr: histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket[5m])) > 0.025
for: 5m
labels:
severity: warning
annotations:
summary: "Latence disque etcd élevée (> 25ms)"
- alert: EtcdDatabaseSpaceExceeded
expr: etcd_mvcc_db_total_size_in_bytes / etcd_server_quota_backend_bytes > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Base etcd proche du quota (> 80%)"

Fenêtre de terminal
# Santé d'un endpoint
etcdctl --endpoints=https://127.0.0.1:2379 endpoint health
# Santé de tout le cluster
etcdctl --endpoints=https://127.0.0.1:2379 endpoint health --cluster
# Statut détaillé (leader, taille, index)
etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --cluster --write-out=table
# Liste des membres
etcdctl --endpoints=https://127.0.0.1:2379 member list --write-out=table
Fenêtre de terminal
# Créer un snapshot
etcdctl --endpoints=https://127.0.0.1:2379 snapshot save /path/to/snapshot.db
# Vérifier un snapshot (etcdutl — compatible 3.5/3.6)
etcdutl snapshot status /path/to/snapshot.db --write-out=table
# Restaurer (etcdutl — compatible 3.5/3.6)
etcdutl snapshot restore /path/to/snapshot.db --data-dir /var/lib/etcd
Fenêtre de terminal
# Compacter jusqu'à la révision N
etcdctl --endpoints=https://127.0.0.1:2379 compact <revision>
# Défragmenter un membre (online)
etcdctl defrag --endpoints=https://<IP>:2379
# Défragmenter offline (etcd arrêté)
etcdutl defrag --data-dir /var/lib/etcd
# Lister les alarmes
etcdctl --endpoints=https://127.0.0.1:2379 alarm list
# Désarmer les alarmes
etcdctl --endpoints=https://127.0.0.1:2379 alarm disarm
Fenêtre de terminal
# Lister toutes les clés (ATTENTION : beaucoup de sortie)
etcdctl --endpoints=https://127.0.0.1:2379 get "" --prefix --keys-only | head -20
# Lire une clé spécifique
etcdctl --endpoints=https://127.0.0.1:2379 get /registry/pods/default/my-pod
# Compter les clés
etcdctl --endpoints=https://127.0.0.1:2379 get "" --prefix --keys-only | wc -l

Runbooks “symptôme → diagnostic → action”

Section intitulée « Runbooks “symptôme → diagnostic → action” »
  1. etcdctl --endpoints=https://127.0.0.1:2379 alarm list → confirme NOSPACE
  2. Compacter : etcdctl --endpoints=https://127.0.0.1:2379 compact $(etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --write-out=json | grep -o '"revision":[0-9]*' | head -1 | cut -d: -f2)
  3. etcdctl defrag --endpoints=https://<IP>:2379 (membre par membre, followers d’abord)
  4. etcdctl --endpoints=https://127.0.0.1:2379 alarm disarm
  5. Vérifier : etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --cluster --write-out=table (DB SIZE réduit)
  1. Identifier les membres down : etcdctl --endpoints=https://127.0.0.1:2379 member list --write-out=table
  2. Si 1 seul membre down sur 3 : attendre son retour ou le remplacer
  3. Si 2+ membres down : restauration depuis snapshot obligatoire avec etcdutl snapshot restore
  1. etcdctl --endpoints=https://127.0.0.1:2379 endpoint status --cluster --write-out=table → vérifier latence
  2. Logs : kubectl logs -n kube-system etcd-xxx | grep "slow\|took too long"
  3. Vérifier IOPS du disque : iostat -x 1
  4. Vérifier latence réseau : ping <IP_PEER> (doit être < 10ms)
  5. Solution : migrer vers SSD NVMe, améliorer réseau

Symptômes : transport: authentication handshake failed

  1. Vérifier expiration : openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -dates
  2. Renouveler avec kubeadm : kubeadm certs renew etcd-server && kubeadm certs renew etcd-peer
  3. Redémarrer les pods etcd : kubectl delete pod -n kube-system -l component=etcd

  • Backups automatisés et testés (restauration réussie)
  • Monitoring : alertes sur leader, latence, espace disque
  • SSD : stockage avec latence < 10ms
  • Réseau : latence < 10ms entre membres etcd
  • TLS : mTLS activé pour clients et peers
  • Quota : configuré et surveillé
  • Maintenance : compaction auto + defrag planifié
  • Documentation : runbooks accessibles à l’équipe

  1. etcd = SPOF logique : même avec 3 nœuds, une mauvaise config bloque le cluster
  2. Toujours 3 ou 5 membres : jamais 2, jamais plus de 7
  3. SSD obligatoire : la latence disque tue etcd
  4. Backup = snapshot + test de restauration : un backup non testé ne vaut rien
  5. Compaction + defrag : maintenance obligatoire pour éviter NOSPACE
  6. TLS everywhere : etcd exposé = cluster compromis


Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.