본문 바로가기
CICD/Gitlab

Gitlab Backup & Restore (Omnibus, Multi-node)

by wlsdn3004 2023. 12. 12.
728x90
반응형

 

이번 글에서는 GitLab에서 프로젝트를 삭제한 후에 발생할 수 있는 비상 상황에 대비하여 백업 및 복원 시나리오를 다뤄보려 한다.

 

Backup & Restore 시나리오 개요

  1. GitLab 프로젝트 삭제:  GitLab에서 실수로 프로젝트를 삭제했다고 가정한다.
  2. Backup 수행: 프로젝트를 삭제하기 전 백업을 수행한다.
  3. 프로젝트 Restore: 프로젝트를 삭제한 후, 백업 파일을 사용하여 프로젝트를 복원한다.
  4. 프로젝트 확인: 프로젝트 복원이 완료되었으면 안에 파일 및 내용이 정상인지 확인한다.

 

본 글은 이전에 작성된 [Gitlab 고가용성 환경 구성하기]의 실습을 기반으로 하기 때문에 본 글의 Backup & Restore 실습을 진행하려면 이전 글에서 다룬 GitLab HA 구성 환경이 필요하다.

[참고]
Gitlab Backup & Restore 작업은 전부 Rails 인스턴스에서 진행한다.

 

 

구성 환경

  • AWS EC2 Instance(15 EA)
  • OS : Amazon Linux 2023
  • Kernel : 6.1.61-85.141.amzn2023.x86_64
  • Instance type : c5.large

전제 조건

설치 버전

  • Gitlab 16.6.0-ee

 

1. Gitlab 백업


이전에 작성한  [Gitlab 고가용성 구성하기 / 8. Sidekiq & Rails 구성]글에서 구성했던 환경에서 rails 인스턴스의 설정파일을 보면 아래와 같이 Internal Loadbalancer인 Haproxy를 통해 Pgbouncer를 바라보고 있다.

## /etc/gitlab/gitlab.rb
...
gitlab_rails['db_host'] = '10.10.1.233'  ## internal load balancer IP (Pgbouncer)
gitlab_rails['db_port'] = 6432
...

 

Backup을 진행할 때 Postgresql Leader 인스턴스를 바라보게 지정하여 Backup을 진행해야 한다.

Postgresql Leader IP를 모른다면 Postgresql 인스턴스에 들어가서 아래와 같이 명령어를 사용하여 Leader를 조회한다.

$ gitlab-ctl patroni members
+ Cluster: postgresql-ha (7311200128971677808) ----+----+-----------+
| Member         | Host        | Role    | State   | TL | Lag in MB |
+----------------+-------------+---------+---------+----+-----------+
| ip-10-10-1-155 | 10.10.1.155 | Leader  | running |  2 |           |
| ip-10-10-1-201 | 10.10.1.201 | Replica | running |  2 |         0 |
+----------------+-------------+---------+---------+----+-----------+

 

아래와 같이 Pgbouncer IP를 Postgresql Leader IP로 변경한다. 

$ vi /var/opt/gitlab/gitlab-rails/etc/database.yml

production:
  main:
...
    host: "10.10.1.155"  ## Postgresql Leader IP
    port: 5432  ## Postgresql Port
...

 

Postgresql Leader의 IP로 변경이 완료되었으면 gitlab-backup 명령어로 Postgresql 및 Repository를 백업한다.

$ GITLAB_BACKUP_PGHOST=10.10.1.155 GITLAB_BACKUP_PGPORT=5432 gitlab-backup create

