Если вы держите Kubernetes-кластер или высокодоступное хранилище конфигурации на облачном VDS, то etcd — ваш «единый источник истины». Любая ошибка с диском, внезапное переполнение базы, повреждение данных или неосторожный массовый апдейт — и контроль-плейн может перестать жить. Хорошая новость: у etcd есть надёжные механизмы резервного копирования (snapshot), обслуживания (compact и defrag) и предсказуемое восстановление (restore). Плохая: всё это нужно делать аккуратно и по расписанию.
Что нужно знать заранее
Немного теории в одну минуту. etcd — распределённый KV-store на базе Raft. Он хранит ревизии ключей, поддерживает историю версий и создаёт периодические внутренние срезы. Отсюда следуют практические вещи:
- Snapshot — офлайн-файл состояния на конкретной ревизии. Его можно переносить, копировать, хранить на другом VDS.
- Compaction — логическая «прореживация» истории до выбранной ревизии. Становится меньше версий, снижаются накладные расходы на хранения индексов/ревизий, но файл базы на диске не уменьшается.
- Defrag — реальное «ужатие» базы на диске с возвратом свободного места файловой системе. Выполняется на каждом члене кластера по отдельности и даёт нагрузку на I/O.
- Restore — развёртывание нового data-dir из snapshot. Для мульти-узлового кластера требует продуманной процедуры и корректной реконкигурации параметров кластера.
Snapshot — это ваш главный страховочный трос. Compact и defrag — сервисное обслуживание, которое держит кластер в форме и не даёт разрастись базе до неприятных размеров.
Если вы строите внешние сервисы координации, пригодится смежный разбор про DCS и отказоустойчивость: Patroni, DCS и отказоустойчивость.
Подготовка окружения на VDS
Перед тем как автоматизировать backup и обслуживание, убедитесь, что базовые вещи закрыты:
- Диски SSD и запас по IOPS. Defrag и массовые операции пишут много.
- Стабильное время (chrony) и предсказуемые сетевые задержки между членами кластера.
- Ограничения по ресурсам: ulimit по файловым дескрипторам, отдельный каталог данных (обычно
/var/lib/etcd), контроль свободного места. - Сертификаты TLS и доступ к endpoint'ам. etcd обычно слушает клиентские
2379и p2p2380порты. - Версии
etcdиetcdctlсогласованы (API v3). Для новых релизов естьetcdutl, но в статье опираемся наetcdctl.
Если определяете мощность по CPU, RAM и дискам, взгляните на материал о выборе конфигурации: как подобрать ресурсы VDS под нагрузку.
Снимок кластера: безопасный snapshot
Базовая команда одинакова везде: etcdctl snapshot save. Важно правильно передать endpoint'ы и TLS-сертификаты, а также зафиксировать API v3.
export ETCDCTL_API=3
# Пример для внешнего single-node/HA-кластера etcd (вне Kubernetes)
# Замените пути к сертификатам и адреса на свои
etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/pki/ca.crt --cert=/etc/etcd/pki/client.crt --key=/etc/etcd/pki/client.key snapshot save /var/backups/etcd/etcd-$(date +%F_%H%M%S).db
# Проверка файла snapshot
etcdctl snapshot status /var/backups/etcd/etcd-2025-01-01_120000.db
В Kubernetes с kubeadm «стековый» etcd обычно работает как static pod на control-plane узлах. Удобно выполнять snapshot прямо внутри pod, чтобы гарантировать совместимость версий утилит и клиентских сертификатов:
# Определяем имя pod etcd на текущем control-plane узле
kubectl -n kube-system get pods -o wide | grep etcd-
# Снимаем snapshot (пути к сертификатам берём из манифеста /etc/kubernetes/manifests/етcd.yaml)
kubectl -n kube-system exec etcd-CPNODE -- sh -c 'ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/етcd/healthcheck-client.key snapshot save /var/lib/etcd/backup-$(date +%F-%H%M%S).db && etcdctl snapshot status /var/lib/etcd/backup-$(date +%F-%H%M%S).db'
Где хранить файлы? На том же узле — только временно. Как можно быстрее выгружайте их на отдельный VDS и в объектное хранилище. Шифруйте архив, придерживайтесь политики retention и тестируйте восстановление.
Плановое резервное копирование: systemd timers
Для надёжности используйте systemd unit + timer. Он должен снимать снимок, проверять статус, подписывать/шифровать при необходимости и выгружать на «холодное» хранилище. Важная деталь: не храните секреты и приватные ключи рядом с бэкапом, используйте отдельные учётные данные с минимальными правами.
# /etc/systemd/system/etcd-snapshot.service
[Unit]
Description=etcd snapshot backup
After=network-online.target
[Service]
Type=oneshot
Environment=ETCDCTL_API=3
ExecStart=/usr/local/bin/etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/pki/ca.crt --cert=/etc/etcd/pki/client.crt --key=/etc/etcd/pki/client.key snapshot save /var/backups/etcd/etcd-$(date +%%F_%%H%%M%%S).db
ExecStartPost=/usr/local/bin/etcdctl snapshot status /var/backups/etcd/etcd-$(date +%%F_%%H%%M%%S).db
# /etc/systemd/system/etcd-snapshot.timer
[Unit]
Description=Run etcd snapshot daily
[Timer]
Persistent=true
[Install]
WantedBy=timers.target
Добавьте отдельную задачу, которая синхронизирует «последний успешный» snapshot на удалённую площадку и чистит старые файлы по ретенции.
Compaction и Defrag: когда, зачем и как
С ростом нагрузки и числа изменений база etcd разрастается. При этом разрастаются две вещи: число ревизий (история) и физический размер файла на диске. Этими проблемами занимаются:
compact— удаляет старые ревизии до выбранного номера. Уменьшает «логическую» историю, снижает нагрузку на индекс и потребление памяти.defrag— высвобождает свободное место в файле базы, которое накопилось после удалений/компактаций. Требует I/O и может вызывать краткосрочные задержки ответов.
Хорошая практика: регулярно делать compact до «безопасной» ревизии, где нет активных watchers, а затем по метрикам инициировать defrag, если файл базы превышает разумный порог. Частый ориентир — если размер базы в 2–3 раза больше активных данных, или в абсолюте переваливает за пару гигабайт на маленьком VDS.
# Компактация до последней ревизии
export ETCDCTL_API=3
REV=$(etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/pki/ca.crt --cert=/etc/етcd/pki/client.crt --key=/etc/etcd/pki/client.key endpoint status --write-out=json | jq -r '.[0].Status.header.revision')
echo "Compacting to revision $REV"
etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/etcd/pki/ca.crt --cert=/etc/етcd/pki/client.crt --key=/etc/etcd/pki/client.key compact $REV
Defrag выполняйте по одному участнику за раз. Если вы дёрнете команду сразу по всем endpoints, кластер может ощутимо «просесть» и словить локальные таймауты. Последовательная дефрагментация на каждом endpoint, с паузой между запросами — правильный путь.
# Последовательный defrag
for ep in https://10.0.0.11:2379 https://10.0.0.12:2379 https://10.0.0.13:2379; do
echo "Defragment $ep"
etcdctl --endpoints=$ep --cacert=/etc/etcd/pki/ca.crt --cert=/etc/етcd/pki/client.crt --key=/etc/etcd/pki/client.key defragment
sleep 30
done
Отслеживайте метрики: полезны etcd_server_has_leader, etcd_debugging_mvcc_db_total_size_in_bytes, etcd_mvcc_db_compaction_keys_total, latency RPC, а также общее состояние диска (iostat). Планируйте defrag на «тихое» окно по трафику.

