InfoGrab Docs

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

요약

GitLab이 관리하는 모든 리포지터리를 다른 파일 시스템이나 다른 서버로 이동합니다. GitLab API를 사용하여 Git 리포지터리를 이동합니다: GitLab 리포지터리는 프로젝트, 그룹, 스니펫과 연결될 수 있습니다.

GitLab이 관리하는 모든 리포지터리를 다른 파일 시스템이나 다른 서버로 이동합니다.

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

GitLab API를 사용하여 Git 리포지터리를 이동합니다:

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

GitLab 리포지터리는 프로젝트, 그룹, 스니펫과 연결될 수 있습니다. 이러한 각 유형은 리포지터리를 이동하기 위한 별도의 API가 있습니다. GitLab 인스턴스의 모든 리포지터리를 이동하려면 각 스토리지에 대해 각 유형의 리포지터리를 이동해야 합니다.

각 리포지터리는 이동하는 동안 읽기 전용으로 설정되며 이동이 완료될 때까지 쓸 수 없습니다.

리포지터리를 이동하려면:

  1. 모든 로컬 및 클러스터 스토리지가 GitLab 인스턴스에서 접근 가능한지 확인합니다. 이 예시에서는 <original_storage_name><cluster_storage_name>입니다.
  2. 새 스토리지가 모든 새 프로젝트를 받도록 리포지터리 스토리지 가중치를 구성합니다. 이렇게 하면 마이그레이션이 진행되는 동안 기존 스토리지에 새 프로젝트가 생성되지 않습니다.
  3. 프로젝트, 스니펫, 그룹에 대한 리포지터리 이동을 예약합니다.
  4. Geo를 사용하는 경우 모든 리포지터리를 다시 동기화합니다.
  5. Sidekiq 파드에서 수평 파드 자동 스케일러를 사용하는 경우 마이그레이션 중에 스케일링을 방지하기 위해 Sidekiq 파드에 대한 HPA를 비활성화합니다.

프로젝트 이동#

모든 프로젝트 또는 개별 프로젝트를 이동할 수 있습니다.

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

    또는 Rails 콘솔을 사용하여 모든 프로젝트가 이동했는지 확인합니다:

    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 콘솔을 사용하여 모든 스니펫이 이동했는지 확인합니다:

    SnippetRepository.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/group_repository_storage_moves"
    
  2. 가장 최근 리포지터리 이동을 조회합니다. 응답은 다음 중 하나를 나타냅니다:

    • 이동이 성공적으로 완료됨. state 필드가 finished임.
    • 이동이 진행 중. 성공적으로 완료될 때까지 리포지터리 이동을 다시 조회합니다.
    • 이동이 실패. 대부분의 실패는 일시적이며 이동을 다시 예약하면 해결됩니다.
  3. 이동이 완료된 후 Rails 콘솔을 사용하여 모든 그룹이 이동했는지 확인합니다:

    GroupWikiRepository.for_repository_storage('<original_storage_name>')
    

    이 명령은 원래 스토리지의 그룹을 반환해서는 안 됩니다.

  4. 필요에 따라 각 스토리지에 대해 반복합니다.

모든 그룹을 이동하지 않으려면 개별 그룹 지침을 따릅니다.

다른 GitLab 인스턴스로 마이그레이션#

새 GitLab 환경으로 마이그레이션하는 경우 API를 사용하여 데이터를 이동할 수 없습니다. 예:

  • 단일 노드 GitLab에서 스케일 아웃 아키텍처로.
  • 개인 데이터 센터의 GitLab 인스턴스에서 클라우드 공급자로.

이 경우 시나리오에 따라 /var/opt/gitlab/git-data/repositories에서 /mnt/gitlab/repositories로 모든 리포지터리를 복사하는 방법이 있습니다:

  • 대상 디렉토리가 비어 있습니다.
  • 대상 디렉토리에 오래된 리포지터리 사본이 있습니다.
  • 수천 개의 리포지터리가 있을 때.
Warning

각 접근 방식은 대상 디렉토리 /mnt/gitlab/repositories의 데이터를 덮어쓸 수 있거나 덮어씁니다. 소스와 대상을 올바르게 지정해야 합니다.

백업 및 복원 사용 (권장)#

Gitaly 또는 Gitaly 클러스터(Praefect) 대상 모두에 대해 GitLab 백업 및 복원 기능을 사용해야 합니다. Git 리포지터리는 Gitaly에 의해 데이터베이스로 GitLab 서버에서 접근, 관리, 저장됩니다. rsync와 같은 도구를 사용하여 Gitaly 파일에 직접 접근하고 복사하면 데이터 손실이 발생할 수 있습니다. 다음을 수행할 수 있습니다:

Gitaly 클러스터(Praefect) 대상에는 백업 및 복원 방법을 사용해야 합니다.

