GitLabのバックアップ

GitLabをバックアップする正確な手順は、多くの要因によって異なります。あなたの特定のデプロイの使い方と設定によって、どのようなデータが存在し、どこにあり、どれだけの量があるのかが決まります。これらの要因は、バックアップの実行方法、保存方法、復元方法の選択肢に影響します。

簡単なバックアップ手順

大まかなガイドラインとして、1kリファレンスアーキテクチャを使用しており、データ量が100GB未満の場合は、以下の手順に従ってください:

  1. backupコマンドを実行します。
  2. 該当する場合は、オブジェクトストレージをバックアップします。
  3. 設定ファイルを手動でバックアップします。

バックアップの拡張

GitLabのデータ量が増えると、バックアップコマンドの実行に時間がかかります。Git リポジトリの同時バックアップや、リポジトリの増分バックアップなどの バックアップオプションは、実行時間の短縮に役立ちます。ある時点で、バックアップコマンドはそれだけでは実用的でなくなります。例えば、24時間以上かかることもあります。

場合によっては、バックアップをスケールできるようにアーキテクチャを変更する必要があるかもしれません。GitLabリファレンスアーキテクチャを使っている場合は、大規模なリファレンスアーキテクチャのバックアップと復元を参照してください。

詳細については、代替バックアップ戦略をご覧ください。

どのようなデータをバックアップする必要がありますか?

PostgreSQLデータベース

最も単純なケースでは、GitLabは他のすべてのGitLabサービスと同じVM上の1つのPostgreSQLサーバーに1つのPostgreSQLデータベースを持ちます。しかし、設定によっては、GitLabは複数のPostgreSQLサーバーで複数のPostgreSQLデータベースを使うことができます。

一般的に、このデータは、イシューやマージリクエストの内容、コメント、権限、クレデンシャルのような、ウェブ・インターフェイスでユーザーが生成するほとんどのコンテンツのための単一の真実のソースです。

PostgreSQLはHTMLレンダリングされたMarkdownやデフォルトではマージリクエストの差分などのキャッシュデータも保持します。しかし、マージリクエストの差分をファイルシステムやオブジェクトストレージにオフロードするように設定することもできます。

Gitaly ClusterのPreefectサービスは、Gitalyノードを管理するための単一の真実のソースとしてPostgreSQLデータベースを使用します。

一般的なPostgreSQLユーティリティであるpg_dump 、PostgreSQLデータベースをリストアするために使用できるバックアップファイルを作成します。backupコマンドはこのユーティリティを使用します。

残念ながら、データベースが大きくなればなるほど、pg_dump の実行に時間がかかります。状況にもよりますが、この時間はある時点で実用的ではなくなります(例えば数日)。データベースが100GBを超える場合、pg_dump 、ひいてはバックアップコマンドは使用できない可能性が高いです。詳細については、別のバックアップ戦略を参照してください。

Gitリポジトリ

GitLabインスタンスは1つ以上のリポジトリシャードを持つことができます。各シャードはGitalyインスタンスまたはGitalyクラスターで、ローカルに保存されたGitリポジトリへのアクセスとオペレーションを担当します。Gitalyはマシン上で実行できます:

  • シングルディスク
  • 複数のディスクを1つのマウントポイントとしてマウントした場合(RAIDアレイのように)。
  • LVMの使用。

各プロジェクトは最大3つの異なるリポジトリを持つことができます:

  • プロジェクトリポジトリ:ソースコードが保存されます。
  • Wiki リポジトリ:Wiki コンテンツが保存されます。
  • デザインリポジトリ:デザインのアーティファクトがインデックス化されます(アセットは実際にはLFSにあります)。

これらはすべて同じシャードに存在し、Wikiとデザインリポジトリの場合は、-wiki-design のサフィックスを持つ同じベース名を共有します。

個人とプロジェクトのスニペット、グループのWikiコンテンツはGitリポジトリに保存されます。

プロジェクトのフォークは、プールリポジトリを使ってGitLabサイト内で重複排除されます。

backup コマンドは各リポジトリの Git バンドルを作成し、それらをすべて tar アップします。これにより、すべてのフォークにプールリポジトリのデータが複製されます。私たちのテストでは、100GBのGitリポジトリのバックアップとS3へのアップロードに2時間強かかりました。Git データが 400 GB ぐらいになると、backup コマンドは定期的なバックアップには使えなくなるでしょう。詳しくは、別のバックアップ戦略をご覧ください。

ブロブ

GitLabはイシューの添付ファイルやLFSオブジェクトのようなブロブ(またはファイル)をどちらかに保存します:

  • 特定の場所のファイルシステム。
  • オブジェクトストレージ・ソリューション。オブジェクトストレージ・ソリューションには次のようなものがあります:
    • Amazon S3やGoogle Cloud Storageのようなクラウドベース。
    • MinIOのような)お客様によるホスティング。
    • オブジェクトストレージ互換のAPIを公開するストレージアプライアンス。

オブジェクトストレージ

backupコマンドは、ファイルシステムに保存されていないblobをバックアップしません。オブジェクトストレージを使用している場合は、必ずオブジェクトストレージプロバイダでバックアップを有効にしてください。たとえば、以下を参照してください:

コンテナレジストリ

GitLab Container Registryのストレージは、以下のどちらかで設定できます:

  • 特定の場所のファイルシステム。
  • オブジェクトストレージ・ソリューション。オブジェクトストレージ・ソリューションには次のようなものがあります:
    • Amazon S3やGoogle Cloud Storageのようなクラウドベース。
    • MinIOのような)お客様によるホスティング。
    • オブジェクトストレージ互換のAPIを公開するストレージアプライアンス。

バックアップコマンドは、レジストリデータがファイルシステム上のデフォルトの場所に保存されている場合にバックアップします。

オブジェクトストレージ

backupコマンドは、ファイルシステムに保存されていないblobをバックアップしません。オブジェクトストレージを使用している場合は、必ずオブジェクトストレージプロバイダでバックアップを有効にしてください。たとえば、以下を参照してください:

設定ファイルの保存

caution
GitLabが提供するバックアップRakeタスクは、設定ファイルを保存_しません_。その主な理由は、データベースには二要素認証やCI/CD_セキュア_変数のための暗号化された情報を含む項目が含まれているからです。暗号化された情報をそのキーと同じ場所に保存することは、そもそも暗号化を使う目的を破ります。たとえば、シークレットファイルにはデータベースの暗号化キーが含まれています。もしこれを失ったら、GitLabアプリケーションはデータベース内の暗号化された値を復号化することができません。
caution
シークレットファイルはアップグレード後に変更されることがあります。

設定ディレクトリをバックアップする必要があります。最低限、バックアップは必要です:

Linux package
  • /etc/gitlab/gitlab-secrets.json
  • /etc/gitlab/gitlab.rb

詳細は、「Linuxパッケージ(Omnibus)設定のバックアップとリストア」を参照してください。

Self-compiled
  • /home/git/gitlab/config/secrets.yml
  • /home/git/gitlab/config/gitlab.yml
Docker
  • 設定ファイルが保存されているボリュームをバックアップします。ドキュメントに従ってGitLabコンテナを作成した場合は、/srv/gitlab/config ディレクトリにあるはずです。
GitLab Helm chart

また、TLSキーと証明書(/etc/gitlab/ssl,/etc/gitlab/trusted-certs)、SSHホストキーもバックアップしておくと、マシンのフルリストアを行う際に中間者攻撃の警告を回避できます。

万が一シークレットファイルが失われた場合は、トラブルシューティングのセクションを参照してください。

その他のデータ

GitLabはRedisをキャッシュストアとして、またバックグラウンドジョブシステムであるSidekiqの永続的なデータを保持するために使っています。提供されているbackupコマンドはRedisのデータをバックアップ_しません_。つまり、backupコマンドで一貫性のあるバックアップを取るには、保留中のジョブや実行中のバックグラウンド・ジョブがない必要があります。Redisを手動でバックアップすることは可能です。

Elasticsearchは高度な検索を行うためのオプションのデータベースです。ソースコードレベルと、イシュー、マージリクエスト、ディスカッションなどのユーザー生成コンテンツの両方の検索を改善することができます。backup コマンドはElasticsearch のデータをバックアップ_しません_。Elasticsearch のデータはリストア後に PostgreSQL のデータから再生成することができます。Elasticsearch を手動でバックアップすることは可能です。

コマンドラインインタフェース

GitLabはインスタンス全体をバックアップするためのコマンドラインインターフェイスを提供しています:

  • データベース
  • 添付ファイル
  • Gitリポジトリデータ
  • CI/CDジョブの出力ログ
  • CI/CDジョブのアーティファクト
  • LFSオブジェクト
  • Terraform ステート(GitLab 14.7 で導入)
  • コンテナレジストリイメージ
  • GitLabページのコンテンツ
  • パッケージ(GitLab 14.7 で導入)
  • スニペット
  • グループWiki
  • プロジェクトレベルのセキュアファイル(GitLab 16.1 で導入)

