InfoGrab DocsInfoGrab Docs

GitLab 복원

요약

GitLab 복원 작업은 시스템 연속성을 유지하고 데이터 손실에서 복구하기 위해 백업에서 데이터를 복구합니다. 복원 프로세스에는 백업과 동일한 버전의 기존 GitLab 설치가 필요합니다. 복원을 수행하려면 먼저 작동하는 GitLab 설치가 있어야 합니다.

GitLab 복원 작업은 시스템 연속성을 유지하고 데이터 손실에서 복구하기 위해 백업에서 데이터를 복구합니다. 복원 작업은 다음을 수행합니다.

  • 데이터베이스 레코드와 구성을 복구합니다
  • Git 리포지터리, 컨테이너 레지스트리 이미지, 업로드된 콘텐츠를 복원합니다
  • 패키지 레지스트리 데이터와 CI/CD 아티팩트를 복원합니다
  • 계정 및 그룹 설정을 복원합니다
  • 프로젝트 및 그룹 위키를 복구합니다
  • 프로젝트 수준 보안 파일을 복원합니다
  • 외부 머지 리퀘스트 diff를 복구합니다

복원 프로세스에는 백업과 동일한 버전의 기존 GitLab 설치가 필요합니다. 사전 요구 사항을 따르고, 프로덕션에서 사용하기 전에 전체 복원 프로세스를 테스트합니다.

복원 사전 요구 사항#

대상 GitLab 인스턴스가 이미 작동하고 있어야 합니다#

복원을 수행하려면 먼저 작동하는 GitLab 설치가 있어야 합니다. 복원 작업을 수행하는 시스템 사용자(git)는 일반적으로 데이터를 가져올 SQL 데이터베이스 (gitlabhq_production)를 생성하거나 삭제할 권한이 없기 때문입니다.

대상 GitLab 인스턴스에 기존 데이터가 없어야 합니다#

복원 프로세스는 데이터 유형에 따라 기존 데이터를 다르게 처리합니다.

  • PostgreSQL 데이터는 복원 프로세스 중에 자동으로 지워집니다.
  • Git 리포지터리: 같은 이름의 리포지터리가 이미 있으면 "repository already exists" 오류와 함께 복원이 실패합니다. 자세한 내용은 이슈 118459를 참고합니다.
  • 파일 시스템 데이터는 가능한 경우 복원 전에 별도의 디렉터리로 이동됩니다.
  • 오브젝트 스토리지 데이터는 자동으로 지워지지 않습니다. 고아 데이터가 남지 않도록 복원 전에 오브젝트 스토리지 버킷을 직접 비워야 합니다.

예를 들어 프로덕션에서 스테이징으로의 복원을 자동화할 때처럼 안정적인 복원 프로세스가 필요하면, 백업과 동일한 버전의 새 GitLab 설치를 사용합니다.

SQL 데이터를 복원할 때 PostgreSQL 익스텐션이 소유한 뷰는 건너뜁니다.

대상 GitLab 인스턴스가 정확히 동일한 버전이어야 합니다#

백업은 그것을 생성한 GitLab과 정확히 같은 버전 및 종류(CE 또는 EE)로만 복원할 수 있습니다. 예를 들어 CE 15.1.4입니다.

백업이 현재 설치된 버전과 다르면, 백업을 복원하기 전에 GitLab 설치를 다운그레이드하거나 업그레이드해야 합니다.

GitLab 시크릿을 복원해야 합니다#

백업을 복원하려면 GitLab 시크릿도 복원해야 합니다. 새 GitLab 인스턴스로 마이그레이션하는 경우에는 이전 서버에서 GitLab 시크릿 파일을 복사해야 합니다. 여기에는 데이터베이스 암호화 키, CI/CD 변수, 2단계 인증에 사용하는 변수가 포함됩니다. 이 키가 없으면 2단계 인증을 사용하는 사용자가 액세스를 잃고 GitLab Runner가 로그인할 수 없는 등 여러 문제가 발생합니다.

Warning

다른 FQDN으로 복원하면 WebAuthn 장치가 비활성화됩니다: WebAuthn 등록(예: YubiKey)은 등록이 생성된 오리진(도메인/호스트명)에 암호학적으로 바인딩됩니다. 원래 인스턴스와 다른 FQDN을 가진 GitLab 인스턴스로 백업을 복원하면 모든 WebAuthn 장치가 비활성화됩니다. 복원이 완료된 후 사용자는 WebAuthn 장치를 다시 등록해야 합니다.

WebAuthn과 호스트명 요구 사항에 대한 자세한 내용은 2단계 인증을 참고합니다.

설치 방법에 따라 다음을 복원합니다.

/etc/gitlab/gitlab-secrets.json

/etc/gitlab을 /srv/gitlab/config 아래에 마운트했다면 다음과 같습니다.

/srv/gitlab/config/gitlab-secrets.json
/home/git/gitlab/.secret

다음 문서도 참고합니다.

특정 GitLab 구성은 원본 백업 환경과 일치해야 합니다#

이전의 /etc/gitlab/gitlab.rb(Linux 패키지 설치) 또는 /home/git/gitlab/config/gitlab.yml(자체 컴파일 설치)과 TLS 또는 SSH 키 및 인증서는 별도로 복원하는 것이 좋습니다.

일부 구성은 PostgreSQL의 데이터와 결합되어 있습니다. 예를 들어 다음과 같습니다.

  • 원본 환경에 리포지터리 스토리지가 세 개(예: default, my-storage-1, my-storage-2) 있다면, 대상 환경의 구성에도 최소한 그 스토리지 이름이 정의되어 있어야 합니다.
  • 로컬 스토리지를 사용하는 환경의 백업을 복원하면 대상 환경이 오브젝트 스토리지를 사용하더라도 로컬 스토리지로 복원됩니다. 오브젝트 스토리지로의 마이그레이션은 복원 전이나 후에 수행해야 합니다.

자세한 내용은 백업에 포함되지 않는 데이터를 참고합니다.

마운트 지점인 디렉터리 복원#

마운트 지점인 디렉터리로 복원하는 경우에는 복원을 시도하기 전에 해당 디렉터리가 비어 있어야 합니다. 그렇지 않으면 GitLab이 새 데이터를 복원하기 전에 이 디렉터리를 이동하려 하고, 이로 인해 오류가 발생합니다.

NFS 마운트 구성에 대한 자세한 내용을 참고합니다.

Linux 패키지 설치의 복원#

이 절차는 다음을 전제합니다.

  • 백업을 생성한 GitLab과 정확히 같은 버전 및 종류(CE/EE)를 설치했습니다.
  • sudo gitlab-ctl reconfigure를 최소 한 번 실행했습니다.
  • GitLab이 실행 중입니다. 실행 중이 아니면 sudo gitlab-ctl start로 시작합니다.

