Восстановление после аварии
etcd рассчитан на отказы машин. Кластер etcd автоматически восстанавливается после временных сбоев, например перезагрузки машины, и допускает до (N-1)/2 постоянных отказов в кластере из N участников. При постоянном отказе из-за неисправности оборудования или повреждения диска участник теряет доступ к кластеру. Если кластер навсегда теряет более (N-1)/2 участников, происходит катастрофический отказ с безвозвратной потерей кворума. Без кворума кластер не может достичь консенсуса и продолжать принимать обновления.
Для восстановления после катастрофического отказа etcd v3 предоставляет средства снимков и восстановления, позволяющие воссоздать кластер без потери данных ключей v3. Восстановление ключей v2 описано в руководстве администратора v2 .
Создание снимка пространства ключей
Для восстановления кластера сначала нужен снимок пространства ключей одного
участника etcd. Его можно создать с работающего участника командой
etcdctl snapshot save либо скопировать файл member/snap/db из каталога данных
etcd. Следующая команда сохраняет пространство ключей, обслуживаемое $ENDPOINT,
в файл snapshot.db:
Обратите внимание: снимок из файла member/snap/db может потерять ещё не
записанные данные, находящиеся в каталоге wal (журнале предзаписи).
Состояние снимка
Чтобы узнать ревизию и хеш снимка, используйте команду etcdutl snapshot status:
Восстановление кластера
Разница ревизий
При восстановлении кластера существующие клиенты могут увидеть откат ревизии на сотни или тысячи значений. Снимок содержит историю данных только до момента создания, тогда как текущее состояние могло уйти далеко вперёд.
Это особенно опасно для Kubernetes с etcd, где контроллеры и операторы могут
использовать так называемые informers как локальные кэши, получающие уведомления
об обновлениях через наблюдения. Восстановление старой ревизии может неправильно
обновить кэши и вызвать непредсказуемое, несогласованное поведение контроллеров.
При известных потребителях API наблюдения, локальных кэшированных копиях данных etcd или использовании Kubernetes настоятельно рекомендуется восстанавливать снимок с описанным ниже «увеличением ревизии».
Восстановление из снимка
Для восстановления кластера достаточно одного файла снимка “db”. Команда
etcdutl snapshot restore создаёт новые каталоги данных etcd; все участники
должны восстанавливаться из одного снимка. При восстановлении перезаписывается
часть метаданных снимка, в частности идентификаторы участника и кластера, поэтому
участник теряет прежнюю идентичность. Это не позволяет новому участнику случайно
присоединиться к существующему кластеру. Следовательно, восстановление из снимка
обязательно должно запускать новый логический кластер.
Простое восстановление выполняется так:
Проверка целостности
Целостность снимка можно проверить при восстановлении. Снимок, созданный
etcdctl snapshot save, содержит хеш целостности, который проверяет
etcdutl snapshot restore. У снимка, скопированного из каталога данных, хеша
нет, и восстановить его можно только с --skip-hash-check.
Восстановление с увеличением ревизии
Чтобы после восстановления ревизии никогда не уменьшались, укажите
--bump-revision. Параметр принимает 64 bit целое число ревизий, добавляемых к
текущей ревизии снимка. Каждая запись в etcd увеличивает ревизию на один, поэтому
для снимка недельной давности достаточно увеличения на 1'000'000'000, если etcd
обрабатывает менее 1500 записей в секунду.
Для контроллеров Kubernetes важно также пометить все ревизии, включая добавленные,
как компактизированные через --mark-compacted. Тогда все наблюдения завершаются,
а etcd не отвечает на запросы о ревизиях после создания снимка, фактически
инвалидируя кэши informer.
Полная команда выглядит так:
Восстановление с обновлённым составом
Участники кластера etcd хранятся в самом etcd и обслуживаются алгоритмом консенсуса Raft. После полной потери кворума можно изменить место и способ формирования нового кластера, например создать его из совершенно нового набора участников.
При восстановлении из снимка новый состав можно сразу записать в хранилище:
Так новый кластер будет подключаться только к другим восстановленным участникам с указанным токеном, а не к старым участникам, которые ещё могут работать и пытаться подключиться.
В качестве альтернативы при запуске etcd можно указать --force-new-cluster,
чтобы перезаписать состав кластера, сохранив данные приложения. Это настоятельно
не рекомендуется: если другие участники прежнего кластера ещё работают, произойдёт
аварийное завершение. Обязательно регулярно сохраняйте снимки.
Сквозной пример End-2-End
Получите снимок работающего кластера командой:
В продолжение примера следующие команды создают новые каталоги данных etcd
(m1.etcd, m2.etcd, m3.etcd) для кластера из трёх участников:
Затем запустите etcd с новыми каталогами данных:
Теперь восстановленный кластер etcd должен быть доступен и обслуживать пространство ключей из снимка.
Начиная с etcd v3.6, снимок данных создаётся только с помощью etcdctl, а
восстановление выполняется через etcdutl. Если --data-dir не указан, значение
--data-dir по умолчанию — <name>.etcd, где <name> берётся из --name. Например,
если --data-dir отсутствует, а участников зовут m1, m2 и m3, каталогами
--data-dir будут m1.etcd, m2.etcd и m3.etcd.