バックアップには含まれません:

caution
GitLabは設定ファイル(/etc/gitlab)、TLSキーと証明書、システムファイルをバックアップしません。設定ファイルの保存について読むことを強くお勧めします。

要件

バックアップとリストアができるように、Rsyncがシステムにインストールされていることを確認してください。GitLabをインストールした場合:

  • Using the Linux パッケージをインストールした場合は、Rsync は既にインストールされています。
  • セルフコンパイルを使用して、rsync がインストールされているかどうかを確認します。Rsyncがインストールされていない場合は、インストールしてください。例えば

     # Debian/Ubuntu
     sudo apt-get install rsync
       
     # RHEL/CentOS
     sudo yum install rsync
    

バックアップ・コマンド

caution
バックアップコマンドは、オブジェクトストレージ内のアイテムをバックアップしません。
caution
インストールがPgBouncerを使用している場合、パフォーマンス上の理由から、あるいはPatroniクラスターで使用する場合、backupコマンドには追加のパラメータが必要です。
caution
GitLab 15.5.0以前では、イシュー362593で説明されているように、backupコマンドは別のバックアップが既に実行されているかどうかを検証しません。新しいバックアップを開始する前に、全てのバックアップが完了していることを確認することを強くお勧めします。
note
バックアップを復元できるのは、それが作成されたGitLabと全く同じバージョンとタイプ(CE/EE)のみです。
Linux package (Omnibus)
sudo gitlab-backup create
Helm chart (Kubernetes)

kubectl 、GitLab toolboxポッド上でbackup-utility スクリプトを実行してバックアップタスクを実行します。詳細については、Chart backup documentationを参照してください。

Docker

ホストからバックアップを実行します。

  • GitLab 12.2 以降:
docker exec -t <container name> gitlab-backup create
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production

GitLabデプロイに複数のノードがある場合、バックアップコマンドを実行するノードを選択する必要があります。指定したノードが

  • が永続的で、自動スケーリングの対象になっていないことを確認する必要があります。
  • GitLab Railsアプリケーションがインストールされていること。PumaまたはSidekiqが実行されている場合、Railsがインストールされています。
  • バックアップファイルを作成するのに十分なストレージとメモリがあります。

出力例です:

Dumping database tables:
- Dumping table events... [DONE]
- Dumping table issues... [DONE]
- Dumping table keys... [DONE]
- Dumping table merge_requests... [DONE]
- Dumping table milestones... [DONE]
- Dumping table namespaces... [DONE]
- Dumping table notes... [DONE]
- Dumping table projects... [DONE]
- Dumping table protected_branches... [DONE]
- Dumping table schema_migrations... [DONE]
- Dumping table services... [DONE]
- Dumping table snippets... [DONE]
- Dumping table taggings... [DONE]
- Dumping table tags... [DONE]
- Dumping table users... [DONE]
- Dumping table users_projects... [DONE]
- Dumping table web_hooks... [DONE]
- Dumping table wikis... [DONE]
Dumping repositories:
- Dumping repository abcd... [DONE]
Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
Deleting tmp directories...[DONE]
Deleting old backups... [SKIPPING]

バックアップタイムスタンプ

バックアップ・アーカイブは、config/gitlab.yml ファイルで指定されたbackup_path に保存されます。デフォルトのパスは/var/opt/gitlab/backups です。ファイル名は[TIMESTAMP]_gitlab_backup.tar で、TIMESTAMP は各バックアップが作成された時刻とGitLabのバージョンを示しています。タイムスタンプは、GitLabをリストアする必要があり、複数のバックアップがある場合に必要です。

例えば、バックアップ名が1493107454_2018_04_25_10.6.4-ce_gitlab_backup.tar の場合、タイムスタンプは1493107454_2018_04_25_10.6.4-ce となります。

バックアップ・オプション

GitLabがインスタンスをバックアップするために提供しているコマンドラインツールは、より多くのオプションを受け入れることができます。

バックアップ戦略オプション

デフォルトのバックアップ戦略は、基本的にLinuxコマンドtar およびgzip を使用して、それぞれのデータロケーションからバックアップにデータをストリームすることです。これはほとんどの場合うまく機能しますが、データが急速に変化する場合には問題が発生する可能性があります。

tar がデータを読み込んでいる間にデータが変更されると、エラーfile changed as we read it が発生し、バックアップ処理が失敗することがあります。このような場合は、copy というバックアップ戦略を使用します。このストラテジーは、targzip を呼び出す前にデータ・ファイルを一時的な場所にコピーし、エラーを回避します。

副作用として、バックアップ処理にはさらに1倍のディスク容量が必要になります。このプロセスは各ステージで一時ファイルをクリーンアップするよう最善を尽くしますので、問題は深刻化しませんが、大規模なインストールではかなりの変更になる可能性があります。

デフォルトのストリーミング戦略の代わりにcopy 戦略を使用するには、Rake タスクコマンドでSTRATEGY=copy を指定します。たとえば

sudo gitlab-backup create STRATEGY=copy

バックアップファイル名

caution
カスタム・バックアップ・ファイル名を使用する場合、バックアップの有効期間を制限することはできません。

デフォルトでは、バックアップ・ファイルは前の「バックアップのタイムスタンプ」セクションの指定に従って作成されます。ただし、環境変数BACKUP を設定することで、ファイル名の[TIMESTAMP] 部分を上書きできます。例えば

sudo gitlab-backup create BACKUP=dump

結果のファイル名はdump_gitlab_backup.tar になります。これは、rsyncや増分バックアップを使用するシステムで便利で、転送速度がかなり速くなります。

アーカイブの確認

生成されたアーカイブが rsync で転送可能であることを確認するには、GZIP_RSYNCABLE=yes オプションを設定します。これは、--rsyncable オプションをgzip に設定します。これは、Backup filename オプションの設定と組み合わせてのみ有効です。

gzip--rsyncable オプションは、すべてのディストリビューションで利用できることを保証するものではありません。お使いのディストリビューションで利用可能かどうかを確認するには、gzip --help を実行するか、マニュアルページを参照してください。

sudo gitlab-backup create BACKUP=dump GZIP_RSYNCABLE=yes

特定のディレクトリをバックアップから除外

特定のディレクトリをバックアップから除外するには、環境変数SKIP を追加します。この変数には、以下のオプションをカンマ区切りで指定します:

  • db (データベース)
  • uploads (添付ファイル)
  • builds (CIジョブ出力ログ)
  • artifacts (CIジョブのアーティファクト)
  • lfs (LFSオブジェクト)
  • terraform_state (Terraformの状態)
  • registry (コンテナレジストリイメージ)
  • pages (ページコンテンツ)
  • repositories (Gitリポジトリデータ)
  • packages (パッケージ)
  • ci_secure_files (プロジェクトレベルのセキュアファイル)
note
Helmチャートのバックアップとリストアには、GitLabパッケージレジストリによって管理されているパッケージを参照する追加オプションpackages があります。詳細はコマンドライン引数を参照してください。

すべてのWikiはrepositories グループの一部としてバックアップされます。存在しないWikiはバックアップ中にスキップされます。

Linux package (Omnibus)
sudo gitlab-backup create SKIP=db,uploads
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=db,uploads RAILS_ENV=production

SKIP= は次のようにも使われます:

tar作成のスキップ

note
バックアップにオブジェクトストレージを使用する場合、tarの作成をスキップすることはできません。

バックアップ作成の最後の部分は、.tar すべてのパーツを含むファイルの .tar生成です。.tar 場合によっては .tar、ファイルを.tar 作成する .tarことは無駄な労力であったり、直接的に有害であったりすることがあるので、環境変数SKIPtar を追加することで、このステップをスキップすることができます。使用例

  • バックアップが他のバックアップソフトウェアによってピックアップされる場合。
  • 毎回バックアップを抽出する手間を省き、増分バックアップを高速化する場合。(この場合、PREVIOUS_BACKUPBACKUP は指定しないでください。指定しないと、指定したバックアップは抽出されますが、最後に.tar ファイルは生成されません)。

SKIP 変数にtar を追加すると、中間ファイルに使用されるディレクトリにバックアップを含むファイルとディレクトリが残ります。これらのファイルは、新しいバックアップが作成されるときに上書きされるため、バックアップはシステム上に1つしか存在できないため、他の場所にコピーされていることを確認する必要があります。

Linux package (Omnibus)
sudo gitlab-backup create SKIP=tar
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=tar RAILS_ENV=production

サーバー側リポジトリバックアップの作成

