GitLab 복원

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

GitLab은 전체 설치를 복원하기 위한 명령줄 인터페이스를 제공하며, 사용자의 필요에 맞게 유연하게 작동합니다.

복원 전 필수 조건 섹션에는 중요한 정보가 포함되어 있습니다. 복원 프로세스를 완전히 읽고 테스트를 하나 이상 수행한 후 복원을 본능적인 환경에서 시도해야 합니다.

복원 전 필수 조건

대상 GitLab 인스턴스는 이미 작동 중이어야 함

복원을 수행하려면 먼저 작동 중인 GitLab 설치가 있어야 합니다. 이는 복원 작업을 수행하는 시스템 사용자(git)가 일반적으로 데이터를 가져올 SQL 데이터베이스를 생성하거나 삭제할 수 없기 때문입니다. 기존 데이터는 일반적으로 지워지거나 별도의 디렉터리(예: 리포지터리 및 업로드)로 이동됩니다. SQL 데이터 복원 작업은 PostgreSQL 익스텐션에 의해 소유된 뷰를 건너뜁니다.

대상 GitLab 인스턴스는 원본 백업 환경과 정확히 동일한 버전이어야 함

백업은 생성된 GitLab의 정확히 동일한 버전과 타입(CE 또는 EE)으로만 복원할 수 있습니다. 예를 들어 CE 15.1.4와 같은 버전입니다.

만약 백업이 현재 설치된 버전과 다른 경우 백업을 복원하기 전에 설치된 GitLab을 다운그레이드하거나 업그레이드해야 합니다.

GitLab secrets를 반드시 복원해야 함

백업을 복원하려면 GitLab secrets도 복원해야 합니다. 이는 데이터베이스 암호화 키, CI/CD 변수이중 인증용 변수를 포함합니다. 키가 없으면 여러 문제가 발생하며, 이중 인증이 활성화된 사용자의 접근 권한이 손상되고 GitLab 러너는 로그인할 수 없게 됩니다.

복원: - /etc/gitlab/gitlab-secrets.json (Linux 패키지 설치) - /home/git/gitlab/.secret (자체 컴파일 설치) - Secrets 복원 (클라우드 네이티브 GitLab) - 필요한 경우 GitLab Helm 차트 secrets를 Linux 패키지 형식으로 변환할 수 있습니다.

특정 GitLab 구성이 원본 백업 환경과 일치해야 함

일반적으로 이전의 /etc/gitlab/gitlab.rb(Linux 패키지 설치용) 또는 /home/git/gitlab/config/gitlab.yml(자체 컴파일 설치용) 및 TLS 키, 인증서(/etc/gitlab/ssl, /etc/gitlab/trusted-certs) 또는 SSH 호스트 키를 복원할 것입니다.