2023-12-12 01:17:39 UTC -- Dumping database ...
Dumping PostgreSQL database gitlabhq_production ... [DONE]
2023-12-12 01:17:52 UTC -- Dumping database ... done
2023-12-12 01:17:52 UTC -- Dumping repositories ...
{"command":"create","gl_project_path":"root/test3","level":"info","msg":"started create","pid":4418,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git","storage_name":"default","time":"2023-12-12T01:17:52.944Z"}
{"command":"create","gl_project_path":"root/test3.wiki","level":"info","msg":"started create","pid":4418,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki.git","storage_name":"default","time":"2023-12-12T01:17:52.980Z"}
{"command":"create","gl_project_path":"root/test3","level":"info","msg":"completed create","pid":4418,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git","storage_name":"default","time":"2023-12-12T01:17:53.002Z"}
{"command":"create","gl_project_path":"root/test5555","level":"info","msg":"started create","pid":4418,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git","storage_name":"default","time":"2023-12-12T01:17:53.002Z"}
{"command":"create","gl_project_path":"root/test3.wiki","level":"info","msg":"completed create","pid":4418,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki.git","storage_name":"default","time":"2023-12-12T01:17:53.019Z"}
{"command":"create","gl_project_path":"root/test5555.wiki","level":"info","msg":"started create","pid":4418,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git","storage_name":"default","time":"2023-12-12T01:17:53.019Z"}
{"command":"create","gl_project_path":"root/test5555","level":"info","msg":"completed create","pid":4418,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git","storage_name":"default","time":"2023-12-12T01:17:53.025Z"}
{"command":"create","gl_project_path":"root/test5555.wiki","level":"info","msg":"completed create","pid":4418,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git","storage_name":"default","time":"2023-12-12T01:17:53.033Z"}
2023-12-12 01:17:53 UTC -- Dumping repositories ... done
2023-12-12 01:17:53 UTC -- Dumping uploads ...
2023-12-12 01:17:53 UTC -- Dumping uploads ... done
2023-12-12 01:17:53 UTC -- Dumping builds ...
2023-12-12 01:17:53 UTC -- Dumping builds ... done
2023-12-12 01:17:53 UTC -- Dumping artifacts ...
2023-12-12 01:17:53 UTC -- Dumping artifacts ... done
2023-12-12 01:17:53 UTC -- Dumping pages ...
2023-12-12 01:17:53 UTC -- Dumping pages ... done
2023-12-12 01:17:53 UTC -- Dumping lfs objects ...
2023-12-12 01:17:53 UTC -- Dumping lfs objects ... done
2023-12-12 01:17:53 UTC -- Dumping terraform states ...
2023-12-12 01:17:53 UTC -- Dumping terraform states ... done
2023-12-12 01:17:53 UTC -- Dumping container registry images ... [DISABLED]
2023-12-12 01:17:53 UTC -- Dumping packages ...
2023-12-12 01:17:53 UTC -- Dumping packages ... done
2023-12-12 01:17:53 UTC -- Dumping ci secure files ...
2023-12-12 01:17:53 UTC -- Dumping ci secure files ... done
2023-12-12 01:17:53 UTC -- Creating backup archive: 1702343859_2023_12_12_16.6.0-ee_gitlab_backup.tar ...
2023-12-12 01:17:53 UTC -- Creating backup archive: 1702343859_2023_12_12_16.6.0-ee_gitlab_backup.tar ... done
2023-12-12 01:17:53 UTC -- Uploading backup archive to remote storage  ... [SKIPPED]
2023-12-12 01:17:53 UTC -- Deleting old backups ... [SKIPPED]
2023-12-12 01:17:53 UTC -- Deleting tar staging files ...
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/backup_information.yml
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/db
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/repositories
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/uploads.tar.gz
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/builds.tar.gz
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/artifacts.tar.gz
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/pages.tar.gz
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/lfs.tar.gz
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/terraform_state.tar.gz
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/packages.tar.gz
2023-12-12 01:17:53 UTC -- Cleaning up /var/opt/gitlab/backups/ci_secure_files.tar.gz
2023-12-12 01:17:53 UTC -- Deleting tar staging files ... done
2023-12-12 01:17:53 UTC -- Deleting backups/tmp ...
2023-12-12 01:17:53 UTC -- Deleting backups/tmp ... done
2023-12-12 01:17:53 UTC -- Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data
and are not included in this backup. You will need these files to restore a backup.
Please back them up manually.
2023-12-12 01:17:53 UTC -- Backup 1702343859_2023_12_12_16.6.0-ee is done.
2023-12-12 01:17:53 UTC -- Deleting backup and restore PID file ... done

Backup 메세지를 보면 database, repositories 데이터 덤프 후 압축하여 "/var/opt/gitlab/backups/" 위치에 "1702343859_2023_12_12_16.6.0-ee" 이름으로 백업된 걸 확인할 수 있다.

 

들어가서 확인하면 아래와 같이 백업 파일이 존재한다.

$ ls -lh /var/opt/gitlab/backups/
-rw-------. 1 git git 189M Dec 12 01:17 1702343859_2023_12_12_16.6.0-ee_gitlab_backup.tar

 

tar파일 내용을 확인해 보면 아래와 같이 백업되어 있는 파일들을 확인할 수 있다.

$ tar -tvf /var/opt/gitlab/backups/1702343859_2023_12_12_16.6.0-ee_gitlab_backup.tar
-rw-r--r-- git/git         442 2023-12-12 01:17 backup_information.yml
drwxr-xr-x git/git           0 2023-12-12 01:17 db/
-rw------- git/git   195245708 2023-12-12 01:17 db/database.sql.gz
drwx------ git/git           0 2023-12-12 01:17 repositories/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/6b/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/6b/86/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b/1702343859_2023_12_12_16.6.0-ee/
-rw------- git/git        1234 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b/1702343859_2023_12_12_16.6.0-ee/001.refs
-rw------- git/git        5348 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b/1702343859_2023_12_12_16.6.0-ee/001.bundle
-rw------- git/git       10240 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b/1702343859_2023_12_12_16.6.0-ee/001.custom_hooks.tar
-rw------- git/git           3 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b/1702343859_2023_12_12_16.6.0-ee/LATEST
-rw------- git/git          31 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b/LATEST
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki/1702343859_2023_12_12_16.6.0-ee/
-rw------- git/git         103 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki/1702343859_2023_12_12_16.6.0-ee/001.refs
-rw------- git/git     1855283 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki/1702343859_2023_12_12_16.6.0-ee/001.bundle
-rw------- git/git           3 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki/1702343859_2023_12_12_16.6.0-ee/LATEST
-rw------- git/git          31 2023-12-12 01:17 repositories/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki/LATEST
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/d4/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/d4/73/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35/1702343859_2023_12_12_16.6.0-ee/
-rw------- git/git         103 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35/1702343859_2023_12_12_16.6.0-ee/001.refs
-rw------- git/git        2981 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35/1702343859_2023_12_12_16.6.0-ee/001.bundle
-rw------- git/git           3 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35/1702343859_2023_12_12_16.6.0-ee/LATEST
-rw------- git/git          31 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35/LATEST
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki/
drwx------ git/git           0 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki/1702343859_2023_12_12_16.6.0-ee/
-rw------- git/git           0 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki/1702343859_2023_12_12_16.6.0-ee/001.refs
-rw------- git/git           3 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki/1702343859_2023_12_12_16.6.0-ee/LATEST
-rw------- git/git          31 2023-12-12 01:17 repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki/LATEST
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/6b/
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/6b/86/
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git/
-rw------- git/git         494 2023-12-12 01:17 repositories/manifests/default/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git/1702343859_2023_12_12_16.6.0-ee.toml
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki.git/
-rw------- git/git         509 2023-12-12 01:17 repositories/manifests/default/@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki.git/1702343859_2023_12_12_16.6.0-ee.toml
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/d4/
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/d4/73/
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git/
-rw------- git/git         494 2023-12-12 01:17 repositories/manifests/default/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git/1702343859_2023_12_12_16.6.0-ee.toml
drwx------ git/git           0 2023-12-12 01:17 repositories/manifests/default/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git/
-rw------- git/git         509 2023-12-12 01:17 repositories/manifests/default/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git/1702343859_2023_12_12_16.6.0-ee.toml
-rw------- git/git         147 2023-12-12 01:17 uploads.tar.gz
-rw------- git/git         147 2023-12-12 01:17 builds.tar.gz
-rw------- git/git         146 2023-12-12 01:17 artifacts.tar.gz
-rw------- git/git         154 2023-12-12 01:17 pages.tar.gz
-rw------- git/git         147 2023-12-12 01:17 lfs.tar.gz
-rw------- git/git         147 2023-12-12 01:17 terraform_state.tar.gz
-rw------- git/git         147 2023-12-12 01:17 packages.tar.gz
-rw------- git/git         147 2023-12-12 01:17 ci_secure_files.tar.gz

backup_information.yml 파일 내용은 backup 관련된 내용을 담고 있다.

 

백업이 완료되었으면 database.yml파일을 원래대로 복구한다.

$ vi /var/opt/gitlab/gitlab-rails/etc/database.yml

production:
  main:
...
    host: "10.10.1.182"  ## Internal Loadbalancer IP (Pgbouncer)
    port: 6432  ## Pgbouncer Port
...

 

추가로 아래 두 개의 파일도 복구 시 필요한 파일로 백업해야 한다.

  • /etc/gitlab/gitlab-secrets.json
  • /etc/gitlab/gitlab.rb

 

만약 외부 Postgresql을 사용하고 있다면 아래와 같이 백업을 진행한다.

1. 외부 Postgresql 백업

  • /$ opt/gitlab/embedded/bin/pg_dump -h 10.10.1.155 -U gitlab-psql -d gitlabhq_production > gitlab_db_backup.sql

2. Postgresql을 제외한 Repository 백업

  • $ GITLAB_BACKUP_PGHOST=10.10.1.155 GITLAB_BACKUP_PGPORT=5432 gitlab-backup create  SKIP=db

 

2. Gitlab Project 삭제


Gitlab UI로 들어가 삭제할 Porject의 내용을 확인한다.

test3 Project repository의 test.txt, test2.txt,Issues 2개, Merge requests 1개가 존재한다.

위 Project를 삭제한 뒤 restore를 통해 정상 복원되는지 확인해 볼 것이다.

 

test3이라는 Project를 삭제하기 위해 Gitlab에서 아래 위치로 이동한다.

  • Admin Area > Projects

 

 

정상 삭제 되었는지 확인한다.

 

3. Gitlab 복원


데이터 복원 시 Gitlab의 쓰기 동작을 잠시 멈춰야 하기 때문에 Rails를 중지해야 한다.

$ gitlab-ctl stop

 

Backup때와 동일하게 Pgbouncer IP를 Postgresql Leader IP로 변경한다.

$ vi /var/opt/gitlab/gitlab-rails/etc/database.yml

production:
  main:
...
    host: "10.10.1.155"  ## Postgresql Leader IP
    port: 5432  ## Postgresql Port
...

 

gitlab-backup 명령어로 restore를 진행한다.

$ gitlab-backup restore BACKUP=1702343859_2023_12_12_16.6.0-ee
2023-12-12 01:53:27 UTC -- Unpacking backup ...
2023-12-12 01:53:27 UTC -- Unpacking backup ... done
2023-12-12 01:53:27 UTC -- Restoring database ...
2023-12-12 01:53:27 UTC -- Be sure to stop Puma, Sidekiq, and any other process that
...
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-12-12 01:53:39 UTC -- Cleaning the database ...
2023-12-12 01:53:42 UTC -- done
Restoring PostgreSQL database gitlabhq_production ... ERROR:  must be owner of function public.pg_shadow_lookup
...
[DONE]
Source backup for the database ci doesn't exist. Skipping the task
2023-12-12 01:55:11 UTC -- Restoring database ... done
2023-12-12 01:55:11 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-12-12 01:56:19 UTC -- Restoring repositories ...
{"command":"restore","gl_project_path":"root/test3","level":"info","msg":"started restore","pid":6676,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git","storage_name":"default","time":"2023-12-12T01:56:19.614Z"}
{"command":"restore","gl_project_path":"root/test3.wiki","level":"info","msg":"started restore","pid":6676,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki.git","storage_name":"default","time":"2023-12-12T01:56:19.671Z"}
{"command":"restore","gl_project_path":"root/test3","level":"info","msg":"completed restore","pid":6676,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.git","storage_name":"default","time":"2023-12-12T01:56:19.791Z"}
{"command":"restore","gl_project_path":"root/test5555","level":"info","msg":"started restore","pid":6676,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git","storage_name":"default","time":"2023-12-12T01:56:19.791Z"}
{"command":"restore","gl_project_path":"root/test3.wiki","level":"info","msg":"completed restore","pid":6676,"relative_path":"@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b.wiki.git","storage_name":"default","time":"2023-12-12T01:56:19.853Z"}
{"command":"restore","gl_project_path":"root/test5555.wiki","level":"info","msg":"started restore","pid":6676,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git","storage_name":"default","time":"2023-12-12T01:56:19.853Z"}
{"command":"restore","gl_project_path":"root/test5555.wiki","level":"info","msg":"completed restore","pid":6676,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.wiki.git","storage_name":"default","time":"2023-12-12T01:56:19.873Z"}
{"command":"restore","gl_project_path":"root/test5555","level":"info","msg":"completed restore","pid":6676,"relative_path":"@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git","storage_name":"default","time":"2023-12-12T01:56:19.899Z"}
2023-12-12 01:56:19 UTC -- Restoring repositories ... done
2023-12-12 01:56:19 UTC -- Restoring uploads ...
2023-12-12 01:56:19 UTC -- Restoring uploads ... done
2023-12-12 01:56:19 UTC -- Restoring builds ...
2023-12-12 01:56:19 UTC -- Restoring builds ... done
2023-12-12 01:56:19 UTC -- Restoring artifacts ...
2023-12-12 01:56:19 UTC -- Restoring artifacts ... done
2023-12-12 01:56:19 UTC -- Restoring pages ...
2023-12-12 01:56:19 UTC -- Restoring pages ... done
2023-12-12 01:56:19 UTC -- Restoring lfs objects ...
2023-12-12 01:56:19 UTC -- Restoring lfs objects ... done
2023-12-12 01:56:19 UTC -- Restoring terraform states ...
2023-12-12 01:56:19 UTC -- Restoring terraform states ... done
2023-12-12 01:56:19 UTC -- Restoring packages ...
2023-12-12 01:56:19 UTC -- Restoring packages ... done
2023-12-12 01:56:19 UTC -- Restoring ci secure files ...
2023-12-12 01:56:19 UTC -- Restoring ci secure files ... done
This task will now rebuild the authorized_keys file.
You will lose any data stored in the authorized_keys file.
Do you want to continue (yes/no)? yes

2023-12-12 01:56:34 UTC -- Deleting tar staging files ...
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/backup_information.yml
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/db
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/repositories
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/uploads.tar.gz
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/builds.tar.gz
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/artifacts.tar.gz
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/pages.tar.gz
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/lfs.tar.gz
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/terraform_state.tar.gz
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/packages.tar.gz
2023-12-12 01:56:34 UTC -- Cleaning up /var/opt/gitlab/backups/ci_secure_files.tar.gz
2023-12-12 01:56:34 UTC -- Deleting tar staging files ... done
2023-12-12 01:56:34 UTC -- Deleting backups/tmp ...
2023-12-12 01:56:34 UTC -- Deleting backups/tmp ... done
2023-12-12 01:56:34 UTC -- Warning: Your gitlab.rb and gitlab-secrets.json files contain sensitive data
and are not included in this backup. You will need to restore these files manually.
2023-12-12 01:56:34 UTC -- Restore task is done.
2023-12-12 01:56:34 UTC -- Deleting backup and restore PID file ... done

메세지를 보면 복원 순서는 아래와 같다.

  1. Postgresql gitlabhq_production 데이터베이스 삭제
  2. gitlabhq_production 데이터베이스 복원
  3. Repositories 복원

만약, 외부 Postgresql을 사용한다면 복원 시 위 절차를 준수해야 한다.

 

복원이 완료되었으면 database.yml파일을 원래대로 복구한다.

$ vi /var/opt/gitlab/gitlab-rails/etc/database.yml

production:
  main:
...
    host: "10.10.1.182"  ## Internal Loadbalancer IP (Pgbouncer)
    port: 6432  ## Pgbouncer Port
...

 

중지했던 gitlab을 시작한다.

$ gitlab-ctl start

 

 

4. 복원 확인


삭제했던 Project가 정상 복원 되었는지 Gitlab에 접근하여 확인한다.

  • Admin Area > Projects

 

test3이라는 Project 내용이 전부 정상 복원되었는지 확인한다.

 

Issues, Merge requests, test.txt, test2.txt 전부 복원된 걸 확인할 수 있다.

 

5. 증분 백업 & 복원


GitLab의 증분 백업(incremental backup)은 데이터의 전체 백업을 매번 수행하지 않고, 마지막 백업 이후 변경된 부분만 백업하는 방법이다. 그렇기 때문에 백업이 보다 빠르게 수행된다.

 

먼저 이전 백업 이후 변경사항을 만들기 위해 Gitlab의 test3 프로젝트 repository에 test3.txt 파일을 생성한다.

  • New file 선택.

 

  • test3.txt라는 이름의 파일 생성.

 

  • test3.txt 파일 생성되었는지 확인.

 

새로운 파일이 생성되었으면 증분 백업을 진행한다.

  • PREVIOUS_BACKUP 옵션값에는 이전 백업한 파일 id를 지정해야 한다.
$ GITLAB_BACKUP_PGHOST=10.10.1.155 GITLAB_BACKUP_PGPORT=5432 gitlab-backup create INCREMENTAL=yes PREVIOUS_BACKUP=1702343859_2023_12_12_16.6.0-ee
...
2023-12-12 04:26:49 UTC -- Unpacking backup ...
2023-12-12 04:26:49 UTC -- Unpacking backup ... done
2023-12-12 04:26:49 UTC -- Dumping database ...
Dumping PostgreSQL database gitlabhq_production ... [DONE]
2023-12-12 04:27:02 UTC -- Dumping database ... done
2023-12-12 04:27:02 UTC -- Dumping repositories ...
...
2023-12-12 04:27:03 UTC -- Creating backup archive: 1702355209_2023_12_12_16.6.0-ee_gitlab_backup.tar ...
2023-12-12 04:27:03 UTC -- Creating backup archive: 1702355209_2023_12_12_16.6.0-ee_gitlab_backup.tar ... done
...

처음 백업했을 때 보다 빠르게 백업되는 걸 확인할 수 있다.

메세지를 보면 기본 백업과는 달리 Unpacking backup이라고 나오는데, 이전 백업 파일을 압축 해제 후 backup_information.yml 파일 내용을 참조하여 증분 백업을 진행한다. 이후 변경된 내용을 백업 후 tar 파일로 압축하여 새로운 압축 파일을 생성한다.

 

보통 증분 백업을 수행할 때는 최초 백업 파일과 변경된 사항만 저장하는 백업 파일을 따로 생성하여 관리하는 것이 일반적이다. 그러나 GitLab에서는 증분 백업을 하나의 tar 파일로 관리한다.

 

아래 명령을 통해 증분 백업된 파일과 이전 백업 파일의 용량 차이를 확인한다.

$ cd /var/opt/gitlab/backups
$ du -csk ./*
192572  ./1702343859_2023_12_12_16.6.0-ee_gitlab_backup.tar  ## 일반 백업 후 생성 파일
192712  ./1702355209_2023_12_12_16.6.0-ee_gitlab_backup.tar  ## 증분 백업 후 생성 파일

 

다음으로 프로젝트 삭제를 진행한다.

위에서 진행한 [2. Gitlab Project 삭제] 절차와 동일하게 Gitlab에 접근하여 test3 프로젝트를 삭제한다.

  • Admin Area > Projects

 

 

정상 삭제 되었는지 확인한다.

 

다음으로 데이터 복원을 진행한다.

데이터 복원 시 Gitlab의 쓰기를 잠시 멈춰야 하기 때문에 Rails 인스턴스에서 gitlab을 중지한다.

$ gitlab-ctl stop

 

Backup때와 동일하게 Pgbouncer IP를 Postgresql Leader IP로 변경한다.

$ vi /var/opt/gitlab/gitlab-rails/etc/database.yml

production:
  main:
...
    host: "10.10.1.155"  ## Postgresql Leader IP
    port: 5432  ## Postgresql Port
...

 

gitlab-backup 명령어로 restore를 진행한다.

$ gitlab-backup restore BACKUP=1702355209_2023_12_12_16.6.0-ee

 

복원이 완료되었으면 database.yml파일을 원래대로 복구한다.

$ vi /var/opt/gitlab/gitlab-rails/etc/database.yml

production:
  main:
...
    host: "10.10.1.182"  ## Internal Loadbalancer IP (Pgbouncer)
    port: 6432  ## Pgbouncer Port
...

 

중지했던 gitlab을 시작한다.

$ gitlab-ctl start

 

Gitlab UI에서 파일이 전부 존재하는지 확인한다.

 

정상 확인 되었으면 증분 백업 전 파일을 삭제한다.

$ rm -f 1702343859_2023_12_12_16.6.0-ee_gitlab_backup.tar

 

마무리


GitLab에서 프로젝트를 삭제한 후에도 안전하게 복원하는 방법에 대해 다뤄보았다. 비상 상황에 대비하여 주기적으로 백업을 수행하는 스크립트를 작성하여 관리하면 백업 파일을 보다 효율적으로 관리할 수 있다. 백업 및 복원 절차를 숙지하여 문제 발생 시 신속하게 복원할 수 있도록 미리 대비하자.

반응형

댓글