GitLab: міграція даних з GitLab cloud та процес backup-restore у self-hosted версії в Kubernetes

Автор |  01/03/2023

Продовжуємо рухатись до запуску нашого self-hosted GitLab в production.

Див. попередні частини – GitLab: компоненти, архітектура, інфраструктура та запуск з Helm-чарту в Minikube та GitLab: Helm-чарт values, залежності та деплой у Kubernetes з AWS S3.

Міграція даних

Ще дуже хотілося написати пост про міграцію даних з GitLab Cloud до self-hosted, але немає часу, та й пройшло це майже повз мене – автоматизували через GitLab API та скрипт силами девелоперів.

Проте, я таки трохи інвестигейтив це питання, і в двох словах – “дефолтна” міграція, тобто direct transfer (recommended) не підтягувала проекти, тож використали depricated, але робочий варіант з file export, тобто коли для групи або проекту у Cloud-версії робиться експорт у файл, а потім імпортується вже у self-hosted.

Ну і поки девелопери працюють над допилюванням міграції – я займуся тествування та налаштування backups/restore на впипадок, якщо (коли?) “щось піде не так” (с).

Отже – подивимось, як зробити бекап вручну, як налаштувати запуск створення бекапів за розкладом, та спробуємо відновити дані. Забігаючи наперед – відновити вдалось, але з PostgreSQL довелося трошки повозитися.

GitLab Toolbox

“Recommended way” – це використовувати Toolbox pod, в якому по cron можна створювати бекапи, та при потребі – відновити дані.

Под Toolbox має декілька корисних утіліт:

  • gitlab-rails: дозволяє виконувати з консолі всякі адміністративні задачі в GitLab, пов’язані з траблшутінгом або для отримання якихось даних
  • gitlab-rake: теж для консолі, теж для адміністративних задач, в тому числі по бекапу та відновленню
  • backup-utility: ну й та сама утіліта, яку ми будемо використовувати для створення повного бекапу GitLab та всіх його залежностей типу бази даних

GitLab backup

Документація – Backing up a GitLab installation та Backup and restore.

backup-utility

Створення резервної копії виконується за допомогою поду з GitLab Toolbox, в якому є утіліта backup-utility:

[simterm]

git@gitlab-cluster-prod-toolbox-778bb8dc9f-knsr8:/$ which backup-utility
/usr/local/bin/backup-utility

[/simterm]

Яка являє собою bash-скрипт:

[simterm]

git@gitlab-cluster-prod-toolbox-778bb8dc9f-knsr8:/$ cat /usr/local/bin/backup-utility
#!/bin/bash
set -e

ACTION=""
export BACKUP_BUCKET_NAME=${BACKUP_BUCKET_NAME-gitlab-backups}
export BACKUP_BACKEND=${BACKUP_BACKEND-s3}
export S3_TOOL=${S3_TOOL-s3cmd}
export AWS_KMS_SETTINGS=""
export AWS_S3_SETTINGS=""
AWS_KMS_SETTINGS_LIST=()
AWS_S3_SETTINGS_LIST=()
S3_CMD_BACKUP_OPTION=""

rails_dir=/srv/gitlab
backups_path=$rails_dir/tmp/backups
backup_tars_path=$rails_dir/tmp/backup_tars
object_storage_backends=( registry uploads artifacts lfs packages external_diffs terraform_state pages ci_secure_files )
...

[/simterm]

По дефолту бекап виконується за допомогую s3cmd:

...
--s3tool TOOL                          S3 CLI tool to use. Can be either 's3cmd' or 'awscli'
...

Всі опції можна побачити за допомогою backup-utility --help.

При створенні бекапу, backup-utility виконає:

  • бекап бази даних Постгрі
  • бекап репозиторієв
  • бекап сторейджів – Package registry, Container registry, etc

Див. Sequence of execution.