Restore: сценарии восстановления
Восстановление всегда должно быть отрепетировано. Минимум — на изолированном тестовом VDS, лучше — на полнокопийном стенде. Разберём три практических сценария.
1) Одиночный узел (standalone) etcd вне Kubernetes
Чаще всего — сервис на том же VDS, где живёт приложение. Алгоритм:
- Остановить службу etcd.
- Сделать копию текущего data-dir (на случай дополнительных разборов).
- Выполнить
etcdctl snapshot restoreв новый каталог. - Заменить рабочий data-dir на восстановленный.
- Запустить службу и проверить здоровье.
systemctl stop etcd
mv /var/lib/etcd /var/lib/etcd.broken-$(date +%s)
ETCD_NAME=node1
ETCD_DATA_DIR=/var/lib/etcd
etcdctl snapshot restore /var/backups/etcd/good.db --name $ETCD_NAME --data-dir $ETCD_DATA_DIR --initial-cluster $ETCD_NAME=https://127.0.0.1:2380 --initial-advertise-peer-urls https://127.0.0.1:2380 --initial-cluster-token restored-$(date +%s) --initial-cluster-state new
systemctl start etcd
etcdctl endpoint health
Убедитесь, что сертификаты, адреса и флаги в unit-файле соответствуют восстановленной конфигурации (имя узла, peer-urls, advertise-client-urls).
2) Внешний HA-кластер etcd (несколько узлов) вне Kubernetes
Сложнее, но управляемо. Важные моменты: мы формируем новый кластер из snapshot (новый cluster-id) и поднимаем членов с согласованной --initial-cluster и --name.
- Остановить etcd на всех узлах.
- Для каждого члена подготовить уникальный
--name,--initial-advertise-peer-urlsи общий список--initial-cluster. - На каждом узле выполнить
snapshot restoreв свойdata-dirс соответствующими параметрами. - Запустить члены, проверяя логи. После формирования лидера — проверить
endpoint status.
# На узле A
systemctl stop etcd
rm -rf /var/lib/etcd
etcdctl snapshot restore /backups/good.db --name etcd-a --data-dir /var/lib/etcd --initial-advertise-peer-urls https://10.0.0.11:2380 --initial-cluster etcd-a=https://10.0.0.11:2380,etcd-b=https://10.0.0.12:2380,etcd-c=https://10.0.0.13:2380 --initial-cluster-token restore-2025 --initial-cluster-state new
systemctl start etcd
# Повторить на B и C с их именами и адресами
Не смешивайте старый и новый кластера. После restore кластер получает новый cluster-id; попытка подключить старого члена приведёт к конфликту. Также следите, чтобы сертификаты для peer-urls и client-urls покрывали имена/адреса, заявленные в новой топологии.
3) Kubernetes с kubeadm (стековый etcd как static pod)
kubeadm по умолчанию поднимает etcd как static pod на control-plane узлах. Для snapshot/restore удобно использовать те же бинарники и сертификаты, что в контейнере. Базовый путь до данных — /var/lib/etcd, манифест — /etc/kubernetes/manifests/etcd.yaml.
Простой случай — один control-plane узел (lab, edge, dev):
- Снять snapshot, как показано выше.
- Отключить kubelet, чтобы остановить static pod etcd (и тем самым kube-apiserver): переместите манифест и/или остановите kubelet.
- Очистить каталог данных, выполнить restore, вернуть манифест на место и запустить kubelet.
- Проверить здоровье apiserver и
kubectl get nodes.
# На control-plane узле
mv /etc/kubernetes/manifests/etcd.yaml /etc/kubernetes/manifests/etcd.yaml.bak
systemctl stop kubelet
rm -rf /var/lib/etcd
ETCD_NAME=$(hostname -s)
etcdctl snapshot restore /var/lib/etcd/backup-good.db --name $ETCD_NAME --data-dir /var/lib/etcd --initial-advertise-peer-urls https://127.0.0.1:2380 --initial-cluster $ETCD_NAME=https://127.0.0.1:2380 --initial-cluster-state new
mv /etc/kubernetes/manifests/etcd.yaml.bak /etc/kubernetes/manifests/etcd.yaml
systemctl start kubelet
kubectl get cs
kubectl get nodes
Случай с несколькими control-plane узлами сложнее и обычно требует последовательного восстановления каждого control-plane из одного и того же snapshot с согласованной новой топологией etcd. Часто проще и безопаснее: восстановить первый узел (образует новый кластер etcd), затем повторно присоединить остальные control-plane узлы командами kubeadm join с актуальными токенами. Перед работами обязательно оцените RTO/RPO и подготовьте план деградации трафика для приложений.