GitLab 16.3 で導入されました

大きなリポジトリのバックアップをバックアップアーカイブに保存する代わりに、リポジトリのバックアップは、各リポジトリをホストするGitalyノードがバックアップの作成とオブジェクトストレージへのストリーミングを担当するように設定することができます。これにより、バックアップの作成と復元に必要なネットワークリソースを削減できます。

  1. Gitalyでサーバー側のバックアップ先を設定します。
  2. REPOSITORIES_SERVER_SIDE 変数を使用してバックアップを作成します。以下の例を参照してください。
Linux package (Omnibus)
sudo gitlab-backup create REPOSITORIES_SERVER_SIDE=true
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create REPOSITORIES_SERVER_SIDE=true

Git リポジトリの同時バックアップ

複数のリポジトリストレージを使用している場合、CPU時間をフルに活用するためにリポジトリを同時にバックアップまたはリストアすることができます。Rakeタスクのデフォルトの動作を変更するために、以下の変数が利用可能です:

  • GITLAB_BACKUP_MAX_CONCURRENCY:同時にバックアップするプロジェクトの最大数。デフォルトは論理CPU数(GitLab 14.1以前では、デフォルトは1 )。
  • GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY:各ストレージで同時にバックアップするプロジェクトの最大数。これにより、リポジトリのバックアップをストレージに分散させることができます。デフォルトは2 です(GitLab 14.1 以前のデフォルトは1 )。

例えば、4つのリポジトリストレージの場合:

Linux package (Omnibus)
sudo gitlab-backup create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1

リポジトリの増分バックアップ

フラグ: セルフマネジメントのGitLabでは、デフォルトでこの機能が利用可能です。この機能を隠すには、管理者がincremental_repository_backup という機能フラグを無効にします。GitLab.comでは、この機能は利用できません。

note
リポジトリのみが増分バックアップをサポートしています。したがって、INCREMENTAL=yes を使用すると、タスクは自己完結型のバックアップtarアーカイブを作成します。リポジトリ以外のすべてのサブタスクがフルバックアップを作成するためです(既存のフルバックアップを上書きします)。すべてのサブタスクで増分バックアップをサポートする機能要求については、イシュー19256を参照してください。

インクリメンタルリポジトリバックアップは、各リポジトリのバックアップバンドルに最後のバックアップ以降の変更のみをパックするため、フルリポジトリバックアップよりも高速です。各アーカイブはインスタンスの自己完結型バックアップです。増分バックアップを作成するには、既存のバックアップが必要です:

  • GitLab 14.9 と 14.10 では、BACKUP=<timestamp_of_backup> オプションを使って使用するバックアップを選択します。選択した以前のバックアップは上書きされます。
  • GitLab 15.0以降では、PREVIOUS_BACKUP=<timestamp_of_backup> オプションを使用して使用するバックアップを選択します。デフォルトでは、バックアップタイムスタンプセクションで説明されているようにバックアップファイルが作成されます。BACKUP 環境変数を設定することで、ファイル名の[TIMESTAMP] 部分を上書きすることができます。

増分バックアップを作成するには、以下を実行します:

  • GitLab 15.0以降で:

     sudo gitlab-backup create INCREMENTAL=yes PREVIOUS_BACKUP=<timestamp_of_backup>
    
  • GitLab 14.9と14.10の場合:

     sudo gitlab-backup create INCREMENTAL=yes BACKUP=<timestamp_of_backup>
    

tarredbackupからuntarredincremental backupを作成するには、SKIP=tar

sudo gitlab-backup create INCREMENTAL=yes SKIP=tar

特定のリポジトリストレージのバックアップ

GitLab 15.0 で導入されました

複数のリポジトリストレージを使用している場合、REPOSITORIES_STORAGES オプションを使って特定のリポジトリストレージのリポジトリを個別にバックアップすることができます。このオプションには、ストレージ名をカンマ区切りで指定します。

使用例:

Linux package (Omnibus)
sudo gitlab-backup create REPOSITORIES_STORAGES=storage1,storage2
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create REPOSITORIES_STORAGES=storage1,storage2

特定のリポジトリのバックアップ

GitLab 15.1で導入されました

REPOSITORIES_PATHS オプションを使って特定のリポジトリをバックアップできます。同様に、SKIP_REPOSITORIES_PATHS を使って特定のリポジトリをスキップすることもできます。どちらのオプションも、プロジェクトまたはグループのパスをカンマ区切りで指定します。グループパスを指定した場合、どちらのオプションを使用したかに応じて、そのグループおよび子孫グループ内のすべてのプロジェクトのすべてのリポジトリが含まれるかスキップされます。

たとえば、グループ A(group-a) のすべてのプロジェクトのすべてのリポジトリ、グループ B(group-b/project-c) のプロジェクト Cのリポジトリをバックアップし、グループ A(group-a/project-d) のプロジェクト Dをスキップします:

Linux package (Omnibus)
sudo gitlab-backup create REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d

リモート(クラウド)ストレージへのバックアップのアップロード

note
バックアップにオブジェクトストレージを使用する場合、tarの作成をスキップすることはできません。

バックアップスクリプトが作成した.tar ファイルを(Fog ライブラリを使用して)アップロードさせることができます。以下の例では、ストレージにAmazon S3を使用していますが、Fogでは他のストレージプロバイダを使用することもできます。GitLabはAWS、Google、Aliyunのクラウドドライバもインポートしています。ローカルドライバもあります。

GitLab でのオブジェクトストレージの使用について、詳しくはこちらをご覧ください。

Amazon S3を使う

Linuxパッケージ(Omnibus)の場合:

  1. /etc/gitlab/gitlab.rb に以下を追加してください:

    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'AWS',
      'region' => 'eu-west-1',
      'aws_access_key_id' => 'AKIAKIAKI',
      'aws_secret_access_key' => 'secret123'
      # If using an IAM Profile, don't configure aws_access_key_id & aws_secret_access_key
      # 'use_iam_profile' => true
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket'
    # Consider using multipart uploads when file size reaches 100MB. Enter a number in bytes.
    # gitlab_rails['backup_multipart_chunk_size'] = 104857600
    
  2. 変更を有効にするためにGitLab を再設定します。

S3 暗号化バケット

GitLab 14.3で導入されました

AWSはサーバー側の暗号化でこれらのモードをサポートしています:

  • Amazon S3-Managed Keys (SSE-S3)
  • AWS鍵管理サービス(SSE-KMS)に保存されたカスタマーマスターキー(CMK)
  • 顧客提供鍵(SSE-C)

GitLabでお好きなモードをお使いください。それぞれのモードは似ていますが、若干設定方法が異なります。

SSE-S3

SSE-S3 を有効にするには、バックアップ・ストレージ・オプションでserver_side_encryption フィールドをAES256 に設定します。例えば、Linuxパッケージ(Omnibus)では、次のようになります:

gitlab_rails['backup_upload_storage_options'] = {
  'server_side_encryption' => 'AES256'
}
SSE-KMS

SSE-KMS を有効にするには、arn:aws:kms:region:acct-id:key/key-id 形式の Amazon リソース名(ARN) を介した KMS キーが必要です。backup_upload_storage_options 設定で、次のように設定します:

  • server_side_encryptionaws:kms に設定します。
  • server_side_encryption_kms_key_id をキーのARNに変換します。

例えば、Linuxパッケージ(Omnibus)の場合:

gitlab_rails['backup_upload_storage_options'] = {
  'server_side_encryption' => 'aws:kms',
  'server_side_encryption_kms_key_id' => 'arn:aws:<YOUR KMS KEY ID>:'
}
SSE-C

SSE-C では、これらの暗号化オプションを設定する必要があります:

  • backup_encryption:AES256。
  • backup_encryption_key:エンコードされていない32バイト(256ビット)の鍵。これが正確に32バイトでない場合、アップロードは失敗します。

例えば、Linuxパッケージ(Omnibus)の場合:

gitlab_rails['backup_encryption'] = 'AES256'
gitlab_rails['backup_encryption_key'] = '<YOUR 32-BYTE KEY HERE>'

キーにバイナリ文字が含まれ、UTF-8 でエンコードできない場合は、代わりにGITLAB_BACKUP_ENCRYPTION_KEY 環境変数でキーを指定します。例えば

gitlab_rails['env'] = { 'GITLAB_BACKUP_ENCRYPTION_KEY' => "\xDE\xAD\xBE\xEF" * 8 }
デジタルオーシャンスペース

この例は、アムステルダムのバケット(AMS3)に使用できます:

  1. /etc/gitlab/gitlab.rb に以下を追加してください:

    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'AWS',
      'region' => 'ams3',
      'aws_access_key_id' => 'AKIAKIAKI',
      'aws_secret_access_key' => 'secret123',
      'endpoint'              => 'https://ams3.digitaloceanspaces.com'
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket'
    
  2. 変更を有効にするためにGitLab を再設定します。