Так як у нас вже налаштовано ServiceAccount з AWS IAM роллю, яка дозволяє доступ до S3, то замість s3cmd, до якоїх потрібен окремий конфіг, спробуємо AWS CLI.

Поки відкрите питання по розміру диску для самого Toolbox, бо бекап у вигляді TAR-архіву спочатку створюється у поді, а потім вигружається до S3-бакету. Поки зилишимо, як є, але маємо на увазі на майбутнє – якщо що, то можна буде збільшити диск для Toolbox, там це не страшно робити, бо ніяких даних він не сберігає (тобто под з Toolbox є stateless-сервісом).

UPD – схоже, що можна додати окремий диск через values та gitlab.toolbox.backups.persistence.

UPD-2: А ось знайшлось про розмір диску у документації по restore:

GitLab repositories data

Найбільше цікавить, звісно, бекап репозиторіїв.

Самі репозиторії зберігаються у Kubernetes PersistenVolume, який підключено до поду з Gitaly:

[simterm]

$ kk -n gitlab-cluster-prod describe pod gitlab-cluster-prod-gitaly-0
...
Containers:
  gitaly:
  ...
    Mounts:
      ...
      /home/git/repositories from repo-data (rw)
...

[/simterm]

В якому і є весь наш код:

[simterm]

$ kk -n gitlab-cluster-prod exec -ti gitlab-cluster-prod-gitaly-0 -- ls -l /home/git/repositories
Defaulted container "gitaly" out of: gitaly, certificates (init), configure (init)
total 28
drwxrwsr-x  3 git  git  4096 Feb 28 17:10 +gitaly
drwxrws--- 19 git  git  4096 Feb 28 16:04 @hashed
drwxrwsr-x  4 git  git  4096 Feb 24 11:39 gitlab.com-import
drwxrws---  2 root git 16384 Feb 21 13:31 lost+found

[/simterm]

Я б ще окремо подумав би про бекап цього PV/EBS за допомогою External Snaphotter та/або чи Amazon Data Lifecycle Manager.

Ручний запуск бекапу

Спробуємо спочатку запустити вручну – потім глянемо, як це налаштувати по cron-джобі:

[simterm]

git@gitlab-cluster-prod-toolbox-778bb8dc9f-knsr8:/$ backup-utility --s3tool awscli
2023-03-01 11:59:41 UTC -- Dumping main_database ... 
Dumping PostgreSQL database gitlabhq_production ... pg_dump: warning: could not find where to insert IF EXISTS in statement "-- *not* dropping schema, since initdb creates it
"
[DONE]
2023-03-01 11:59:45 UTC -- Dumping main_database ... done
2023-03-01 11:59:45 UTC -- Dumping ci_database ... [DISABLED]
2023-03-01 11:59:45 +0000 -- Deleting backup and restore lock file
2023-03-01 11:59:55 UTC -- Dumping repositories ... 
{"command":"create","gl_project_path":"gitlab-root.wiki","level":"info","msg":"started create","relative_path":"@groups/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git","storage_name":"default","time":"2023-03-01T11:59:55.890Z"}
{"command":"create","error":"manager: repository empty: repository skipped","gl_project_path":"gitlab-root.wiki","level":"warning","msg":"skipped create","relative_path":"@groups/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git","storage_name":"default","time":"2023-03-01T11:59:55.898Z"}
...
{"command":"create","gl_project_path":"migration-testing/companyname/apps/apple","level":"info","msg":"started create","relative_path":"@hashed/f6/e0/f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae.git","storage_name":"default","time":"2023-03-01T12:00:00.994Z"}
...
{"command":"create","gl_project_path":"migration-testing/companyname/apps/apple","level":"info","msg":"completed create","relative_path":"@hashed/f6/e0/f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae.git","storage_name":"default","time":"2023-03-01T12:00:05.826Z"}
...
2023-03-01 12:00:05 UTC -- Dumping repositories ... done
2023-03-01 12:00:05 +0000 -- Deleting backup and restore lock file
Dumping registry ...
empty
Dumping uploads ...
done
Dumping artifacts ...
done
Bucket not found: or-git-lfs-prod. Skipping backup of lfs ...
Dumping packages ...
empty
Dumping external_diffs ...
empty
Dumping terraform_state ...
empty
Bucket not found: gitlab-pages. Skipping backup of pages ...
Dumping ci_secure_files ...
empty
Packing up backup tar
[DONE] Backup can be found at s3://or-gitlab-backups-prod/1677671971_2023_03_01_15.8.1-ee_gitlab_backup.tar

