ADG Оставить заявку
Блог Системное администрирование 5 мин чтения

DR-тест Kubernetes: восстановление etcd-кластера за 12 минут - проверено заранее

Провели первый плановый DR-тест Kubernetes-кластера клиента: восстановление из etcd-снапшота. 12 минут простоя - это цифра, которую хорошо знать до, а не во время реального сбоя.

Контекст момента

Практика DR-тестирования Kubernetes etcd-кластера становится обязательной в production 2018

Одна из неочевидных вещей в сопровождении Kubernetes-кластеров: бэкап etcd настроить проще, чем убедиться что восстановление из него реально работает. Бэкапы снимаются, в Cron всё зелёное, снапшоты копируются в S3 - и всё, галочка стоит. Что произойдёт когда придётся этот снапшот развернуть - никто не проверял.

В ноябре мы закрыли этот пробел для одного из production-кластеров на managed-обслуживании: провели плановый DR-тест, восстановление из etcd-бэкапа от начала до конца в изолированном окружении. Вот что из этого вышло.

Почему etcd - это отдельная история

etcd - единственная stateful-компонента control plane Kubernetes. Всё состояние кластера - объекты, конфигурации, секреты, привязки - хранится там. Если etcd утрачен без бэкапа или бэкап не восстанавливается - кластер нужно поднимать с нуля, а workload вспоминать из манифестов. В хорошем случае манифесты есть в Git. В реальной жизни бывает по-разному.

У клиента кластер трёхнодовый, etcd - тоже кластер из трёх членов, quorum поддерживается. Штатный сценарий - выход одного члена - переживается без DR: etcd election работает, API отвечает. DR нужен когда теряем большинство или весь кластер. Это редкость, но вероятность не нулевая - железо падает, датацентры горят, администраторы ошибаются.

Как готовили тест

Первое - договорились о метриках. Нас интересовали два числа: RTO (сколько времени занимает восстановление) и RPO (насколько свежий снапшот мы можем гарантировать). По бэкап-расписанию снапшоты снимались каждый час, хранились 48 часов в S3 с репликацией. RPO у нас был теоретически час. RTO - неизвестен, его и шли измерять.

Второе - изолированное окружение. Восстанавливаться на production-кластере клиента никто не собирался. Подняли идентичный по конфигурации тестовый кластер: те же версии (Kubernetes 1.12, etcd 3.3), те же сертификаты инфраструктуры, та же топология. Взяли снапшот etcd из S3 - не самый свежий, а трёхдневной давности, чтобы было что терять и находить.

Третье - полный сброс etcd. Имитировали сценарий «все три члена потеряны»: остановили etcd на всех трёх нодах, очистили data-директории, удалили member-state. Чистый лист.

Что делали и сколько это заняло

Процедура восстановления etcd из снапшота выглядит примерно так:

  • Скачать снапшот из S3 и проверить через etcdctl snapshot status. Это первое что стоит сделать - убедиться что файл целый, а не оборванная загрузка.
  • Восстановить данные на каждом члене через etcdctl snapshot restore с параметрами имени кластера, peer-URL-ов и начального состояния new. Это создаёт новые data-директории с нужным содержимым и свежими member-идентификаторами.
  • Запустить etcd на всех нодах с флагом --initial-cluster-state=new - они узнают друг друга и формируют новый кластер из восстановленных данных.
  • Проверить что API-сервер Kubernetes поднялся и видит объекты из снапшота.
  • Перезапустить controller manager и scheduler - они иногда зависают на старых соединениях после перезапуска etcd.

По времени: скачивание снапшота (он был около 200 МБ) - 2 минуты. Восстановление данных на трёх нодах параллельно - 3 минуты. Запуск etcd и ожидание quorum - 4 минуты. Проверка состояния кластера, объектов, нескольких workload - ещё 3 минуты. Итого - 12 минут от «начали» до «кластер работает, данные на месте».

12 минут - это немного, но это и не мгновенно. Для кластера где крутится production-нагрузка, 12 минут простоя control plane - это простой всего что масштабируется, деплоится или перезапускается в этот момент. Workload, которые уже запущены и не падают, продолжают работать - kubelet на нодах автономен. Но новые поды не стартуют, ConfigMap не обновляются, Ingress-правила не меняются.

Что обнаружили по ходу

Несколько моментов, которые не очевидны пока не попробуешь вживую.

Сертификаты etcd. При восстановлении важно использовать те же CA-сертификаты, что были в оригинальном кластере. Если сертификаты утрачены вместе с кластером - восстановить etcd из снапшота технически можно, но придётся перевыпускать все клиентские сертификаты Kubernetes-компонентов. Это отдельная работа, которая не входит в 12 минут.

Порядок запуска. Восстанавливать etcd нужно сначала на всех нодах, и только потом запускать - а не запускать первый, ждать, запускать второй. Если запустить первый без указания остальных пиров, он поднимется в single-member режиме со своим cluster-ID, и добавить к нему остальных уже нельзя будет через restore.

coredns и системные поды. После того как API поднялся, несколько минут системные поды (coredns, kube-proxy) показывали Unknown статус - kubelet ещё не успел отрапортовать. Это нормально, прошло само. Но без понимания этого первая реакция - паника.

Что это дало

Главное что дал тест - уверенность, что процедура рабочая. До теста было: «бэкапы есть, восстановление должно работать». После - конкретная отработанная последовательность действий, измеренное время и понимание подводных камней.

Оформили runbook: пошаговый документ на случай реального DR, с командами, именами файлов под этот кластер, контактами. Это не большой документ - две страницы. Но две страницы с реальными командами лучше, чем документация etcd в момент когда всё горит.

Тест планируем повторять раз в квартал - и при обновлении etcd или Kubernetes. Процедура restore немного меняется между версиями, лучше знать об этом заранее.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.