Digital Ocean Spacesの使用時に400 Bad Request のエラーメッセージが表示される場合、バックアップの暗号化が原因である可能性があります。Digital Ocean Spacesは暗号化をサポートしていないため、gitlab_rails['backup_encryption'] を含む行を削除するかコメントしてください。

その他のS3プロバイダ

全ての S3 プロバイダが Fog ライブラリと完全に互換性があるわけではありません。例えば、アップロードしようとした後に411 Length Required のエラーメッセージが表示された場合、このイシューのためにaws_signature_version の値をデフォルト値から2 にダウングレードする必要があるかもしれません。

セルフコンパイルによるインストールの場合:

  1. home/git/gitlab/config/gitlab.yml を編集します:

      backup:
        # snip
        upload:
          # Fog storage connection settings, see https://fog.io/storage/ .
          connection:
            provider: AWS
            region: eu-west-1
            aws_access_key_id: AKIAKIAKI
            aws_secret_access_key: 'secret123'
            # If using an IAM Profile, leave aws_access_key_id & aws_secret_access_key empty
            # ie. aws_access_key_id: ''
            # use_iam_profile: 'true'
          # The remote 'directory' to store your backups. For S3, this would be the bucket name.
          remote_directory: 'my.s3.bucket'
          # Specifies Amazon S3 storage class to use for backups, this is optional
          # storage_class: 'STANDARD'
          #
          # Turns on AWS Server-Side Encryption with Amazon Customer-Provided Encryption Keys for backups, this is optional
          #   'encryption' must be set in order for this to have any effect.
          #   'encryption_key' should be set to the 256-bit encryption key for Amazon S3 to use to encrypt or decrypt.
          #   To avoid storing the key on disk, the key can also be specified via the `GITLAB_BACKUP_ENCRYPTION_KEY`  your data.
          # encryption: 'AES256'
          # encryption_key: '<key>'
          #
          #
          # Turns on AWS Server-Side Encryption with Amazon S3-Managed keys (optional)
          # https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html
          # For SSE-S3, set 'server_side_encryption' to 'AES256'.
          # For SS3-KMS, set 'server_side_encryption' to 'aws:kms'. Set
          # 'server_side_encryption_kms_key_id' to the ARN of customer master key.
          # storage_options:
          #   server_side_encryption: 'aws:kms'
          #   server_side_encryption_kms_key_id: 'arn:aws:kms:YOUR-KEY-ID-HERE'
    
  2. GitLab を再起動して変更を有効にします。

バックアップを S3 にアップロードする場合は、アクセス権を制限した新しい IAM ユーザーを作成する必要があります。アップロードユーザーにバックアップをアップロードするためだけのアクセス権を与えるには、my.s3.bucket をバケット名に置き換えて以下の IAM プロファイルを作成します:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1412062044000",
      "Effect": "Allow",
      "Action": [
        "s3:AbortMultipartUpload",
        "s3:GetBucketAcl",
        "s3:GetBucketLocation",
        "s3:GetObject",
        "s3:GetObjectAcl",
        "s3:ListBucketMultipartUploads",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Resource": [
        "arn:aws:s3:::my.s3.bucket/*"
      ]
    },
    {
      "Sid": "Stmt1412062097000",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketLocation",
        "s3:ListAllMyBuckets"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "Stmt1412062128000",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my.s3.bucket"
      ]
    }
  ]
}
Googleクラウドストレージの使用

Googleクラウドストレージを使用してバックアップを保存するには、まずGoogleコンソールからアクセスキーを作成する必要があります:

  1. Googleストレージの設定ページにアクセスします。
  2. 相互運用性」を選択し、アクセスキーを作成します。
  3. アクセスキーと シークレットをメモし、以下の設定で置き換えてください。
  4. バケツの詳細設定で、アクセスコントロールオプションのSet object-level and bucket-level permissionsが選択されていることを確認してください。
  5. バケツを作成済みであることを確認します。

Linuxパッケージ(Omnibus)の場合:

  1. /etc/gitlab/gitlab.rb を編集します:

    gitlab_rails['backup_upload_connection'] = {
      'provider' => 'Google',
      'google_storage_access_key_id' => 'Access Key',
      'google_storage_secret_access_key' => 'Secret',
       
      ## If you have CNAME buckets (foo.example.com), you might run into SSL issues
      ## when uploading backups ("hostname foo.example.com.storage.googleapis.com
      ## does not match the server certificate"). In that case, uncomnent the following
      ## setting. See: https://github.com/fog/fog/issues/2834
      #'path_style' => true
    }
    gitlab_rails['backup_upload_remote_directory'] = 'my.google.bucket'
    
  2. 変更を有効にするためにGitLab を再設定します。

セルフコンパイルによるインストールの場合:

  1. home/git/gitlab/config/gitlab.yml を編集します:

      backup:
        upload:
          connection:
            provider: 'Google'
            google_storage_access_key_id: 'Access Key'
            google_storage_secret_access_key: 'Secret'
          remote_directory: 'my.google.bucket'
    
  2. GitLab を再起動して変更を有効にします。

Azure Blobストレージの使用

GitLab 13.4 で導入されました

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb を編集します:

    gitlab_rails['backup_upload_connection'] = {
     'provider' => 'AzureRM',
     'azure_storage_account_name' => '<AZURE STORAGE ACCOUNT NAME>',
     'azure_storage_access_key' => '<AZURE STORAGE ACCESS KEY>',
     'azure_storage_domain' => 'blob.core.windows.net', # Optional
    }
    gitlab_rails['backup_upload_remote_directory'] = '<AZURE BLOB CONTAINER>'
    
  2. 変更を有効にするためにGitLab を再設定します。

Self-compiled
  1. home/git/gitlab/config/gitlab.yml を編集します:

      backup:
        upload:
          connection:
            provider: 'AzureRM'
            azure_storage_account_name: '<AZURE STORAGE ACCOUNT NAME>'
            azure_storage_access_key: '<AZURE STORAGE ACCESS KEY>'
          remote_directory: '<AZURE BLOB CONTAINER>'
    
  2. GitLab を再起動して変更を有効にします。

詳細はAzureパラメータの表をご覧ください。

バックアップ用のカスタムディレクトリの指定

このオプションはリモート・ストレージでのみ機能します。バックアップをグループ化したい場合は、DIRECTORY 環境変数を渡します:

sudo gitlab-backup create DIRECTORY=daily
sudo gitlab-backup create DIRECTORY=weekly

リモートストレージへのバックアップのアップロードをスキップ

GitLabがリモートストレージにバックアップをアップロードするように設定している場合、SKIP=remote オプションを使用すると、リモートストレージへのバックアップのアップロードをスキップすることができます。

Linux package (Omnibus)
sudo gitlab-backup create SKIP=remote
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=remote RAILS_ENV=production

ローカルにマウントされた共有へのアップロード

FogLocal ストレージ・プロバイダを使用して、ローカルにマウントされた共有(たとえば、NFSCIFSSMB )にバックアップを送信できます。

これを行うには、以下の設定キーを設定する必要があります:

  • backup_upload_connection.local_rootバックアップがコピーされるマウント・ディレクトリ。
  • backup_upload_remote_directory:backup_upload_connection.local_root ディレクトリのサブディレクトリ。存在しない場合は作成されます。tarballs をマウントされたディレクトリのルートにコピーしたい場合は、. を使用してください。

マウントされた場合、local_root キーで設定されたディレクトリの所有者は次のいずれかでなければなりません:

  • git ユーザー。そのため、CIFSSMBgit ユーザーのuid= でマウントします。
  • バックアップ・タスクを実行するユーザー。Linux パッケージ(Omnibus)の場合、これはgit ユーザーです。

ファイルシステムのパフォーマンスはGitLab全体のパフォーマンスに影響する可能性があるため、ストレージにクラウドベースのファイルシステムを使うことはお勧めしません。

競合する設定を避ける

以下の設定キーを同じパスに設定しないでください:

  • gitlab_rails['backup_path'] (backup.path セルフコンパイル・インストール用)。
  • gitlab_rails['backup_upload_connection'].local_root (backup.upload.connection.local_root セルフコンパイル・インストール用)。

backup_path 設定キーは、バックアップファイルの内部ロケーションを設定します。upload 設定キーは、バックアップファイルをアーカイブ目的で別のサーバにアップロードする場合に使用します。

これらの設定キーが同じ場所に設定されている場合、アップロード場所にすでにバックアップが存在するため、アップロード機能が失敗します。この失敗により、アップロード機能は、アップロードに失敗した後に残っているファイルだと判断してバックアップを削除します。