tar 사용#

다음과 같은 경우 tar 파이프를 사용하여 리포지터리를 이동할 수 있습니다:

  • Gitaly Cluster 대상이 아닌 Gitaly 대상을 지정합니다.
  • 대상 디렉토리 /mnt/gitlab/repositories가 비어 있습니다.

이 방법은 오버헤드가 낮으며 tar은 보통 시스템에 사전 설치되어 있습니다. 그러나 중단된 tar 파이프를 재개할 수 없습니다. tar가 중단되면 대상 디렉토리를 비우고 모든 데이터를 다시 복사해야 합니다.

tar 프로세스의 진행 상황을 보려면 -xf-xvf로 바꿉니다.

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

다른 서버로 tar 파이프 사용#

Gitaly 대상의 경우 tar 파이프를 사용하여 데이터를 다른 서버로 복사할 수 있습니다. git 사용자가 git@<newserver>로 새 서버에 SSH 액세스 권한이 있으면 SSH를 통해 데이터를 파이프할 수 있습니다.

네트워크를 통과하기 전에 데이터를 압축하려면 (CPU 사용량이 증가함) sshssh -C로 바꿀 수 있습니다.

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

rsync 사용#

다음과 같은 경우 rsync를 사용하여 리포지터리를 이동할 수 있습니다:

  • Gitaly Cluster 대상이 아닌 Gitaly 대상을 지정합니다.
  • 대상 디렉토리에 이미 리포지터리의 부분적 또는 오래된 사본이 있어 tar로 모든 데이터를 다시 복사하는 것이 비효율적입니다.
Warning

rsync를 사용할 때 --delete 옵션을 사용해야 합니다. --delete 없이 rsync를 사용하면 데이터 손실과 리포지터리 손상이 발생할 수 있습니다. 자세한 내용은 이슈 270422를 참조하세요.

다음 명령에서 /.가 매우 중요하며, 그렇지 않으면 대상 디렉토리에 잘못된 디렉토리 구조가 생길 수 있습니다. 진행 상황을 보려면 -a-av로 바꿉니다.

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

다른 서버로 rsync 사용#

Gitaly 대상의 경우 소스 시스템의 git 사용자가 대상 서버에 SSH 액세스 권한이 있으면 rsync로 네트워크를 통해 리포지터리를 전송할 수 있습니다.

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

관련 항목#

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

Tier: Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기
요약

GitLab이 관리하는 모든 리포지터리를 다른 파일 시스템이나 다른 서버로 이동합니다. GitLab API를 사용하여 Git 리포지터리를 이동합니다: GitLab 리포지터리는 프로젝트, 그룹, 스니펫과 연결될 수 있습니다.

GitLab이 관리하는 모든 리포지터리를 다른 파일 시스템이나 다른 서버로 이동합니다.

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

GitLab API를 사용하여 Git 리포지터리를 이동합니다:

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

GitLab 리포지터리는 프로젝트, 그룹, 스니펫과 연결될 수 있습니다. 이러한 각 유형은 리포지터리를 이동하기 위한 별도의 API가 있습니다. GitLab 인스턴스의 모든 리포지터리를 이동하려면 각 스토리지에 대해 각 유형의 리포지터리를 이동해야 합니다.

각 리포지터리는 이동하는 동안 읽기 전용으로 설정되며 이동이 완료될 때까지 쓸 수 없습니다.

리포지터리를 이동하려면:

  1. 모든 로컬 및 클러스터 스토리지가 GitLab 인스턴스에서 접근 가능한지 확인합니다. 이 예시에서는 <original_storage_name><cluster_storage_name>입니다.
  2. 새 스토리지가 모든 새 프로젝트를 받도록 리포지터리 스토리지 가중치를 구성합니다. 이렇게 하면 마이그레이션이 진행되는 동안 기존 스토리지에 새 프로젝트가 생성되지 않습니다.
  3. 프로젝트, 스니펫, 그룹에 대한 리포지터리 이동을 예약합니다.
  4. Geo를 사용하는 경우 모든 리포지터리를 다시 동기화합니다.
  5. Sidekiq 파드에서 수평 파드 자동 스케일러를 사용하는 경우 마이그레이션 중에 스케일링을 방지하기 위해 Sidekiq 파드에 대한 HPA를 비활성화합니다.

프로젝트 이동#

