Резервное копирование и восстановление работы 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 в сетевой файловой системе не на Master-узлах, а, например, /nfs/share. Это может быть полезным в случае недоступности Master-узлов.
Пример конфигурации запуска
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

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

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

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

  1. На Master-узле переместите манифест пода с менем файла 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 на 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.

  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 на 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.

Скриншот

etcdinstall

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

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

Скриншот

etcdexec1

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

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

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

etcdrejoin

Обратите внимание! Если контейнер 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-адрес узла.

Скриншот

etcdip1

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

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

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

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

  1. На первом Master-узле выполните команду для подготовки конфигурации после смены IP:
Команда
etcdhelper prepare --nodeip=НОВЫЙ IP адрес
  1. Добавьте опцию --force-new-cluster в манифест /etc/kubernetes/manifests/etcd.yaml.

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

  3. Отредактируйте запись об узле в кластере etcd:

Команда
etcdhelper exec – member list - посмотреть id ноды

etcdhelper exec – member update ID --peer-urls=https://НОВЫЙ_IP:2380
  1. Удалите опцию --force-new-cluster из манифеста /etc/kubernetes/manifests/etcd.yaml.
  2. Перезагрузите первый узел.
  3. Убедитесь, что клстер kubernetes работает.
  4. Удалите оставшиеся Master-узлы из кластера:
Команда
kubectl get node (ноды в статусе NotReady)

kubectl delete node ИМЯ_НОДЫ
  1. Получите токен для добавления хостов в кластер
Команда
kubeadm token list
10. Добавьте оставшиеся Master-узлы в кластер:
Команда
etcdhelper kuberrejoin --token=ТОКЕН
×