Из резервной копии ETCD

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

Создать резервную копию 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
×