• Русский
  • Официальное резервное копирование и восстановление GitLab

    Это решение основано на официальном подходе GitLab к резервному копированию и восстановлению. Для подробной информации обратитесь к официальной документации GitLab.

    Применимость

    Это решение применимо только к экземплярам GitLab версии 17.8 и выше, которые настроены с использованием object storage.

    Если ваш экземпляр GitLab не настроен с object storage, GitLab предоставляет решение для миграции данных. Вы можете сначала использовать это решение для миграции данных, а затем применять данное решение для резервного копирования и восстановления.

    Как проверить, настроен ли Object Storage
    export GITLAB_NAMESPACE=<namespace экземпляра GitLab для резервного копирования>
    export GITLAB_NAME=<имя экземпляра GitLab для резервного копирования>
    
    kubectl get gitlabofficial ${GITLAB_NAME} -n ${GITLAB_NAMESPACE} -o jsonpath='{.spec.helmValues.global.appConfig.object_store}'
    
    # Вывод:
    # {"connection":{"key":"connection","secret":"gitlab-rails-storage"},"enabled":true}

    Если поле enabled равно true, а поле connection не пустое, это означает, что для экземпляра настроен object storage.

    Терминология

    ТерминОпределение
    Source InstanceЭкземпляр GitLab до резервного копирования
    Target InstanceЭкземпляр GitLab после восстановления
    Source NamespaceNamespace, в котором расположен исходный экземпляр
    Target NamespaceNamespace, в котором расположен целевой экземпляр
    GitLab CR ResourceОписывает конфигурацию развертывания экземпляра GitLab, используется Operator для развертывания экземпляров GitLab

    Предварительные требования

    1. Развернуть MinIO Object Storage: официальное решение резервного копирования и восстановления использует object storage для сохранения данных резервных копий, поэтому требуется предварительно развернутый экземпляр MinIO. ACP предоставляет MinIO Object Storage для быстрого создания экземпляра MinIO.
    2. Установить командную утилиту mc: mc — это командная утилита MinIO для управления экземплярами MinIO. Инструкции по установке смотрите в официальной документации MinIO.
    3. Установить командную утилиту kubectl: kubectl — это командная утилита Kubernetes для управления кластерами Kubernetes. Инструкции по установке смотрите в официальной документации Kubernetes.

    Для удобства последующих операций сначала задайте переменные окружения:

    export MINIO_HOST=<адрес доступа к экземпляру MinIO> # Пример: http://192.168.1.100:32008
    export MINIO_ACCESS_KEY=<ключ доступа к экземпляру MinIO> # Пример: minioadmin
    export MINIO_SECRET_KEY=<секретный ключ экземпляра MinIO> # Пример: minioadminpassword
    export MINIO_ALIAS_NAME=<псевдоним экземпляра MinIO> # Пример: myminio
    
    export GITLAB_NAMESPACE=<namespace экземпляра GitLab для резервного копирования>
    export GITLAB_NAME=<имя экземпляра GitLab для резервного копирования>

    Выполните следующие команды для настройки утилиты mc и проверки соединения:

    mc alias set ${MINIO_ALIAS_NAME} ${MINIO_HOST} ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY}
    mc ping ${MINIO_ALIAS_NAME}
    
    # Вывод:
    #   1: http://192.168.131.56:32571:32571   min=98.86ms    max=98.86ms    average=98.86ms    errors=0   roundtrip=98.86ms 
    #   2: http://192.168.131.56:32571:32571   min=29.57ms    max=98.86ms    average=64.21ms    errors=0   roundtrip=29.57ms 
    #   3: http://192.168.131.56:32571:32571   min=29.57ms    max=98.86ms    average=52.77ms    errors=0   roundtrip=29.88ms 

    Если ping к экземпляру MinIO прошёл успешно, значит mc настроен корректно.

    Резервное копирование

    Предварительные требования

    Создание бакетов

    Необходимо создать два бакета:

    1. Бакет для хранения данных резервной копии, с именем: gitlab-backups
    2. Бакет для хранения временных данных во время резервного копирования, с именем: gitlab-backups-tmp

    Выполните следующие команды для создания бакетов:

    mc mb ${MINIO_ALIAS_NAME}/gitlab-backups
    mc mb ${MINIO_ALIAS_NAME}/gitlab-backups-tmp
    
    # Вывод:
    # Bucket created successfully `myminio/gitlab-backups`.
    # Bucket created successfully `myminio/gitlab-backups-tmp`.

    Выполните следующую команду, чтобы проверить успешное создание бакетов:

    mc ls ${MINIO_ALIAS_NAME} | grep gitlab-backups
    
    # Вывод:
    # [2025-06-30 11:58:09 CST]     0B gitlab-backups/
    # [2025-06-30 11:58:13 CST]     0B gitlab-backups-tmp/

    Резервное копирование вручную

    Развертывание компонента toolbox

    Для выполнения официального резервного копирования GitLab необходимо запускать команду резервного копирования внутри toolbox pod. В процессе резервного копирования файлы будут загружаться в object storage. Поэтому заранее нужно подготовить конфигурационный файл object storage. Выполните следующий скрипт для генерации необходимого конфигурационного файла:

    set -e
    
    if [[ -z "${GITLAB_NAMESPACE}" ]]; then
        echo "GITLAB_NAMESPACE не установлен, пожалуйста, установите его и повторите попытку"
        exit 1
    fi
    
    CLEAN_HOST=${MINIO_HOST#http://}
    CLEAN_HOST=${CLEAN_HOST#https://}
    use_https="False"
    if [[ $MINIO_HOST == https://* ]]; then
        use_https="True"
    fi
     
    CONFIG_DATA=$(cat << EOF
    [default]
    host_base = ${CLEAN_HOST}
    host_bucket = ${CLEAN_HOST}/%(bucket)
    access_key = ${MINIO_ACCESS_KEY}
    secret_key = ${MINIO_SECRET_KEY}
    bucket_location = us-east-1
    use_https = ${use_https}
    EOF
    )
    
    kubectl create secret generic s3cfg \
        -n ${GITLAB_NAMESPACE} \
        --from-literal=config="$CONFIG_DATA"
    
    # Вывод:
    # secret/s3cfg создан

    Выполните следующую команду в кластере, где расположен GitLab, чтобы отредактировать CR экземпляра GitLab:

    kubectl edit gitlabofficial ${GITLAB_NAME} -n ${GITLAB_NAMESPACE}

    Сначала отредактируйте следующий yaml-конфиг согласно комментариям, затем добавьте его в CR:

    spec:
      helmValues:
        global:
          appConfig:
            backups:
              # Имена этих двух бакетов должны совпадать с именами бакетов, созданных на предыдущих шагах
              bucket: gitlab-backups
              tmpBucket: gitlab-backups-tmp
        gitlab:
          toolbox:
            backups:
              objectStorage:
                config:
                  key: config
                  # Имя секрета, созданного на предыдущем шаге
                  secret: s3cfg
            enabled: true
            persistence:
              accessMode: ReadWriteMany
              enabled: true
              # Резервное копирование требует локальной упаковки всех файлов, поэтому необходимо достаточное пространство
              # Размер PVC определяйте исходя из занятого места на диске экземпляра
              size: 10Gi
              # Имя класса хранилища
              storageClass: nfs

    После обновления CR GitLab автоматически развернёт новый компонент toolbox. Используйте следующую команду, чтобы проверить успешность развертывания компонента toolbox:

    kubectl get pod -n ${GITLAB_NAMESPACE} | grep toolbox
    
    # Вывод:
    # xx-gitlab-toolbox-6f578f6b-f7wlw                 1/1     Running       0          4h11m

    Если статус pod — Running, значит компонент toolbox успешно развернут.

    Выполнение резервного копирования

    Используйте следующую команду, чтобы войти в терминал pod toolbox:

    export TOOLBOX_POD_NAME=$(kubectl get pod -n ${GITLAB_NAMESPACE} | grep ${GITLAB_NAME}-toolbox | awk '{print $1}')
    kubectl exec -it ${TOOLBOX_POD_NAME} -n ${GITLAB_NAMESPACE} -- bash

    Выполните резервное копирование:

    cd ~/; nohup backup-utility > output.log 2>&1 &

    Процесс резервного копирования занимает некоторое время, используйте следующую команду для просмотра лога резервного копирования и контроля прогресса:

    cd ~/; tail -f output.log
    
    # Вывод:
    # Bucket not found: gitlab-packages. Skipping backup of packages ...
    # Bucket not found: gitlab-mr-diffs. Skipping backup of external_diffs ...
    # Bucket not found: gitlab-terraform-state. Skipping backup of terraform_state ...
    # Bucket not found: gitlab-pages. Skipping backup of pages ...
    # Bucket not found: gitlab-ci-secure-files. Skipping backup of ci_secure_files ...
    # Packing up backup tar
    # WARNING: Module python-magic is not available. Guessing MIME types based on file extensions.
    # [DONE] Backup can be found at s3://gitlab-backups/1751272314_2025_06_30_17.11.4_gitlab_backup.tar

    Когда программа завершится успешно, процесс резервного копирования будет завершён.

    ID резервной копии

    Имя файла резервной копии генерируется динамически на основе времени резервного копирования и информации о версии, например 1751272314_2025_06_30_17.11.4_gitlab_backup.tar. 1751272314_2025_06_30_17.11.4 — уникальный идентификатор (backup ID) этой резервной копии. При выполнении операции восстановления необходимо указать соответствующий backup ID.

    Плановое резервное копирование

    Плановое резервное копирование GitLab выполняется через компонент toolbox. В отличие от ручного резервного копирования, плановое использует Crontab для реализации периодического резервного копирования.

    Выполните следующую команду в кластере, где расположен GitLab, чтобы отредактировать CR экземпляра GitLab:

    kubectl edit gitlabofficial ${GITLAB_NAME} -n ${GITLAB_NAMESPACE}

    Сначала отредактируйте следующий yaml-конфиг согласно комментариям, затем добавьте его в CR:

    spec:
      helmValues:
        global:
          appConfig:
            backups:
              # Имена этих двух бакетов должны совпадать с именами бакетов, созданных на предыдущих шагах
              bucket: gitlab-backups
              tmpBucket: gitlab-backups-tmp
        gitlab:
          toolbox:
            enabled: true
            backups:
              cron:
                enabled: true
                # Настройка цикла резервного копирования
                schedule: "0 1 * * *"
                persistence:
                  enabled: true
                  accessMode: ReadWriteMany
                  # Резервное копирование требует упаковки всех файлов в pod toolbox, поэтому необходимо достаточное пространство
                  # Размер PVC определяйте исходя из занятого места на диске экземпляра
                  size: 10Gi
                  # Имя класса хранилища
                  storageClass: nfs
              objectStorage:
                config:
                  key: config
                  # Имя секрета, созданного на предыдущем шаге
                  secret: s3cfg
    Как настроить цикл резервного копирования

    Правило Crontab состоит из пяти временных полей, разделённых пробелами, слева направо:

    • Минуты (Minute): в какую минуту часа выполнять задачу, диапазон 0-59
    • Часы (Hour): в какой час дня выполнять задачу, диапазон 0-23
    • День месяца (Day of the month): в какой день месяца выполнять задачу, диапазон 1-31
    • Месяц (Month): в каком месяце года выполнять задачу, диапазон 1-12 (можно использовать сокращённые названия месяцев, например Jan, Feb, Mar и т.д.)
    • День недели (Day of the week): в какой день недели выполнять задачу, диапазон 0-7 (0 и 7 оба означают воскресенье, 1 — понедельник и так далее. Можно использовать сокращённые названия дней недели, например Sun, Mon, Tue и т.д.)

    Примеры:

    1. Выполнять каждый день в 3:00: 0 3 * * *
    2. Выполнять в 3:00 1-го и 15-го числа каждого месяца: 0 3 1,15 * *
    3. Выполнять каждые 10 минут: */10 * * * *

    Дождитесь, пока GitLab выполнит резервное копирование, затем вы можете проверить файлы резервной копии.

    Проверка файлов резервной копии

    Выполните следующую команду, чтобы проверить, были ли файлы резервной копии загружены в object storage:

    mc ls ${MINIO_ALIAS_NAME}/gitlab-backups
    
    # Вывод:
    # [2025-06-30 16:33:18 CST] 570KiB STANDARD 1751272314_2025_06_30_17.8.5_gitlab_backup.tar
    # [2025-06-30 18:19:26 CST] 570KiB STANDARD 1751278684_2025_06_30_17.8.5_gitlab_backup.tar

    Если вы видите список файлов резервных копий, значит резервное копирование прошло успешно.

    Восстановление

    Предварительные требования

    Выбор резервной копии для восстановления

    Используйте команду mc для получения списка файлов резервных копий:

    mc ls ${MINIO_ALIAS_NAME}/gitlab-backups
    
    # Вывод:
    # [2025-06-30 16:33:18 CST] 570KiB STANDARD 1751272314_2025_06_30_17.8.5_gitlab_backup.tar
    # [2025-06-30 18:19:26 CST] 570KiB STANDARD 1751278684_2025_06_30_17.8.5_gitlab_backup.tar

    Исходя из даты в имени файла резервной копии, выберите нужную для восстановления и скопируйте backup ID из имени файла, например 1751272314_2025_06_30_17.11.4.

    Определение метода восстановления экземпляра GitLab

    Существует два варианта восстановления:

    1. Восстановление непосредственно на исходном экземпляре, что перезапишет данные экземпляра данными из резервной копии
    2. (Рекомендуется) Развернуть новый экземпляр для восстановления данных, при этом новый экземпляр должен соответствовать следующим требованиям:
      1. Новый экземпляр должен иметь включённый object storage
      2. Новый экземпляр должен развернуть компонент toolbox и настроить конфигурацию object storage так же, как в исходном экземпляре

    Операции восстановления

    WARNING

    Все последующие операции выполняются на целевом экземпляре.

    Сначала задайте следующие переменные окружения:

    export NEW_GITLAB_NAMESPACE=<namespace нового экземпляра GitLab>
    export NEW_GITLAB_NAME=<имя нового экземпляра GitLab>

    Остановка рабочих нагрузок

    Для корректного выполнения восстановления необходимо остановить компоненты sidekiq и webservice во время восстановления.

    kubectl annotate deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=sidekiq skip-sync="true"
    kubectl scale deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=sidekiq --replicas=0
    kubectl annotate deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=webservice skip-sync="true"
    kubectl scale deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=webservice --replicas=0
    
    # Вывод:
    # deployment.apps/xx-gitlab-sidekiq-all-in-1-v2 annotated
    # deployment.apps/xx-gitlab-sidekiq-all-in-1-v2 scaled
    # deployment.apps/xx-gitlab-webservice-default annotated
    # deployment.apps/xx-gitlab-webservice-default scaled

    Выполнение восстановления

    Используйте следующую команду, чтобы войти в терминал pod toolbox:

    export NEW_TOOLBOX_POD_NAME=$(kubectl get pod -n ${NEW_GITLAB_NAMESPACE} | grep ${NEW_GITLAB_NAME}-toolbox | awk '{print $1}')
    kubectl exec -it ${NEW_TOOLBOX_POD_NAME} -n ${NEW_GITLAB_NAMESPACE} -- bash
    DANGER

    Перед восстановлением базы данных все существующие таблицы будут удалены, чтобы избежать проблем с будущими обновлениями. Учтите, что если у вас есть пользовательские таблицы в базе данных GitLab, эти таблицы и все данные в них будут удалены.

    В терминале выполните следующую команду для восстановления, где backup ID замените на нужный идентификатор резервной копии, например 1751272314_2025_06_30_17.11.4:

    export BACKUP_ID=<backup ID>
    rm -rf /srv/gitlab/tmp/*
    backup-utility --restore -t ${BACKUP_ID}
     
    # Вывод:
    # 2025-06-30 15:33:53 UTC -- [DONE]
    # 2025-06-30 15:33:53 UTC -- Source backup for the database ci doesn't exist. Skipping the task
    # 2025-06-30 15:33:53 UTC -- Restoring database ... done
    # 2025-06-30 15:33:53 UTC -- Deleting backup and restore PID file at [/srv/gitlab/tmp/backup_restore.pid] ... done
    # 2025-06-30 15:34:12 UTC -- Restoring repositories ... 
    # 2025-06-30 15:34:12 UTC -- Restoring repositories ... done
    # 2025-06-30 15:34:12 UTC -- Deleting backup and restore PID file at [/srv/gitlab/tmp/backup_restore.pid] ... done

    Когда программа завершится успешно, процесс восстановления будет завершён.

    Примечания по восстановлению на новом экземпляре

    Если восстановление выполняется на новом развернутом экземпляре, после выполнения вышеуказанных шагов необходимо выполнить дополнительные действия:

    Восстановление Rails Secrets

    Необходимо обновить Rails secrets нового экземпляра, чтобы они совпадали с исходным экземпляром.

    Получите содержимое Rails secrets из исходного экземпляра:

    kubectl get secret ${GITLAB_NAME}-rails-secret -n ${GITLAB_NAMESPACE} -o jsonpath='{.data.secrets\.yml}' | base64 --decode

    Обновите Rails secrets нового экземпляра. Смотрите Как задать Rails Secrets.

    Переключение доменного имени

    Если исходный экземпляр был развернут с использованием доменного имени, после восстановления на новом экземпляре необходимо переключить доменное имя нового экземпляра на доменное имя исходного экземпляра для восстановления доступа к сервисам. Смотрите Настройка сетевого доступа к экземпляру для изменения доменного имени доступа к экземпляру.

    Запуск рабочих нагрузок

    Компоненты sidekiq и webservice были остановлены во время восстановления и должны быть запущены после завершения восстановления.

    kubectl annotate deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=sidekiq skip-sync-
    kubectl scale deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=sidekiq --replicas=1
    kubectl annotate deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=webservice skip-sync-
    kubectl scale deployment -n ${NEW_GITLAB_NAMESPACE} -l release=${NEW_GITLAB_NAME},app=webservice --replicas=1
    
    # Вывод:
    # deployment.apps/xx-gitlab-sidekiq-all-in-1-v2 annotated
    # deployment.apps/xx-gitlab-sidekiq-all-in-1-v2 scaled
    # deployment.apps/xx-gitlab-webservice-default annotated
    # deployment.apps/xx-gitlab-webservice-default scaled

    Проверка восстановления

    После того как статус экземпляра вернётся в нормальное состояние, войдите в GitLab и проверьте успешность восстановления данных. Проверяемые элементы включают, но не ограничиваются:

    • Группы
    • Репозитории
    • Пользователи
    • Merge Requests