먼저 백업 tar 파일이 gitlab.rb 구성의 gitlab_rails['backup_path']에 지정된 백업 디렉터리에 있는지 확인합니다. 기본값은 /var/opt/gitlab/backups입니다. 백업 파일은 git 사용자가 소유해야 합니다.

sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/
sudo chown git:git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar

데이터베이스에 연결된 프로세스를 중지합니다. GitLab의 나머지 부분은 계속 실행해 둡니다.

sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
# Verify
sudo gitlab-ctl status

다음으로 복원 사전 요구 사항 단계를 완료했는지, 그리고 원본 설치에서 GitLab 시크릿 파일을 복사한 뒤 gitlab-ctl reconfigure를 실행했는지 확인합니다.

다음으로 복원하려는 백업의 ID를 지정해 백업을 복원합니다.

Warning

다음 명령은 GitLab 데이터베이스의 콘텐츠를 덮어씁니다.

# NOTE: "_gitlab_backup.tar" is omitted from the name
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

백업 tar 파일과 설치된 GitLab 버전이 일치하지 않으면 복원 명령이 다음 오류 메시지와 함께 중단됩니다.

GitLab version mismatch:
  Your current GitLab version (16.5.0-ee) differs from the GitLab version in the backup!
  Please switch to the following version and try again:
  version: 16.4.3-ee

올바른 GitLab 버전을 설치한 뒤 다시 시도합니다.

Warning

성능상의 이유로 또는 Patroni 클러스터와 함께 PgBouncer를 사용하는 설치에서는 복원 명령에 추가 파라미터가 필요합니다.

PostgreSQL 노드에서 reconfigure를 실행합니다.

sudo gitlab-ctl reconfigure

다음으로 GitLab을 시작하고 확인합니다.

sudo gitlab-ctl start
sudo gitlab-rake gitlab:check SANITIZE=true

특히 /etc/gitlab/gitlab-secrets.json을 복원했거나 복원 대상이 다른 서버인 경우에는 데이터베이스 값을 복호화할 수 있는지 확인합니다.

sudo gitlab-rake gitlab:doctor:secrets

추가 확신을 얻으려면 업로드된 파일에 대해 무결성 검사를 수행할 수 있습니다.

sudo gitlab-rake gitlab:artifacts:check
sudo gitlab-rake gitlab:lfs:check
sudo gitlab-rake gitlab:uploads:check

복원이 완료된 후에는 데이터베이스 성능을 개선하고 UI의 불일치를 방지하기 위해 데이터베이스 통계를 생성하는 것이 좋습니다.

  1. 데이터베이스 콘솔에 들어갑니다.

  2. 다음을 실행합니다.

    SET STATEMENT_TIMEOUT=0 ; ANALYZE VERBOSE;
    

이 명령을 복원 명령에 통합하는 논의가 진행 중입니다. 자세한 내용은 이슈 276184를 참고합니다.

복원 후 검증 가이드:

Docker 이미지 및 GitLab Helm 차트 설치의 복원#

Docker 이미지나 Kubernetes 클러스터의 GitLab Helm 차트를 사용하는 GitLab 설치에서는 복원 작업이 복원 디렉터리가 비어 있기를 기대합니다. 그러나 Docker 및 Kubernetes 볼륨 마운트에서는 Linux 운영 체제의 lost+found 디렉터리처럼 일부 시스템 수준 디렉터리가 볼륨 루트에 생성될 수 있습니다. 이러한 디렉터리는 보통 root가 소유하는데, 복원 Rake 태스크는 git 사용자로 실행되기 때문에 액세스 권한 오류가 발생할 수 있습니다. GitLab 설치를 복원하려면 사용자가 복원 대상 디렉터리가 비어 있는지 확인해야 합니다.

이 두 설치 유형 모두에서 백업 tarball이 백업 위치(기본 위치는 /var/opt/gitlab/backups)에 있어야 합니다.

Helm 차트 설치의 복원#

GitLab Helm 차트는 GitLab Helm 차트 설치 복원에 문서화된 프로세스를 사용합니다

Docker 이미지 설치의 복원#

Docker Swarm을 사용하는 경우, Puma가 종료되어 컨테이너 상태 확인이 실패하기 때문에 복원 과정에서 컨테이너가 다시 시작될 수 있습니다. 이 문제를 우회하려면 상태 확인 메커니즘을 일시적으로 비활성화합니다.

  1. docker-compose.yml을 편집합니다.

    healthcheck:
      disable: true
    
  2. 스택을 배포합니다.

    docker stack deploy --compose-file docker-compose.yml mystack
    

자세한 내용은 이슈 6846을 참고합니다.

복원 작업은 호스트에서 실행할 수 있습니다.

# Stop the processes that are connected to the database
docker exec -it <name of container> gitlab-ctl stop puma
docker exec -it <name of container> gitlab-ctl stop sidekiq

# Verify that the processes are all down before continuing
docker exec -it <name of container> gitlab-ctl status

# Run the restore. NOTE: "_gitlab_backup.tar" is omitted from the name
docker exec -it <name of container> gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

# Restart the GitLab container
docker restart <name of container>

# Check GitLab
docker exec -it <name of container> gitlab-rake gitlab:check SANITIZE=true

자체 컴파일 설치의 복원#

  1. 먼저 백업 tar 파일이 gitlab.yml 구성에 지정된 백업 디렉터리에 있는지 확인합니다.

    ## Backup settings
    backup:
      path: "tmp/backups"   # Relative paths are relative to Rails.root (default: tmp/backups/)
    

    기본값은 /home/git/gitlab/tmp/backups이며, git 사용자가 소유해야 합니다.

  2. 백업 절차를 시작합니다.

    # Stop processes that are connected to the database
    sudo service gitlab stop
    
    sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
    

    출력 예시:

    Unpacking backup... [DONE]
    Restoring database tables:
    -- create_table("events", {:force=>true})
      -> 0.2231s
    [...]
    - Loading fixture events...[DONE]
    - Loading fixture issues...[DONE]
    - Loading fixture keys...[SKIPPING]
    - Loading fixture merge_requests...[DONE]
    - Loading fixture milestones...[DONE]
    - Loading fixture namespaces...[DONE]
    - Loading fixture notes...[DONE]
    - Loading fixture projects...[DONE]
    - Loading fixture protected_branches...[SKIPPING]
    - Loading fixture schema_migrations...[DONE]
    - Loading fixture services...[SKIPPING]
    - Loading fixture snippets...[SKIPPING]
    - Loading fixture taggings...[SKIPPING]
    - Loading fixture tags...[SKIPPING]
    - Loading fixture users...[DONE]
    - Loading fixture users_projects...[DONE]
    - Loading fixture web_hooks...[SKIPPING]
    - Loading fixture wikis...[SKIPPING]
    Restoring repositories:
    - Restoring repository abcd... [DONE]
    - Object pool 1 ...
    Deleting tmp directories...[DONE]
    
  3. 필요하면 /home/git/gitlab/.secret을 복원합니다.

  4. GitLab을 다시 시작합니다.

    sudo service gitlab restart
    

