Featured image of post Установка Velero в Kubernetes

Установка Velero в Kubernetes

Бэкап ресурсов кубернетес с помощью Velero

Velero - это программное обеспечение с открытым исходным кодом, предназначенное для создания резервных копий, восстановления после сбоев и миграции ресурсов Kubernetes-кластера, включая постоянные хранилища (PV). Решение входит в экосистему продуктов VMware — VMware Tanzu, ориентированных на использование в production-среде и упрощающих автоматизацию администрирования Kubernetes-кластеров. Velero распространяется по лицензии Apache License 2.0.

Созданные резервные копии могут применяться для миграции инфраструктуры, восстановления состояния кластера на определённый момент времени, а также для клонирования тестовых или рабочих окружений.

Процесс установки и эксплуатации Velero относительно простой, однако при его использовании необходимо учитывать несколько особенностей. В частности, Velero сохраняет резервные копии манифестов в S3-совместимом хранилище. Для этого можно использовать как облачный S3-bucket, так и развернуть собственное хранилище, например MinIO.

Требования:

  • Готовый кластер k8s
  • Minio хранилище или Ceph
  • Docker или nerdctl
  • Установлен Helm
  • Репозиторий образов и Helm чартов: Harbor

Задача:

  • Развернуть средство для бэкапирования на базе “Velero”
  • Настроить расписание автоматического создания бэкапов

Как я вижу архитектуру резервного копирования для кластера Kubernetes в текущем гайде:

Шаг 1. Онлайн установка Velero

Здесь всё просто и нетривиально. Настраиваете свой S3 например MinIO.

1
2
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update

Создаём файл с переменными:

1
nano velero-values.yaml

Передаёте в файле переменных имя бакета, адрес сервера с MinIO, токен

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
credentials:
  useSecret: true
  secretContents:
    cloud: |
      [default]
      aws_access_key_id=Keyid_ot_Minio
      aws_secret_access_key=Access_ot_Minio
configuration:
  backupStorageLocation:
    - name: default
      provider: aws
      bucket: velero
      default: true
      accessMode: ReadWrite
      config:
        region: minio
        s3ForcePathStyle: "true"
        s3Url: https://s3.minio.domain.local
        # если MinIO с самоподписанным TLS и ты не хочешь CA можно так:
        # insecureSkipTLSVerify: "true"
	  # Если есть ЦА СЮДА добавить строку если нет удалить и активировать верхний параметр insecureSkipTLSVerify
      caCert: LS0tLS1CRUdJTiBDRVJ.......................................
  volumeSnapshotLocation: []
# Чтобы бэкапить содержимое PVC включаем node-agent daemonset
deployNodeAgent: true
nodeAgent:
  disableHostPath: false
  podVolumePath: /var/lib/kubelet/pods
  pluginVolumePath: /var/lib/kubelet/plugins

И запускаете установку

1
helm install velero vmware-tanzu/velero -n velero --create-namespace -f velero-values.yaml

Шаг 2. Оффлайн установка Velero

В данном сценарии мы самостоятельно загрузим каждый образ в наш приватный репозиторий на основе Harbor.

1
2
3
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm repo update
helm pull vmware-tanzu/velero --untar

Переходим в директорию:

1
cd velero

Выгружаем список образов:

1
helm template velero ../velero -f values.yaml > rendered.yaml

Выгружаем образы в файл:

1
2
grep image: rendered.yaml | awk '{print $2}' | sort -u > velero-images.txt
grep -oE 'image:\s*"?[^"]+' rendered.yaml | sed -E 's/^image:\s*"?//; s/"$//' | sort -u > velero-images.txt

Также нужно забрать плагин для работы с нашим Minio S3
Актуальную версию можно узнать так:

1
cat values.yaml | grep velero/velero-plugin-for-aws

Вывод:

1
  #   image: velero/velero-plugin-for-aws:v1.13.1

Открываем файл:

1
nano velero-images.txt

Добавить строку. У вас тег будет свой:

1
docker.io/velero/velero-plugin-for-aws:v1.13.1

Выкачиваем:

1
2
3
for img in $(cat velero-images.txt); do
  docker pull $img
done

Сохраняем:

1
docker save -o velero-images.tar $(cat velero-images.txt)

Упаковываем HELM чарт:

1
2
cd ~
tar -cvf velero.tgz velero

Переносим в закрытый контур.

Шаг 2.1. Загрузка пакетов в приватный репозиторий

Распаковываем:

1
tar -xvf /home/admin/velero.tgz

Достать архив с образами:

1
2
mv velero/cm-images.txt ./
mv velero/velero.tgz ./

Удаляем мусор:

1
rm velero/rendered.yaml

Упаковываем чарт:

1
2
helm package ./velero -d .
helm push velero-*.tgz oci://harbor.domain.local/helm

Загрузить образы:

1
sudo docker load -i velero-images.tar

Далее я создал проект с именем platform в Harbor.

Изменяйте имя репозитория и проект в переменных на свои:

1
2
3
4
5
6
7
8
9
export HARBOR="harbor.domain.local"
export PROJECT="platform"
docker login ${HARBOR}

while read -r img; do
  new="${HARBOR}/${PROJECT}/${img}"
  docker tag "${img}" "$new"
  docker push "$new"
done < velero-images.txt

Создаём ns и секрет, если Harbor с авторизацией. Если нет, то пропускаем:

1
2
3
4
5
6
kubectl create ns velero
kubectl -n velero create secret docker-registry harbor-pull \
  --docker-server=harbor.k8s.domain.local \
  --docker-username='<USER>' \
  --docker-password='<PASS>' \
  --docker-email='devnull@example.com'

Шаг 2.2. Настройка Minio хранилища

