GitLab이 관리하는 저장소 이동하기

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

GitLab이 관리하는 모든 저장소를 다른 파일 시스템이나 다른 서버로 이동할 수 있습니다.

GitLab 인스턴스에서 데이터 이동

GitLab API는 다음과 같은 Git 저장소를 이동하는 권장 방법입니다.

  • 서버 간
  • 서로 다른 저장소 간
  • 단일 노드 Gitaly에서 Gitaly 클러스터로

자세한 정보는 다음을 참조하세요:

저장소 이동

GitLab 저장소는 프로젝트, 그룹 및 스니펫과 연관될 수 있습니다. 각 유형에는 이동할 해당 저장소를 예약하기 위한 별도의 API가 있습니다. GitLab 인스턴스의 모든 저장소를 이동하려면 각 유형마다 각 저장소를 이동할 수 있어야 합니다.

이동하는 동안 각 저장소는 읽기 전용으로 만들어집니다. 저장소는 이동이 완료될 때까지 쓰기 가능하지 않습니다.

저장소를 이동하려면:

  1. 로컬 및 클러스터 스토리지가 GitLab 인스턴스에 액세스 가능한지 확인하십시오. 이 예에서는 <original_storage_name><cluster_storage_name>입니다.
  2. 저장소 스토리지 가중치 구성하여 새 스토리지가 모든 새 프로젝트를 수신하도록 합니다. 이렇게 하면 마이그레이션이 진행되는 동안 기존 스토리지에 새로운 프로젝트가 생성되지 않습니다.
  3. 저장소를 이동하려면:
  4. Geo가 활성화되어 있는 경우 모든 저장소 동기화를 실행하세요.

모든 프로젝트 이동

API를 사용하여 모든 프로젝트를 이동하려면:

  1. API를 사용하여 저장소 샤드의 모든 프로젝트에 대한 저장소 이동 예약을 예약하세요. 예:

    curl --request POST --header "Private-Token: <your_access_token>" \
         --header "Content-Type: application/json" \
         --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \
         "https://gitlab.example.com/api/v4/project_repository_storage_moves"
    
  2. API를 사용하여 가장 최근의 저장소 이동을 조회합니다. 응답에는 다음 중 하나가 표시됩니다:
    • 이동이 성공적으로 완료되었습니다. ‘state’ 필드가 ‘finished’입니다.
    • 이동이 진행 중입니다. 저장소 이동이 성공적으로 완료될 때까지 저장소 이동을 다시 조회합니다.
    • 이동에 실패했습니다. 대부분의 오류는 일시적이며 이동을 다시 예약함으로써 해결됩니다.
  3. 이동이 완료되면 API를 사용하여 프로젝트를 조회하고 모든 프로젝트가 이동되었는지 확인하세요. 이 중에는 ‘repository_storage’ 필드가 이전 저장소로 설정된 프로젝트가 없어야 합니다. 예를 들어:

    curl --header "Private-Token: <your_access_token>" --header "Content-Type: application/json" \
    "https://gitlab.example.com/api/v4/projects?repository_storage=<original_storage_name>"
    

    또는 레일즈 콘솔을 사용하여 모든 프로젝트가 이동되었는지 확인하세요. 레일즈 콘솔에서 다음을 실행하세요:

    ProjectRepository.for_repository_storage('<original_storage_name>')
    
  4. 필요에 따라 각 저장소를 위해 반복하세요.

모든 스니펫 이동

API를 사용하여 모든 스니펫을 이동하려면:

  1. 저장소 샤드의 모든 스니펫에 대한 저장소 이동 예약을 예약하세요. 예:

    curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
         --header "Content-Type: application/json" \
         --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \
         "https://gitlab.example.com/api/v4/snippet_repository_storage_moves"
    
  2. 가장 최근의 저장소 이동을 조회하세요. 응답에는 다음 중 하나가 표시됩니다:
    • 이동이 성공적으로 완료되었습니다. ‘state’ 필드가 ‘finished’입니다.
    • 이동이 진행 중입니다. 저장소 이동이 성공적으로 완료될 때까지 저장소 이동을 다시 조회합니다.
    • 이동에 실패했습니다. 대부분의 오류는 일시적이며 이동을 다시 예약함으로써 해결됩니다.
  3. 이동이 완료되면 레일즈 콘솔을 사용하여 모든 스니펫이 이동되었는지 확인하세요. 원래 저장소에 대한 스니펫이 반환되지 않아야 합니다. 레일즈 콘솔에서 다음을 실행하세요:

    SnippetRepository.for_repository_storage('<original_storage_name>')
    
  4. 필요에 따라 각 저장소를 위해 반복하세요.

모든 그룹 이동

Tier: Premium, Ultimate Offering: Self-Managed

API를 사용하여 모든 그룹을 이동하려면:

  1. 저장소 샤드의 모든 그룹에 대한 저장소 이동 예약을 예약하세요. 예:

    curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
         --header "Content-Type: application/json" \
         --data '{"source_storage_name":"<original_storage_name>","destination_storage_name":"<cluster_storage_name>"}' \
         "https://gitlab.example.com/api/v4/group_repository_storage_moves"
    
  2. 가장 최근의 저장소 이동을 조회하세요. 응답에는 다음 중 하나가 표시됩니다:
    • 이동이 성공적으로 완료되었습니다. ‘state’ 필드가 ‘finished’입니다.
    • 이동이 진행 중입니다. 저장소 이동이 성공적으로 완료될 때까지 저장소 이동을 다시 조회합니다.
    • 이동에 실패했습니다. 대부분의 오류는 일시적이며 이동을 다시 예약함으로써 해결됩니다.
  3. 이동이 완료되면 레일즈 콘솔을 사용하여 모든 그룹이 이동되었는지 확인하세요. 원래 저장소에 대한 그룹이 반환되지 않아야 합니다. 레일즈 콘솔에서 다음을 실행하세요:

    GroupWikiRepository.for_repository_storage('<original_storage_name>')
    
  4. 필요에 따라 각 저장소를 위해 반복하세요.