백업에서 하나 또는 몇 개의 프로젝트나 그룹만 복원#

GitLab 인스턴스를 복원하는 Rake 태스크는 단일 프로젝트나 그룹의 복원을 지원하지 않지만, 백업을 별도의 임시 GitLab 인스턴스로 복원한 다음 그곳에서 프로젝트나 그룹을 내보내는 방법을 우회 수단으로 사용할 수 있습니다.

  1. 복원하려는 백업 인스턴스와 같은 버전으로 새 GitLab 인스턴스를 설치합니다.
  2. 이 새 인스턴스에 백업을 복원한 다음, 프로젝트 또는 그룹을 내보냅니다. 무엇이 내보내지고 무엇이 내보내지지 않는지에 대한 자세한 내용은 내보내기 기능 문서를 참고합니다.
  3. 내보내기가 완료되면 이전 인스턴스로 이동해 가져옵니다.
  4. 원하던 프로젝트나 그룹의 가져오기가 완료되면 새로 만든 임시 GitLab 인스턴스를 삭제할 수 있습니다.

개별 프로젝트나 그룹의 직접 복원을 제공하는 기능 요청은 이슈 #17517에서 논의되고 있습니다.

증분 리포지터리 백업 복원#

gitlab-backup으로 증분 리포지터리 백업을 생성하면, 생성된 백업 아카이브에는 전체 복원에 필요한 모든 리포지터리 데이터가 들어 있습니다. 복원할 때는 일반 백업 아카이브를 복원할 때와 같은 지침을 사용합니다.

내부적으로 증분 리포지터리 백업은 이전 백업 이후에 변경된 내용만 저장합니다. 증분 백업을 생성하면 gitlab-backup은 원래의 전체 백업 이후의 모든 단계를 백업 아카이브에 함께 담습니다. 따라서 개별 리포지터리 백업 번들이 서로 의존하더라도 아카이브는 자체적으로 완결됩니다.

서버 측 리포지터리 백업에서는 백업 아카이브에 리포지터리 데이터가 들어 있지 않습니다. 대신 각 Gitaly 노드가 리포지터리 데이터를 오브젝트 스토리지에 저장하고, 각 증분은 별도의 객체로 저장됩니다. 서버 측 복원에서는 Gitaly가 백업 매니페스트를 읽고 각 증분을 순서대로 적용합니다.

Warning

오브젝트 스토리지에서 증분 백업 파일을 삭제하지 않습니다. 중간 파일이 삭제되면(예: 오브젝트 스토리지 수명 주기 정책으로 인해) 백업 체인이 끊어져 백업을 복원할 수 없습니다.

복원 옵션#

GitLab이 백업에서 복원하기 위해 제공하는 명령줄 도구는 더 많은 옵션을 받을 수 있습니다.

백업이 여러 개일 때 복원할 백업 지정#

백업 파일은 백업 ID로 시작하는 이름 규칙을 사용합니다. 백업이 두 개 이상 있으면 환경 변수 BACKUP=<backup-id>를 설정해 어떤 <backup-id>_gitlab_backup.tar 파일을 복원할지 지정해야 합니다.

복원 중 프롬프트 비활성화#

백업에서 복원하는 동안 복원 스크립트는 다음 시점에 확인을 요청합니다.

  • Write to authorized_keys 설정이 활성화된 경우, 복원 스크립트가 authorized_keys 파일을 삭제하고 다시 만들기 전.
  • 데이터베이스를 복원할 때, 복원 스크립트가 기존 테이블을 모두 제거하기 전.
  • 데이터베이스를 복원한 후 스키마 복원에 오류가 있었다면, 이후에 더 많은 문제가 발생할 가능성이 크므로 계속 진행하기 전.

이 프롬프트를 비활성화하려면 GITLAB_ASSUME_YES 환경 변수를 1로 설정합니다.

  • Linux 패키지 설치:

    sudo GITLAB_ASSUME_YES=1 gitlab-backup restore
    
  • 자체 컴파일 설치:

    sudo -u git -H GITLAB_ASSUME_YES=1 bundle exec rake gitlab:backup:restore RAILS_ENV=production
    

force=yes 환경 변수도 이 프롬프트를 비활성화합니다.

복원 시 작업 제외#

환경 변수 SKIP을 추가해 복원 시 특정 작업을 제외할 수 있습니다. 값은 다음 옵션을 쉼표로 구분한 목록입니다.

  • db(데이터베이스)
  • uploads(첨부 파일)
  • builds(CI job 출력 로그)
  • artifacts(CI job 아티팩트)
  • lfs(LFS 객체)
  • terraform_state(Terraform 상태)
  • registry(컨테이너 레지스트리 이미지)
  • pages(Pages 콘텐츠)
  • repositories(Git 리포지터리 데이터)
  • packages(패키지)

특정 작업을 제외하려면 다음과 같이 진행합니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> SKIP=db,uploads
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> SKIP=db,uploads RAILS_ENV=production
    

특정 리포지터리 스토리지 복원#

Warning

GitLab 17.1 및 이전 버전은 데이터 손실을 유발할 수 있는 경쟁 조건의 영향을 받습니다. 이 문제는 포크되었고 GitLab 객체 풀을 사용하는 리포지터리에 영향을 줍니다. 데이터 손실을 방지하려면 GitLab 17.2 이상에서만 백업을 복원합니다.

여러 리포지터리 스토리지를 사용할 때는 REPOSITORIES_STORAGES 옵션으로 특정 리포지터리 스토리지의 리포지터리를 따로 복원할 수 있습니다. 이 옵션은 스토리지 이름을 쉼표로 구분한 목록을 받습니다.

예를 들어 다음과 같습니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> REPOSITORIES_STORAGES=storage1,storage2
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> REPOSITORIES_STORAGES=storage1,storage2
    

특정 리포지터리 복원#

히스토리
  • SKIP_REPOSITORIES_PATHS 복원이 GitLab 19.4에서 백업에서 제외된 리포지터리를 더 이상 제거하지 않도록 변경되었습니다.
Warning

