Резервное копирование и восстановление работы ETCD

Создать резервную копию ETCD

В платформе “Штурвал” вы можете создать резервную копию ETCD с помощью объекта NCI. Резервное копирование данных кластера ETCD может понадобиться для восстановления кластера. Рекомендуется выполнять резервное копирования в период наименьшей нагрузки на кластер.

  1. Подготовьте скрипт для резервного копирования, например, с именем 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

  1. В графическом интерфейсе кластера откройте страницу Конфигурация узлов раздела Администрирование, нажмите + Добавить NCI. На странице добавления NCI:
  • Задайте имя, например, etcdbackup и в селекторе узлов из выпадающего списка выберите ключ лейбла node-role.kubernetes.io/control-plane. Значение для лейбла не устанавливайте.
  • В блоке Настраиваемые разделы выберите Файлы и директории и Пакеты для установки, нажмите Продолжить.
Скриншот

etcdnci1

  • В открывшемся окне на шаге конфигурации раздела Пакеты для установки нажмите + и укажите пакет etcdhelper, выберите целевое состояние пакета Present.
Скриншот

etcdp etcdp2

  • Нажмите Добавить и затем Продолжить, чтобы перейти к разделу Файлы и директории.
  • На шаге Файлы и директории нажмите + и в поле Путь к файлу или директории пропишите путь до создаваемого файла со скриптом резервного копирования. В типе файла/директории должно быть выбрано Файл.
  • В поле права доступа укажите необходимые права, например, 0755, что обеспечит владельцу полный доступ к файлу, группе владельца другим пользователям доступ на чтение и выполнение. Владелец и группа должны быть root.
  • В поле Содержимое файла вставьте содержимое подготовленного скрипта из файла etcdbackup.sh, нажмите Добавить.
Скриншот

etcdsh4 etcdsh5

  • Нажмите + и в поле Путь к файлу или директории пропишите путь до файла с расписанием запуска резервного копирования.
  • В поле права доступа укажите необходимые права, например, 0600, что обеспечит правами только владельца файла на чтение и запись. Владелец и группа должны быть root.
  • В поле Содержимое файла укажите конфигурацию запуска резервного копирования: расписание в cron формате, путь до файла со скриптом и путь до создаваемой резервной копии ETCD. В поле Содержимое файла после записи конфигурации запуска требуется выполнить перенос строки.
  • Нажмите Добавить. Обратите внимание! Рекомендуется хранить резервную копию ETCD в сетевой файловой системе не на Control Plane узлах, а, например, /nfs/share. Это может быть полезным в случае недоступности Control Plane узлов.
Пример конфигурации запуска
30 18 * * * /opt/etcdbackup.sh /tmp/
Скриншот

etcdcron3 etcdcron4

  • Нажмите Завершить.
Пример 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

В результате успешного выполнения скрипта по расписанию для каждого Control Plane узла будет создана резервная копия ETCD.

Восстановить резервную копию ETCD

Чтобы восстановить из резервной копии ETCD, для каждого Control Plane узла необходимо выполнить restore.

  1. На Control Plane узле переместите манифест пода с менем файла kube-apiserver.yaml из etc/kubernetes/manifests/ в другую папку, например, /root, чтобы остановить работу API-сервера. После перемещения необходимо дождаться удаления пода.
Команда
# Перемещение пода в папку /root/
mv /etc/kubernetes/manifests/kube-apiserver.yaml  /root/
# Получение информации о поде API-сервера
crictl ps | grep api
Скриншот

etcdapi

  1. Выполните восстановление из резервной копии 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.

Скриншот

etcdrestore

Обратите внимание! В случае восстановления ETCD на Control Plane узлах нового созданного кластера, необходимо восстановить 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.

  1. Перезапустите под API-сервера, переместив файл kube-apiserver.yaml обратно в etc/kubernetes/manifests/ на узле.
Команда
mv /root/kube-apiserver.yaml /etc/kubernetes/manifests/
# Получение информации о поде API-сервера
crictl ps | grep api
Скриншот

etcdapi2

Рекомендуется:

  • Перезапустить kube-scheduler, kube-controller-manager на Control Plane узлах. Поочередно переместите файлы с манифестами в папку 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.

Скриншот

etcdinstall

  • Чтобы выполнить запрос к кластеру ETCD, запустите etcdctl с необходимыми параметрами, с помощью команды etcdhelper exec. Требуемые параметры будут получены из /etc/kubernetes/manifests/etcd.yaml.
Команда
/usr/local/bin/etcdhelper exec -- member list -w table

Где параметр -- необходим для корректной передачи ключей в скрипте.

Скриншот

etcdexec1

Восстановление недоступного узла кластера ETCD

Если IP-адрес и имя API-сервера не изменились, но на Control Plane узле повреждены данные, пересоздайте узел в кластере ETCD, выполнив команду etcdhelper rejoin.

Команда
/usr/local/bin/etcdhelper rejoin
Скриншот

etcdrejoin

