Документация находится в разработке, может содержать неполную информацию.
Резервное копирование etcd
Автоматическое резервное копирование
Deckhouse создаёт CronJob kube-system/d8-etcd-backup-*
, который срабатывает в 00:00 по UTC+0. Резервная копия данных etcd сохраняется в архив /var/lib/etcd/etcd-backup.tar.gz
на всех master-узлах.
Резервное копирование вручную с помощью Deckhouse CLI
В кластерах Deckhouse v1.65 и выше резервную копию данных etcd можно создать одной командой d8 backup etcd
:
d8 backup etcd --kubeconfig $KUBECONFIG ./etcd.db
Резервное копирование вручную с помощью etcdctl
Не рекомендуется использовать в версиях Deckhouse 1.65 и выше.
В кластерах Deckhouse версии v1.64 и ниже запустите следующий скрипт на любом master-узле от пользователя root
:
#!/usr/bin/env bash
set -e
pod=etcd-`hostname`
d8 k -n kube-system exec "$pod" -- /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/ snapshot save /var/lib/etcd/${pod##*/}.snapshot && \
mv /var/lib/etcd/"${pod##*/}.snapshot" etcd-backup.snapshot && \
cp -r /etc/kubernetes/ ./ && \
tar -cvzf kube-backup.tar.gz ./etcd-backup.snapshot ./kubernetes/
rm -r ./kubernetes ./etcd-backup.snapshot
В текущей директории будет создан файл kube-backup.tar.gz
со снимком базы etcd одного из узлов etcd-кластера.
Из полученного снимка можно будет восстановить состояние кластера etcd.
Также рекомендуется сделать бэкап директории /etc/kubernetes
, в которой находятся:
- манифесты и конфигурация компонентов control-plane;
- PKI кластера Kubernetes.
Мы рекомендуем хранить резервные копии снимков состояния кластера etcd, а также бэкап директории /etc/kubernetes/
в зашифрованном виде вне кластера Deckhouse.
Для этого вы можете использовать сторонние инструменты резервного копирования файлов, например Restic, Borg, Duplicity и т.д.
Полное восстановление состояния кластера из резервной копии etcd
Далее будут описаны шаги по восстановлению кластера до предыдущего состояния из резервной копии при полной потере данных.
Восстановление кластера с одним master-узлом
Для корректного восстановления кластера с одним master-узлом выполните следующие шаги:
-
Загрузите утилиту etcdctl на сервер (желательно чтобы её версия была такая же, как и версия etcd в кластере).
wget "https://github.com/etcd-io/etcd/releases/download/v3.5.4/etcd-v3.5.4-linux-amd64.tar.gz" tar -xzvf etcd-v3.5.4-linux-amd64.tar.gz && mv etcd-v3.5.4-linux-amd64/etcdctl /usr/local/bin/etcdctl
Проверить версию etcd в кластере можно выполнив следующую команду:
d8 k -n kube-system exec -ti etcd-$(hostname) -- etcdctl version
-
Остановите etcd.
Etcd запущен в виде статического пода, поэтому достаточно переместить файл манифеста:
mv /etc/kubernetes/manifests/etcd.yaml ~/etcd.yaml
-
Сохраните текущие данные etcd.
cp -r /var/lib/etcd/member/ /var/lib/deckhouse-etcd-backup
-
Очистите директорию etcd.
rm -rf /var/lib/etcd/member/
-
Поместите резервную копию etcd в файл
~/etcd-backup.snapshot
. -
Восстановите базу данных etcd.
ETCDCTL_API=3 etcdctl snapshot restore ~/etcd-backup.snapshot --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/ --data-dir=/var/lib/etcd
-
Запустите etcd.
mv ~/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
Восстановление мультимастерного кластера
Для корректного восстановления мультимастерного кластера выполните следующие шаги:
-
Явно включите режим High Availability (HA) с помощью глобального параметра highAvailability. Это нужно, например, чтобы не потерять одну реплику Prometheus и её PVC, поскольку в режиме кластера с одним master-узлом HA отключен по умолчанию.
-
Переведите кластер в режим с одним master-узлом, в соответствии с инструкцией для облачных кластеров или самостоятельно выведите статические master-узлы из кластера.
-
На оставшемся единственном master-узле выполните шаги по восстановлению etcd из резервной копии в соответствии с инструкцией для кластера с одним master-узлом.
-
Когда работа etcd будет восстановлена, удалите из кластера информацию об уже удаленных в п.1 master-узлах, воспользовавшись следующей командой (укажите название узла):
d8 k delete node <MASTER_NODE_I>
-
Перезапустите все узлы кластера.
-
Дождитесь выполнения заданий из очереди Deckhouse:
d8 k -n d8-system exec svc/deckhouse-leader -c deckhouse -- deckhouse-controller queue main
-
Переведите кластер обратно в режим мультимастерного в соответствии с инструкцией для облачных кластеров или инструкцией для статических или гибридных кластеров.
Восстановление объекта Kubernetes из резервной копии etcd
Краткий сценарий восстановления отдельных объектов из резервной копии etcd:
- Получите резервную копию данных.
- Запустите временный экземпляр etcd.
- Наполните его данными из резервной копии.
- Получите описания нужных объектов с помощью утилиты
etcdhelper
.
Шаги по восстановлению объектов из резервной копии etcd
В примере:
etcd-snapshot.bin
— файл с резервной копией данных etcd (snapshot);infra-production
— пространство имен, в котором нужно восстановить объекты.
- Запустите под с временным экземпляром etcd.
Желательно, чтобы версия запускаемого экземпляра etcd совпадала с версией etcd, из которой создавалась резервная копия. Для простоты экземпляр запускается не локально, а в кластере, так как в кластере заведомо есть образ etcd.
-
Подготовьте файл
etcd.pod.yaml
с манифестом пода:cat <<EOF >etcd.pod.yaml apiVersion: v1 kind: Pod metadata: name: etcdrestore namespace: default spec: containers: - command: - /bin/sh - -c - "sleep 96h" image: IMAGE imagePullPolicy: IfNotPresent name: etcd volumeMounts: - name: etcddir mountPath: /default.etcd volumes: - name: etcddir emptyDir: {} EOF
-
Установите актуальное имя образа etcd:
IMG=`kubectl -n kube-system get pod -l component=etcd -o jsonpath="{.items[0].spec. containers[*].image}"` sed -i -e "s#IMAGE#$IMG#" etcd.pod.yaml
-
Создайте под:
kubectl create -f etcd.pod.yaml
Скопируйте etcdhelper
и снимок etcd в контейнер пода.
etcdhelper
можно собрать из исходного кода или скопировать из готового образа (например, из образа etcdhelper
на Docker Hub).
Пример:
kubectl cp etcd-snapshot.bin default/etcdrestore:/tmp/etcd-snapshot.bin
kubectl cp etcdhelper default/etcdrestore:/usr/bin/etcdhelper
В контейнере установите права на запуск etcdhelper
, восстановите данные из резервной копии и запустите etcd.
Пример:
~ # kubectl -n default exec -it etcdrestore -- sh
/ # chmod +x /usr/bin/etcdhelper
/ # etcdctl snapshot restore /tmp/etcd-snapshot.bin
/ # etcd &
Получите описания нужных объектов кластера, отфильтровав их с помощью grep
.
Пример:
~ # kubectl -n default exec -it etcdrestore -- sh
/ # mkdir /tmp/restored_yaml
/ # cd /tmp/restored_yaml
/tmp/restored_yaml # for o in `etcdhelper -endpoint 127.0.0.1:2379 ls /registry/ | grep infra-production` ; do etcdhelper -endpoint 127.0.0.1:2379 get $o > `echo $o | sed -e "s#/registry/##g;s#/#_#g"`.yaml ; done
Замена символов с помощью sed
в примере позволяет сохранить описания объектов в файлы, именованные подобно структуре реестра etcd. Например: /registry/deployments/infra-production/supercronic.yaml
→ deployments_infra-production_supercronic.yaml
.
-
Скопируйте полученные описания объектов из пода на master-узел командой:
d8 k cp default/etcdrestore:/tmp/restored_yaml restored_yaml
-
Удалите из полученных описаний объектов информацию о времени создания, UID, status и прочие оперативные данные, после чего восстановите объекты командой:
d8 k create -f restored_yaml/deployments_infra-production_supercronic.yaml
-
Под с временным экземпляром etcd можно удалить командой:
d8 k delete -f etcd.pod.yaml
Как получить список узлов кластера etcd
Используйте команду etcdctl member list
.
Пример:
d8 k -n kube-system exec -ti $(d8 k -n kube-system get pod -l component=etcd,tier=control-plane -o name | head -n1) -- \
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
Внимание. Последний параметр в таблице вывода показывает, что узел кластера etcd находится в состоянии learner, а не в состоянии leader.
Как получить список узлов кластера etcd (вариант 2)
Используйте команду etcdctl endpoint status
. Для этой команды, после флага --endpoints
нужно подставить адрес каждого узла control-plane.
Значение true
в пятом столбце вывода указывает на лидера.
Пример скрипта, который автоматически передает все адреса узлов control-plane:
MASTER_NODE_IPS=($(d8 k get nodes -l \
node-role.kubernetes.io/control-plane="" \
-o 'custom-columns=IP:.status.addresses[?(@.type=="InternalIP")].address' \
--no-headers))
unset ENDPOINTS_STRING
for master_node_ip in ${MASTER_NODE_IPS[@]}
do ENDPOINTS_STRING+="--endpoints https://${master_node_ip}:2379 "
done
d8 k -n kube-system exec -ti $(d8 k -n kube-system get pod \
-l component=etcd,tier=control-plane -o name | head -n1) \
-- etcdctl --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/ca.crt \
--key /etc/kubernetes/pki/etcd/ca.key \
$(echo -n $ENDPOINTS_STRING) endpoint status -w table
Пересборка кластера etcd
Пересборка может потребоваться в случае, если etcd-кластер развалился, либо при миграции из мультимастерного кластера в кластер с одним master-узлом.
- Выберите узел, с которого начнётся восстановление кластера etcd. В случае миграции в кластер с одним master-узлом это узел, на котором должен остаться etcd.
- Остановите etcd на всех остальных узлах. Для этого удалите файл
/etc/kubernetes/manifests/etcd.yaml
. - На оставшемся узле в манифесте
/etc/kubernetes/manifests/etcd.yaml
добавьте аргумент--force-new-cluster
в полеspec.containers.command
. - После успешного запуска кластера удалите параметр
--force-new-cluster
.
Операция деструктивна, она полностью уничтожает консенсус и запускает etcd-кластер с состояния, которое сохранилось на выбранном узле. Любые pending-записи пропадут.
Устранение бесконечного рестарта
Данный вариант может понадобиться, если запуск с аргументом --force-new-cluster
не восстанавливает работу etcd. Такое может случиться при неудачном converge master-узлов, когда новый master-узел был создан со старым диском etcd, поменял свой адрес из локальной сети, и другие master-узлы отсутствуют. Стоит использовать данный способ, если контейнер etcd в бесконечном рестарте, а в его логе ошибка: panic: unexpected removal of unknown remote peer
.
- Установите утилиту etcdutl.
-
С текущего локального снапшота базы etcd (
/var/lib/etcd/member/snap/db
) выполните создание нового снапшота:./etcdutl snapshot restore /var/lib/etcd/member/snap/db --name <HOSTNAME> \ --initial-cluster=HOSTNAME=https://<ADDRESS>:2380 --initial-advertise-peer-urls=https://ADDRESS:2380 \ --skip-hash-check=true --data-dir /var/lib/etcdtest
где:
<HOSTNAME>
— название master-узла;<ADDRESS>
— адрес master-узла.
-
Выполните команды для использования нового снапшота:
cp -r /var/lib/etcd /tmp/etcd-backup rm -rf /var/lib/etcd mv /var/lib/etcdtest /var/lib/etcd
-
Найдите контейнеры
etcd
иkube-apiserver
:crictl ps -a --name "^etcd|^kube-apiserver"
-
Удалите найденные контейнеры
etcd
иkube-apiserver
:crictl rm <CONTAINER-ID>
-
Перезапустите master-узел.