GitLab 17.1 및 이전 버전은 데이터 손실을 유발할 수 있는 경쟁 조건의 영향을 받습니다. 이 문제는 포크되었고 GitLab 객체 풀을 사용하는 리포지터리에 영향을 줍니다. 데이터 손실을 방지하려면 GitLab 17.2 이상에서만 백업을 복원합니다.

REPOSITORIES_PATHS와 SKIP_REPOSITORIES_PATHS 옵션으로 특정 리포지터리를 복원할 수 있습니다. 두 옵션 모두 프로젝트와 그룹 경로를 쉼표로 구분한 목록을 받습니다. 그룹 경로를 지정하면, 사용한 옵션에 따라 그 그룹과 하위 그룹의 모든 프로젝트에 있는 모든 리포지터리가 포함되거나 건너뛰어집니다. 그룹과 프로젝트는 모두 지정된 백업이나 대상 인스턴스에 존재해야 합니다.

Note

REPOSITORIES_PATHS와 SKIP_REPOSITORIES_PATHS 옵션은 Git 리포지터리에만 적용됩니다. 프로젝트나 그룹의 데이터베이스 항목에는 적용되지 않습니다. SKIP=db로 리포지터리 백업을 생성했다면, 그 백업만으로는 특정 리포지터리를 새 인스턴스로 복원할 수 없습니다.

REPOSITORIES_PATHS 또는 SKIP_REPOSITORIES_PATHS 중 하나를 설정하면 특정 리포지터리만 복원됩니다. 이런 복원에서는 인스턴스에 이미 있는 리포지터리가 제거되지 않습니다. 따라서 나중의 복원이 앞선 복원으로 복원된 리포지터리를 제거하지 않으므로, 이런 복원을 여러 번 연달아 실행할 수 있습니다.

두 옵션을 모두 지정하지 않는 전체 복원에서는 복원 중인 백업에 포함되지 않은 리포지터리가 모두 제거됩니다. 이렇게 하면 오래된 리포지터리, 예를 들어 백업을 만든 뒤 생성된 프로젝트에 속한 리포지터리가 정리됩니다.

예를 들어 Group A(group-a)의 모든 프로젝트에 있는 모든 리포지터리와 Group B의 Project C 리포지터리(group-b/project-c)를 복원하고 Group A의 Project D(group-a/project-d)를 건너뛰려면 다음과 같이 진행합니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
    

Group A의 Project D(group-a/project-d) 리포지터리를 제외한 백업의 모든 항목을 복원하려면 다음과 같이 진행합니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> SKIP_REPOSITORIES_PATHS=group-a/project-d
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> SKIP_REPOSITORIES_PATHS=group-a/project-d
    

압축되지 않은 백업 복원#

SKIP=tar로 만든 압축되지 않은 백업이 있고 BACKUP=<backup-id>로 백업을 선택하지 않으면, 압축되지 않은 백업이 사용됩니다.

예를 들어 다음과 같습니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore
    

서버 측 리포지터리 백업을 사용한 복원#

히스토리

서버 측 백업을 수집하면 복원 프로세스는 기본적으로 서버 측 리포지터리 백업 생성에 나오는 서버 측 복원 메커니즘을 사용합니다. 각 리포지터리를 호스팅하는 Gitaly 노드가 필요한 백업 데이터를 오브젝트 스토리지에서 직접 가져오도록 백업 복원을 구성할 수 있습니다.

  1. Gitaly에서 서버 측 백업 대상을 구성합니다.
  2. 복원하려는 백업의 ID를 지정해 서버 측 백업 복원 프로세스를 시작합니다.
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce
sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=11493107454_2018_04_25_10.6.4-ce
kubectl exec  -it -- backup-utility --restore -t <backup_ID> --repositories-server-side

cron 기반 백업을 사용할 때는 추가 인수에 --repositories-server-side 플래그를 추가합니다.

문제 해결#

다음은 발생할 수 있는 문제와 해결 방법 후보입니다.

Linux 패키지 설치의 출력 경고와 함께 데이터베이스 백업 복원#

백업 복원 절차를 사용하면 다음 경고 메시지가 나타날 수 있습니다.

ERROR: must be owner of extension pg_trgm
ERROR: must be owner of extension btree_gist
ERROR: must be owner of extension plpgsql
WARNING:  no privileges could be revoked for "public" (two occurrences)
WARNING:  no privileges were granted for "public" (two occurrences)

이러한 경고 메시지가 나타나더라도 백업은 정상적으로 복원됩니다.

Rake 태스크는 이를 gitlab 사용자로 실행하는데, 이 사용자에게는 데이터베이스에 대한 superuser 액세스 권한이 없습니다. 복원을 시작할 때도 gitlab 사용자로 실행되지만, 액세스 권한이 없는 객체를 변경하려고 시도합니다. 이러한 객체는 데이터베이스 백업이나 복원에 영향을 주지 않지만 경고 메시지를 표시합니다.

자세한 내용은 다음을 참고합니다.

Git 서버 훅으로 인한 복원 실패#

백업에서 복원하는 동안 다음 조건이 모두 참이면 오류가 발생할 수 있습니다.

  • GitLab 15.10 및 이전 버전의 방식으로 Git 서버 훅(custom_hook)이 구성되어 있음
  • GitLab 버전이 15.11 이상임
  • GitLab이 관리하는 위치 밖의 디렉터리로 심볼릭 링크를 만들었음

오류는 다음과 같습니다.

{"level":"fatal","msg":"restore: pipeline: 1 failures encountered:\n - @hashed/path/to/hashed_repository.git (path/to_project): manager: restore custom hooks, \"@hashed/path/to/hashed_repository/_-ee/001.custom_hooks.tar\": rpc error: code = Internal desc = setting custom hooks: generating prepared vote: walking directory: copying file to hash: read /mnt/gitlab-app/git-data/repositories/+gitaly/tmp/default-repositories.old.<timestamp>.<temporaryfolder>/custom_hooks/compliance-triggers.d: is a directory\n","pid":3256017,"time":"2023-08-10T20:09:44.395Z"}

이를 해결하려면 GitLab 15.11 이상에 맞게 Git 서버 훅을 업데이트하고 새 백업을 생성합니다.

fapolicyd를 사용할 때 복원은 성공했지만 리포지터리가 비어 있는 것으로 표시되는 문제#

보안을 강화하기 위해 fapolicyd를 사용하면 GitLab이 복원이 성공했다고 보고하지만 리포지터리가 비어 있는 것으로 표시될 수 있습니다. 추가 문제 해결 도움말은 Gitaly 문제 해결 문서를 참고합니다.

GitLab 복원

GitLab v19.4
Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기

요약