ローカルにマウントされた共有へのアップロードの設定
Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb を編集します:

    gitlab_rails['backup_upload_connection'] = {
      :provider => 'Local',
      :local_root => '/mnt/backups'
    }
       
    # The directory inside the mounted folder to copy backups to
    # Use '.' to store them in the root directory
    gitlab_rails['backup_upload_remote_directory'] = 'gitlab_backups'
    
  2. 変更を有効にするためにGitLabを再設定します。

Self-compiled
  1. home/git/gitlab/config/gitlab.yml を編集します:

    backup:
      upload:
        # Fog storage connection settings, see https://fog.io/storage/ .
        connection:
          provider: Local
          local_root: '/mnt/backups'
        # The directory inside the mounted folder to copy backups to
        # Use '.' to store them in the root directory
        remote_directory: 'gitlab_backups'
    
  2. 変更を有効にするためにGitLabを再起動します。

アーカイブのバックアップ権限

GitLabによって作成されたバックアップアーカイブ(1393513186_2014_02_27_gitlab_backup.tar)はデフォルトでオーナー/グループgit/とgit0600の権限を持っています。これは他のシステムユーザーがGitLabのデータを読むことを避けるためです。バックアップアーカイブに異なる権限を持たせたい場合は、archive_permissions

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb を編集します:

    gitlab_rails['backup_archive_permissions'] = 0644 # Makes the backup archives world-readable
    
  2. 変更を有効にするためにGitLabを再設定します。

Self-compiled
  1. /home/git/gitlab/config/gitlab.yml を編集します:

    backup:
      archive_permissions: 0644 # Makes the backup archives world-readable
    
  2. 変更を有効にするためにGitLabを再起動します。

毎日バックアップを取るためのcronの設定

caution
以下のcronジョブはGitLabの設定ファイルや SSHホストキーをバックアップしません。

リポジトリとGitLabメタデータをバックアップするcronジョブをスケジュールすることができます。

Linux package (Omnibus)
  1. root ユーザーの crontab を編集します:

    sudo su -
    crontab -e
    
  2. そこに以下の行を追加して、毎日午前2時にバックアップをスケジュールします:

    0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1
    
Self-compiled
  1. git ユーザーの crontab を編集します:

    sudo -u git crontab -e
    
  2. 一番下に以下の行を追加してください:

    # Create a full backup of the GitLab repositories and SQL database every day at 2am
    0 2 * * * cd /home/git/gitlab && PATH=/usr/local/bin:/usr/bin:/bin bundle exec rake gitlab:backup:create RAILS_ENV=production CRON=1
    

このCRON=1 環境設定は、エラーがない場合、すべての進捗出力を非表示にするようバックアップスクリプトに指示 CRON=1します。CRON=1 これはcronスパムを減らすために推奨されます。しかし、バックアップのトラブルシューティングを CRON=1行う場合は、--trace CRON=1 に置き換えて CRON=1冗長にログを記録してください。

ローカルファイルのバックアップ有効期間を制限(古いバックアップを削除)

caution
バックアップにカスタムファイル名を使用した場合、このセクションで説明するプロセスは機能しません。

定期的なバックアップがすべてのディスク容量を使用するのを防ぐために、バックアップの有効期間を制限することができます。次にバックアップ・タスクが実行されると、backup_keep_time より古いバックアップは削除されます。

この設定オプションはローカルファイルのみを管理します。GitLabはサードパーティのオブジェクトストレージに保存された古いファイルをプルーニングしません。なぜなら、ユーザーにはファイルをリストしたり削除したりする権限がない可能性があるからです。オブジェクトストレージ(例えばAWS S3)に適切なリテンションポリシーを設定することをお勧めします。

Linux package (Omnibus)
  1. /etc/gitlab/gitlab.rb を編集します:

    ## Limit backup lifetime to 7 days - 604800 seconds
    gitlab_rails['backup_keep_time'] = 604800
    
  2. 変更を有効にするためにGitLabを再設定します。

Self-compiled
  1. /home/git/gitlab/config/gitlab.yml を編集します:

    backup:
      ## Limit backup lifetime to 7 days - 604800 seconds
      keep_time: 604800
    
  2. 変更を有効にするためにGitLabを再起動します。

PgBouncerを使ったインストールのバックアップと復元

PgBouncer接続を通してGitLabをバックアップまたはリストアしないでください。これらのタスクはPgBouncerをバイパスしてPostgreSQLプライマリデータベースノードに直接接続しなければなりません。

GitLabのバックアップやリストアタスクをPgBouncerで使用すると、以下のエラーメッセージが表示されます:

ActiveRecord::StatementInvalid: PG::UndefinedTable

GitLabバックアップが実行されるたびに、GitLabは500エラーを生成し始め、PostgreSQLによってテーブルが見つからないというエラーが記録されます:

ERROR: relation "tablename" does not exist at character 123

これはタスクがpg_dumpNULL検索パスを設定し、 CVE-2018-1058にアドレスするためにすべてのSQLクエリに明示的にスキーマを含めるためです。

トランザクションプーリングモードのPgBouncerでは接続が再利用されるため、PostgreSQLはデフォルトのpublic スキーマの検索に失敗します。その結果、この検索パスのクリアによってテーブルと列が欠落して表示されます。

PgBouncerのバイパス

これを解決するには2つの方法があります:

  1. 環境変数を使用して、バックアップタスクのデータベース設定を上書きします。
  2. PostgreSQLプライマリデータベースノードに直接接続するようにノードを再構成します。
環境変数のオーバーライド

デフォルトでは、GitLabは設定ファイル(database.yml)に保存されたデータベース設定を使用します。しかし、GITLAB_BACKUP_ を先頭に持つ環境変数を設定することで、バックアップ・リストアタスクのデータベース設定を上書きすることができます:

  • GITLAB_BACKUP_PGHOST
  • GITLAB_BACKUP_PGUSER
  • GITLAB_BACKUP_PGPORT
  • GITLAB_BACKUP_PGPASSWORD
  • GITLAB_BACKUP_PGSSLMODE
  • GITLAB_BACKUP_PGSSLKEY
  • GITLAB_BACKUP_PGSSLCERT
  • GITLAB_BACKUP_PGSSLROOTCERT
  • GITLAB_BACKUP_PGSSLCRL
  • GITLAB_BACKUP_PGSSLCOMPRESSION

例えば、データベースのホストとポートをLinuxパッケージ(Omnibus)で192.168.1.10とポート5432を使用するように上書きします:

sudo GITLAB_BACKUP_PGHOST=192.168.1.10 GITLAB_BACKUP_PGPORT=5432 /opt/gitlab/bin/gitlab-backup create

これらのパラメータが何をするのかについては、PostgreSQLのドキュメントを参照してください。

gitaly-backup リポジトリのバックアップとリストア用

このgitaly-backup バイナリは、Gitalyからリポジトリのバックアップを作成・復元するためのbackup Rakeタスクによって使用されます。 gitaly-backupGitLabからGitaly上のRPCを直接呼び出す以前のバックアップ方法を置き換えます。

バックアップRakeタスクはこの実行ファイルを見つけることができなければなりません。ほとんどの場合、バイナリのパスを変更する必要はありません。デフォルトのパス/opt/gitlab/embedded/bin/gitaly-backup で問題なく動作するはずです。パスを変更する特別な理由がある場合は、Linuxパッケージ(Omnibus)で設定できます:

  1. /etc/gitlab/gitlab.rb に以下を追加してください:

    gitlab_rails['backup_gitaly_backup_path'] = '/path/to/gitaly-backup'
    
  2. 変更を有効にするためにGitLabを再設定します。

別のバックアップ戦略

デプロイごとに機能が異なる可能性があるため、まずバックアップが必要なデータのレビュアー を確認し、それらを活用できるかどうか、またどのように活用できるかを理解する必要があります。

例えば、Amazon RDSを使っているのであれば、GitLabのPostgreSQLデータを扱うためにその組み込みのバックアップとリストア機能を使い、バックアップコマンドを使うときにはPostgreSQLデータを除外することを選択するかもしれません。

次のような場合は、バックアップ戦略の一環としてファイルシステムのデータ転送やスナップショットの利用を検討してください:

  • GitLabインスタンスに多くのGitリポジトリデータがあり、GitLabバックアップスクリプトが遅すぎる場合。
  • あなたのGitLabインスタンスには多くのフォークされたプロジェクトがあり、通常のバックアップタスクはそれら全てのGitデータを複製します。
  • あなたの GitLab インスタンスに問題があり、通常のバックアップとインポート Rake タスクを使用することができません。