Обратите внимание! Если контейнер ETCD на узле в статусе Running, то команда etcdhelper rejoin не может быть выполнена.

В результате выполнения команды произойдет:

  • Удаление нерабочего узла из кластера ETCD.
  • Остановка kubelet.
  • Удаление контейнера ETCD.
  • Переименование каталога с данными ETCD.
  • Добавление нового узла в кластер ETCD.
  • Запуск kubelet.

Восстановление при изменении IP-адреса Control Plane узла

Если IP-адрес одного из Control Plane узлов изменен, то восстановите работу кластера ETCD, использовав команду etcdhelper ip.

Пример команды
 /usr/local/bin/etcdhelper ip --nodeip=ВВЕДИТЕ-НОВЫЙ-IP-АДРЕС-УЗЛА
Скриншот

etcdip1

В результате команды будет выполнено:

  • Резервное копирование манифестов и сертификатов.
  • Изменен IP-адрес узла в манифестах.
  • Удалены сертификаты ETCD, за исключением сертификата CA.
  • Сгенерированы сертификаты, в том числе для API-сервера.
  • Изменен IP-адрес узла в кластере ETCD.

Восстановление при изменении IP-адресов всех Control Plane узлов

Для восстановления работоспособности кластера etcd выполните последовательно действия:

  1. На первом Control Plane узле запустите команду для подготовки конфигурации, использовав свои значения параметров:
Пример команды
/usr/local/bin/etcdhelper prepare --nodeip=ВВЕДИТЕ-НОВЫЙ-IP-АДРЕС-УЗЛА
  1. В манифест /etc/kubernetes/manifests/etcd.yaml добавьте опцию --force-new-cluster.

  2. Перезагрузите первый Control Plane узел.

    1. Отредактируйте запись об узле в кластере etcd.
Пример команды
# Посмотреть ID узла
/usr/local/bin/etcdhelper exec -- member list -w table
# Обновить запись об узле 
/usr/local/bin/etcdhelper exec -- member update ВВЕДИТЕ-ID-УЗЛА --peer-urls=https://ВВЕДИТЕ-НОВЫЙ-IP-АДРЕС-УЗЛА:2380
  1. Удалите опцию --force-new-cluster из манифеста /etc/kubernetes/manifests/etcd.yaml.

  2. Перезагрузите первый узел.

  3. Убедитесь, что кластер kubernetes работает.

  4. При восстановлении кластера управления убедитесь, что все поды в неймспейсе shturval-backend запущены. Если shturval-backend-redis или shturval-backend-valkey не запущены, выполните принудительное удаление для перезапуска.

  5. При восстановлении кластера (клиентского, управления) с провайдером Shturval v2, подготовьте новые хосты и добавьте их в экземпляр провайдера.

  6. В графическом интерфейсе кластера откройте раздел Администрирование и перейдите на страницу Управление узлами, нажмите на Конфигурация группы Control Plane. На вкладке Конфигурация ClusterAPI установите 1 в поле Запрошено реплик.

Примеры команд для применения в интерфейсе командной строки
# Изменить количество реплик в KubeadmControlPlane 
kubectl edit KubeadmControlPlane -n ИМЯ-КЛАСТЕРА ИМЯ-КЛАСТЕРА-control-plane  

В spec KubeadmControlPlane установите значение 1 для параметра `replicas.

  1. Вернитесь на страницу Управление узлами и скопируйте имена узлов в статусе NotReady.
Пример команды для применения в интерфейсе командной строки
# Получить имена узлов кластера
kubectl get node
  1. Получите список Machines и удалите Machines, соответствующие Control Plane узлам в статусе NotReady.
Примеры команд
# Получить все Machines кластера
kubectl get machines -n ИМЯ-КЛАСТЕРА
# Удалить поочередно Machines, соответствующие Control Plane узлам в статусе `NotReady`
kubectl delete machines -n ИМЯ-КЛАСТЕРА ИМЯ-MACHINE

Удаление занимает некоторое время. В результате будут удалены Machines, узлы и ВМ, если кластер развернут с провайдером отличным от Shturval v2.

Обратите внимание! В случае длительного удаления, например, более 15 минут, вы можете удалить Machines ручным способом:

  • Отредактируйте удаляемый ресурс Machine, удалив finalizer.
  • Удалите узел из кластера и ВМ в платформе виртуализации.
  1. Когда удалены все Machines, в графическом интерфейсе кластера откройте раздел Администрирование и перейдите на страницу Управление узлами, нажмите на Конфигурация группы Control Plane. На вкладке Конфигурация ClusterAPI установите 3 в поле Запрошено реплик.
Примеры команд для применения в интерфейсе командной строки
# Изменить количество реплик в KubeadmControlPlane
kubectl edit KubeadmControlPlane -n ИМЯ-КЛАСТЕРА ИМЯ-КЛАСТЕРА-control-plane  

В spec KubeadmControlPlane установите значение 3 для параметра `replicas.

×