GitLab 복원 작업은 시스템 연속성을 유지하고 데이터 손실에서 복구하기 위해 백업에서 데이터를 복구합니다. 복원 프로세스에는 백업과 동일한 버전의 기존 GitLab 설치가 필요합니다. 복원을 수행하려면 먼저 작동하는 GitLab 설치가 있어야 합니다.

GitLab 복원 작업은 시스템 연속성을 유지하고 데이터 손실에서 복구하기 위해 백업에서 데이터를 복구합니다. 복원 작업은 다음을 수행합니다.

  • 데이터베이스 레코드와 구성을 복구합니다
  • Git 리포지터리, 컨테이너 레지스트리 이미지, 업로드된 콘텐츠를 복원합니다
  • 패키지 레지스트리 데이터와 CI/CD 아티팩트를 복원합니다
  • 계정 및 그룹 설정을 복원합니다
  • 프로젝트 및 그룹 위키를 복구합니다
  • 프로젝트 수준 보안 파일을 복원합니다
  • 외부 머지 리퀘스트 diff를 복구합니다

복원 프로세스에는 백업과 동일한 버전의 기존 GitLab 설치가 필요합니다. 사전 요구 사항을 따르고, 프로덕션에서 사용하기 전에 전체 복원 프로세스를 테스트합니다.

복원 사전 요구 사항#

대상 GitLab 인스턴스가 이미 작동하고 있어야 합니다#

복원을 수행하려면 먼저 작동하는 GitLab 설치가 있어야 합니다. 복원 작업을 수행하는 시스템 사용자(git)는 일반적으로 데이터를 가져올 SQL 데이터베이스 (gitlabhq_production)를 생성하거나 삭제할 권한이 없기 때문입니다.

대상 GitLab 인스턴스에 기존 데이터가 없어야 합니다#

복원 프로세스는 데이터 유형에 따라 기존 데이터를 다르게 처리합니다.

  • PostgreSQL 데이터는 복원 프로세스 중에 자동으로 지워집니다.
  • Git 리포지터리: 같은 이름의 리포지터리가 이미 있으면 "repository already exists" 오류와 함께 복원이 실패합니다. 자세한 내용은 이슈 118459를 참고합니다.
  • 파일 시스템 데이터는 가능한 경우 복원 전에 별도의 디렉터리로 이동됩니다.
  • 오브젝트 스토리지 데이터는 자동으로 지워지지 않습니다. 고아 데이터가 남지 않도록 복원 전에 오브젝트 스토리지 버킷을 직접 비워야 합니다.

예를 들어 프로덕션에서 스테이징으로의 복원을 자동화할 때처럼 안정적인 복원 프로세스가 필요하면, 백업과 동일한 버전의 새 GitLab 설치를 사용합니다.

SQL 데이터를 복원할 때 PostgreSQL 익스텐션이 소유한 뷰는 건너뜁니다.

대상 GitLab 인스턴스가 정확히 동일한 버전이어야 합니다#

백업은 그것을 생성한 GitLab과 정확히 같은 버전 및 종류(CE 또는 EE)로만 복원할 수 있습니다. 예를 들어 CE 15.1.4입니다.

백업이 현재 설치된 버전과 다르면, 백업을 복원하기 전에 GitLab 설치를 다운그레이드하거나 업그레이드해야 합니다.

GitLab 시크릿을 복원해야 합니다#

백업을 복원하려면 GitLab 시크릿도 복원해야 합니다. 새 GitLab 인스턴스로 마이그레이션하는 경우에는 이전 서버에서 GitLab 시크릿 파일을 복사해야 합니다. 여기에는 데이터베이스 암호화 키, CI/CD 변수, 2단계 인증에 사용하는 변수가 포함됩니다. 이 키가 없으면 2단계 인증을 사용하는 사용자가 액세스를 잃고 GitLab Runner가 로그인할 수 없는 등 여러 문제가 발생합니다.

Warning

다른 FQDN으로 복원하면 WebAuthn 장치가 비활성화됩니다: WebAuthn 등록(예: YubiKey)은 등록이 생성된 오리진(도메인/호스트명)에 암호학적으로 바인딩됩니다. 원래 인스턴스와 다른 FQDN을 가진 GitLab 인스턴스로 백업을 복원하면 모든 WebAuthn 장치가 비활성화됩니다. 복원이 완료된 후 사용자는 WebAuthn 장치를 다시 등록해야 합니다.

WebAuthn과 호스트명 요구 사항에 대한 자세한 내용은 2단계 인증을 참고합니다.

설치 방법에 따라 다음을 복원합니다.

/etc/gitlab/gitlab-secrets.json

/etc/gitlab을 /srv/gitlab/config 아래에 마운트했다면 다음과 같습니다.

/srv/gitlab/config/gitlab-secrets.json
/home/git/gitlab/.secret

다음 문서도 참고합니다.

특정 GitLab 구성은 원본 백업 환경과 일치해야 합니다#

이전의 /etc/gitlab/gitlab.rb(Linux 패키지 설치) 또는 /home/git/gitlab/config/gitlab.yml(자체 컴파일 설치)과 TLS 또는 SSH 키 및 인증서는 별도로 복원하는 것이 좋습니다.

일부 구성은 PostgreSQL의 데이터와 결합되어 있습니다. 예를 들어 다음과 같습니다.

  • 원본 환경에 리포지터리 스토리지가 세 개(예: default, my-storage-1, my-storage-2) 있다면, 대상 환경의 구성에도 최소한 그 스토리지 이름이 정의되어 있어야 합니다.
  • 로컬 스토리지를 사용하는 환경의 백업을 복원하면 대상 환경이 오브젝트 스토리지를 사용하더라도 로컬 스토리지로 복원됩니다. 오브젝트 스토리지로의 마이그레이션은 복원 전이나 후에 수행해야 합니다.

자세한 내용은 백업에 포함되지 않는 데이터를 참고합니다.

마운트 지점인 디렉터리 복원#

마운트 지점인 디렉터리로 복원하는 경우에는 복원을 시도하기 전에 해당 디렉터리가 비어 있어야 합니다. 그렇지 않으면 GitLab이 새 데이터를 복원하기 전에 이 디렉터리를 이동하려 하고, 이로 인해 오류가 발생합니다.

NFS 마운트 구성에 대한 자세한 내용을 참고합니다.

Linux 패키지 설치의 복원#

이 절차는 다음을 전제합니다.

  • 백업을 생성한 GitLab과 정확히 같은 버전 및 종류(CE/EE)를 설치했습니다.
  • sudo gitlab-ctl reconfigure를 최소 한 번 실행했습니다.
  • GitLab이 실행 중입니다. 실행 중이 아니면 sudo gitlab-ctl start로 시작합니다.