[/simterm]

Воу… Працює)

Перевіримо зміст S3:

[simterm]

$ aws --profile internal s3 ls or-gitlab-backups-prod
2023-03-01 14:01:31 1006673920 1677671971_2023_03_01_15.8.1-ee_gitlab_backup.tar

[/simterm]

Backup Cron

Теперь додамо запуск створення бекапу за роскладом, наприклад – о 6 ранку по Києву, що наче як виходить 23.00 у США, бо наша команда є і там, і там, і навряд чи хтось буде пушити в GitLab в ці години.

Див. Configuration та values самого чарту Toolbox.

Використаємо https://crontab.guru.

Для тесту в розкладі cronjob задамо якийсь наближчий час.

Перевіряємо час в поді, бо може бути інша таймзона:

[simterm]

git@gitlab-cluster-prod-toolbox-778bb8dc9f-knsr8:/$ date
Wed Mar  1 12:32:12 UTC 2023

[/simterm]

А в Києві зараз 14:32, тож поставимо запуск на 13:00, як перевіримо – змінимо на 6 ранку.

Оновлюємо конфіг:

...
    toolbox:
      backups:
        cron:
          enabled: true
          concurrencyPolicy: Replace
          failedJobsHistoryLimit: 1
          schedule: "0 13 * * *"
          successfulJobsHistoryLimit: 3
          suspend: false
          backoffLimit: 6
          restartPolicy: "OnFailure"
          extraArgs: "--s3tool awscli"
          resources:
            requests:
              cpu: 50m
              memory: 350M
          persistence:
            enabled: false
            accessMode: ReadWriteOnce
            size: 10Gi
        objectStorage:
          backend: s3
...

Я тут навмисно вписав дефолтні resources.requests та persistence, щоб потім легше було їх змінити.

У objectStorage.config.secret спробуємо той самий сікрет, який ми створювали для appConfig.object_store, бо Toolbox його вимагає.

І в extraArgs: "--s3tool awscli" задаємо використання AWS CLI.

Деплоїмо, переверіяємо чи додалась кронджоба:

[simterm]

$ kk -n gitlab-cluster-prod get cj     
NAME                                        SCHEDULE     SUSPEND   ACTIVE   LAST SCHEDULE   AGE
gitlab-cluster-prod-toolbox-backup          0 13 * * *   False     0        <none>          6s
logical-backup-devops-gitlab-cluster-psql   0 1 * * *    False     0        11h             19d

[/simterm]

І чекаємо на 13.00 – спрацює, чи ні?

І такі да – о 13.00 з’явився под gitlab-cluster-prod-toolbox-backup-27961260-x4n45, в якому почав виконуватись бекап:

Ну – виглядає, наче ОК?

Давайте спробує відновити наш GitLab.

GitLab restore

Документація – Restoring the backup file.

Що хочеться протестити:

  • відновлення репозиторія
  • відновлення бази Postgres

Що зробимо:

  • створимо табличку в базі
  • створимо тестовий репозиторій

Потім створимо бекап, потім видалимо тестові дані, і спробуємо запустити рестор.

Тестовий проект

Створюємо проект:

Побудемо трошки рубістами:

Тестова PostgreSQL

Далі, логінимось до PostgreSQL.

В нас, нагадаю, PostgreSQL Operator (давно в чернетках пост по ньому, якось закінчу).