Проверки целостности и здоровья после restore
После любого restore выполните набор проверок:
etcdctl endpoint status --write-out=tableиetcdctl endpoint healthпо всем endpoint'ам.- Наличие лидера (
etcd_server_has_leaderравен 1). - Размер базы и время ответа на операции get/put на тестовом префиксе.
- В Kubernetes — доступность kube-apiserver, scheduler, controller-manager, корректность admission и webhooks, readiness основных workloads.
Сравните содержимое ключевых префиксов с ожиданиями (в Kubernetes это, например, объекты API из namespaces kube-system и ваши CRD). Если используете шифрование секретов на уровне etcd, убедитесь, что ключи шифрования на месте и соответствуют моменту snapshot.
Защита бэкапов и комплаенс
Snapshot обязательно храните в зашифрованном виде, отдельно от ключей. Минимизируйте права доступа к директориям бэкапов на VDS и к облачному хранилищу. Введите ротацию ключей (KMS или офлайн-ключи), контроль целостности (хэши, подписи), журналирование доступа и периодическое тестовое восстановление в песочнице. Для TLS-каналов и клиентской аутентификации используйте корректные цепочки сертификатов, при необходимости — обновите SSL-сертификаты.
Типичные ошибки и как их избегать
- Snapshot снят с несовместимой версией etcdctl. Используйте утилиту того же минорного релиза, что и сервер.
- Отсутствие TLS-параметров. Большинство продовых кластеров слушают только TLS. Без
--cacert,--cert,--keyкоманды просто не дойдут. - Defrag сразу на всех узлах. Делайте последовательно, с паузами.
- Недостаточно места под snapshot. Планируйте в 1.5–2 раза больше текущего размера базы, учитывая сжатие и overhead.
- Смешивание старого и нового кластера при restore. После восстановления cluster-id другой; старая конфигурация членов недопустима.
- Забыли compact. Со временем история разрастается и тянет за собой рост задержек и памяти. Регулярный compact — must-have.
- Нет тестового restore. Бэкап, который никогда не восстанавливали, — это надежда, а не стратегия.
Наблюдаемость и алерты
Минимальный набор сигналов для продового кластера на VDS:
- Наличие лидера и стабильность выборов (частые переизбрания — тревога по сети/диску/ресурсам).
- Рост
etcd_debugging_mvcc_db_total_size_in_bytesи дисковая заполненность — триггер на compact/defrag окно. - Просадка
grpc_server_handled_totalна фоне высоких латенсий — перегрев I/O. - Проверка актуальности snapshot (не старше N часов/суток) и успешности последнего прогона.
Рекомендованные циклы обслуживания
- Snapshot: часто (каждый час для control-plane с активными изменениями; минимум — раз в сутки). Хранить: «часовые» сутки, «суточные» недели, «недельные» месяцы — под свою политику RPO.
- Compact: ежедневно или еженедельно, в зависимости от интенсивности изменений.
- Defrag: по метрикам, но не чаще раза в несколько дней. Выполнять по одному endpoint за прогон.
- Тестовый restore: ежеквартально на стенде с версионным соответствием (ядро, etcd, контейнер-рантайм в Kubernetes).
Чек-лист перед внедрением
- Согласованы версии etcd/etcdctl, есть доступ к TLS-сертификатам.
- Настроены systemd timer'ы и ретенция, выгрузка на внешний VDS/облако.
- Есть метрики и алерты для размера базы, лидера, латенсий, успешности бэкапов.
- Процедура restore описана и оттестирована для вашего сценария (standalone, внешний HA, kubeadm).
- Документированы пути данных, unit-файлы, флаги запуска и контакты ответственных.
Итог
etcd требователен к дисциплине обслуживания, но очень предсказуем при правильной эксплуатации. На VDS это означает: надёжный и быстрый диск, расписания snapshot, регулярный compact и аккуратный defrag, плюс периодическое отрабатывание restore. Такой подход даёт понятные RPO/RTO и снижает риск «внезапного» падения control-plane. Не откладывайте: начните с автоматизации бэкапа уже сегодня, добавьте compact/defrag по метрикам, а затем отрепетируйте восстановление — и ваш Kubernetes, сервис-дискавери или конфиг-стор будут спать спокойно.