먼저 백업 tar 파일이 gitlab.rb 구성의 gitlab_rails['backup_path']에 지정된 백업 디렉터리에 있는지 확인합니다. 기본값은 /var/opt/gitlab/backups입니다. 백업 파일은 git 사용자가 소유해야 합니다.

sudo cp 11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar /var/opt/gitlab/backups/
sudo chown git:git /var/opt/gitlab/backups/11493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar

데이터베이스에 연결된 프로세스를 중지합니다. GitLab의 나머지 부분은 계속 실행해 둡니다.

sudo gitlab-ctl stop puma
sudo gitlab-ctl stop sidekiq
# Verify
sudo gitlab-ctl status

다음으로 복원 사전 요구 사항 단계를 완료했는지, 그리고 원본 설치에서 GitLab 시크릿 파일을 복사한 뒤 gitlab-ctl reconfigure를 실행했는지 확인합니다.

다음으로 복원하려는 백업의 ID를 지정해 백업을 복원합니다.

Warning

다음 명령은 GitLab 데이터베이스의 콘텐츠를 덮어씁니다.

# NOTE: "_gitlab_backup.tar" is omitted from the name
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

백업 tar 파일과 설치된 GitLab 버전이 일치하지 않으면 복원 명령이 다음 오류 메시지와 함께 중단됩니다.

GitLab version mismatch:
  Your current GitLab version (16.5.0-ee) differs from the GitLab version in the backup!
  Please switch to the following version and try again:
  version: 16.4.3-ee

올바른 GitLab 버전을 설치한 뒤 다시 시도합니다.

Warning

성능상의 이유로 또는 Patroni 클러스터와 함께 PgBouncer를 사용하는 설치에서는 복원 명령에 추가 파라미터가 필요합니다.

PostgreSQL 노드에서 reconfigure를 실행합니다.

sudo gitlab-ctl reconfigure

다음으로 GitLab을 시작하고 확인합니다.

sudo gitlab-ctl start
sudo gitlab-rake gitlab:check SANITIZE=true

특히 /etc/gitlab/gitlab-secrets.json을 복원했거나 복원 대상이 다른 서버인 경우에는 데이터베이스 값을 복호화할 수 있는지 확인합니다.

sudo gitlab-rake gitlab:doctor:secrets

추가 확신을 얻으려면 업로드된 파일에 대해 무결성 검사를 수행할 수 있습니다.

sudo gitlab-rake gitlab:artifacts:check
sudo gitlab-rake gitlab:lfs:check
sudo gitlab-rake gitlab:uploads:check

복원이 완료된 후에는 데이터베이스 성능을 개선하고 UI의 불일치를 방지하기 위해 데이터베이스 통계를 생성하는 것이 좋습니다.

  1. 데이터베이스 콘솔에 들어갑니다.

  2. 다음을 실행합니다.

    SET STATEMENT_TIMEOUT=0 ; ANALYZE VERBOSE;
    

이 명령을 복원 명령에 통합하는 논의가 진행 중입니다. 자세한 내용은 이슈 276184를 참고합니다.

복원 후 검증 가이드:

Docker 이미지 및 GitLab Helm 차트 설치의 복원#

Docker 이미지나 Kubernetes 클러스터의 GitLab Helm 차트를 사용하는 GitLab 설치에서는 복원 작업이 복원 디렉터리가 비어 있기를 기대합니다. 그러나 Docker 및 Kubernetes 볼륨 마운트에서는 Linux 운영 체제의 lost+found 디렉터리처럼 일부 시스템 수준 디렉터리가 볼륨 루트에 생성될 수 있습니다. 이러한 디렉터리는 보통 root가 소유하는데, 복원 Rake 태스크는 git 사용자로 실행되기 때문에 액세스 권한 오류가 발생할 수 있습니다. GitLab 설치를 복원하려면 사용자가 복원 대상 디렉터리가 비어 있는지 확인해야 합니다.

이 두 설치 유형 모두에서 백업 tarball이 백업 위치(기본 위치는 /var/opt/gitlab/backups)에 있어야 합니다.

Helm 차트 설치의 복원#

GitLab Helm 차트는 GitLab Helm 차트 설치 복원에 문서화된 프로세스를 사용합니다

Docker 이미지 설치의 복원#

Docker Swarm을 사용하는 경우, Puma가 종료되어 컨테이너 상태 확인이 실패하기 때문에 복원 과정에서 컨테이너가 다시 시작될 수 있습니다. 이 문제를 우회하려면 상태 확인 메커니즘을 일시적으로 비활성화합니다.

  1. docker-compose.yml을 편집합니다.

    healthcheck:
      disable: true
    
  2. 스택을 배포합니다.

    docker stack deploy --compose-file docker-compose.yml mystack
    

자세한 내용은 이슈 6846을 참고합니다.

복원 작업은 호스트에서 실행할 수 있습니다.

# Stop the processes that are connected to the database
docker exec -it <name of container> gitlab-ctl stop puma
docker exec -it <name of container> gitlab-ctl stop sidekiq

# Verify that the processes are all down before continuing
docker exec -it <name of container> gitlab-ctl status

# Run the restore. NOTE: "_gitlab_backup.tar" is omitted from the name
docker exec -it <name of container> gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

# Restart the GitLab container
docker restart <name of container>

# Check GitLab
docker exec -it <name of container> gitlab-rake gitlab:check SANITIZE=true

자체 컴파일 설치의 복원#

  1. 먼저 백업 tar 파일이 gitlab.yml 구성에 지정된 백업 디렉터리에 있는지 확인합니다.

    ## Backup settings
    backup:
      path: "tmp/backups"   # Relative paths are relative to Rails.root (default: tmp/backups/)
    

    기본값은 /home/git/gitlab/tmp/backups이며, git 사용자가 소유해야 합니다.

  2. 백업 절차를 시작합니다.

    # Stop processes that are connected to the database
    sudo service gitlab stop
    
    sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
    

    출력 예시:

    Unpacking backup... [DONE]
    Restoring database tables:
    -- create_table("events", {:force=>true})
      -> 0.2231s
    [...]
    - Loading fixture events...[DONE]
    - Loading fixture issues...[DONE]
    - Loading fixture keys...[SKIPPING]
    - Loading fixture merge_requests...[DONE]
    - Loading fixture milestones...[DONE]
    - Loading fixture namespaces...[DONE]
    - Loading fixture notes...[DONE]
    - Loading fixture projects...[DONE]
    - Loading fixture protected_branches...[SKIPPING]
    - Loading fixture schema_migrations...[DONE]
    - Loading fixture services...[SKIPPING]
    - Loading fixture snippets...[SKIPPING]
    - Loading fixture taggings...[SKIPPING]
    - Loading fixture tags...[SKIPPING]
    - Loading fixture users...[DONE]
    - Loading fixture users_projects...[DONE]
    - Loading fixture web_hooks...[SKIPPING]
    - Loading fixture wikis...[SKIPPING]
    Restoring repositories:
    - Restoring repository abcd... [DONE]
    - Object pool 1 ...
    Deleting tmp directories...[DONE]
    
  3. 필요하면 /home/git/gitlab/.secret을 복원합니다.

  4. GitLab을 다시 시작합니다.

    sudo service gitlab restart
    

