• Русский
  • Официальное резервное копирование и восстановление 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