일부 구성은 PostgreSQL의 데이터와 직접적으로 연결되어 있습니다. 예를 들어:

  • 원본 환경에 리포지터리 스토리지가 세 개(예: 기본, 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
# 확인
sudo gitlab-ctl status

다음으로 복원 전 필수 조건 단계를 완료했으며, GitLab 원본 설치로부터 GitLab secrets 파일을 복사한 후 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 버전과 다릅니다!
  다음 버전으로 전환한 후 다시 시도하세요:
  버전: 16.4.3-ee

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

caution
복원 명령은 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

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를 참조하세요.

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

# 데이터베이스에 연결된 프로세스 중지
docker exec -it <컨테이너 이름> gitlab-ctl stop puma
docker exec -it <컨테이너 이름> gitlab-ctl stop sidekiq

# 계속하기 전에 모든 프로세스가 종료되었는지 확인하세요
docker exec -it <컨테이너 이름> gitlab-ctl status

# 복원 실행. 참고: 백업 이름에서 "_gitlab_backup.tar"은 생략됩니다
docker exec -it <컨테이너 이름> gitlab-backup restore BACKUP=11493107454_2018_04_25_10.6.4-ce

# GitLab 컨테이너 재시작
docker restart <컨테이너 이름>

# GitLab 확인
docker exec -it <컨테이너 이름> gitlab-rake gitlab:check SANITIZE=true

직접 컴파일한 설치를 위한 복원

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

## 백업 설정
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
[...]
- Loading fixture events...[완료]
- Loading fixture issues...[완료]
- Loading fixture keys...[중단]
- Loading fixture merge_requests...[완료]
- Loading fixture milestones...[완료]
- Loading fixture namespaces...[완료]
- Loading fixture notes...[완료]
- Loading fixture projects...[완료]
- Loading fixture protected_branches...[중단]
- Loading fixture schema_migrations...[완료]
- Loading fixture services...[중단]
- Loading fixture snippets...[중단]
- Loading fixture taggings...[중단]
- Loading fixture tags...[중단]
- Loading fixture users...[완료]
- Loading fixture users_projects...[완료]
- Loading fixture web_hooks...[중단]
- Loading fixture wikis...[중단]
리포지터리 복원:

- 리포지터리 abcd 복원... [완료]
- Object pool 1 ...
임시 디렉터리 삭제...[완료]

그 다음, 필요한 경우 /home/git/gitlab/.secret를 복원하세요. 이전에 언급된대로 GitLab을 다시 시작하세요:

sudo service gitlab restart

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

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

  1. 복원하려는 백업된 인스턴스와 동일한 버전의 새로운 GitLab 인스턴스를 설치하세요.
  2. 이 새 인스턴스에 백업을 복원한 다음, 여기서 프로젝트그룹을 내보내세요. 내보내는 내용 및 안 내보내는 내용에 대한 자세한 내용은 내보내기 기능 문서를 참조하세요.
  3. 내보내기가 완료되면 이를 이전 인스턴스로 가져가세요.
  4. 원하는 프로젝트나 그룹을 가져온 후, 새로운 임시 GitLab 인스턴스를 삭제할 수 있습니다.

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

증분 리포지터리 백업 복원

각 백업 아카이브는 증분 리포지터리 백업 절차를 통해 생성된 것을 포함하여 전체 독립형 백업을 포함합니다. 증분 리포지터리 백업을 복원하려면 다른 정규 백업 아카이브를 복원하는 것과 동일한 지침을 사용하세요.

복원 옵션

GitLab이 제공하는 명령줄 도구는 더 많은 옵션을 허용합니다.

둘 이상을 복원할 경우 복원할 백업을 지정

여러 개의 백업이 있을 때, 환경 변수 BACKUP=<백업-id>를 설정하여 어떤 <백업-id>_gitlab_backup.tar 파일을 복원할지 지정해야 합니다.

복원 중 프롬프트 비활성화

백업을 복원하는 중에 복원 스크립트는 확인을 요청합니다:

  • Write to authorized_keys 설정이 활성화되어 있을 때 authorized_keys 파일을 삭제하고 다시 빌드하기 전
  • 데이터베이스를 복원하는 중, 모든 기존 테이블을 제거하기 전
  • 데이터베이스 복원 후, 스키마를 복원하는 중 오류가 있을 경우 추가적인 문제가 발생할 가능성이 있으므로 계속하기 전에 확인

이러한 프롬프트를 비활성화하려면 GITLAB_ASSUME_YES 환경 변수를 1로 설정하세요.

  • 리눅스 패키지 설치:

    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=<백업-id> SKIP=db,uploads
    
  • 직접 컴파일한 설치:

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

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

여러 리포지터리 스토리지를 사용할 때, 특정 리포지터리 스토리지의 리포지터리를 복원할 수 있도록 REPOSITORIES_STORAGES 옵션을 사용하세요. 이 옵션은 리포지터리 이름들의 쉼표로 구분된 디렉터리을 허용합니다.

예를 들어:

  • 리눅스 패키지 설치:

    sudo gitlab-backup restore BACKUP=<백업-id> REPOSITORIES_STORAGES=storage1,storage2
    
  • 직접 컴파일한 설치:

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

특정 리포지터리 복원

REPOSITORIES_PATHSSKIP_REPOSITORIES_PATHS 옵션을 사용하여 특정 리포지터리를 복원할 수 있습니다. 두 옵션 모두 프로젝트 및 그룹 경로의 쉼표로 구분된 디렉터리을 허용합니다. 그룹 경로를 지정하면 해당 옵션에 따라 그룹 및 하위 그룹의 모든 프로젝트에 있는 모든 리포지터리가 포함되거나 제외됩니다. 본인이 사용한 백업에 프로젝트 및 그룹 리포지터리가 있어야 합니다.

예를 들어, Group A (group-a)의 모든 프로젝트의 모든 리포지터리, Group B (group-b)의 Project C의 리포지터리, 그리고 Group A (group-a)의 Project D를 건너뛰려면:

  • Linux 패키지 설치:

    sudo gitlab-backup restore 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=<백업ID> REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
    

풀지 않은 백업 복원

SKIP=tar로 생성된 풀지 않은 백업이 발견되면, BACKUP=<백업ID>로 백업을 선택하지 않은 경우 풀지 않은 백업이 사용됩니다.

예를 들어:

  • Linux 패키지 설치:

    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 이상에 대한 서버 후크를 업데이트하고 새로운 백업을 생성할 수 있습니다.

fapolicyd를 사용하여 복원 시 리포지터리가 비어 있는 것으로 표시될 때의 성공적인 복원

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