ファイルシステムのデータ転送またはスナップショットの使用を検討する場合:

  • これらの方法は、あるオペレーションシステムから別のオペレーションシステムへのマイグレーションには使用しないでください。移行元と移行先のオペレーションシステムは、できる限り類似している必要があります。例えば、UbuntuからFedoraへのマイグレーションにこれらの方法を使用しないでください。
  • データの一貫性はとても重要です。ファイルシステムの転送を行ったり(例えばrsync)、スナップショットを取ったりする前に、sudo gitlab-ctl stop でGitLabを停止してください。

例Amazon Elastic Block Storeの例(EBS)

  • Amazon AWSでホストされているLinuxパッケージ(Omnibus)を使ったGitLabサーバー。
  • ext4ファイルシステムを含むEBSドライブが/var/opt/gitlab にマウントされています。
  • この場合、EBSスナップショットを取得することで、アプリケーションのバックアップを作成できます。
  • バックアップにはすべてのリポジトリ、アップロード、PostgreSQLデータが含まれます。

例論理ボリュームマネージャ(LVM) スナップショット + rsync

  • Linuxパッケージ(Omnibus)を使ったGitLabサーバーで、/var/opt/gitlabにLVM論理ボリュームがマウントされています。
  • rsync を使って/var/opt/gitlab ディレクトリを複製しても、rsync の実行中に変更されるファイルが多すぎて信頼できません。
  • /var/opt/gitlab を rsync する代わりに、一時的な LVM スナップショットを作成し、/mnt/gitlab_backup に読み取り専用ファイルシステムとしてマウントします。
  • これで、リモートサーバー上に一貫性のあるレプリカを作成するrsyncジョブを長時間実行できるようになりました。
  • レプリカには、すべてのリポジトリ、アップロード、PostgreSQLデータが含まれます。

GitLabを仮想サーバー上で動かしている場合は、GitLabサーバー全体のVMスナップショットを作成することもできます。しかし、VMスナップショットを作成するにはサーバーの電源を落とす必要があることが珍しくありません。

リポジトリデータを個別にバックアップ

まず、リポジトリをスキップしながら既存の GitLab データをバックアップすることを確認します:

Linux package (Omnibus)
sudo gitlab-backup create SKIP=repositories
Self-compiled
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=repositories RAILS_ENV=production

Git リポジトリのデータを手動でディスクにバックアップするには、複数の方法が考えられます:

書き込みを防止して Git リポジトリのデータをコピーします。

Git リポジトリは一貫した方法でコピーしなければなりません。矛盾や破損のイシューにつながる可能性があるからです。詳細については、イシュー#270422Provide に、潜在的な問題について説明した長い議論があります。

Git リポジトリのデータへの書き込みを防ぐには、2つの方法があります:

  • メンテナンスモードを使用して、GitLabを読み取り専用状態にします。
  • リポジトリをバックアップする前にすべてのGitalyサービスを停止することで、明示的なダウンタイムを作成します:

     sudo gitlab-ctl stop gitaly
     # execute git data copy step
     sudo gitlab-ctl start gitaly
    

コピーされるデータへの書き込みが禁止されている限り、どのような方法でもGitリポジトリのデータをコピーすることができます(不整合や破損の問題を防ぐため)。優先順位と安全性の観点から、推奨される方法は以下の通りです:

  1. rsync に archive-mode、delete、checksum オプションなどを指定します:

    rsync -aR --delete --checksum source destination # be extra safe with the order as it will delete existing data if inverted
    
  2. リポジトリのディレクトリ全体を別のサーバーや場所にコピーするにはtar パイプを使用します.

  3. sftp,scp,cp, またはその他のコピー方法を使用してください。

リポジトリを読み取り専用にすることによるオンラインバックアップ(実験的)

インスタンス全体のダウンタイムを必要とせずにリポジトリをバックアップする1つの方法は、基礎となるデータをコピーしながら、プログラムを使用してプロジェクトを読み取り専用にマークすることです。

これにはいくつかの欠点があります:

  • リポジトリは、リポジトリのサイズに比例した期間、読み取り専用になります。
  • 各プロジェクトを読み取り専用にするため、バックアップの完了に時間がかかり、矛盾が生じる可能性があります。たとえば、バックアップされる最初のプロジェクトとバックアップされる最後のプロジェクトで、利用可能な最後のデータの日付が異なる可能性があります。
  • フォーク・ネットワークは、プール・リポジトリへの潜在的な変更を防ぐために、内部のプロジェクトがバックアップされる間、完全に読み取り専用にする必要があります。

Geo チームの Runbooks プロジェクトには、このプロセスを自動化しようとする実験的なスクリプトがあります。

トラブルシューティング

以下は、遭遇する可能性のある問題とその解決策です。

シークレットファイルが失われた場合

シークレットファイルをバックアップしていなかった場合、GitLabを再び正しく動作させるためにいくつかのステップを完了する必要があります。

シークレットファイルは、必要な機密情報を含むカラムの暗号化キーを保存する役割を担っています。鍵が失われた場合、GitLabはそれらのカラムを復号化することができず、以下の項目へのアクセスを妨げます:

CI/CD変数やRunner認証のようなケースでは、次のような予期せぬ動作が発生する可能性があります:

  • ジョブが動かない
  • 500エラー。

この場合、CI/CD変数とRunner認証のためのすべてのトークンをリセットする必要があります。トークンをリセットすると、プロジェクトにアクセスできるようになり、ジョブが再び実行されるようになります。

caution
このセクションの手順は、上記の項目のデータ損失につながる可能性があります。PremiumまたはUltimateをご利用の場合は、サポートリクエストの作成をご検討ください。

すべての値が復号化できることを確認

データベースに復号化できない値が含まれているかどうかは、Rakeタスクを使用することで確認できます。

バックアップを取る

紛失したシークレットファイルを回避するためには、GitLabのデータを直接修正する必要があります。

caution
変更を試みる前に、必ずデータベースの完全なバックアップを作成してください。

ユーザー二要素認証(2FA)を無効にします。

2FAを有効にしているユーザーはGitLabにサインインできません。その場合、全員の2FAを無効にし、その後ユーザーは2FAを再度有効にする必要があります。

CI/CD変数のリセット

  1. データベースコンソールに入ります:

    Linuxパッケージ(Omnibus) GitLab 14.1以前の場合:

    sudo gitlab-rails dbconsole
    

    Linuxパッケージ(Omnibus)の場合 GitLab 14.2以降:

    sudo gitlab-rails dbconsole --database main
    

    セルフコンパイルしたインストールでは、GitLab 14.1以前:

    sudo -u git -H bundle exec rails dbconsole -e production
    

    セルフコンパイルしたインストールでは、GitLab 14.2以降:

    sudo -u git -H bundle exec rails dbconsole -e production --database main
    
  2. ci_group_variablesci_variables テーブルを調べてください:

    SELECT * FROM public."ci_group_variables";
    SELECT * FROM public."ci_variables";
    

    これらは削除する必要がある変数です。

  3. すべての変数を削除します:

    DELETE FROM ci_group_variables;
    DELETE FROM ci_variables;
    
  4. もし、変数を削除したい特定のグループやプロジェクトがわかっていれば、DELETE に、それを指定するWHERE ステートメントを含めることができます:

    DELETE FROM ci_group_variables WHERE group_id = <GROUPID>;
    DELETE FROM ci_variables WHERE project_id = <PROJECTID>;
    

変更を有効にするには、GitLab を再設定したり再起動したりする必要があるかもしれません。

ランナー登録トークンのリセット

  1. データベースコンソールに入ります:

    Linuxパッケージ(Omnibus) GitLab 14.1以前の場合:

    sudo gitlab-rails dbconsole
    

    Linuxパッケージ(Omnibus)の場合 GitLab 14.2以降:

    sudo gitlab-rails dbconsole --database main
    

    セルフコンパイルしたインストールでは、GitLab 14.1以前:

    sudo -u git -H bundle exec rails dbconsole -e production
    

    セルフコンパイルしたインストールでは、GitLab 14.2以降:

    sudo -u git -H bundle exec rails dbconsole -e production --database main
    
  2. プロジェクト、グループ、インスタンス全体のすべてのトークンをクリアします:

    caution
    最後のUPDATE のオペレーションは、Runnerが新しいジョブをピックアップできないようにします。新しいランナーを登録する必要があります。
    -- Clear project tokens
    UPDATE projects SET runners_token = null, runners_token_encrypted = null;
    -- Clear group tokens
    UPDATE namespaces SET runners_token = null, runners_token_encrypted = null;
    -- Clear instance tokens
    UPDATE application_settings SET runners_registration_token_encrypted = null;
    -- Clear key used for JWT authentication
    -- This may break the $CI_JWT_TOKEN job variable:
    -- https://gitlab.com/gitlab-org/gitlab/-/issues/325965
    UPDATE application_settings SET encrypted_ci_jwt_signing_key = null;
    -- Clear runner tokens
    UPDATE ci_runners SET token = null, token_encrypted = null;
    

