Table des matières

  1. [[#Diagnostic du cluster]]
  2. [[#Résolution NOSPACE]]
  3. [[#Backup et Restore]]
  4. [[#Configuration préventive]]
  5. [[#Monitoring]]
  6. [[#Erreurs courantes]]

Contexte

etcd est la base de données clé-valeur distribuée qui stocke toutes les données du cluster Kubernetes. Quand etcd atteint sa limite d'espace (quota), il déclenche une alarme NOSPACE et bloque toutes les écritures, rendant le cluster inutilisable.

Symptômes

  • Impossible de créer/modifier des ressources Kubernetes
  • Erreurs etcdserver: mvcc: database space exceeded
  • Alarme NOSPACE dans le statut etcd

Diagnostic du cluster

Variables d'environnement (à adapter)

`

``
# Définir le hostname du nœud actuel
export HOSTNAME=$(hostname)

# Alias pour simplifier les commandes
alias etcdctl='ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379'

```

💡 Ajouter cet alias dans ~/.bashrc pour le rendre permanent

Vérifier l'état du cluster

```

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  endpoint status --write-out="table"

```

Résultat problématique (NOSPACE)

```

+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------------------------------+
|        ENDPOINT        |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX |             ERRORS             |
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------------------------------+
| https://127.0.0.1:2379 | c86ff3441b28d209 |  3.5.16 |  2.2 GB |      true |      false |      2059 | 1390189688 |         1390189688 |  memberID:14443030003839455753 |
|                        |                  |         |         |           |            |           |            |                    |                alarm:NOSPACE   |
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------------------------------+

```

⚠️ alarm:NOSPACE = le cluster est en mode lecture seule !

### Lister les membres du cluster

```

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  member list

```

### Vérifier les alarmes actives

```

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  alarm list

```


Résolution NOSPACE

⚠️ IMPORTANT : Traiter chaque membre individuellement, un à la fois, pour éviter la perte de quorum.

### Étape 1 : Obtenir la révision actuelle

```

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  endpoint status --write-out="json" | jq '.[] | .Status.header.revision'

```

📝 Noter cette valeur (ex: 1300874200)

### Étape 2 : Compacter la base de données

Utiliser une révision légèrement antérieure (-200) pour éviter les erreurs :

```

# Remplacer [REVISION] par la valeur obtenue - 200
ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  compact [REVISION-200]

```

*Exemple concret :*

```
# Si révision = 1300874200, compacter à 1300874000
ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  compact 1300874000

```

✅ Sortie attendue : compacted revision 1300874000

### Étape 3 : Défragmenter la base

Libère l'espace disque physique :

```
ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  --command-timeout=60s defrag

```

⚠️ Opération locale uniquement (sur le nœud courant) ⚠️ Peut prendre plusieurs minutes selon la taille de la base

✅ Sortie attendue : Finished defragmenting etcd member[ID]

### Étape 4 : Désactiver les alarmes

```

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  alarm disarm

```

⚠️ L'alarme NOSPACE est cluster-wide. Elle ne disparaît que quand TOUS les membres sont traités.

### Étape 5 : Répéter sur chaque membre

1.  Se connecter au membre suivant
2.  Répéter les étapes 1 à 4
3.  Continuer jusqu'à avoir traité tous les membres

### Étape 6 : Vérification finale

```

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  endpoint status --write-out="table"

```

### Résultat attendu (cluster sain)

```
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|        ENDPOINT        |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://127.0.0.1:2379 | c86ff3441b28d209 |  3.5.16 |  550 MB |     false |      false |      2061 | 1390232719 |         1390232719 |        |
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

```

✅ Pas d'erreur + taille réduite = cluster opérationnel


**## Backup et Restore

Sauvegarder la configuration**

```

sudo cp /etc/etcd.env /etc/etcd.env.bak_$(date +%Y%m%d)

```

### Créer un snapshot

```

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  snapshot save /backup/etcd-snapshot-$(date +%Y%m%d).db

```

### Vérifier un snapshot

```

ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot-20250101.db --write-out=table

```

**### Restaurer un snapshot

⚠️ ATTENTION : Opération destructive ! Arrêter etcd d'abord.**

``` # 1. Arrêter etcd

sudo systemctl stop etcd

# 2. Restaurer

ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  snapshot restore /backup/etcd-snapshot-20250101.db

# 3. Redémarrer

sudo systemctl daemon-reload
sudo systemctl start etcd

# 4. Vérifier

systemctl status etcd

```

⚠️ Après restauration, reconfigurer --name, --initial-cluster selon la topologie.


Configuration préventive

Augmenter le quota d'espace

Éditer/etc/etcd.env :

``` sudo vi /etc/etcd.env

```

Ajouter ou modifier :

```

ETCD_QUOTA_BACKEND_BYTES=8589934592  # 8 GB (défaut: 2 GB)

```

Appliquer :

```

sudo systemctl stop etcd
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl start etcd

```

Activer la compaction automatique

Ajouter dans la configuration etcd :

```
--auto-compaction-retention=1h
--auto-compaction-mode=periodic

```

Paramètre

Description

`auto-compaction-mode`

`periodic`  ou  `revision`

`auto-compaction-retention`

Durée (1h, 24h) ou nombre de révisions

### Valeurs recommandées

Paramètre

Production

Dev/Test

`quota-backend-bytes`

8 GB

2 GB

`auto-compaction-retention`

1h

24h

`snapshot-count`

10000

10000

Monitoring

Script de surveillance****

```

#!/bin/bash
# etcd-monitor.sh - Surveille l'utilisation d'espace etcd

HOSTNAME=$(hostname)
THRESHOLD=80  # Alerte si > 80%

# Obtenir la taille de la DB
DB_SIZE=$(ETCDCTL_API=3 etcdctl \
  --cacert=/etc/ssl/etcd/ssl/ca.pem \
  --cert=/etc/ssl/etcd/ssl/admin-${HOSTNAME}.pem \
  --key=/etc/ssl/etcd/ssl/admin-${HOSTNAME}-key.pem \
  --endpoints=https://127.0.0.1:2379 \
  endpoint status --write-out="json" | jq '.[] | .Status.dbSize')

# Obtenir le quota (défaut 2GB si non défini)
QUOTA=${ETCD_QUOTA_BACKEND_BYTES:-2147483648}

# Calculer le pourcentage
USAGE_PERCENT=$((DB_SIZE * 100 / QUOTA))

echo "etcd DB Size: $((DB_SIZE / 1024 / 1024)) MB"
echo "etcd Quota: $((QUOTA / 1024 / 1024)) MB"
echo "Usage: ${USAGE_PERCENT}%"

if [ $USAGE_PERCENT -gt $THRESHOLD ]; then
    echo "⚠️ ALERTE: etcd utilise ${USAGE_PERCENT}% de l'espace !"
    # Envoyer une notification (email, Slack, etc.)
    exit 1
fi

echo "✅ etcd OK"
exit 0

```

### Cron job

```

# Ajouter dans crontab -e
0 * * * * /opt/scripts/etcd-monitor.sh >> /var/log/etcd-monitor.log 2>&1

```

### Métriques Prometheus

etcd expose des métriques sur le port 2379 :

``` # prometheus scrape config

- job_name: 'etcd'
  static_configs:
    - targets:
      - '192.168.0.110:2379'
      - '192.168.0.120:2379'
      - '192.168.0.130:2379'
  scheme: https
  tls_config:
    ca_file: /etc/ssl/etcd/ssl/ca.pem
    cert_file: /etc/ssl/etcd/ssl/admin.pem
    key_file: /etc/ssl/etcd/ssl/admin-key.pem

```

Métriques importantes :

Métrique

Description

`etcd_mvcc_db_total_size_in_bytes`

Taille totale de la DB

`etcd_mvcc_db_total_size_in_use_in_bytes`

Espace utilisé

`etcd_server_quota_backend_bytes`

Quota configuré

`etcd_server_has_leader`

Leader présent (1/0)


**## Erreurs courantes

❌ "required revision is a future revision"**

```

Error: etcdserver: mvcc: required revision is a future revision

```

*Solution* : Utiliser une révision plus ancienne (-1000 ou -2000)

```

# Si révision = 1300874200, essayer
compact 1300872200  # -2000

```

### ❌ Timeout lors de la défragmentation

``` Failed to defragment etcd member (context deadline exceeded)

```

*Solutions* :

```

Augmenter le timeout

--command-timeout=120s

Ou effectuer pendant les heures creuses

```

### ❌ Les alarmes persistent après traitement

*Cause* : Pas tous les membres traités

*Solution : S'assurer que compaction + defrag ont été faits sur CHAQUE* membre

``` # Vérifier les alarmes

etcdctl alarm list

# Lister tous les membres

etcdctl member list

Traiter chaque membre individuellement

```

### ❌ "database space exceeded" sur Kubernetes

```
etcdserver: mvcc: database space exceeded

```

*Cause* : etcd est plein, Kubernetes ne peut plus écrire

*Solution urgente* :

```

# 1. Compacter immédiatement
# 2. Défragmenter
# 3. Désarmer les alarmes
# 4. Augmenter le quota pour éviter la récidive

```


## Commandes rapides (Quick Reference)

```

# === DIAGNOSTIC ===
etcdctl endpoint status --write-out="table"   # État du cluster
etcdctl member list                            # Lister les membres
etcdctl alarm list                             # Alarmes actives
etcdctl endpoint health                        # Santé des endpoints

# === MAINTENANCE ===
etcdctl compact [REVISION]                     # Compacter
etcdctl defrag --command-timeout=60s           # Défragmenter
etcdctl alarm disarm                           # Désarmer les alarmes

# === BACKUP ===
etcdctl snapshot save /backup/snap.db          # Sauvegarder
etcdctl snapshot status /backup/snap.db        # Vérifier
etcdctl snapshot restore /backup/snap.db       # Restaurer
```
Retour à la liste