Знаходимо пароль – беремо із сікрету postgres.devops-gitlab-cluster-psql.credentials.postgresql.acid.zalan.do, виводимо в json, з jq отримаємо значення поля .data.password, та декодимо з base64:

[simterm]

$ kk -n gitlab-cluster-prod get secret postgres.devops-gitlab-cluster-psql.credentials.postgresql.acid.zalan.do -o json | jq -r '.data.password' | base64 -d
IcL***dPP

[/simterm]

Знаходимо master-інстанс:

[simterm]

$ kk -n gitlab-cluster-prod get pod -l application=spilo -L spilo-role
NAME                           READY   STATUS    RESTARTS   AGE     SPILO-ROLE
devops-gitlab-cluster-psql-0   2/2     Running   0          21h     replica
devops-gitlab-cluster-psql-1   2/2     Running   0          6d23h   replica
devops-gitlab-cluster-psql-2   2/2     Running   0          11d     master

[/simterm]

Відкриваємо доступ до поду:

[simterm]

$ kk -n gitlab-cluster-prod port-forward devops-gitlab-cluster-psql-2 5432:5432
Forwarding from 127.0.0.1:5432 -> 5432
Forwarding from [::1]:5432 -> 5432

[/simterm]

Логінимось в кластер з юзером postgres:

[simterm]