保留中のパイプラインジョブのリセット

  1. データベースコンソールに入ります:

    Linuxパッケージ(Omnibus) GitLab 14.1以前の場合:

    sudo gitlab-rails dbconsole
    

    Linuxパッケージ(Omnibus)の場合 GitLab 14.2以降:

    sudo gitlab-rails dbconsole --database main
    

    セルフコンパイルしたインストールでは、GitLab 14.1以前:

    sudo -u git -H bundle exec rails dbconsole -e production
    

    セルフコンパイルしたインストールでは、GitLab 14.2以降:

    sudo -u git -H bundle exec rails dbconsole -e production --database main
    
  2. 保留中のジョブのトークンをすべてクリアします:

    GitLab 15.3以前の場合:

    -- Clear build tokens
    UPDATE ci_builds SET token = null, token_encrypted = null;
    

    GitLab 15.4以降の場合:

    -- Clear build tokens
    UPDATE ci_builds SET token_encrypted = null;
    

残りの機能についても同様の戦略を採用できます。復号化できないデータを削除することで、GitLabをオペレーションに戻し、失われたデータを手動で置き換えることができます。

インテグレーションとWebhookの修正

シークレットを紛失した場合、インテグレーション設定Webhook 設定ページに500 エラーメッセージが 500表示されることがあります。500 シークレットを紛失 500すると、以前に設定したインテグレーションや Webhook があるプロジェクトのリポジトリにアクセスしようとした500 ときにも 500エラーが発生する500 可能性が 500あります。

修正方法は、影響を受けるテーブル(暗号化されたカラムを含むテーブル)を切り捨てることです。これにより、設定済みのインテグレーション、Webhook、関連するメタデータがすべて削除されます。データを削除する前に、シークレットが根本的な原因であることを確認する必要があります。

  1. データベースコンソールに入ります:

    Linuxパッケージ(Omnibus) GitLab 14.1以前の場合:

    sudo gitlab-rails dbconsole
    

    Linuxパッケージ(Omnibus)の場合 GitLab 14.2以降:

    sudo gitlab-rails dbconsole --database main
    

    セルフコンパイルしたインストールでは、GitLab 14.1以前:

    sudo -u git -H bundle exec rails dbconsole -e production
    

    セルフコンパイルしたインストールでは、GitLab 14.2以降:

    sudo -u git -H bundle exec rails dbconsole -e production --database main
    
  2. 以下のテーブルを切り捨ててください:

    -- truncate web_hooks table
    TRUNCATE integrations, chat_names, issue_tracker_data, jira_tracker_data, slack_integrations, web_hooks, zentao_tracker_data, web_hook_logs CASCADE;
    

バックアップからのリストア後のコンテナレジストリプッシュの失敗

コンテナレジストリを使用している場合、Linux パッケージ(Omnibus)インスタンスでバックアップをリストアした後にレジストリデータをリストアすると、レジストリへのプッシュに失敗することがあります。

これらの失敗は、レジストリログの権限の問題に言及します:

level=error
msg="response completed with error"
err.code=unknown
err.detail="filesystem: mkdir /var/opt/gitlab/gitlab-rails/shared/registry/docker/registry/v2/repositories/...: permission denied"
err.message="unknown error"

