GitLabで管理されているリポジトリの移動
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
GitLabで管理されているすべてのリポジトリを、別のファイルシステムまたは別のサーバーに移動します。
GitLabインスタンス内のデータを移動
GitLab APIを使用してGitリポジトリを移動します:
- サーバー間。
- 異なるストレージ間。
- 単一ノードGitalyからGitaly Cluster (Praefect)
GitLabのリポジトリは、プロジェクト、グループ、およびスニペットに関連付けることができます。これらの各タイプには、リポジトリを移動するための個別のAPIがあります。GitLabインスタンス上のすべてのリポジトリを移動するには、各リポジトリのタイプごとにストレージを移動する必要があります。
各リポジトリは、リポジトリの移動中は読み取り専用になり、リポジトリの移動が完了するまで書き込みできません。
リポジトリを移動するには:
- すべてのローカルおよびクラスターストレージがGitLabインスタンスにアクセスできることを確認します。この例では、これらは
<original_storage_name>と<cluster_storage_name>です。 - 新しいストレージがすべての新規プロジェクトを受信するように、リポジトリストレージウェイトを構成します。これにより、移行の進行中に、既存のストレージに新規プロジェクトが作成されるのを防ぎます。
- プロジェクト、スニペット、およびグループのリポジトリの移動をスケジュールします。
- Geoを使用している場合は、すべてのリポジトリを再同期します。
- SidekiqポッドでHorizontal Pod Autoscalerを使用する場合は、移行中のスケーリングを防ぐために、SidekiqポッドのHPAを無効にします。
プロジェクトを移動する
すべてのプロジェクトまたは個別のプロジェクトを移動できます。
APIを使用してすべてのプロジェクトを移動するには:
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"APIを使用して、最も最近のリポジトリの移動をクエリします。応答は次のいずれかを示します:
- リポジトリの移動は正常に完了しました。
stateフィールドはfinishedです。 - リポジトリの移動が進行中です。リポジトリの移動が正常に完了するまで再クエリします。
- リポジトリの移動は失敗しました。ほとんどの失敗は一時的なものであり、リポジトリの移動を再スケジュールすることで解決されます。
- リポジトリの移動は正常に完了しました。
リポジトリの移動が完了したら、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>')必要に応じて各ストレージで繰り返します。
すべてのプロジェクトを移動したくない場合は、個別のプロジェクトを移動する手順に従ってください。
スニペットを移動する
すべてのスニペットまたは個別のスニペットを移動できます。
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"最も最近のリポジトリの移動をクエリします。応答は次のいずれかを示します:
- リポジトリの移動は正常に完了しました。
stateフィールドはfinishedです。 - リポジトリの移動が進行中です。リポジトリの移動が正常に完了するまで再クエリします。
- リポジトリの移動は失敗しました。ほとんどの失敗は一時的なものであり、リポジトリの移動を再スケジュールすることで解決されます。
- リポジトリの移動は正常に完了しました。
リポジトリの移動が完了したら、Railsコンソールを使用して、すべてのスニペットが移動されたことを確認します:
SnippetRepository.for_repository_storage('<original_storage_name>')このコマンドは、元のストレージのスニペットを返すべきではありません。
必要に応じて各ストレージで繰り返します。
すべてのスニペットを移動したくない場合は、個別のスニペットの手順に従ってください。
グループを移動する
- プラン: Premium、Ultimate
- 提供形態: GitLab Self-Managed
すべてのグループまたは個別のグループを移動できます。
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"最も最近のリポジトリの移動をクエリします。応答は次のいずれかを示します:
- リポジトリの移動は正常に完了しました。
stateフィールドはfinishedです。 - リポジトリの移動が進行中です。リポジトリの移動が正常に完了するまで再クエリします。
- リポジトリの移動は失敗しました。ほとんどの失敗は一時的なものであり、リポジトリの移動を再スケジュールすることで解決されます。
- リポジトリの移動は正常に完了しました。
リポジトリの移動が完了したら、Railsコンソールを使用して、すべてのグループが移動されたことを確認します:
GroupWikiRepository.for_repository_storage('<original_storage_name>')このコマンドは、元のストレージのグループを返すべきではありません。
必要に応じて各ストレージで繰り返します。
すべてのグループを移動したくない場合は、個別のグループの手順に従ってください。
別のGitLabインスタンスへ移行する
新しいGitLab環境に移行する場合は、APIを使用してデータを移動することはできません。例:
- 単一ノードのGitLabからスケールアウトアーキテクチャへ。
- プライベートデータセンター内のGitLabインスタンスからクラウドプロバイダーへ。
この場合、シナリオに応じてすべてのリポジトリを/var/opt/gitlab/git-data/repositoriesから/mnt/gitlab/repositoriesにコピーする方法があります:
- ターゲットディレクトリが空である。
- ターゲットディレクトリにリポジトリの古いコピーが含まれている。
- リポジトリが数千ある場合。
いずれのアプローチも、ターゲットディレクトリ/mnt/gitlab/repositoriesのデータを上書きする可能性があります。ソースとターゲットを正しく指定する必要があります。
バックアップと復元を使用する(推奨)
GitalyまたはGitaly Cluster (Praefect)のターゲットには、GitLabのバックアップと復元機能を使用する必要があります。Gitリポジトリは、GitalyによってデータベースとしてGitLabサーバー上でアクセス、管理、保存されます。rsyncのようなツールを使用してGitalyファイルに直接アクセスしてコピーすると、データ損失が発生する可能性があります。次のことができます:
- 複数のリポジトリを同時に処理することで、バックアップパフォーマンスを向上させます。
- スキップ機能を使用して、リポジトリのみのバックアップを作成します。
Gitaly Cluster (Praefect)ターゲットには、バックアップと復元の方法を使用する必要があります。
tarを使用する
次の場合、tarパイプを使用してリポジトリを移動できます:
- Gitalyターゲットを指定し、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使用率が増加します)は、sshをssh -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ターゲットを指定し、Gitalyクラスターターゲットは指定しません。
- ターゲットディレクトリにすでにリポジトリの部分的または古いコピーが含まれているため、
tarでデータをすべて再度コピーするのは非効率です。
rsyncを使用する場合は、--deleteオプションを使用する必要があります。rsyncを--deleteなしで使用すると、データ損失やリポジトリの破損を引き起こす可能性があります。詳細については、イシュー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'