백업에서 하나 또는 몇 개의 프로젝트나 그룹만 복원#

GitLab 인스턴스를 복원하는 Rake 태스크는 단일 프로젝트나 그룹의 복원을 지원하지 않지만, 백업을 별도의 임시 GitLab 인스턴스로 복원한 다음 그곳에서 프로젝트나 그룹을 내보내는 방법을 우회 수단으로 사용할 수 있습니다.

  1. 복원하려는 백업 인스턴스와 같은 버전으로 새 GitLab 인스턴스를 설치합니다.
  2. 이 새 인스턴스에 백업을 복원한 다음, 프로젝트 또는 그룹을 내보냅니다. 무엇이 내보내지고 무엇이 내보내지지 않는지에 대한 자세한 내용은 내보내기 기능 문서를 참고합니다.
  3. 내보내기가 완료되면 이전 인스턴스로 이동해 가져옵니다.
  4. 원하던 프로젝트나 그룹의 가져오기가 완료되면 새로 만든 임시 GitLab 인스턴스를 삭제할 수 있습니다.

개별 프로젝트나 그룹의 직접 복원을 제공하는 기능 요청은 이슈 #17517에서 논의되고 있습니다.

증분 리포지터리 백업 복원#

gitlab-backup으로 증분 리포지터리 백업을 생성하면, 생성된 백업 아카이브에는 전체 복원에 필요한 모든 리포지터리 데이터가 들어 있습니다. 복원할 때는 일반 백업 아카이브를 복원할 때와 같은 지침을 사용합니다.

내부적으로 증분 리포지터리 백업은 이전 백업 이후에 변경된 내용만 저장합니다. 증분 백업을 생성하면 gitlab-backup은 원래의 전체 백업 이후의 모든 단계를 백업 아카이브에 함께 담습니다. 따라서 개별 리포지터리 백업 번들이 서로 의존하더라도 아카이브는 자체적으로 완결됩니다.

서버 측 리포지터리 백업에서는 백업 아카이브에 리포지터리 데이터가 들어 있지 않습니다. 대신 각 Gitaly 노드가 리포지터리 데이터를 오브젝트 스토리지에 저장하고, 각 증분은 별도의 객체로 저장됩니다. 서버 측 복원에서는 Gitaly가 백업 매니페스트를 읽고 각 증분을 순서대로 적용합니다.

Warning

오브젝트 스토리지에서 증분 백업 파일을 삭제하지 않습니다. 중간 파일이 삭제되면(예: 오브젝트 스토리지 수명 주기 정책으로 인해) 백업 체인이 끊어져 백업을 복원할 수 없습니다.

복원 옵션#

GitLab이 백업에서 복원하기 위해 제공하는 명령줄 도구는 더 많은 옵션을 받을 수 있습니다.

백업이 여러 개일 때 복원할 백업 지정#

백업 파일은 백업 ID로 시작하는 이름 규칙을 사용합니다. 백업이 두 개 이상 있으면 환경 변수 BACKUP=<backup-id>를 설정해 어떤 <backup-id>_gitlab_backup.tar 파일을 복원할지 지정해야 합니다.

복원 중 프롬프트 비활성화#

백업에서 복원하는 동안 복원 스크립트는 다음 시점에 확인을 요청합니다.

  • Write to authorized_keys 설정이 활성화된 경우, 복원 스크립트가 authorized_keys 파일을 삭제하고 다시 만들기 전.
  • 데이터베이스를 복원할 때, 복원 스크립트가 기존 테이블을 모두 제거하기 전.
  • 데이터베이스를 복원한 후 스키마 복원에 오류가 있었다면, 이후에 더 많은 문제가 발생할 가능성이 크므로 계속 진행하기 전.

이 프롬프트를 비활성화하려면 GITLAB_ASSUME_YES 환경 변수를 1로 설정합니다.

  • Linux 패키지 설치:

    sudo GITLAB_ASSUME_YES=1 gitlab-backup restore
    
  • 자체 컴파일 설치:

    sudo -u git -H GITLAB_ASSUME_YES=1 bundle exec rake gitlab:backup:restore RAILS_ENV=production
    

force=yes 환경 변수도 이 프롬프트를 비활성화합니다.

복원 시 작업 제외#

환경 변수 SKIP을 추가해 복원 시 특정 작업을 제외할 수 있습니다. 값은 다음 옵션을 쉼표로 구분한 목록입니다.

  • db(데이터베이스)
  • uploads(첨부 파일)
  • builds(CI job 출력 로그)
  • artifacts(CI job 아티팩트)
  • lfs(LFS 객체)
  • terraform_state(Terraform 상태)
  • registry(컨테이너 레지스트리 이미지)
  • pages(Pages 콘텐츠)
  • repositories(Git 리포지터리 데이터)
  • packages(패키지)

특정 작업을 제외하려면 다음과 같이 진행합니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> SKIP=db,uploads
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> SKIP=db,uploads RAILS_ENV=production
    

특정 리포지터리 스토리지 복원#

Warning

GitLab 17.1 및 이전 버전은 데이터 손실을 유발할 수 있는 경쟁 조건의 영향을 받습니다. 이 문제는 포크되었고 GitLab 객체 풀을 사용하는 리포지터리에 영향을 줍니다. 데이터 손실을 방지하려면 GitLab 17.2 이상에서만 백업을 복원합니다.

여러 리포지터리 스토리지를 사용할 때는 REPOSITORIES_STORAGES 옵션으로 특정 리포지터리 스토리지의 리포지터리를 따로 복원할 수 있습니다. 이 옵션은 스토리지 이름을 쉼표로 구분한 목록을 받습니다.

예를 들어 다음과 같습니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> REPOSITORIES_STORAGES=storage1,storage2
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> REPOSITORIES_STORAGES=storage1,storage2
    

특정 리포지터리 복원#

히스토리
  • SKIP_REPOSITORIES_PATHS 복원이 GitLab 19.4에서 백업에서 제외된 리포지터리를 더 이상 제거하지 않도록 변경되었습니다.
Warning

GitLab 17.1 및 이전 버전은 데이터 손실을 유발할 수 있는 경쟁 조건의 영향을 받습니다. 이 문제는 포크되었고 GitLab 객체 풀을 사용하는 리포지터리에 영향을 줍니다. 데이터 손실을 방지하려면 GitLab 17.2 이상에서만 백업을 복원합니다.