このイシューは、リストアが非特権ユーザー(git )として実行され、リストア処理中にレジストリファイルに正しい所有権を割り当てられないために発生します(issue #62759Incorrect)。

レジストリを再び使用できるようにするには、以下の手順に従ってください:

sudo chown -R registry:registry /var/opt/gitlab/gitlab-rails/shared/registry/docker

レジストリのデフォルトのファイルシステムの場所を変更した場合は、/var/opt/gitlab/gitlab-rails/shared/registry/docker の代わりに、chown を実行します。

Gzipエラーでバックアップが完了しません。

バックアップを実行すると、Gzipエラーメッセージが表示されることがあります:

sudo /opt/gitlab/bin/gitlab-backup create
...
Dumping ...
...
gzip: stdout: Input/output error

Backup failed

この場合は、以下を確認してください:

  • Gzipオペレーションに十分なディスク領域があることを確認します。デフォルトのストラテジを使用するバックアップでは、バックアップ作成時にインスタンス・サイズの半分の空きディスク容量が必要になることは珍しくありません。
  • NFSを使用している場合は、マウント・オプションtimeout が設定されているかどうかを確認します。デフォルトは600 で、これを小さい値に変更すると、このエラーが発生します。

バックアップがFile name too long エラーで失敗します。

バックアップ中にFile name too long エラー(イシュー#354984)が発生することがあります。例えば

Problem: <class 'OSError: [Errno 36] File name too long:

この問題により、バックアップスクリプトが完了しなくなります。この問題を解決するには、問題の原因となっているファイル名を切り詰める必要があります。ファイル拡張子を含め、最大 246 文字まで許可されます。

caution
このセクションの手順を実行すると、データが失われる可能性があります。すべての手順は、指定された順序に厳密に従う必要があります。PremiumまたはUltimateをご利用のお客様は、サポートリクエストの作成をご検討ください。

エラーを解決するためにファイル名を切り詰めます:

  • データベースで追跡されていないリモートアップロードされたファイルのクリーンアップ。
  • データベースのファイル名の切り捨て。
  • バックアップ・タスクの再実行。

リモートアップロードされたファイルのクリーンアップ

既知のイシューにより、親リソースが削除された後もオブジェクトストアのアップロードが残ることがありました。このイシューは解決されました。

これらのファイルを修正するには、uploads データベース テーブルで追跡されていない、ストレージ内にあるすべてのリモート アップロード ファイルをクリーンアップする必要があります。

  1. GitLabデータベースに存在しない場合、紛失・発見ディレクトリに移動できるオブジェクトストアのアップロードファイルをすべてリストアップします:

    bundle exec rake gitlab:cleanup:remote_upload_files RAILS_ENV=production
    
  2. これらのファイルを削除し、参照されていないアップロードファイルを全て削除したい場合は、実行してください:

    caution
    次のアクションは元に戻せません
    bundle exec rake gitlab:cleanup:remote_upload_files RAILS_ENV=production DRY_RUN=false
    

データベースが参照するファイル名を切り捨てます。

問題の原因となっているデータベースによって参照されているファイルを切り捨てる必要があります。データベースが参照するファイル名は保存されています:

  • uploads テーブル。
  • 見つかった参照。他のデータベース・テーブルやカラムから見つかった参照。
  • ファイルシステム上。

uploads テーブルのファイル名を切り詰めます:

  1. データベースコンソールに入ります:

    Linuxパッケージ(Omnibus)の場合 GitLab 14.2以降:

    sudo gitlab-rails dbconsole --database main
    

    Linuxパッケージ(Omnibus) GitLab 14.1以前の場合:

    sudo gitlab-rails dbconsole
    

    セルフコンパイルしたインストールでは、GitLab 14.2以降:

    sudo -u git -H bundle exec rails dbconsole -e production --database main
    

    セルフコンパイルしたインストールでは、GitLab 14.1以前:

    sudo -u git -H bundle exec rails dbconsole -e production
    
  2. uploads テーブルで 246 文字以上のファイル名を検索します:

    以下のクエリは、246文字以上のファイル名を持つuploads レコードを 0 から 10000 までのバッチで選択します。これにより、1000レコードを持つテーブルを持つ大規模な GitLab インスタンスでのパフォーマンスが向上します。

    CREATE TEMP TABLE uploads_with_long_filenames AS
    SELECT ROW_NUMBER() OVER(ORDER BY id) row_id, id, path
    FROM uploads AS u
    WHERE LENGTH((regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1]) > 246;
       
    CREATE INDEX ON uploads_with_long_filenames(row_id);
       
    SELECT
       u.id,
       u.path,
       -- Current filename
       (regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1] AS current_filename,
       -- New filename
       CONCAT(
          LEFT(SPLIT_PART((regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1], '.', 1), 242),
          COALESCE(SUBSTRING((regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1] FROM '\.(?:.(?!\.))+$'))
       ) AS new_filename,
       -- New path
       CONCAT(
          COALESCE((regexp_match(u.path, '(.*\/).*'))[1], ''),
          CONCAT(
             LEFT(SPLIT_PART((regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1], '.', 1), 242),
             COALESCE(SUBSTRING((regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1] FROM '\.(?:.(?!\.))+$'))
          )
       ) AS new_path
    FROM uploads_with_long_filenames AS u
    WHERE u.row_id > 0 AND u.row_id <= 10000;
    

    出力例:

    -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    id               | 34
    path             | public/@hashed/loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelitsedvulputatemisitloremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelitsedvulputatemisit.txt
    current_filename | loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelitsedvulputatemisitloremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelitsedvulputatemisit.txt
    new_filename     | loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelitsedvulputatemisitloremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelits.txt
    new_path         | public/@hashed/loremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelitsedvulputatemisitloremipsumdolorsitametconsecteturadipiscingelitseddoeiusmodtemporincididuntutlaboreetdoloremagnaaliquaauctorelits.txt

    どこに:

    • current_filename現在246文字以上のファイル名。
    • new_filename: 最大246文字に切り詰められたファイル名。
    • new_path new_filename (切り捨て) を考慮した新しいパス。

    バッチ結果を検証した後、次の一連の番号(10000~20000)を使用してバッチ・サイズ(row_id )を変更する必要があります。uploads テーブルの最後のレコードに達するまで、このプロセスを繰り返します。

  3. uploads テーブルで見つかったファイルの名前を、長いファイル名から新しい切り捨てファイル名に変更します。次のクエリは更新をロールバックするので、トランザクション・ラッパーで安全に結果を確認できます:

    CREATE TEMP TABLE uploads_with_long_filenames AS
    SELECT ROW_NUMBER() OVER(ORDER BY id) row_id, path, id
    FROM uploads AS u
    WHERE LENGTH((regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1]) > 246;
       
    CREATE INDEX ON uploads_with_long_filenames(row_id);
       
    BEGIN;
    WITH updated_uploads AS (
       UPDATE uploads
       SET
          path =
          CONCAT(
             COALESCE((regexp_match(updatable_uploads.path, '(.*\/).*'))[1], ''),
             CONCAT(
                LEFT(SPLIT_PART((regexp_match(updatable_uploads.path, '[^\\/:*?"<>|\r\n]+$'))[1], '.', 1), 242),
                COALESCE(SUBSTRING((regexp_match(updatable_uploads.path, '[^\\/:*?"<>|\r\n]+$'))[1] FROM '\.(?:.(?!\.))+$'))
             )
          )
       FROM
          uploads_with_long_filenames AS updatable_uploads
       WHERE
          uploads.id = updatable_uploads.id
       AND updatable_uploads.row_id > 0 AND updatable_uploads.row_id  <= 10000
       RETURNING uploads.*
    )
    SELECT id, path FROM updated_uploads;
    ROLLBACK;
    

    バッチ更新の結果を検証した後、次の一連の番号(10000~20000)を使用してバッチサイズ(row_id )を変更する必要があります。この処理を、uploads テーブルの最後のレコードに達するまで繰り返します。

  4. 前のクエリからの新しいファイル名が期待されるものであることを確認します。前のステップで見つかったレコードを246文字に切り詰めたいことが確かであれば、以下を実行してください:

    caution
    次のアクションは元に戻せません
    CREATE TEMP TABLE uploads_with_long_filenames AS
    SELECT ROW_NUMBER() OVER(ORDER BY id) row_id, path, id
    FROM uploads AS u
    WHERE LENGTH((regexp_match(u.path, '[^\\/:*?"<>|\r\n]+$'))[1]) > 246;
       
    CREATE INDEX ON uploads_with_long_filenames(row_id);
       
    UPDATE uploads
    SET
    path =
       CONCAT(
          COALESCE((regexp_match(updatable_uploads.path, '(.*\/).*'))[1], ''),
          CONCAT(
             LEFT(SPLIT_PART((regexp_match(updatable_uploads.path, '[^\\/:*?"<>|\r\n]+$'))[1], '.', 1), 242),
             COALESCE(SUBSTRING((regexp_match(updatable_uploads.path, '[^\\/:*?"<>|\r\n]+$'))[1] FROM '\.(?:.(?!\.))+$'))
          )
       )
    FROM
    uploads_with_long_filenames AS updatable_uploads
    WHERE
    uploads.id = updatable_uploads.id
    AND updatable_uploads.row_id > 0 AND updatable_uploads.row_id  <= 10000;
    

    バッチ更新を終了したら、次の一連の番号(10000~20000)を使用してバッチサイズ(updatable_uploads.row_id )を変更する必要があります。このプロセスを、uploads テーブルの最後のレコードに達するまで繰り返します。

見つかった参照のファイル名を切り捨てます:

  1. これらのレコードがどこかで参照されているかどうかをチェックします。これを行う1つの方法は、データベースをダンプし、親ディレクトリ名とファイル名を検索することです:

    1. データベースをダンプするには、例として以下のコマンドを使用できます:

      pg_dump -h /var/opt/gitlab/postgresql/ -d gitlabhq_production > gitlab-dump.tmp
      
    2. その後、grep コマンドを使用して参照を検索できます。親ディレクトリとファイル名を組み合わせるとよいでしょう。例えば

      grep public/alongfilenamehere.txt gitlab-dump.tmp
      
  2. これらの長いファイル名を、uploads テーブルをクエリして得られた新しいファイル名で置き換えます。

ファイルシステム上のファイル名を切り詰めます。ファイルシステム上のファイル名を手動で変更し、uploads テーブルのクエリから取得した新しいファイル名に変更する必要があります。

バックアップ・タスクを再実行します。

前述の手順をすべて実行した後、バックアップ・タスクを再実行します。

pg_stat_statements が以前に有効になっていた場合、データベースのバックアップの復元に失敗します。

PostgreSQL データベースの GitLab バックアップには、データベースで以前に有効になっていた拡張機能を有効にするために必要なすべての SQL 文が含まれています。

pg_stat_statements 拡張モジュールは、superuser ロールを持つ PostgreSQL ユーザーによってのみ有効化または無効化することができます。リストアプロセスは制限された権限を持つデータベースユーザーを使用するため、以下のSQL文を実行することはできません:

DROP EXTENSION IF EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS pg_stat_statements WITH SCHEMA public;

pg_stats_statements 拡張機能を持たない PostgreSQL インスタンスでバックアップをリストアしようとすると、以下のエラーメッセージが表示されます:

ERROR: permission denied to create extension "pg_stat_statements"
HINT: Must be superuser to create this extension.
ERROR: extension "pg_stat_statements" does not exist

pg_stats_statements 拡張機能が有効になっているインスタンスでリストアしようとすると、以下のようなエラーメッセージが表示され、クリーンアップステップに失敗します:

rake aborted!
ActiveRecord::StatementInvalid: PG::InsufficientPrivilege: ERROR: must be owner of view pg_stat_statements
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:42:in `block (4 levels) in <top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `each'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `block (3 levels) in <top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rake:71:in `block (3 levels) in <top (required)>'
/opt/gitlab/embedded/bin/bundle:23:in `load'
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
Caused by:
PG::InsufficientPrivilege: ERROR: must be owner of view pg_stat_statements
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:42:in `block (4 levels) in <top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `each'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/db.rake:41:in `block (3 levels) in <top (required)>'
/opt/gitlab/embedded/service/gitlab-rails/lib/tasks/gitlab/backup.rake:71:in `block (3 levels) in <top (required)>'
/opt/gitlab/embedded/bin/bundle:23:in `load'
/opt/gitlab/embedded/bin/bundle:23:in `<main>'
Tasks: TOP => gitlab:db:drop_tables
(See full trace by running task with --trace)

ダンプ・ファイルにpg_stat_statements

バックアップバンドルの一部であるPostgreSQLダンプファイルに拡張子が含まれないようにするには、public スキーマ以外のスキーマで拡張子を有効にしてください:

CREATE SCHEMA adm;
CREATE EXTENSION pg_stat_statements SCHEMA adm;

public スキーマで拡張機能を有効にしていた場合は、新しいスキーマに移動してください:

CREATE SCHEMA adm;
ALTER EXTENSION pg_stat_statements SET SCHEMA adm;

スキーマを変更した後にpg_stat_statements のデータをクエリするには、ビュー名の前に新しいスキーマを付けます:

SELECT * FROM adm.pg_stat_statements limit 0;

public スキーマで有効になっていることを期待するサードパーティのモニタリング・ソリューションと互換性を持たせるために、search_path

set search_path to public,adm;

への参照を削除するために、既存のダンプ・ファイルを修正します。pg_stat_statements

既存のバックアップ・ファイルを修正するには、以下の変更を行います:

  1. バックアップから次のファイルを抽出します:db/database.sql.gz.
  2. ファイルを解凍するか、圧縮されたファイルを扱えるエディタを使用してください。
  3. 以下の行、または類似の行を削除してください:

    CREATE EXTENSION IF NOT EXISTS pg_stat_statements WITH SCHEMA public;
    
    COMMENT ON EXTENSION pg_stat_statements IS 'track planning and execution statistics of all SQL statements executed';
    
  4. 変更を保存し、ファイルを再圧縮します。
  5. 変更したdb/database.sql.gz でバックアップファイルを更新します。