Восстановление при ошибках
В процессе работы DKP автоматически создает резервные копии конфигурации и данных, которые могут пригодиться в случае возникновения проблем. Эти резервные копии сохраняются в директории /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-узла нужно в любом рабочем кластере под управлением DKP выполнить команду:
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
Если в поле 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
на тот, который был задан в манифесте.
Дефрагментация etcd
Перед дефрагментацией создайте резервную копию etcd.
Для просмотра размера БД etcd на определенном узле перед дефрагментацией и после ее выполнения используйте команду (здесь NODE_NAME
— имя master-узла):
d8 k -n kube-system exec -it etcd-NODE_NAME -- /usr/bin/etcdctl \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
endpoint status --cluster -w table
Пример вывода (размер БД etcd на узле указывается в колонке DB SIZE
):
+-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| ENDPOINT | ID | VERSION | STORAGE VERSION | DB SIZE | IN USE | PERCENTAGE NOT IN USE | QUOTA | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | DOWNGRADE TARGET VERSION | DOWNGRADE ENABLED |
+-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| https://192.168.199.80:2379 | 489a8af1e7acd7a0 | 3.6.1 | 3.6.0 | 76 MB | 62 MB | 20% | 2.1 GB | true | false | 56 | 258054684 | 258054684 | | | false |
+-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| https://192.168.199.81:2379 | 589a8ad1e7ccd7b0 | 3.6.1 | 3.6.0 | 76 MB | 62 MB | 20% | 2.1 GB | false | false | 56 | 258054685 | 258054685 | | | false |
+-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
| https://192.168.199.82:2379 | 229a8cd1e7bcd7a0 | 3.6.1 | 3.6.0 | 76 MB | 62 MB | 20% | 2.1 GB | false | false | 56 | 258054685 | 258054685 | | | false |
+-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
Как выполнить дефрагментацию etcd узла в кластере с одним master-узлом
Дефрагментация etcd — ресурсоемкая операция, которая на время полностью блокирует работу etcd на данном узле. Учитывайте это при выборе времени для проведения операции в кластере с одним master-узлом.
Чтобы выполнить дефрагментацию etcd в кластере с одним master-узлом, используйте следующую команду (здесь NODE_NAME
— имя master-узла):
d8 k -n kube-system exec -ti etcd-NODE_NAME -- /usr/bin/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/ defrag --command-timeout=30s
Пример вывода при успешном выполнении операции:
Finished defragmenting etcd member[https://localhost:2379]. took 848.948927ms
При появлении ошибки из-за таймаута увеличивайте значение параметра
–command-timeout
из команды выше, пока дефрагментация не выполнится успешно.
Как выполнить дефрагментацию etcd в кластере с несколькими master-узлами
Чтобы выполнить дефрагментацию etcd в кластере с несколькими master-узлами:
-
Получите список подов etcd. Для этого используйте следующую команду:
d8 k -n kube-system get pod -l component=etcd -o wide
Пример вывода:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES etcd-master-0 1/1 Running 0 3d21h 192.168.199.80 master-0 <none> <none> etcd-master-1 1/1 Running 0 3d21h 192.168.199.81 master-1 <none> <none> etcd-master-2 1/1 Running 0 3d21h 192.168.199.82 master-2 <none> <none>
-
Определите master-узел — лидер. Для этого обратитесь к любому поду etcd и получите список узлов — участников кластера etcd с помощью команды (где
NODE_NAME
— имя master-узла):d8 k -n kube-system exec -it etcd-NODE_NAME -- /usr/bin/etcdctl \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ endpoint status --cluster -w table
Пример вывода (у лидера в колонке
IS LEADER
будет значениеtrue
):+-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | ENDPOINT | ID | VERSION | STORAGE VERSION | DB SIZE | IN USE | PERCENTAGE NOT IN USE | QUOTA | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | DOWNGRADE TARGET VERSION | DOWNGRADE ENABLED | +-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | https://192.168.199.80:2379 | 489a8af1e7acd7a0 | 3.6.1 | 3.6.0 | 76 MB | 62 MB | 20% | 2.1 GB | true | false | 56 | 258054684 | 258054684 | | | false | +-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | https://192.168.199.81:2379 | 589a8ad1e7ccd7b0 | 3.6.1 | 3.6.0 | 76 MB | 62 MB | 20% | 2.1 GB | false | false | 56 | 258054685 | 258054685 | | | false | +-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+ | https://192.168.199.82:2379 | 229a8cd1e7bcd7a0 | 3.6.1 | 3.6.0 | 76 MB | 62 MB | 20% | 2.1 GB | false | false | 56 | 258054685 | 258054685 | | | false | +-----------------------------+------------------+---------+-----------------+---------+--------+-----------------------+--------+------------+------------+-----------+------------+--------------------+--------+--------------------------+-------------------+
-
Поочередно выполните дефрагментацию etcd узлов — участников etcd кластера. Для дефрагментации используйте команду (здесь
NODE_NAME
— имя master-узла):Важно: дефрагментацию лидера необходимо выполнять в последнюю очередь.
Восстановление etcd на узле после дефрагментации может занять некоторое время. Рекомендуется подождать не менее минуты прежде чем переходить к дефрагментации etcd следующего узла.
d8 k -n kube-system exec -ti etcd-NODE_NAME -- /usr/bin/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/ defrag --command-timeout=30s
Пример вывода при успешном выполнении операции:
Finished defragmenting etcd member[https://localhost:2379]. took 848.948927ms
При появлении ошибки из-за таймаута увеличивайте значение параметра
–command-timeout
из команды выше, пока дефрагментация не выполнится успешно.
Отказоустойчивость
Если какой-либо компонент 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 запускает поды на новых узлах.
- DKP создает или обновляет файлы в
/etc/kubernetes
: манифесты, конфигурации, сертификаты и т.д. - Все модули DKP с поддержкой отказоустойчивости автоматически включают её, если значение глобальной настройки
highAvailability
не переопределено вручную.
Удаление узлов control plane выполняется в обратном порядке:
- Удаляются лейблы
node-role.kubernetes.io/control-plane
,node-role.kubernetes.io/master
,node.deckhouse.io/group
. - DKP удаляет свои поды с этих узлов.
- Члены etcd, расположенные на этих узлах, удаляются автоматически.
- Если число узлов уменьшается с двух до одного, etcd может перейти в статус
readonly
. В этом случае требуется запуск с параметром--force-new-cluster
, который следует убрать после успешного запуска.