$ psql -h localhost -U postgres -d gitlabhq_production
Password for user postgres: 
psql (15.1, server 14.4 (Ubuntu 14.4-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

gitlabhq_production=# 

[/simterm]

Створюємо табличку в базі gitlabhq_production:

[simterm]

gitlabhq_production=# CREATE TABLE test_restore(key_id serial PRIMARY KEY, key_name VARCHAR (255) UNIQUE NOT NULL);
CREATE TABLE

[/simterm]

Перевіряємо, що вона є:

[simterm]

gitlabhq_production-# \dt test_restore
            List of relations
 Schema |     Name     | Type  |  Owner   
--------+--------------+-------+----------
 public | test_restore | table | postgres
(1 row)

[/simterm]

Переходимо до поду з Toolbox, та запускаємо бекап:

[simterm]

git@gitlab-cluster-prod-toolbox-6fc9c7fc89-8jws7:/$ backup-utility --s3tool awscli
2023-03-01 14:34:22 UTC -- Dumping main_database ... 
Dumping PostgreSQL database gitlabhq_production ... pg_dump: error: query failed: ERROR:  permission denied for table test_restore
pg_dump: detail: Query was: LOCK TABLE public.test_restore IN ACCESS SHARE MODE
[FAILED]
2023-03-01 14:34:22 UTC -- Dumping main_database failed: Failed to create compressed file '/srv/gitlab/tmp/backups/db/database.sql.gz' when trying to backup the main database:
 - host: 'devops-gitlab-cluster-psql'
 - port: '5432'
 - database: 'gitlabhq_production'
...

[/simterm]

Oops… “Щось пішло не так”.

Читаємо доку про GRANT, та задаємо права всім:

[simterm]

gitlabhq_production=# GRANT ALL ON test_restore TO PUBLIC;
GRANT

[/simterm]

Пробуємо ще раз, і:

[simterm]

git@gitlab-cluster-prod-toolbox-6fc9c7fc89-8jws7:/$ backup-utility --s3tool awscli
2023-03-01 14:37:39 UTC -- Dumping main_database ... 
Dumping PostgreSQL database gitlabhq_production ... pg_dump: error: query failed: ERROR:  permission denied for sequence test_restore_key_id_seq
pg_dump: detail: Query was: SELECT last_value, is_called FROM public.test_restore_key_id_seq
...

[/simterm]

Твою ж…

Додаємо ще прав на SEQUENCE:

[simterm]

gitlabhq_production=# GRANT USAGE, SELECT ON SEQUENCE test_restore_key_id_seq TO PUBLIC;
GRANT

[/simterm]

Тепер пішло:

[simterm]

git@gitlab-cluster-prod-toolbox-6fc9c7fc89-8jws7:/$ backup-utility --s3tool awscli
2023-03-01 14:40:38 UTC -- Dumping main_database ... 
Dumping PostgreSQL database gitlabhq_production ... pg_dump: warning: could not find where to insert IF EXISTS in statement "-- *not* dropping schema, since initdb creates it
"
[DONE]
2023-03-01 14:40:43 UTC -- Dumping main_database ... done
...
Packing up backup tar
[DONE] Backup can be found at s3://or-gitlab-backups-prod/1677681628_2023_03_01_15.8.1-ee_gitlab_backup.tar

[/simterm]

Добре.

Видалення даних

Тепер – видаляємо таблицю з бази:

[simterm]

gitlabhq_production=# DROP TABLE test_restore;
DROP TABLE
gitlabhq_production=# \dt test_restore
Did not find any relation named "test_restore".

[/simterm]

І видаляємо тестовий проект з його репозиторієм:

Відновлення даних з бекапу

Be sure to stop Puma, Sidekiq, and any other process

Ну і пробуємо – визиваємо той самий backup-utility з опцією --restore:

[simterm]

git@gitlab-cluster-prod-toolbox-6fc9c7fc89-8jws7:/$ backup-utility --s3tool awscli --restore -t 1677681628_2023_03_01_15.8.1-ee
Unpacking backup
2023-03-01 14:48:06 UTC -- Restoring main_database ... 
2023-03-01 14:48:06 UTC -- Be sure to stop Puma, Sidekiq, and any other process that
connects to the database before proceeding. For Omnibus
installs, see the following link for more information:
https://docs.gitlab.com/ee/raketasks/backup_restore.html#restore-for-omnibus-gitlab-installations

Before restoring the database, we will remove all existing
tables to avoid future upgrade problems. Be aware that if you have
custom tables in the GitLab database these tables and all data will be
removed.

[/simterm]

Ага… А в документації про це не говориться… Хоча в цілому варто переглянути Back up and restore GitLab – там ще багато чого цікавого.

Добре – згадаємо, що у нас використовує Postgres – див. Інфраструктура:

Ну, наче тільки Webservice та Sidekiq.

Стопаємо їх:

[simterm]

$ kk -n gitlab-cluster-prod scale deploy gitlab-cluster-prod-sidekiq-all-in-1-v2 --replicas=0
deployment.apps/gitlab-cluster-prod-sidekiq-all-in-1-v2 scaled

$ kk -n gitlab-cluster-prod scale deploy gitlab-cluster-prod-webservice-default --replicas=0
deployment.apps/gitlab-cluster-prod-webservice-default scaled

[/simterm]

Запускаємо рестор знову:

[simterm]

git@gitlab-cluster-prod-toolbox-6fc9c7fc89-8jws7:/$ backup-utility --s3tool awscli --restore -t 1677681628_2023_03_01_15.8.1-ee
Unpacking backup
2023-03-01 15:01:25 UTC -- Restoring main_database ... 
2023-03-01 15:01:25 UTC -- Be sure to stop Puma, Sidekiq, and any other process that
...

[/simterm]

Та ну твою ж дивізію…

Ну, ок… Може це через Postgres Operator? Бо він точно якісь конекти тримає. Чи через моніторинг – експортер?

Глянемо за таким нагугленим запитом:

select pid as process_id, 
       usename as username, 
       datname as database_name, 
       client_addr as client_address, 
       application_name,
       backend_start,
       state,
       state_change
from pg_stat_activity;

Виконуємо:

[simterm]

gitlabhq_production=# select pid as process_id, 
       usename as username, 
       datname as database_name, 
       client_addr as client_address, 
       application_name,
       backend_start,
       state,
       state_change
from pg_stat_activity;
 process_id |            username            |    database_name    | client_address |            application_name            |         backend_start         | state  |         state_change          
------------+--------------------------------+---------------------+----------------+----------------------------------------+-------------------------------+--------+-------------------------------
      25175 |                                |                     |                |                                        | 2023-02-21 10:48:54.37466+00  |        | 
        152 | postgres                       | postgres            |                | Patroni                                | 2023-02-17 14:51:34.098346+00 | idle   | 2023-03-01 15:04:27.471442+00
         77 | postgres                       | postgres            |                |                                        | 2023-02-17 14:51:22.942046+00 |        | 
      25177 | postgres                       | postgres            |                | pg_cron scheduler                      | 2023-02-21 10:48:54.376082+00 | idle   | 2023-02-21 10:48:56.389663+00
      25179 | postgres                       |                     |                |                                        | 2023-02-21 10:48:54.377106+00 |        | 
      25178 | postgres                       |                     |                | TimescaleDB Background Worker Launcher | 2023-02-21 10:48:54.376869+00 |        | 
       5744 | standby                        |                     | 10.0.101.37    | devops-gitlab-cluster-psql-0           | 2023-02-28 16:20:44.085971+00 | active | 2023-02-28 16:20:44.092053+00
      25292 | gitlabhq_production_owner_user | gitlabhq_production | 10.0.81.98     | /usr/bin/gitlab-exporter               | 2023-02-21 10:51:42.135462+00 | idle   | 2023-03-01 15:03:53.761035+00
      15286 | standby                        |                     | 10.0.41.195    | devops-gitlab-cluster-psql-1           | 2023-02-22 14:24:15.551548+00 | active | 2023-02-22 14:24:15.560445+00
      24578 | postgres                       | gitlabhq_production | 127.0.0.1      | psql                                   | 2023-03-01 15:04:24.063071+00 | active | 2023-03-01 15:04:36.803864+00
        147 |                                |                     |                |                                        | 2023-02-17 14:51:33.082497+00 |        | 
      25176 |                                |                     |                |                                        | 2023-02-21 10:48:54.376307+00 |        | 
        146 |                                |                     |                |                                        | 2023-02-17 14:51:33.081686+00 |        | 
      25174 |                                |                     |                |                                        | 2023-02-21 10:48:54.374117+00 |        | 

[/simterm]

Оу, май… Ну, так… Багацько…

ERROR: must be owner of view pg_stat_statements_info

Добре – думаю, можно з цими конектами запускати – ігноруємо помилку, відповідаємо yes на запит “Do you want to continue?“:

[simterm]

git@gitlab-cluster-prod-toolbox-6fc9c7fc89-8jws7:/$ backup-utility --s3tool awscli --restore -t 1677681628_2023_03_01_15.8.1-ee
Unpacking backup
2023-03-01 15:06:43 UTC -- Restoring main_database ... 
2023-03-01 15:06:43 UTC -- Be sure to stop Puma, Sidekiq, and any other process that
...
Do you want to continue (yes/no)? yes
Removing all tables. Press `Ctrl-C` within 5 seconds to abort
2023-03-01 15:07:02 UTC -- Cleaning the database ... 
2023-03-01 15:07:02 +0000 -- Deleting backup and restore lock file
rake aborted!
ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR:  must be owner of view pg_stat_statements_info
...

[/simterm]

SUUUUUKA!)

Окей… Ми вперті.

Гуглимо ішью – Cannot restore to helm-installed version.

Пробуємо видалити Postgres Extention:

[simterm]

gitlabhq_production=# DROP EXTENSION pg_stat_statements;
ERROR:  cannot drop extension pg_stat_statements because other objects depend on it
DETAIL:  function metric_helpers.pg_stat_statements(boolean) depends on type pg_stat_statements
view metric_helpers.pg_stat_statements depends on function metric_helpers.pg_stat_statements(boolean)
extension pg_stat_kcache depends on extension pg_stat_statements
HINT:  Use DROP ... CASCADE to drop the dependent objects too.

[/simterm]

Ну, ок… залежності не виглядають як якісь супер-критичні, і можливо потім ми таки зможемо повернути цей pg_stat_statements.

Пробуємо з CASCADE:

[simterm]

gitlabhq_production=# DROP EXTENSION pg_stat_statements CASCADE;
NOTICE:  drop cascades to 3 other objects
DETAIL:  drop cascades to function metric_helpers.pg_stat_statements(boolean)
drop cascades to view metric_helpers.pg_stat_statements
drop cascades to extension pg_stat_kcache
DROP EXTENSION

[/simterm]

Запускаємо…

І – чудо! Воно пішло, хоча з купою помилок на права доступа.

Знов спитало, чи продовжувати – знов відповідаємо yes:

[simterm]

git@gitlab-cluster-prod-toolbox-6fc9c7fc89-8jws7:/$ backup-utility --s3tool awscli --restore -t 1677681628_2023_03_01_15.8.1-ee
Unpacking backup
2023-03-01 15:14:41 UTC -- Restoring main_database ... 
2023-03-01 15:14:41 UTC -- Be sure to stop Puma, Sidekiq, and any other process that
connects to the database before proceeding. For Omnibus
installs, see the following link for more information:
https://docs.gitlab.com/ee/raketasks/backup_restore.html#restore-for-omnibus-gitlab-installations

Before restoring the database, we will remove all existing
tables to avoid future upgrade problems. Be aware that if you have
custom tables in the GitLab database these tables and all data will be
removed.

Do you want to continue (yes/no)? yes
Removing all tables. Press `Ctrl-C` within 5 seconds to abort
2023-03-01 15:14:49 UTC -- Cleaning the database ... 
2023-03-01 15:14:53 UTC -- done
Restoring PostgreSQL database gitlabhq_production ... ERROR:  permission denied for schema metric_helpers
ERROR:  permission denied for schema metric_helpers
ERROR:  permission denied for schema metric_helpers
ERROR:  permission denied for schema user_management
ERROR:  permission denied for schema user_management
...
ERROR:  permission denied for schema metric_helpers
------ END ERRORS -------
[DONE]
2023-03-01 15:15:39 UTC -- Restoring main_database ... done
2023-03-01 15:15:39 UTC -- There were errors in restoring the schema. This may cause
issues if this results in missing indexes, constraints, or
columns. Please record the errors above and contact GitLab
Support if you have questions:
https://about.gitlab.com/support/

Do you want to continue (yes/no)? yes
...
2023-03-01 15:16:45 UTC -- Restoring repositories ... done
2023-03-01 15:16:45 +0000 -- Deleting backup and restore lock file
Restoring uploads ...
done
Restoring artifacts ...
done

[/simterm]

Перевіряємо нашу тестову таблицю:

[simterm]

gitlabhq_production=# \dt test_restore
                       List of relations
 Schema |     Name     | Type  |             Owner              
--------+--------------+-------+--------------------------------
 public | test_restore | table | gitlabhq_production_owner_user
(1 row)

[/simterm]

Запускаємо стопнуті сервіси:

[simterm]

$ kk -n gitlab-cluster-prod scale deploy gitlab-cluster-prod-webservice-default --replicas=2
deployment.apps/gitlab-cluster-prod-webservice-default scaled

$ kk -n gitlab-cluster-prod scale deploy gitlab-cluster-prod-sidekiq-all-in-1-v2 --replicas=1
deployment.apps/gitlab-cluster-prod-sidekiq-all-in-1-v2 scaled

[/simterm]

Перевіряємо наш репозиторій:

Все є…

Дивно…)

Але ок – виглядає так, наче воно працює.

Плюс, для бази PostgreSQL робиться окремий бекап самим Оператором, тож, думаю, можна йти далі.

Хоча дуже сподіваюсь, що використовувати restore ніколи не доведеться.