REPOSITORIES_PATHS와 SKIP_REPOSITORIES_PATHS 옵션으로 특정 리포지터리를 복원할 수 있습니다. 두 옵션 모두 프로젝트와 그룹 경로를 쉼표로 구분한 목록을 받습니다. 그룹 경로를 지정하면, 사용한 옵션에 따라 그 그룹과 하위 그룹의 모든 프로젝트에 있는 모든 리포지터리가 포함되거나 건너뛰어집니다. 그룹과 프로젝트는 모두 지정된 백업이나 대상 인스턴스에 존재해야 합니다.

Note

REPOSITORIES_PATHS와 SKIP_REPOSITORIES_PATHS 옵션은 Git 리포지터리에만 적용됩니다. 프로젝트나 그룹의 데이터베이스 항목에는 적용되지 않습니다. SKIP=db로 리포지터리 백업을 생성했다면, 그 백업만으로는 특정 리포지터리를 새 인스턴스로 복원할 수 없습니다.

REPOSITORIES_PATHS 또는 SKIP_REPOSITORIES_PATHS 중 하나를 설정하면 특정 리포지터리만 복원됩니다. 이런 복원에서는 인스턴스에 이미 있는 리포지터리가 제거되지 않습니다. 따라서 나중의 복원이 앞선 복원으로 복원된 리포지터리를 제거하지 않으므로, 이런 복원을 여러 번 연달아 실행할 수 있습니다.

두 옵션을 모두 지정하지 않는 전체 복원에서는 복원 중인 백업에 포함되지 않은 리포지터리가 모두 제거됩니다. 이렇게 하면 오래된 리포지터리, 예를 들어 백업을 만든 뒤 생성된 프로젝트에 속한 리포지터리가 정리됩니다.

예를 들어 Group A(group-a)의 모든 프로젝트에 있는 모든 리포지터리와 Group B의 Project C 리포지터리(group-b/project-c)를 복원하고 Group A의 Project D(group-a/project-d)를 건너뛰려면 다음과 같이 진행합니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
    

Group A의 Project D(group-a/project-d) 리포지터리를 제외한 백업의 모든 항목을 복원하려면 다음과 같이 진행합니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore BACKUP=<backup-id> SKIP_REPOSITORIES_PATHS=group-a/project-d
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=<backup-id> SKIP_REPOSITORIES_PATHS=group-a/project-d
    

압축되지 않은 백업 복원#

SKIP=tar로 만든 압축되지 않은 백업이 있고 BACKUP=<backup-id>로 백업을 선택하지 않으면, 압축되지 않은 백업이 사용됩니다.

예를 들어 다음과 같습니다.

  • Linux 패키지 설치:

    sudo gitlab-backup restore
    
  • 자체 컴파일 설치:

    sudo -u git -H bundle exec rake gitlab:backup:restore
    

서버 측 리포지터리 백업을 사용한 복원#

히스토리

서버 측 백업을 수집하면 복원 프로세스는 기본적으로 서버 측 리포지터리 백업 생성에 나오는 서버 측 복원 메커니즘을 사용합니다. 각 리포지터리를 호스팅하는 Gitaly 노드가 필요한 백업 데이터를 오브젝트 스토리지에서 직접 가져오도록 백업 복원을 구성할 수 있습니다.

  1. Gitaly에서 서버 측 백업 대상을 구성합니다.
  2. 복원하려는 백업의 ID를 지정해 서버 측 백업 복원 프로세스를 시작합니다.
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce
sudo -u git -H bundle exec rake gitlab:backup:restore BACKUP=11493107454_2018_04_25_10.6.4-ce
kubectl exec  -it -- backup-utility --restore -t <backup_ID> --repositories-server-side

cron 기반 백업을 사용할 때는 추가 인수에 --repositories-server-side 플래그를 추가합니다.

문제 해결#

다음은 발생할 수 있는 문제와 해결 방법 후보입니다.

Linux 패키지 설치의 출력 경고와 함께 데이터베이스 백업 복원#

백업 복원 절차를 사용하면 다음 경고 메시지가 나타날 수 있습니다.

ERROR: must be owner of extension pg_trgm
ERROR: must be owner of extension btree_gist
ERROR: must be owner of extension plpgsql
WARNING:  no privileges could be revoked for "public" (two occurrences)
WARNING:  no privileges were granted for "public" (two occurrences)

이러한 경고 메시지가 나타나더라도 백업은 정상적으로 복원됩니다.

Rake 태스크는 이를 gitlab 사용자로 실행하는데, 이 사용자에게는 데이터베이스에 대한 superuser 액세스 권한이 없습니다. 복원을 시작할 때도 gitlab 사용자로 실행되지만, 액세스 권한이 없는 객체를 변경하려고 시도합니다. 이러한 객체는 데이터베이스 백업이나 복원에 영향을 주지 않지만 경고 메시지를 표시합니다.

자세한 내용은 다음을 참고합니다.

Git 서버 훅으로 인한 복원 실패#

백업에서 복원하는 동안 다음 조건이 모두 참이면 오류가 발생할 수 있습니다.

  • GitLab 15.10 및 이전 버전의 방식으로 Git 서버 훅(custom_hook)이 구성되어 있음
  • GitLab 버전이 15.11 이상임
  • GitLab이 관리하는 위치 밖의 디렉터리로 심볼릭 링크를 만들었음

오류는 다음과 같습니다.

{"level":"fatal","msg":"restore: pipeline: 1 failures encountered:\n - @hashed/path/to/hashed_repository.git (path/to_project): manager: restore custom hooks, \"@hashed/path/to/hashed_repository/_-ee/001.custom_hooks.tar\": rpc error: code = Internal desc = setting custom hooks: generating prepared vote: walking directory: copying file to hash: read /mnt/gitlab-app/git-data/repositories/+gitaly/tmp/default-repositories.old.<timestamp>.<temporaryfolder>/custom_hooks/compliance-triggers.d: is a directory\n","pid":3256017,"time":"2023-08-10T20:09:44.395Z"}

이를 해결하려면 GitLab 15.11 이상에 맞게 Git 서버 훅을 업데이트하고 새 백업을 생성합니다.

fapolicyd를 사용할 때 복원은 성공했지만 리포지터리가 비어 있는 것으로 표시되는 문제#

보안을 강화하기 위해 fapolicyd를 사용하면 GitLab이 복원이 성공했다고 보고하지만 리포지터리가 비어 있는 것으로 표시될 수 있습니다. 추가 문제 해결 도움말은 Gitaly 문제 해결 문서를 참고합니다.