다른 GitLab 인스턴스로 이전하기

API 사용이 새로운 GitLab 환경으로 마이그레이션하는 경우에는 옵션으로 삼을 수 없습니다. 예를 들어:

  • 단일 노드 GitLab에서 확장된 아키텍처로 마이그레이션하는 경우.
  • 개인 데이터 센터의 GitLab 인스턴스에서 클라우드 제공업체로 마이그레이션하는 경우.

문서의 나머지 부분에서는 ‘/var/opt/gitlab/git-data/repositories’에서 ‘/mnt/gitlab/repositories’로 모든 저장소를 복사하는 몇 가지 방법을 살펴봅니다.

우리는 세 가지 시나리오를 살펴봅니다:

  • 대상 디렉토리가 비어 있는 경우.
  • 대상 디렉토리에 오래된 복사본이 포함된 경우.
  • 수천 개의 저장소를 처리하는 방법.

경고: 우리가 나열하는 각 접근 방법은 대상 디렉토리 ‘/mnt/gitlab/repositories’의 데이터를 덮어쓸 수 있거나 덮어쓰거나 합니다. 소스와 대상을 혼돈하지 마십시오.

모든 경우에 권장되는 방법

Gitaly 또는 Gitaly Cluster 대상의 경우, GitLab 백업 및 복원 기능을 사용해야 합니다. Git 저장소는 Gitaly를 통해 데이터베이스로서 GitLab 서버에서 액세스, 관리 및 저장됩니다. rsync와 같은 도구를 사용하여 Gitaly 파일에 직접 액세스하고 복사하는 것은 데이터 손실을 야기할 수 있습니다.

Gitaly Cluster 대상에 대한 다른 방법은 작동하지 않습니다.

대상 디렉토리가 비어 있는 경우: tar 파이프 사용

Gitaly 대상의 경우 (Gitaly Cluster 대상의 경우에는 권장된 방법을 사용), 대상 디렉토리 ‘/mnt/gitlab/repositories’가 비어 있다면 가장 간단한 방법은 tar 파이프를 사용하는 것입니다. 이 방법은 오버헤드가 적으며 대부분의 경우 시스템에 이미 tar가 설치되어 있습니다.

그러나 중단된 tar 파이프를 재개할 수는 없습니다. 그런 경우 모든 데이터를 다시 복사해야 합니다.

sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
  tar -C /mnt/gitlab/repositories -xf -'

진행 상황을 보려면 -xf-xvf로 바꿉니다.

다른 서버로의 tar 파이프

Gitaly 대상의 경우 (Gitaly Cluster 대상에는 권장된 방법을 사용), 다른 서버로 데이터를 복사하기 위해 tar 파이프를 사용할 수도 있습니다. git 사용자가 git@newserver로 새 서버에 SSH 액세스 권한이 있는 경우 데이터를 SSH를 통해 파이핑할 수 있습니다.

sudo -u git sh -c 'tar -C /var/opt/gitlab/git-data/repositories -cf - -- . |\
  ssh git@newserver tar -C /mnt/gitlab/repositories -xf -'

네트워크 전에 데이터를 압축하려면(이는 CPU 사이클을 사용하여 비용이 듭니다) sshssh -C로 대체할 수 있습니다.

대상 디렉토리에 오래된 복사본이 포함된 경우: rsync 사용

경고: Git 데이터를 마이그레이션하는 데 rsync를 사용하면 데이터 손실과 저장소 손상이 발생할 수 있습니다. 이 지침은 검토 중입니다.

대상 디렉토리에 이미 저장소의 일부 또는 오래된 복사본이 있는 경우 tar로 모든 데이터를 다시 복사하는 것은 비효율적일 수 있습니다. 이러한 시나리오에서는 Gitaly 대상의 경우 rsync를 사용하는 것이 좋습니다(Gitaly Cluster 대상의 경우 권장된 방법을 사용).

이 유틸리티는 이미 시스템에 설치되어 있거나 apt 또는 yum을 사용하여 설치할 수 있습니다.

sudo -u git  sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
  /mnt/gitlab/repositories'

상기 명령어의 /.는 매우 중요합니다. 그렇지 않으면 대상 디렉토리의 잘못된 디렉토리 구조를 가져올 수 있습니다. 진행 상황을 보려면 -a-av로 바꿉니다.

다른 서버로의 단일 rsync

경고: Git 데이터를 마이그레이션하는 데 rsync를 사용하면 데이터 손실과 저장소 손상이 발생할 수 있습니다. 이 지침은 검토 중입니다.

Gitaly 대상의 경우 (Gitaly Cluster 대상의 경우에는 권장된 방법을 사용), 소스 시스템의 git 사용자가 대상 서버에 SSH 액세스 권한이 있는 경우 rsync를 사용하여 네트워크를 통해 저장소를 전송할 수 있습니다.

sudo -u git sh -c 'rsync -a --delete /var/opt/gitlab/git-data/repositories/. \
  git@newserver:/mnt/gitlab/repositories'