GitLab 복원

Tier: Free, Premium, Ultimate Offering: Self-managed

GitLab은 전체 설치를 복원할 수 있는 명령줄 인터페이스를 제공하며,
필요에 맞게 유연하게 조정할 수 있습니다.

복원 필수 조건 섹션에는 중요한 정보가 포함되어 있습니다.
생산 환경에서 복원을 시도하기 전에 전체 복원 프로세스를 반드시 한 번
읽고 테스트하세요.

복원 필수 조건

목적지 GitLab 인스턴스는 이미 작동하고 있어야 합니다.

복원을 수행하기 전에 작동하는 GitLab 설치가 필요합니다.
이는 복원 작업을 수행하는 시스템 사용자(git)가 데이터가 가져올
SQL 데이터베이스(gitlabhq_production)를 생성하거나 삭제하는 것이
보통 허용되지 않기 때문입니다. 모든 기존 데이터는 삭제되거나
(SQL) 별도의 디렉터리(예: 리포지토리 및 업로드)로 이동됩니다.
SQL 데이터를 복원하면 PostgreSQL 확장으로 소유된 뷰는 건너뜁니다.

목적지 GitLab 인스턴스는 동일한 버전이어야 합니다.

백업은 정확히 동일한 버전 및 유형(CE 또는 EE) 의 GitLab에만
복원할 수 있습니다. 예를 들어, CE 15.1.4입니다.

백업이 현재 설치와 다른 버전이면, 백업을 복원하기 전에
다운그레이드 또는
업그레이드
를 해야 합니다.

GitLab 비밀도 복원해야 합니다.

백업을 복원하려면 GitLab 비밀도 복원해야 합니다.
여기에는 데이터베이스 암호화 키, CI/CD 변수,
2단계 인증
에 사용되는 변수가 포함됩니다. 키가 없으면
여러 문제가 발생하며,
2단계 인증이 활성화된 사용자에 대한
액세스 손실이 발생하고 GitLab Runner는 로그인할 수 없습니다.

복원:

특정 GitLab 구성은 원래 백업된 환경과 일치해야 합니다.

이전의 /etc/gitlab/gitlab.rb (리눅스 패키지 설치) 또는
/home/git/gitlab/config/gitlab.yml (자가 컴파일 설치) 및
모든 TLS 키, 인증서 (/etc/gitlab/ssl, /etc/gitlab/trusted-certs)
또는 SSH 호스트 키
를 복원하고 싶을 것입니다.

특정 구성은 PostgreSQL의 데이터와 연관되어 있습니다. 예를 들어:

  • 원래 환경에 세 개의 리포지토리 저장소가 있는 경우(예: default, my-storage-1, my-storage-2),
    대상 환경에도 반드시 해당 저장소 이름이 구성에 정의되어 있어야 합니다.
  • 로컬 스토리지를 사용하는 환경에서 백업을 복원하면 대상 환경이
    객체 스토리지를 사용하더라도 로컬 스토리지로 복원됩니다.
    객체 스토리지로의 마이그레이션은 복원 전후에 수행해야 합니다.

마운트 지점인 디렉토리 복원

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

NFS 마운트를 구성하는 방법에 대해 자세히 알아보세요.

Linux 패키지 설치에 대한 복원

이 절차는 다음과 같은 전제를 가지고 있습니다:

  • 백업이 생성된 정확히 동일한 버전 및 유형(CE/EE)의 GitLab이 설치되어 있습니다.
  • 최소한 한 번 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
# 상태 확인
sudo gitlab-ctl status

다음으로 복원 전제 조건을 완료하고 원래 설치에서 GitLab 비밀 파일을 복사한 후 gitlab-ctl reconfigure를 실행했는지 확인하세요.

다음으로 복원을 원할 때 백업의 ID를 지정하여 백업을 복원합니다:

경고: 다음 명령은 GitLab 데이터베이스의 내용을 덮어씁니다!

# 주의: "_gitlab_backup.tar"는 이름에서 생략됩니다
sudo gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

