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. 이동이 완료된 후, Rails 콘솔을 사용하여 모든 스니펫이 이동되었는지 확인합니다. 원본 스토리지에 대해 반환되는 스니펫이 없어야 합니다. Rails 콘솔에서 다음을 실행합니다:

    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. 이동이 완료된 후, Rails 콘솔을 사용하여 모든 그룹이 이동되었는지 확인합니다. 원본 스토리지에 대해 반환되는 그룹이 없어야 합니다. Rails 콘솔에서 다음을 실행합니다:

    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 -'

네트워크를 통해 전송하기 전에 데이터 Compression을 원한다면 (이는 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 단일 사용

경고:

rsync를 사용하여 Git 데이터를 마이그레이션하면 데이터 손실 및 리포지토리 손상이 발생할 수 있습니다.

이 지침은 검토 중입니다.

Gitaly 대상을 위해 (Gitaly 클러스터 대상을 위한 권장 접근 방식을 사용하십시오), 소스 시스템의 git 사용자가 대상 서버에 SSH 접근 권한이 있는 경우, rsync를 사용하여 네트워크를 통해 리포지토리를 전송할 수 있습니다.

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