Резервное копирование и восстановление работы ETCD
Создать резервную копию ETCD
В платформе “Штурвал” вы можете создать резервную копию ETCD с помощью объекта NCI. Резервное копирование данных кластера ETCD может понадобиться для восстановления кластера. Рекомендуется выполнять резервное копирования в период наименьшей нагрузки на кластер.
- Подготовьте скрипт для резервного копирования, например, с именем
etcdbackup.sh
.
Пример скрипта etcdbackup.sh
#!/bin/sh
# Проверка запуска из-под root
if [[ $EUID -ne 0 ]]; then
echo "This script must berun as root"
exit 1
fi
# Проверка установки etcdctl для выполнения резервного копирования
if which etcdctl > /dev/null; then
echo etcdctl found
else
fi
function usage {
echo 'Path to backup dir required: ./cluster-backup.sh <path-to-backup-dir>'
exit 1
}
# If the first argument is missing, or it is an existing file, then print usage and exit
if [ -z "$1" ] || [ -f "$1" ]; then
usage
fi
# Проверка существования манифестов
function checkManifests {
echo 'No manifsts found in /etc/kubernetes/manifests'
exit 1
}
if [ -z "$(ls /etc/kubernetes/manifests/)" ];then
checkManifests
fi
function checkStatus () {
status=$?
if test $status -eq 0
then
echo "passed $1"
else
echo "failed $1"
exit 1
fi
}
# Объявление переменных
archive="$(hostname)-$(date '+%F_%H%M%S').tar.gz" # Имя резервной копии ETCD
backupdate="$1/backup/" # Расположение резервной копии ETCD
mkdir -p $backupdate/manifests # Директория для резервной копии манифестов ETCD
mkdir -p $backupdate/etcd # Директория для резервной копии ETCD
# Получение данных для подключения и создание резервной копии (snapshot)
ETCDCTL_API=3 \
ETCDCTL_CACERT='/etc/kubernetes/pki/etcd/ca.crt' \
ETCDCTL_CERT='/etc/kubernetes/pki/etcd/server.crt' \
ETCDCTL_KEY='/etc/kubernetes/pki/etcd/server.key' \
ETCDCTL_ENDPOINTS='https://XX.XX.XX.XX:2379' \
/usr/local/bin/etcdctl snapshot save $backupdate/etcd/etcd.snapshot ;
checkStatus "etcd backup"
cp -r /etc/kubernetes/manifests/* $backupdate/manifests/
checkStatus "Create copies of static manifests"
echo "Manifests saved at $backupdate/manifests"
# Бэкапирование secrets_encryption.yaml необходимо для кластеров с расширенными параметрами безопасности (secure=true)
cp /etc/kubernetes/secrets_encryption.yaml $backupdate/etcd/ >/dev/null 2>&1
echo "Create copies of secrets_encryption.yaml"
echo "Archiving backup...."
tar -zcf $1/$archive $backupdate 2> /dev/null
checkStatus "archiving file"
echo "Backup archiving finished"
chmod 666 $1/$archive
echo "Backup archive is located in $1/archive"
# Удаление архивов с резервной копией старше 3-х дней
find /tmp/ -name "*.tar.gz" -mtime +3 -delete
checkStatus "removing old backups"
echo Backup finished
exit 0
- В графическом интерфейсе кластера откройте страницу Конфигурация узлов раздела Администрирование, нажмите + Добавить NCI. На странице добавления NCI:
- Задайте имя, например, etcdbackup и в селекторе узлов из выпадающего списка выберите ключ лейбла node-role.kubernetes.io/control-plane. Значение для лейбла не устанавливайте.
- В блоке Настраиваемые разделы выберите Файлы и директории и Пакеты для установки, нажмите Продолжить.
Скриншот
- В открывшемся окне на шаге конфигурации раздела Пакеты для установки нажмите + и укажите пакет
etcdhelper
, выберите целевое состояние пакета Present.
Скриншот
- Нажмите Добавить и затем Продолжить, чтобы перейти к разделу Файлы и директории.
- На шаге Файлы и директории нажмите + и в поле Путь к файлу или директории пропишите путь до создаваемого файла со скриптом резервного копирования. В типе файла/директории должно быть выбрано Файл.
- В поле права доступа укажите необходимые права, например, 0755, что обеспечит владельцу полный доступ к файлу, группе владельца другим пользователям доступ на чтение и выполнение. Владелец и группа должны быть root.
- В поле Содержимое файла вставьте содержимое подготовленного скрипта из файла
etcdbackup.sh
, нажмите Добавить.
Скриншот
- Нажмите + и в поле Путь к файлу или директории пропишите путь до файла с расписанием запуска резервного копирования.
- В поле права доступа укажите необходимые права, например, 0600, что обеспечит правами только владельца файла на чтение и запись. Владелец и группа должны быть root.
- В поле Содержимое файла укажите конфигурацию запуска резервного копирования: расписание в cron формате, путь до файла со скриптом и путь до создаваемой резервной копии ETCD. В поле Содержимое файла после записи конфигурации запуска требуется выполнить перенос строки.
- Нажмите Добавить. Обратите внимание! Рекомендуется хранить резервную копию ETCD в сетевой файловой системе не на Master-узлах, а, например,
/nfs/share
. Это может быть полезным в случае недоступности Master-узлов.
Пример конфигурации запуска
30 18 * * * /opt/etcdbackup.sh /tmp/
Скриншот
- Нажмите Завершить.
Пример NCI
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
annotations:
shturval.tech/name: etcdbackup
finalizers:
- node.shturval.tech/finalizer
name: etcdbackup
spec:
packages:
- name: etcdhelper
state: present
files:
- content: |
#!/bin/sh
if [[ $EUID -ne 0 ]]; then
echo "This script must berun as root"
exit 1
fi
if which etcdctl > /dev/null; then
echo etcdctl found
else
echo etcdctl not found
fi
function usage {
echo 'Path to backup dir required: ./cluster-backup.sh <path-to-backup-dir>'
exit 1
}
# If the first argument is missing, or it is an existing file, then print usage and exit
if [ -z "$1" ] || [ -f "$1" ]; then
usage
fi
function checkManifests {
echo 'No manifsts found in /etc/kubernetes/manifests'
exit 1
}
if [ -z "$(ls /etc/kubernetes/manifests/)" ];then
checkManifests
fi
function checkStatus () {
status=$?
if test $status -eq 0
then
echo "passed $1"
else
echo "failed $1"
exit 1
fi
}
archive="$(hostname)-$(date '+%F_%H%M%S').tar.gz"
backupdate="$1/backup/"
mkdir -p $backupdate/manifests
mkdir -p $backupdate/etcd
ETCDCTL_API=3 \
ETCDCTL_CACERT='/etc/kubernetes/pki/etcd/ca.crt' \
ETCDCTL_CERT='/etc/kubernetes/pki/etcd/server.crt' \
ETCDCTL_KEY='/etc/kubernetes/pki/etcd/server.key' \
ETCDCTL_ENDPOINTS='https://XX.XX.XX.XX:2379' \
/usr/local/bin/etcdctl snapshot save $backupdate/etcd/etcd.snapshot ;
checkStatus "etcd backup"
cp -r /etc/kubernetes/manifests/* $backupdate/manifests/
checkStatus "Create copies of static manifests"
echo "Manifests saved at $backupdate/manifests"
cp /etc/kubernetes/secrets_encryption.yaml $backupdate/etcd/ >/dev/null 2>&1
echo "Create copies of secrets_encryption.yaml"
echo "Archiving backup...."
tar -zcf $1/$archive $backupdate 2> /dev/null
checkStatus "archiving file"
echo "Backup archiving finished"
chmod 666 $1/$archive
echo "Backup archive is located in $1/archive"
find /tmp/ -name "*.tar.gz" -mtime +3 -delete
checkStatus "removing old backups"
echo Backup finished
exit 0
group: root
mode: "0755"
owner: root
path: /opt/etcdbackup.sh
type: file
- content: "30 18 * * * /opt/etcdbackup.sh /tmp/"
group: root
mode: "0600"
owner: root
path: /var/spool/cron/root
type: file
nodeconfigselector:
node-role.kubernetes.io/control-plane: ""
priority: 100
В результате успешного выполнения скрипта по расписанию для каждого Master-узла будет создана резервная копия ETCD.
Восстановить резервную копию ETCD
Чтобы восстановить из резервной копии ETCD, для каждого Master-узла необходимо выполнить restore
.
- На Master-узле переместите манифест пода с менем файла
kube-apiserver.yaml
изetc/kubernetes/manifests/
в другую папку, например,/root
, чтобы остановить работу API-сервера. После перемещения необходимо дождаться удаления пода.
Команда
# Перемещение пода в папку /root/
mv /etc/kubernetes/manifests/kube-apiserver.yaml /root/
# Получение информации о поде API-сервера
crictl ps | grep api
Скриншот
- Выполните восстановление из резервной копии ETCD.
Команда
export ETCDCTL_API=3
/usr/local/bin/etcdctl --data-dir /var/lib/etcd snapshot restore /tmp/backup/etcd/etcd.snapshot
Где вместо /var/lib/etcd
укажите каталог, который будет создан в процессе восстановления резервной копии ETCD, а вместо /tmp/backup/etcd/etcd.snapshot
путь до резервной копии. Обратите внимание! Если вы указываете каталог /var/lib/etcd
, удалите его до выполнения восстановления из резервной копии ETCD.
Скриншот
Обратите внимание! В случае восстановления ETCD на Master-узлах нового созданного кластера, необходимо восстановить secrets_encryption.yaml
из архива. Сохранение secrets_encryption.yaml
требуется для кластеров с расширенными параметрами безопасности (secure=true
).
Команда
cp status/backup/etcd/secrets_encryption.yaml /etc/kubernetes/
Где вместо status/backup/etcd/secrets_encryption.yaml
укажите путь, до сохраненного файла secrets_encryption.yaml
.
- Перезапустите под API-сервера, переместив файл
kube-apiserver.yaml
обратно вetc/kubernetes/manifests/
на узле.
Команда
mv /root/kube-apiserver.yaml /etc/kubernetes/manifests/
# Получение информации о поде API-сервера
crictl ps | grep api
Скриншот
Рекомендуется:
- Перезапустить
kube-scheduler
,kube-controller-manager
на Master-узлах. Поочередно переместите файлы с манифестами в папку root. Проверьте, что под удален, после чего верните манифест обратно в/etc/kubernetes/manifests/
.
Команда перезапуска kube-scheduler
# Перемещение пода в папку /root/
mv /etc/kubernetes/manifests/kube-scheduler.yaml /root/
# Получение информации о поде kube-scheduler. Дождитесь удаления пода
crictl ps | grep scheduler
# Возвращение пода kube-scheduler
mv /root/kube-scheduler.yaml /etc/kubernetes/manifests/
Команда перезапуска kube-controller-manager
# Перемещение пода в папку /root/
mv /etc/kubernetes/manifests/kube-controller-manager.yaml /root/
# Получение информации о поде kube-controller-manager. Дождитесь удаления пода
crictl ps | grep controller
# Возвращение пода kube-controller-manager
mv /root/kube-controller-manager.yaml /etc/kubernetes/manifests/
- Перезапустить
kubelet
.
Команда перезапуска kubelet
sudo systemctl restart kubelet
sudo systemctl status kubelet
Восстановление работы кластера ETCD с помощью etcd-helper
Восстановить работу кластера ETCD с помощью модуля etcd-helper
возможно только в высокодоступном кластере (HA).
- Установите пакет с модулем
etcd-helper
, содержащий утилитыedtcdctl
,etcdutl
,etcdhelper
.
Команда
yum install etcdhelper
Модуль etcd-helper
будет загружен в /usr/local/bin
.
Скриншот
- Чтобы выполнить запрос к кластеру ETCD, запустите
etcdctl
с необходимыми параметрами, с помощью командыetcdhelper exec
. Требуемые параметры будут получены из/etc/kubernetes/manifests/etcd.yaml
.
Команда
/usr/local/bin/etcdhelper exec -- member list -w table
Где параметр --
необходим для корректной передачи ключей в скрипте.
Скриншот
Восстановление недоступного узла кластера ETCD
Если IP-адрес и имя API-сервера не изменились, но на Master-узле повреждены данные, пересоздайте узел в кластере ETCD, выполнив команду etcdhelper rejoin
.
Команда
/usr/local/bin/etcdhelper rejoin
Скриншот
Обратите внимание! Если контейнер ETCD на узле в статусе Running, то команда etcdhelper rejoin
не может быть выполнена.
В результате выполнения команды произойдет:
- Удаление нерабочего узла из кластера ETCD.
- Остановка kubelet.
- Удаление контейнера ETCD.
- Переименование каталога с данными ETCD.
- Добавление нового узла в кластер ETCD.
- Запуск kubelet.
Восстановление при изменении IP-адреса Master-узла
Если IP-адрес одного из Master-узлов изменен, то восстановите работу кластера ETCD, использовав команду etcdhelper ip
.
Команда
/usr/local/bin/etcdhelper ip --nodeip=10.11.16.11
Где вместо 10.11.16.11
укажите новый IP-адрес узла.
Скриншот
В результате команды будет выполнено:
- Резервное копирование манифестов и сертификатов.
- Изменен IP-адрес узла в манифестах.
- Удалены сертификаты ETCD, за исключением сертификата CA.
- Сгенерированы сертификаты, в том числе для API-сервера.
- Изменен IP-адрес узла в кластере ETCD.
Восстановление при изменении IP-адресов всех Master-узлов
Для восстановления работоспособности кластера etcd выполните последовательно действия:
- На первом Master-узле выполните команду для подготовки конфигурации после смены IP:
Команда
etcdhelper prepare --nodeip=НОВЫЙ IP адрес
-
Добавьте опцию
--force-new-cluster
в манифест/etc/kubernetes/manifests/etcd.yaml
. -
Перезагрузите первый узел.
-
Отредактируйте запись об узле в кластере etcd:
Команда
etcdhelper exec – member list - посмотреть id ноды
etcdhelper exec – member update ID --peer-urls=https://НОВЫЙ_IP:2380
- Удалите опцию
--force-new-cluster
из манифеста/etc/kubernetes/manifests/etcd.yaml
. - Перезагрузите первый узел.
- Убедитесь, что клстер kubernetes работает.
- Удалите оставшиеся Master-узлы из кластера:
Команда
kubectl get node (ноды в статусе NotReady)
kubectl delete node ИМЯ_НОДЫ
- Получите токен для добавления хостов в кластер
Команда
kubeadm token list
Команда
etcdhelper kuberrejoin --token=ТОКЕН