TL;DR — Resumen Rápido
Backup y restauración de etcd en Kubernetes: snapshots, verificación, restauración multi-nodo, certificados kubeadm, monitoreo y script de producción.
etcd es el corazón de todo clúster de Kubernetes: un almacén de clave-valor distribuido y fuertemente consistente que guarda el estado completo — deseado y observado — de tu clúster. Cuando etcd funciona correctamente, los comandos kubectl responden en milisegundos y los controladores reconcilian de forma continua. Cuando etcd se pierde sin un backup, el clúster desaparece: cada definición de Deployment, cada Secret, cada política RBAC, cada CRD y cada ConfigMap quedan borrados. Esta guía cubre todo lo que necesitas para construir una estrategia de backup y restauración de etcd de nivel productivo.
Requisitos Previos
- Un clúster de Kubernetes gestionado con kubeadm (v1.22+) o acceso a los certificados de etcd
etcdctlinstalado en el nodo del plano de control (la versión debe coincidir con la de etcd)- Acceso root o sudo en el nodo del plano de control
kubectlconfigurado con permisos de cluster-admin- Familiaridad básica con los componentes del plano de control de Kubernetes
- Para backups automáticos: acceso a S3, GCS o almacenamiento equivalente externo
El Rol de etcd en Kubernetes
Cada vez que ejecutas kubectl apply, el API server de Kubernetes valida la solicitud y escribe el objeto resultante en etcd. Todos los controladores observan etcd a través del mecanismo de watch del API server y reconcilian el clúster en consecuencia. etcd es el único componente con estado en el plano de control — todos los demás componentes son sin estado y pueden reiniciarse desde cero siempre que etcd esté intacto.
Qué reside en etcd:
- Todas las definiciones de objetos de la API: Pods, Deployments, StatefulSets, DaemonSets, Services, Ingresses
- Secrets y ConfigMaps
- RBAC: Roles, ClusterRoles, RoleBindings, ClusterRoleBindings
- Custom Resource Definitions y todas las instancias de recursos personalizados
- Definiciones de Namespaces, ResourceQuotas, LimitRanges
- ServiceAccounts y tokens asociados
- Registros de nodos y objetos de lease
- Registros de elección de líder para kube-controller-manager y kube-scheduler
Lo que no reside en etcd: los datos reales almacenados en los PersistentVolumes. etcd solo guarda los objetos PVC y PV (metadatos y enlace), no los bytes en disco.
Arquitectura de etcd: Raft, WAL y Snapshots
etcd utiliza el algoritmo de consenso Raft para replicar el estado en un clúster de miembros de número impar (típicamente 3 o 5). Raft elige un líder que procesa todas las escrituras; los seguidores replican el registro del líder. El clúster tolera (n-1)/2 fallos de miembros — un clúster de 3 nodos sobrevive 1 fallo, uno de 5 nodos sobrevive 2.
Las escrituras se añaden primero al Write-Ahead Log (WAL) en disco y luego se aplican a un B-tree en memoria (bbolt). Periódicamente, etcd toma un snapshot interno del B-tree en disco y trunca el WAL para evitar un crecimiento ilimitado.
El comando etcdctl snapshot save activa un snapshot del estado actual del B-tree. Este snapshot es un backup completo y autocontenido de todos los datos de etcd en el momento en que se tomó.
Métodos de Backup
Método 1: etcdctl snapshot save (Recomendado)
El método canónico de backup. En un clúster kubeadm, etcd corre como pod estático con TLS. Los certificados se encuentran en /etc/kubernetes/pki/etcd/.
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d-%H%M%S).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
Método 2: CronJob Automatizado
Despliega un CronJob de Kubernetes en el plano de control que monte los certificados de etcd del host y escriba los snapshots en un PVC o en almacenamiento en la nube:
apiVersion: batch/v1
kind: CronJob
metadata:
name: etcd-backup
namespace: kube-system
spec:
schedule: "0 * * * *"
jobTemplate:
spec:
template:
spec:
hostNetwork: true
containers:
- name: etcd-backup
image: bitnami/etcd:3.5
command:
- /bin/sh
- -c
- |
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-$(date +%Y%m%d-%H%M%S).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
volumeMounts:
- name: etcd-certs
mountPath: /etc/kubernetes/pki/etcd
readOnly: true
- name: backup-dir
mountPath: /backup
volumes:
- name: etcd-certs
hostPath:
path: /etc/kubernetes/pki/etcd
- name: backup-dir
persistentVolumeClaim:
claimName: etcd-backup-pvc
restartPolicy: OnFailure
nodeSelector:
node-role.kubernetes.io/control-plane: ""
tolerations:
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
Comparativa de Herramientas de Backup
| Herramienta | Estado etcd | Datos PV | Granularidad de Restauración | Complejidad |
|---|---|---|---|---|
| etcdctl snapshot | Sí | No | Clúster completo | Baja |
| Velero + plugin etcd | Sí | Sí | Namespace o completo | Media |
| etcd-backup-operator | Sí | No | Clúster completo | Media |
| kube-backup | Sí | No | Clúster completo | Baja |
| CronJob manual | Sí | No | Clúster completo | Baja |
Verificación del Snapshot
Nunca confíes en un backup que no has verificado. Después de cada snapshot:
ETCDCTL_API=3 etcdctl snapshot status /backup/etcd-snapshot.db \
--write-out=table
Si TOTAL KEYS es 0 o el hash tiene formato incorrecto, el snapshot está corrupto. Incorpora la verificación en tu CronJob de backup y configura alertas en caso de fallo.
Procedimientos de Restauración
Clúster kubeadm de Un Solo Nodo
Paso 1: Detener el API server y etcd
mkdir -p /tmp/k8s-manifests-backup
mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/k8s-manifests-backup/
mv /etc/kubernetes/manifests/etcd.yaml /tmp/k8s-manifests-backup/
sleep 10
ps aux | grep etcd
Paso 2: Respaldar el directorio de datos existente
mv /var/lib/etcd /var/lib/etcd.bak
Paso 3: Restaurar el snapshot
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
--data-dir=/var/lib/etcd \
--initial-cluster=default=https://127.0.0.1:2380 \
--initial-cluster-token=etcd-cluster-1 \
--initial-advertise-peer-urls=https://127.0.0.1:2380
Paso 4: Restaurar los manifests y verificar
mv /tmp/k8s-manifests-backup/etcd.yaml /etc/kubernetes/manifests/
mv /tmp/k8s-manifests-backup/kube-apiserver.yaml /etc/kubernetes/manifests/
sleep 30
kubectl get nodes
Clúster kubeadm Multi-Nodo
Para un clúster de 3 nodos del plano de control (HA), debes restaurar en todos los miembros de etcd simultáneamente usando valores consistentes de --initial-cluster e --initial-cluster-token:
# En cada nodo del plano de control, ejecuta la restauración con el MISMO snapshot y token
# pero con el --name e --initial-advertise-peer-urls correctos para ese nodo
# Nodo 1
ETCDCTL_API=3 etcdctl snapshot restore /backup/etcd-snapshot.db \
--name=etcd-cp1 \
--data-dir=/var/lib/etcd \
--initial-cluster=etcd-cp1=https://10.0.0.1:2380,etcd-cp2=https://10.0.0.2:2380,etcd-cp3=https://10.0.0.3:2380 \
--initial-cluster-token=etcd-restore-token-$(date +%s) \
--initial-advertise-peer-urls=https://10.0.0.1:2380
Usa un --initial-cluster-token único y diferente del original para evitar que el clúster restaurado se una accidentalmente al clúster anterior degradado.
Consideraciones para Kubernetes Administrado
EKS, GKE, AKS — El proveedor de nube gestiona etcd internamente. No puedes acceder a etcd directamente. Usa los mecanismos nativos del proveedor:
- EKS: Velero con S3; AWS no expone etcd directamente
- GKE: Velero; Google gestiona etcd con backups automáticos en Autopilot
- AKS: Velero + Azure Blob; Microsoft gestiona etcd para los node pools administrados
Monitoreo de Salud de etcd
# Verificar salud del endpoint
ETCDCTL_API=3 etcdctl endpoint health \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# Verificar líder y estado de miembros
ETCDCTL_API=3 etcdctl endpoint status --write-out=table \
--endpoints=https://10.0.0.1:2379,https://10.0.0.2:2379,https://10.0.0.3:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
Alertas de Prometheus recomendadas para etcd:
etcd_server_has_leader == 0— sin líder elegido (crítico)etcd_disk_wal_fsync_duration_seconds{quantile="0.99"} > 0.01— escrituras WAL lentasetcd_server_proposals_failed_total > 0— fallos de consensoetcd_mvcc_db_total_size_in_bytes > 8589934592— BD cerca del límite de 8 GB
Compactación y Desfragmentación
etcd mantiene un historial de todas las revisiones de claves. Con el tiempo, esto consume espacio en disco significativo. Habilita la compactación automática:
--auto-compaction-mode=periodic
--auto-compaction-retention=1h
Ejecuta la desfragmentación periódicamente durante horas de bajo tráfico:
ETCDCTL_API=3 etcdctl defrag \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
Ajuste de Rendimiento
etcd es extremadamente sensible a la latencia de disco. Recomendaciones:
- SSD dedicado: Nunca compartas el disco de datos de etcd con cargas de trabajo de aplicaciones. Usa NVMe o SSD con IOPS de escritura aleatoria sostenida > 2000.
- Timeouts de heartbeat y elección: El
heartbeat-intervalpredeterminado es 100ms y elelection-timeoutes 1000ms. En entornos de alta latencia, aumenta a 250ms / 1250ms. - Cuota de BD: El valor predeterminado es 2 GB. Aumenta a 8 GB para clústeres grandes:
--quota-backend-bytes=8589934592
Script de Backup de Producción con Alertas
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/opt/etcd-backups"
RETENTION_COUNT=24
S3_BUCKET="s3://mi-cluster-etcd-backups"
SLACK_WEBHOOK="https://hooks.slack.com/services/xxx/yyy/zzz"
ETCD_ENDPOINTS="https://127.0.0.1:2379"
CACERT="/etc/kubernetes/pki/etcd/ca.crt"
CERT="/etc/kubernetes/pki/etcd/server.crt"
KEY="/etc/kubernetes/pki/etcd/server.key"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
SNAPSHOT_FILE="${BACKUP_DIR}/etcd-${TIMESTAMP}.db"
alerta() {
local msg="$1"
curl -s -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"[etcd-backup] ${msg}\"}" "${SLACK_WEBHOOK}" || true
}
mkdir -p "${BACKUP_DIR}"
if ! ETCDCTL_API=3 etcdctl snapshot save "${SNAPSHOT_FILE}" \
--endpoints="${ETCD_ENDPOINTS}" \
--cacert="${CACERT}" --cert="${CERT}" --key="${KEY}"; then
alerta "CRÍTICO: etcd snapshot save FALLÓ en $(hostname) a las ${TIMESTAMP}"
exit 1
fi
KEYS=$(ETCDCTL_API=3 etcdctl snapshot status "${SNAPSHOT_FILE}" \
--write-out=json | python3 -c "import sys,json; print(json.load(sys.stdin)['totalKey'])")
if [ "${KEYS}" -lt 100 ]; then
alerta "ADVERTENCIA: el snapshot solo tiene ${KEYS} claves — posible snapshot vacío o corrupto"
exit 1
fi
aws s3 cp "${SNAPSHOT_FILE}" "${S3_BUCKET}/$(basename ${SNAPSHOT_FILE})" \
--storage-class STANDARD_IA
ls -t "${BACKUP_DIR}"/etcd-*.db | tail -n +$((RETENTION_COUNT + 1)) | xargs -r rm -f
echo "Backup completado: ${SNAPSHOT_FILE} (${KEYS} claves)"
Escenarios de Recuperación ante Desastres
Escenario 1: Fallo de un miembro (quórum intacto) — El clúster continúa operando. Reemplaza el miembro fallido con etcdctl member remove + etcdctl member add sin necesidad de restaurar.
Escenario 2: Pérdida de quórum (mayoría de miembros caídos) — El clúster se vuelve de solo lectura. Si los datos están intactos, restablece la conectividad. Si los datos se perdieron, restaura desde snapshot en todos los miembros.
Escenario 3: Restauración completa del clúster — Detén todos los componentes del plano de control, restaura el snapshot en cada nodo con --initial-cluster-token consistente, reinicia en orden: etcd primero, luego kube-apiserver, luego kube-controller-manager y kube-scheduler.
Casos Especiales y Errores Comunes
Incompatibilidad de versión de etcdctl — Siempre establece ETCDCTL_API=3. Verifica que la versión del cliente coincida con la del servidor. Las incompatibilidades causan fallos silenciosos o restauraciones corruptas.
El snapshot de un seguidor puede estar ligeramente desfasado — Para restauraciones críticas, toma el snapshot del líder.
La restauración sobreescribe el directorio de datos — etcdctl snapshot restore escribe en --data-dir. Si el directorio ya existe, la restauración falla. Mueve siempre el directorio existente antes.
Desviación de reloj entre miembros — Los certificados TLS de los pares de etcd son sensibles al tiempo. Asegúrate de que NTP esté configurado y sincronizado en todos los nodos del plano de control.
Resumen
- etcd almacena todo el estado del clúster de Kubernetes; perderlo sin backup significa reconstruir desde cero
- Usa
etcdctl snapshot savecon los flags TLS apuntando a/etc/kubernetes/pki/etcd/para clústeres kubeadm - Siempre ejecuta
etcdctl snapshot statuspara verificar los snapshots tras su creación - La restauración requiere detener el API server y etcd, ejecutar
etcdctl snapshot restorey reiniciar el plano de control - La restauración multi-nodo requiere
--initial-cluster-tokenconsistente y--initial-advertise-peer-urlscorrectas por nodo - Habilita la compactación automática y ejecuta
etcdctl defragmensualmente - Dedica un SSD de baja latencia a los datos de etcd; monitorea la latencia de WAL fsync con Prometheus
- Almacena snapshots de forma externa (S3/GCS) con al menos 24h de retención; automatiza con CronJob + script de alertas