GitLab이 관리하는 리포지터리 이전

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

다른 파일 시스템 또는 다른 서버로 GitLab이 관리하는 모든 리포지터리를 이전할 수 있습니다.

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

GitLab API는 Git 리포지터리를 이전하는 권장 방법입니다.

  • 서버 간.
  • 다른 리포지터리 간.
  • 단일 노드 Gitaly에서 Gitaly 클러스터로.

자세한 내용은 다음을 참조하세요.

  • Gitaly를 위한 추가 리포지터리 구성. 이 예제는 storage1storage2라는 추가 리포지터리를 구성합니다.
  • API 문서에서 프로젝트 리포지터리 이전을 조회하고 예약하는 데 필요한 엔드포인트에 대해 설명합니다.
  • API 문서에서 스니펫 리포지터리 이전을 조회하고 예약하는 데 필요한 엔드포인트에 대해 설명합니다.
  • API 문서에서 그룹 리포지터리 이전을 조회하고 예약하는 데 필요한 엔드포인트에 대해 설명합니다.
  • 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를 사용하여 프로젝트를 조회하고 모든 프로젝트가 이동했는지 확인합니다. 이전 리포지터리가 설정된 프로젝트는 반환되지 않아야 합니다. 예:

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

    또는 Rails 콘솔을 사용하여 모든 프로젝트가 이동했는지 확인합니다. Rails 콘솔에서 다음을 실행하세요:

    ProjectRepository.for_repository_storage('<original_storage_name>')
    
  4. 필요한 경우 각 리포지터리를 위해 반복합니다.

모든 스니펫 이동

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/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. 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/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로 모든 리포지터리를 복사하는 방법 중 일부를 살펴봅니다.

우리는 세 가지 시나리오를 살펴보겠습니다:

  • 대상 디렉터리가 비어 있는 경우.
  • 대상 디렉터리에 리포지터리의 오래된 사본이 있는 경우.
  • 수천 개의 리포지터리를 다루는 방법.
caution
나열된 방법 각각이 또는 대상 디렉터리 /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 사용

caution
Git 데이터를 이전하기 위해 rsync를 사용하는 것은 데이터 손실과 리포지터리 손상을 초래할 수 있습니다. 이 지침은 검토 중입니다..

대상 디렉터리에 이미 리포지터리의 일부 또는 오래된 사본이 포함되어 있는 경우, 모든 데이터를 tar로 다시 복사하는 것은 낭비일 수 있습니다. 이러한 시나리오에서는 Gitaly 대상의 경우 rsync를 사용하는 것이 더 좋습니다(권장된 방법을 사용).

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

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

위의 명령어에서 /.은 매우 중요합니다. 이를 빠트리면 대상 디렉터리에 잘못된 디렉터리 구조가 생길 수 있습니다. 진행 상황을 보려면 -a-av로 대체하세요.

다른 서버로의 단일 rsync

caution
Git 데이터를 이전하기 위해 rsync를 사용하는 것은 데이터 손실과 리포지터리 손상을 초래할 수 있습니다. 이 지침은 검토 중입니다..

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

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