백업 tar 파일과 설치된 GitLab 버전 간에 버전 불일치가 있는 경우 복원 명령이 오류 메시지와 함께 중단됩니다:

GitLab 버전 불일치:
  현재 GitLab 버전(16.5.0-ee)이 백업의 GitLab 버전과 다릅니다!
  다음 버전으로 전환하고 다시 시도하세요:
  version: 16.4.3-ee

올바른 GitLab 버전을 설치한 후 다시 시도하세요.

경고: 복원 명령은 PgBouncer를 사용하는 설치에 대해 추가 매개변수가 필요합니다. 이는 성능상의 이유 또는 Patroni 클러스터와 함께 사용할 때 필요합니다.

다음으로 GitLab을 다시 시작하고 검사합니다:

sudo gitlab-ctl restart
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 이미지 또는 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를 참조하세요.

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

# 데이터베이스에 연결된 프로세스 중지
docker exec -it <name of container> gitlab-ctl stop puma
docker exec -it <name of container> gitlab-ctl stop sidekiq

# 계속 진행하기 전에 모든 프로세스가 중지되었는지 확인
docker exec -it <name of container> gitlab-ctl status

# 복원 실행. 참고: "_gitlab_backup.tar"는 이름에서 생략
docker exec -it <name of container> gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

# GitLab 컨테이너 재시작
docker restart <name of container>

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

셀프 컴파일한 설치를 위한 복원

먼저, gitlab.yml 구성에 설명된 백업 디렉토리에 백업 tar 파일이 있는지 확인하세요:

## 백업 설정
backup:
  path: "tmp/backups"   # 상대 경로는 Rails.root에 상대적입니다 (기본값: tmp/backups/)

기본값은 /home/git/gitlab/tmp/backups이며, git 사용자가 소유해야 합니다. 이제 백업 절차를 시작할 수 있습니다:

# 데이터베이스에 연결된 프로세스 중지
sudo service gitlab stop

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

예제 출력:

백업 압축 해제... [완료]
데이터베이스 테이블 복원:
-- create_table("events", {:force=>true})
   -> 0.2231s
[...]
- 피쳐 이벤트 로드...[완료]
- 피쳐 이슈 로드...[완료]
- 피쳐 키 로드...[건너뜀]
- 피쳐 머지 요청 로드...[완료]
- 피쳐 마일스톤 로드...[완료]
- 피쳐 네임스페이스 로드...[완료]
- 피쳐 노트 로드...[완료]
- 피쳐 프로젝트 로드...[완료]
- 피쳐 보호 브랜치 로드...[건너뜀]
- 피쳐 스키마 마이그레이션 로드...[완료]
- 피쳐 서비스 로드...[건너뜀]
- 피쳐 스니펫 로드...[건너뜀]
- 피쳐 태깅 로드...[건너뜀]
- 피쳐 태그 로드...[건너뜀]
- 피쳐 사용자 로드...[완료]
- 피쳐 사용자 프로젝트 로드...[완료]
- 피쳐 웹 훅 로드...[건너뜀]
- 피쳐 위키 로드...[건너뜀]
레포지토리 복원:
- 레포지토리 abcd 복원... [완료]
- 객체 풀 1 ...
임시 디렉터리 삭제...[완료]

필요한 경우, /home/git/gitlab/.secret을 복원하세요. 앞서 언급한 대로.

GitLab을 재시작하세요:

sudo service gitlab restart

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

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

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

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

증분 리포지토리 백업 복원

각 백업 아카이브는 증분 리포지토리 백업 절차를 통해 생성된 전체 독립 백업을 포함합니다. 증분 리포지토리 백업을 복원하려면 다른 일반 백업 아카이브를 복원하는 것과 동일한 지침을 사용하십시오.

복원 옵션

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

여러 개의 백업 중 복원할 백업 지정

백업 파일은 백업 ID로 시작하는 네이밍 규칙을 사용합니다. 두 개 이상의 백업이 존재하는 경우, 환경 변수 BACKUP=<backup-id>를 설정하여 복원할 <backup-id>_gitlab_backup.tar 파일을 지정해야 합니다.