모든 프로젝트 또는 개별 프로젝트를 이동할 수 있습니다.

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

    또는 Rails 콘솔을 사용하여 모든 프로젝트가 이동했는지 확인합니다:

    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 콘솔을 사용하여 모든 스니펫이 이동했는지 확인합니다:

    SnippetRepository.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/group_repository_storage_moves"
    
  2. 가장 최근 리포지터리 이동을 조회합니다. 응답은 다음 중 하나를 나타냅니다:

    • 이동이 성공적으로 완료됨. state 필드가 finished임.
    • 이동이 진행 중. 성공적으로 완료될 때까지 리포지터리 이동을 다시 조회합니다.
    • 이동이 실패. 대부분의 실패는 일시적이며 이동을 다시 예약하면 해결됩니다.
  3. 이동이 완료된 후 Rails 콘솔을 사용하여 모든 그룹이 이동했는지 확인합니다:

    GroupWikiRepository.for_repository_storage('<original_storage_name>')
    

    이 명령은 원래 스토리지의 그룹을 반환해서는 안 됩니다.

  4. 필요에 따라 각 스토리지에 대해 반복합니다.

모든 그룹을 이동하지 않으려면 개별 그룹 지침을 따릅니다.

다른 GitLab 인스턴스로 마이그레이션#

새 GitLab 환경으로 마이그레이션하는 경우 API를 사용하여 데이터를 이동할 수 없습니다. 예:

  • 단일 노드 GitLab에서 스케일 아웃 아키텍처로.
  • 개인 데이터 센터의 GitLab 인스턴스에서 클라우드 공급자로.

이 경우 시나리오에 따라 /var/opt/gitlab/git-data/repositories에서 /mnt/gitlab/repositories로 모든 리포지터리를 복사하는 방법이 있습니다:

  • 대상 디렉토리가 비어 있습니다.
  • 대상 디렉토리에 오래된 리포지터리 사본이 있습니다.
  • 수천 개의 리포지터리가 있을 때.
Warning

각 접근 방식은 대상 디렉토리 /mnt/gitlab/repositories의 데이터를 덮어쓸 수 있거나 덮어씁니다. 소스와 대상을 올바르게 지정해야 합니다.

백업 및 복원 사용 (권장)#

Gitaly 또는 Gitaly 클러스터(Praefect) 대상 모두에 대해 GitLab 백업 및 복원 기능을 사용해야 합니다. Git 리포지터리는 Gitaly에 의해 데이터베이스로 GitLab 서버에서 접근, 관리, 저장됩니다. rsync와 같은 도구를 사용하여 Gitaly 파일에 직접 접근하고 복사하면 데이터 손실이 발생할 수 있습니다. 다음을 수행할 수 있습니다:

Gitaly 클러스터(Praefect) 대상에는 백업 및 복원 방법을 사용해야 합니다.

tar 사용#

다음과 같은 경우 tar 파이프를 사용하여 리포지터리를 이동할 수 있습니다:

  • Gitaly Cluster 대상이 아닌 Gitaly 대상을 지정합니다.
  • 대상 디렉토리 /mnt/gitlab/repositories가 비어 있습니다.

이 방법은 오버헤드가 낮으며 tar은 보통 시스템에 사전 설치되어 있습니다. 그러나 중단된 tar 파이프를 재개할 수 없습니다. tar가 중단되면 대상 디렉토리를 비우고 모든 데이터를 다시 복사해야 합니다.

tar 프로세스의 진행 상황을 보려면 -xf-xvf로 바꿉니다.

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

다른 서버로 tar 파이프 사용#

Gitaly 대상의 경우 tar 파이프를 사용하여 데이터를 다른 서버로 복사할 수 있습니다. git 사용자가 git@<newserver>로 새 서버에 SSH 액세스 권한이 있으면 SSH를 통해 데이터를 파이프할 수 있습니다.

네트워크를 통과하기 전에 데이터를 압축하려면 (CPU 사용량이 증가함) sshssh -C로 바꿀 수 있습니다.

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

rsync 사용#

다음과 같은 경우 rsync를 사용하여 리포지터리를 이동할 수 있습니다:

  • Gitaly Cluster 대상이 아닌 Gitaly 대상을 지정합니다.
  • 대상 디렉토리에 이미 리포지터리의 부분적 또는 오래된 사본이 있어 tar로 모든 데이터를 다시 복사하는 것이 비효율적입니다.
Warning

rsync를 사용할 때 --delete 옵션을 사용해야 합니다. --delete 없이 rsync를 사용하면 데이터 손실과 리포지터리 손상이 발생할 수 있습니다. 자세한 내용은 이슈 270422를 참조하세요.

다음 명령에서 /.가 매우 중요하며, 그렇지 않으면 대상 디렉토리에 잘못된 디렉토리 구조가 생길 수 있습니다. 진행 상황을 보려면 -a-av로 바꿉니다.

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

다른 서버로 rsync 사용#

Gitaly 대상의 경우 소스 시스템의 git 사용자가 대상 서버에 SSH 액세스 권한이 있으면 rsync로 네트워크를 통해 리포지터리를 전송할 수 있습니다.

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

관련 항목#