Восстановление при ошибках
В процессе работы DVP автоматически создает резервные копии конфигурации и данных, которые могут пригодиться в случае возникновения проблем. Эти резервные копии сохраняются в директории /etc/kubernetes/deckhouse/backup. Если в процессе работы возникли ошибки или непредвиденные ситуации, вы можете использовать эти резервные копии для восстановления до предыдущего исправного состояния.
Восстановление работоспособности кластера etcd
Если кластер etcd не функционирует и не удается восстановить его из резервной копии, вы можете попытаться восстановить его с нуля, следуя шагам ниже.
- Сначала на всех узлах, которые являются частью вашего кластера etcd, кроме одного, удалите манифест
etcd.yaml, который находится в директории/etc/kubernetes/manifests/. После этого только один узел останется активным, и с него будет происходить восстановление состояния мультимастерного кластера. - На оставшемся узле откройте файл манифеста
etcd.yamlи укажите параметр--force-new-clusterвspec.containers.command. - После успешного восстановления кластера, удалите параметр
--force-new-cluster.
Эта операция является деструктивной, так как она полностью уничтожает текущие данные и инициализирует кластер с состоянием, которое сохранено на узле. Все pending-записи будут утеряны.
Восстановление master-узла при ошибке загрузки компонентов control plane через kubelet
Ситуация, когда kubelet не может загрузить компоненты control plane, может возникнуть, если в кластере с одним master-узлом был удалён каталог с образами (например, /var/lib/containerd).
В этом случае после перезапуска kubelet не сможет загрузить образы компонентов control plane, поскольку параметры авторизации для доступа к registry.deckhouse.io на master-узле отсутствуют.
Далее приведена инструкция по восстановлению master-узла.
containerd
-
Для восстановления работоспособности master-узла нужно в любом рабочем кластере под управлением DVP выполнить команду:
d8 k -n d8-system get secrets deckhouse-registry -o json | jq -r '.data.".dockerconfigjson"' | base64 -d | jq -r '.auths."registry.deckhouse.io".auth' -
Скопируйте вывод команды и присвойте переменной
AUTHна поврежденном master-узле. -
Далее на поврежденном master-узле загрузите образы компонентов control plane:
for image in $(grep "image:" /etc/kubernetes/manifests/* | awk '{print $3}'); do crictl pull --auth $AUTH $image done -
После загрузки образов перезапустите kubelet.
Восстановление etcd
Просмотр списка узлов кластера в etcd
Вариант 1
Используйте команду etcdctl member list.
Пример:
for pod in $(d8 k -n kube-system get pod -l component=etcd,tier=control-plane -o name); do
d8 k -n kube-system exec "$pod" -- etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt \
--cert /etc/kubernetes/pki/etcd/ca.crt --key /etc/kubernetes/pki/etcd/ca.key \
--endpoints https://127.0.0.1:2379/ member list -w table
if [ $? -eq 0 ]; then
break
fi
done
Внимание. Последний параметр в таблице вывода показывает, что узел находится в состоянии learner, а не в состоянии leader.
Вариант 2
Используйте команду etcdctl endpoint status. Для лидера в столбце IS LEADER будет указано значение true.
Пример:
for pod in $(d8 k -n kube-system get pod -l component=etcd,tier=control-plane -o name); do
d8 k -n kube-system exec "$pod" -- etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt \
--cert /etc/kubernetes/pki/etcd/ca.crt --key /etc/kubernetes/pki/etcd/ca.key \
--endpoints https://127.0.0.1:2379/ endpoint status --cluster -w table
if [ $? -eq 0 ]; then
break
fi
done
Восстановление кластера etcd при полной недоступности
- Остановите все узлы etcd, кроме одного, удалив манифест
etcd.yamlна остальных. - На оставшемся узле добавьте в команду etcd параметр
--force-new-cluster. - После восстановления удалите этот флаг.
Будьте осторожны: эти действия полностью уничтожают предыдущие данные и формируют новый кластер etcd.
Восстановление etcd при ошибке panic: unexpected removal of unknown remote peer
В некоторых случаях помогает ручное восстановление через etcdutl snapshot restore:
- Сохраните локальный снапшот
/var/lib/etcd/member/snap/db. - Воспользуйтесь
etcdutlс опцией--force-new-cluster. - Полностью очистите
/var/lib/etcdи положите туда восстановленный снапшот. - Удалите «зависшие» контейнеры etcd / kube-apiserver, перезапустите узел.
Действия при переполнении базы данных etcd (превышение quota-backend-bytes)
Когда объем базы данных etcd достигает лимита, установленного параметром quota-backend-bytes, доступ к ней становится read-only. Это означает, что база данных etcd перестает принимать новые записи, но при этом остается доступной для чтения данных. Вы можете понять, что столкнулись с подобной ситуацией, выполнив команду:
d8 k -n kube-system exec -ti $(d8 k -n kube-system get pod -l component=etcd,tier=control-plane -o name | sed -n 1p) -- \
etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt \
--cert /etc/kubernetes/pki/etcd/ca.crt --key /etc/kubernetes/pki/etcd/ca.key \
--endpoints https://127.0.0.1:2379/ endpoint status -w table --cluster
В данной команде используется подстановка: $(d8 k -n kube-system get pod -l component=etcd,tier=control-plane -o name | sed -n 1p). Она автоматически подставит имя первого пода, соответствующего нужным лейблам.
Если в поле ERRORS вы видите подобное сообщение alarm:NOSPACE, значит вам нужно предпринять следующие шаги:
- Найдите строку с
--quota-backend-bytesв файле манифеста пода etcd, расположенного по пути/etc/kubernetes/manifests/etcd.yamlи увеличьте значение, умножив указанный параметр в этой строке на два. Если такой строки нет — добавьте, например:- --quota-backend-bytes=8589934592. Эта настройка задает лимит на 8 ГБ. -
Сбросьте активное предупреждение (alarm) о нехватке места в базе данных. Для этого выполните следующую команду:
d8 k -n kube-system exec -ti $(d8 k -n kube-system get pod -l component=etcd,tier=control-plane -o name | sed -n 1p) -- \ etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt \ --cert /etc/kubernetes/pki/etcd/ca.crt --key /etc/kubernetes/pki/etcd/ca.key \ --endpoints https://127.0.0.1:2379/ alarm disarm - Измените параметр
maxDbSizeв настройках модуляcontrol-plane-managerна тот, который был задан в манифесте.
Отказоустойчивость
Если какой-либо компонент control plane становится недоступным, кластер временно сохраняет текущее состояние, но не может обрабатывать новые события. Например:
- При сбое
kube-controller-managerперестаёт работать масштабирование deployment’ов. - При недоступности
kube-apiserverневозможны любые запросы к Kubernetes API, но уже запущенные приложения продолжают функционировать.
Однако при продолжительной недоступности компонентов нарушается обработка новых объектов, реакция на сбои узлов и другие процессы. Со временем это может привести к деградации работы кластера и повлиять на пользовательские приложения.
Чтобы снизить такие риски, следует масштабировать control plane до отказоустойчивой конфигурации — минимум трёх узлов. Это особенно критично для etcd, так как он требует наличия кворума для выбора лидера. Кворум работает по принципу большинства (N/2 + 1) от общего числа узлов.
Пример:
| Размер кластера | Большинство | Максимальные потери |
|---|---|---|
| 1 | 1 | 0 |
| 3 | 2 | 1 |
| 5 | 3 | 2 |
| 7 | 4 | 3 |
| 9 | 5 | 4 |
Чётное число узлов не даёт преимущества по отказоустойчивости, но увеличивает накладные расходы на репликацию.
В большинстве случаев достаточно трёх узлов etcd, пять — если критична устойчивость. Более семи — крайне редко и не рекомендуется из-за высокой нагрузки.
После добавления новых узлов control plane:
- Устанавливается лейбл
node-role.kubernetes.io/control-plane="". - DaemonSet запускает поды на новых узлах.
- DVP создает или обновляет файлы в
/etc/kubernetes: манифесты, конфигурации, сертификаты и т.д. - Все модули DVP с поддержкой отказоустойчивости автоматически включают её, если значение глобальной настройки
highAvailabilityне переопределено вручную.
Удаление узлов control plane выполняется в обратном порядке:
- Удаляются лейблы
node-role.kubernetes.io/control-plane,node-role.kubernetes.io/master,node.deckhouse.io/group. - DVP удаляет свои поды с этих узлов.
- Члены etcd, расположенные на этих узлах, удаляются автоматически.
- Если число узлов уменьшается с двух до одного, etcd может перейти в статус
readonly. В этом случае требуется запуск с параметром--force-new-cluster, который следует убрать после успешного запуска.