В Minio создаём пользователя с именем velero-s3 и токен, если они ещё не созданы и bucker с именем velero-backup

Полученный токен и ключ будем использовать далее в файле.

Если хотите использовать Minio внутри кубернетес через https, то преобразуйте сертификат от ЦА, которым подписан MinIO в Base64:

1
cat ca.crt | base64 -w0

Получится строка вида:

1
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...

И добавьте в строку в файле:

1
nano velero-values.yaml

Файл с переменными:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
image:
  repository: harbor.domain.local/platform/docker.io/velero/velero
  imagePullSecrets:
    - harbor-pull
kubectl:
  image:
    repository: harbor.domain.local/platform/docker.io/bitnamilegacy/kubectl
    tag: "1.33"
initContainers:
  - name: velero-plugin-for-aws
    image: harbor.domain.local/platform/docker.io/velero/velero-plugin-for-aws:v1.13.1
    volumeMounts:
      - mountPath: /target
        name: plugins
credentials:
  useSecret: true
  # создаст secret внутри velero namespace с ключом "cloud" :contentReference[oaicite:6]{index=6}
  # Полученный ранее токен от MinIO вставляем здесь в aws...
  secretContents:
    cloud: |
      [default]
      aws_access_key_id=Keyidddddddddd_ot_Minio
      aws_secret_access_key=Accesskeyyyy_ot_Minio
configuration:
  backupStorageLocation:
    - name: default
      provider: aws
      bucket: velero
      default: true
      accessMode: ReadWrite
      config:
        region: minio
        s3ForcePathStyle: "true"
        s3Url: https://s3.minio.domain.local
        # если MinIO с самоподписанным TLS и ты не хочешь CA можно так:
        # insecureSkipTLSVerify: "true"
	  # Если есть ЦА СЮДА добавить строку если нет удалить и активировать верхний параметр insecureSkipTLSVerify
      caCert: LS0tLS1CRUdJTiBDRVJ.......................................
  volumeSnapshotLocation: []
# Чтобы бэкапить содержимое PVC включаем node-agent daemonset
deployNodeAgent: true
nodeAgent:
  disableHostPath: false
  podVolumePath: /var/lib/kubelet/pods
  pluginVolumePath: /var/lib/kubelet/plugins

Шаг 2.3. Запускаем Offline установку Velero

1
helm install velero oci://harbor.domain.local/helm/velero -n velero --create-namespace -f velero-values.yaml

После того, как поды поднялись проверяем синхронизацию с Minio:

1
kubectl -n velero get backupstoragelocation

Ожидаем:

1
2
NAME      PHASE       LAST VALIDATED   AGE   DEFAULT
default   Available   19s              26m   true

Если недоступен, то смотрим ошибки здесь:

1
kubectl -n velero describe backupstoragelocation default

И можно посмотреть логи:

1
kubectl logs deployment/velero -n velero.

Шаг 3. Тестовый бэкап

Создаём файл:

1
nano test-ns.yaml

Внутри создаём тестовый namespace и configmap:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: v1
kind: Namespace
metadata:
  name: velero-test
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: velero-test-config
  namespace: velero-test
data:
  test: "ok"
  owner: "velero"
  note: "restore-me"

Применяем и смотрим что создался Namespace:

1
2
kubectl apply -f test-ns.yaml
kubectl -n velero-test get configmap

Создаём файл бэкапа:

1
nano backup-test.yaml

Указываем имя бэкапа и namespace, который будем бэкапить:

1
2
3
4
5
6
7
8
9
apiVersion: velero.io/v1
kind: Backup
metadata:
  name: velero-test-backup
  namespace: velero
spec:
  includedNamespaces:
    - velero-test
  ttl: 24h0m0s

Применяем:

1
kubectl apply -f backup-test.yaml

Проверяем, чтобы статус создания бэкапа был Completed

1
kubectl -n velero get backups.velero.io velero-test-backup -o jsonpath='{.status.phase}{"\n"}'

Удаляем Namespace

1
kubectl delete ns velero-test

Дожидаемся удаления и проверяем

1
kubectl get ns velero-test

Создаём файл запроса восстановления:

1
nano test-restore.yaml

И восстанавливаем из бэкапа:

1
2
3
4
5
6
7
apiVersion: velero.io/v1
kind: Restore
metadata:
  name: velero-test-restore
  namespace: velero
spec:
  backupName: velero-test-backup

Применяем:

1
kubectl apply -f test-restore.yaml

Проверяем:

1
2
kubectl get ns velero-test
kubectl -n velero-test get configmap

Тест можно считать успешным, если:

  • backup velero-test-backup перешёл в Completed
  • namespace velero-test удалился
  • после restore namespace velero-test появился снова
  • ConfigMap velero-test-config вернулся

Шаг 4. Пример задания (cronjob) на бэкап

Для начала должны быть включены node-agent без них не будут бэкапиться PVC с нод. Это мы сделали при первоначальной установке Velero.

1
kubectl -n velero get pods

Создаём задание на бэкапирование:

1
nano prom-graf-backup.yaml

Каждый день в 2 часа ночи создавать бэкап namespace Monitoring в котором у меня живут Promethues, Grafana, Alertmanager со всеми PVC данными и хранить 7 дней. Прописываю это в файле

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: prom-graf-daily
  namespace: velero
spec:
  schedule: "0 2 * * *"
  template:
    includedNamespaces:
      - monitoring
    defaultVolumesToFsBackup: true
    ttl: 168h

Применяем:

1
kubectl apply -f prom-graf-backup.yaml

Проверка:

1
kubectl -n velero get schedules

Ожидаем:

Готово. Задание на бэкапы создано. Установка и настройка Velero завершены

Информацию можно использовать в свободном доступе, с указанием ссылки на сайт
Telegram GitHub YouTube