복원 중 프롬프트 비활성화

백업에서 복원하는 동안 복원 스크립트는 확인을 요구합니다:

  • Write to authorized_keys 설정이 활성화된 경우, 복원 스크립트가 authorized_keys 파일을 삭제하고 재구성하기 전에.
  • 데이터베이스를 복원할 때, 복원 스크립트가 모든 기존 테이블을 제거하기 전에.
  • 데이터베이스를 복원한 후, 스키마 복원에 오류가 있는 경우, 추가 문제가 발생할 가능성이 높기 때문에 계속 진행하기 전에.

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

  • 리눅스 패키지 설치:

    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 작업 출력 로그)
  • artifacts (CI 작업 아티팩트)
  • lfs (LFS 객체)
  • terraform_state (Terraform 상태)
  • registry (컨테이너 레지스트리 이미지)
  • pages (페이지 콘텐츠)
  • repositories (Git 리포지토리 데이터)
  • packages (패키지)

특정 작업을 제외하려면:

  • 리눅스 패키지 설치:

    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
    

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

경고:
GitLab 17.1 및 이전 버전은 경쟁 조건의 영향을 받아 데이터 손실이 발생할 수 있습니다. 문제는 포크된 리포지토리와 GitLab 오브젝트 풀을 사용하는 리포지토리에 영향을 미칩니다. 데이터 손실을 피하려면 GitLab 17.2 이상 버전에서만 백업을 복원하십시오.

multiple repository storages를 사용할 때, 특정 리포지토리 스토리지의 리포지토리를 REPOSITORIES_STORAGES 옵션을 사용하여 별도로 복원할 수 있습니다.

이 옵션은 스토리지 이름의 쉼표 분리 목록을 허용합니다.

예를 들어:

  • 리눅스 패키지 설치:

    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
    

특정 리포지토리 복원

경고:
GitLab 17.1 및 이전 버전은 경쟁 조건의 영향을 받아 데이터 손실이 발생할 수 있습니다. 문제는 포크된 리포지토리와 GitLab 오브젝트 풀을 사용하는 리포지토리에 영향을 미칩니다. 데이터 손실을 피하려면 GitLab 17.2 이상 버전에서만 백업을 복원하십시오.

특정 리포지토리를 복원하려면 REPOSITORIES_PATHSSKIP_REPOSITORIES_PATHS 옵션을 사용할 수 있습니다.

두 옵션 모두 프로젝트 및 그룹 경로의 쉼표 분리 목록을 허용합니다. 그룹 경로를 지정하면 해당 그룹 및 하위 그룹의 모든 프로젝트에서 모든 리포지토리가 포함되거나 건너뛰어집니다.

프로젝트 및 그룹 리포지토리는 지정된 백업에 존재해야 합니다.

노트:
REPOSITORIES_PATHSSKIP_REPOSITORIES_PATHS 옵션은 Git 리포지토리에만 적용됩니다. 이러한 옵션과 관계없이 모든 프로젝트 및 기타 데이터가 복원됩니다.

예를 들어, 그룹 A(group-a)의 모든 프로젝트에 대한 모든 리포지토리, 그룹 B프로젝트 C(group-b/project-c)에 대한 리포지토리, 그리고 그룹 A프로젝트 D(group-a/project-d)를 건너뛰려면:

  • 리눅스 패키지 설치:

    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
    

압축 해제된 백업 복원

SKIP=tar로 생성된 압축 해제된 백업이 발견되고, BACKUP=<backup-id>로 선택된 백업이 없으면, 압축 해제된 백업이 사용됩니다.

예를 들어:

  • 리눅스 패키지 설치:

    sudo gitlab-backup restore
    
  • 셀프 컴파일 설치:

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

문제 해결

다음은 당신이 만날 수 있는 가능한 문제와 잠재적인 솔루션입니다.

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 사용자로 실행되며, 이 사용자는 데이터베이스에 대한 슈퍼유저 접근 권한이 없습니다. 복원이 시작될 때에도 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/<BackupID>_<GitLabVersion>-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 문제 해결 문서를 참조하세요.