- 簡単なバックアップ手順
- バックアップの拡張
- どのようなデータをバックアップする必要がありますか?
-
コマンドラインインタフェース
- 要件
- バックアップ・コマンド
- バックアップタイムスタンプ
-
バックアップ・オプション
- バックアップ戦略オプション
- バックアップファイル名
- アーカイブの確認
- 特定のディレクトリをバックアップから除外
- tar作成のスキップ
- サーバー側リポジトリバックアップの作成
- Git リポジトリの同時バックアップ
- リポジトリの増分バックアップ
- 特定のリポジトリストレージのバックアップ
- 特定のリポジトリのバックアップ
- リモート(クラウド)ストレージへのバックアップのアップロード
- リモートストレージへのバックアップのアップロードをスキップ
- ローカルにマウントされた共有へのアップロード
- アーカイブのバックアップ権限
- 毎日バックアップを取るためのcronの設定
- ローカルファイルのバックアップ有効期間を制限(古いバックアップを削除)
- PgBouncerを使ったインストールのバックアップと復元
gitaly-backup
リポジトリのバックアップとリストア用
- 別のバックアップ戦略
- トラブルシューティング
GitLabのバックアップ
GitLabをバックアップする正確な手順は、多くの要因によって異なります。あなたの特定のデプロイの使い方と設定によって、どのようなデータが存在し、どこにあり、どれだけの量があるのかが決まります。これらの要因は、バックアップの実行方法、保存方法、復元方法の選択肢に影響します。
簡単なバックアップ手順
大まかなガイドラインとして、1kリファレンスアーキテクチャを使用しており、データ量が100GB未満の場合は、以下の手順に従ってください:
- backupコマンドを実行します。
- 該当する場合は、オブジェクトストレージをバックアップします。
- 設定ファイルを手動でバックアップします。
バックアップの拡張
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をバックアップしません。オブジェクトストレージを使用している場合は、必ずオブジェクトストレージプロバイダでバックアップを有効にしてください。たとえば、以下を参照してください:
設定ファイルの保存
設定ディレクトリをバックアップする必要があります。最低限、バックアップは必要です:
/etc/gitlab/gitlab-secrets.json
/etc/gitlab/gitlab.rb
詳細は、「Linuxパッケージ(Omnibus)設定のバックアップとリストア」を参照してください。
/home/git/gitlab/config/secrets.yml
/home/git/gitlab/config/gitlab.yml
- 設定ファイルが保存されているボリュームをバックアップします。ドキュメントに従ってGitLabコンテナを作成した場合は、
/srv/gitlab/config
ディレクトリにあるはずです。
- シークレットのバックアップの指示に従ってください。
また、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 で導入)
バックアップには含まれません:
- Mattermost データ
- Redis(およびSidekiqジョブ)
- オブジェクトストレージ
/etc/gitlab
)、TLSキーと証明書、システムファイルをバックアップしません。設定ファイルの保存について読むことを強くお勧めします。要件
バックアップとリストアができるように、Rsyncがシステムにインストールされていることを確認してください。GitLabをインストールした場合:
- Using the Linux パッケージをインストールした場合は、Rsync は既にインストールされています。
-
セルフコンパイルを使用して、
rsync
がインストールされているかどうかを確認します。Rsyncがインストールされていない場合は、インストールしてください。例えば# Debian/Ubuntu sudo apt-get install rsync # RHEL/CentOS sudo yum install rsync
バックアップ・コマンド
sudo gitlab-backup create
kubectl
、GitLab toolboxポッド上でbackup-utility
スクリプトを実行してバックアップタスクを実行します。詳細については、Chart backup documentationを参照してください。
ホストからバックアップを実行します。
- GitLab 12.2 以降:
docker exec -t <container name> gitlab-backup create
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
というバックアップ戦略を使用します。このストラテジーは、tar
とgzip
を呼び出す前にデータ・ファイルを一時的な場所にコピーし、エラーを回避します。
副作用として、バックアップ処理にはさらに1倍のディスク容量が必要になります。このプロセスは各ステージで一時ファイルをクリーンアップするよう最善を尽くしますので、問題は深刻化しませんが、大規模なインストールではかなりの変更になる可能性があります。
デフォルトのストリーミング戦略の代わりにcopy
戦略を使用するには、Rake タスクコマンドでSTRATEGY=copy
を指定します。たとえば
sudo gitlab-backup create STRATEGY=copy
バックアップファイル名
デフォルトでは、バックアップ・ファイルは前の「バックアップのタイムスタンプ」セクションの指定に従って作成されます。ただし、環境変数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
(プロジェクトレベルのセキュアファイル)
packages
があります。詳細はコマンドライン引数を参照してください。すべてのWikiはrepositories
グループの一部としてバックアップされます。存在しないWikiはバックアップ中にスキップされます。
sudo gitlab-backup create SKIP=db,uploads
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=db,uploads RAILS_ENV=production
SKIP=
は次のようにも使われます:
-
tar ファイル(
SKIP=tar
) の作成をスキップします。 -
リモートストレージへのバックアップのアップロードをスキップします (
SKIP=remote
)。
tar作成のスキップ
バックアップ作成の最後の部分は、.tar
すべてのパーツを含むファイルの .tar
生成です。.tar
場合によっては .tar
、ファイルを.tar
作成する .tar
ことは無駄な労力であったり、直接的に有害であったりすることがあるので、環境変数SKIP
にtar
を追加することで、このステップをスキップすることができます。使用例
- バックアップが他のバックアップソフトウェアによってピックアップされる場合。
- 毎回バックアップを抽出する手間を省き、増分バックアップを高速化する場合。(この場合、
PREVIOUS_BACKUP
とBACKUP
は指定しないでください。指定しないと、指定したバックアップは抽出されますが、最後に.tar
ファイルは生成されません)。
SKIP
変数にtar
を追加すると、中間ファイルに使用されるディレクトリにバックアップを含むファイルとディレクトリが残ります。これらのファイルは、新しいバックアップが作成されるときに上書きされるため、バックアップはシステム上に1つしか存在できないため、他の場所にコピーされていることを確認する必要があります。
sudo gitlab-backup create SKIP=tar
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=tar RAILS_ENV=production
サーバー側リポジトリバックアップの作成
GitLab 16.3 で導入されました。
大きなリポジトリのバックアップをバックアップアーカイブに保存する代わりに、リポジトリのバックアップは、各リポジトリをホストするGitalyノードがバックアップの作成とオブジェクトストレージへのストリーミングを担当するように設定することができます。これにより、バックアップの作成と復元に必要なネットワークリソースを削減できます。
- Gitalyでサーバー側のバックアップ先を設定します。
-
REPOSITORIES_SERVER_SIDE
変数を使用してバックアップを作成します。以下の例を参照してください。
sudo gitlab-backup create REPOSITORIES_SERVER_SIDE=true
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つのリポジトリストレージの場合:
sudo gitlab-backup create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1
sudo -u git -H bundle exec rake gitlab:backup:create GITLAB_BACKUP_MAX_CONCURRENCY=4 GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY=1
リポジトリの増分バックアップ
- GitLab 14.9 で
incremental_repository_backup
というフラグで導入されました。デフォルトでは無効です。- GitLab 14.10ではセルフマネージドで有効。
PREVIOUS_BACKUP
GitLab 15.0で導入されたオプション。
フラグ: セルフマネジメントのGitLabでは、デフォルトでこの機能が利用可能です。この機能を隠すには、管理者がincremental_repository_backup
という機能フラグを無効にします。GitLab.comでは、この機能は利用できません。
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
オプションを使って特定のリポジトリストレージのリポジトリを個別にバックアップすることができます。このオプションには、ストレージ名をカンマ区切りで指定します。
使用例:
sudo gitlab-backup create REPOSITORIES_STORAGES=storage1,storage2
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をスキップします:
sudo gitlab-backup create REPOSITORIES_PATHS=group-a,group-b/project-c SKIP_REPOSITORIES_PATHS=group-a/project-d
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
リモート(クラウド)ストレージへのバックアップのアップロード
バックアップスクリプトが作成した.tar
ファイルを(Fog ライブラリを使用して)アップロードさせることができます。以下の例では、ストレージにAmazon S3を使用していますが、Fogでは他のストレージプロバイダを使用することもできます。GitLabはAWS、Google、Aliyunのクラウドドライバもインポートしています。ローカルドライバもあります。
GitLab でのオブジェクトストレージの使用について、詳しくはこちらをご覧ください。
Amazon S3を使う
Linuxパッケージ(Omnibus)の場合:
-
/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
-
変更を有効にするために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_encryption
をaws: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)に使用できます:
-
/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'
-
変更を有効にするためにGitLab を再設定します。
Digital Ocean Spacesの使用時に400 Bad Request
のエラーメッセージが表示される場合、バックアップの暗号化が原因である可能性があります。Digital Ocean Spacesは暗号化をサポートしていないため、gitlab_rails['backup_encryption']
を含む行を削除するかコメントしてください。
その他のS3プロバイダ
全ての S3 プロバイダが Fog ライブラリと完全に互換性があるわけではありません。例えば、アップロードしようとした後に411 Length Required
のエラーメッセージが表示された場合、このイシューのためにaws_signature_version
の値をデフォルト値から2
にダウングレードする必要があるかもしれません。
セルフコンパイルによるインストールの場合:
-
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'
-
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コンソールからアクセスキーを作成する必要があります:
- Googleストレージの設定ページにアクセスします。
- 相互運用性」を選択し、アクセスキーを作成します。
- アクセスキーと シークレットをメモし、以下の設定で置き換えてください。
- バケツの詳細設定で、アクセスコントロールオプションのSet object-level and bucket-level permissionsが選択されていることを確認してください。
- バケツを作成済みであることを確認します。
Linuxパッケージ(Omnibus)の場合:
-
/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'
-
変更を有効にするためにGitLab を再設定します。
セルフコンパイルによるインストールの場合:
-
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'
-
GitLab を再起動して変更を有効にします。
Azure Blobストレージの使用
GitLab 13.4 で導入されました。
-
/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>'
-
変更を有効にするためにGitLab を再設定します。
-
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>'
-
GitLab を再起動して変更を有効にします。
詳細はAzureパラメータの表をご覧ください。
バックアップ用のカスタムディレクトリの指定
このオプションはリモート・ストレージでのみ機能します。バックアップをグループ化したい場合は、DIRECTORY
環境変数を渡します:
sudo gitlab-backup create DIRECTORY=daily
sudo gitlab-backup create DIRECTORY=weekly
リモートストレージへのバックアップのアップロードをスキップ
GitLabがリモートストレージにバックアップをアップロードするように設定している場合、SKIP=remote
オプションを使用すると、リモートストレージへのバックアップのアップロードをスキップすることができます。
sudo gitlab-backup create SKIP=remote
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=remote RAILS_ENV=production
ローカルにマウントされた共有へのアップロード
FogLocal
ストレージ・プロバイダを使用して、ローカルにマウントされた共有(たとえば、NFS
、CIFS
、SMB
)にバックアップを送信できます。
これを行うには、以下の設定キーを設定する必要があります:
-
backup_upload_connection.local_root
バックアップがコピーされるマウント・ディレクトリ。 -
backup_upload_remote_directory
:backup_upload_connection.local_root
ディレクトリのサブディレクトリ。存在しない場合は作成されます。tarballs をマウントされたディレクトリのルートにコピーしたい場合は、.
を使用してください。
マウントされた場合、local_root
キーで設定されたディレクトリの所有者は次のいずれかでなければなりません:
-
git
ユーザー。そのため、CIFS
とSMB
をgit
ユーザーの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
設定キーは、バックアップファイルをアーカイブ目的で別のサーバにアップロードする場合に使用します。
これらの設定キーが同じ場所に設定されている場合、アップロード場所にすでにバックアップが存在するため、アップロード機能が失敗します。この失敗により、アップロード機能は、アップロードに失敗した後に残っているファイルだと判断してバックアップを削除します。
ローカルにマウントされた共有へのアップロードの設定
-
/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'
-
変更を有効にするためにGitLabを再設定します。
-
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'
-
変更を有効にするためにGitLabを再起動します。
アーカイブのバックアップ権限
GitLabによって作成されたバックアップアーカイブ(1393513186_2014_02_27_gitlab_backup.tar
)はデフォルトでオーナー/グループgit
/とgit
0600の権限を持っています。これは他のシステムユーザーがGitLabのデータを読むことを避けるためです。バックアップアーカイブに異なる権限を持たせたい場合は、archive_permissions
。
-
/etc/gitlab/gitlab.rb
を編集します:gitlab_rails['backup_archive_permissions'] = 0644 # Makes the backup archives world-readable
-
変更を有効にするためにGitLabを再設定します。
-
/home/git/gitlab/config/gitlab.yml
を編集します:backup: archive_permissions: 0644 # Makes the backup archives world-readable
-
変更を有効にするためにGitLabを再起動します。
毎日バックアップを取るためのcronの設定
リポジトリとGitLabメタデータをバックアップするcronジョブをスケジュールすることができます。
-
root
ユーザーの crontab を編集します:sudo su - crontab -e
-
そこに以下の行を追加して、毎日午前2時にバックアップをスケジュールします:
0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON=1
-
git
ユーザーの crontab を編集します:sudo -u git crontab -e
-
一番下に以下の行を追加してください:
# 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
冗長にログを記録してください。
ローカルファイルのバックアップ有効期間を制限(古いバックアップを削除)
定期的なバックアップがすべてのディスク容量を使用するのを防ぐために、バックアップの有効期間を制限することができます。次にバックアップ・タスクが実行されると、backup_keep_time
より古いバックアップは削除されます。
この設定オプションはローカルファイルのみを管理します。GitLabはサードパーティのオブジェクトストレージに保存された古いファイルをプルーニングしません。なぜなら、ユーザーにはファイルをリストしたり削除したりする権限がない可能性があるからです。オブジェクトストレージ(例えばAWS S3)に適切なリテンションポリシーを設定することをお勧めします。
-
/etc/gitlab/gitlab.rb
を編集します:## Limit backup lifetime to 7 days - 604800 seconds gitlab_rails['backup_keep_time'] = 604800
-
変更を有効にするためにGitLabを再設定します。
-
/home/git/gitlab/config/gitlab.yml
を編集します:backup: ## Limit backup lifetime to 7 days - 604800 seconds keep_time: 604800
-
変更を有効にするために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_dump
、NULL検索パスを設定し、 CVE-2018-1058にアドレスするためにすべてのSQLクエリに明示的にスキーマを含めるためです。
トランザクションプーリングモードのPgBouncerでは接続が再利用されるため、PostgreSQLはデフォルトのpublic
スキーマの検索に失敗します。その結果、この検索パスのクリアによってテーブルと列が欠落して表示されます。
PgBouncerのバイパス
これを解決するには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
リポジトリのバックアップとリストア用
- GitLab 14.2で導入されました。
- 機能フラグの後ろにデプロイされ、デフォルトで有効になります。
- GitLab 14.10で一般的に利用可能。機能フラグ
gitaly_backup
は削除されました。
このgitaly-backup
バイナリは、Gitalyからリポジトリのバックアップを作成・復元するためのbackup Rakeタスクによって使用されます。 gitaly-backup
GitLabからGitaly上のRPCを直接呼び出す以前のバックアップ方法を置き換えます。
バックアップRakeタスクはこの実行ファイルを見つけることができなければなりません。ほとんどの場合、バイナリのパスを変更する必要はありません。デフォルトのパス/opt/gitlab/embedded/bin/gitaly-backup
で問題なく動作するはずです。パスを変更する特別な理由がある場合は、Linuxパッケージ(Omnibus)で設定できます:
-
/etc/gitlab/gitlab.rb
に以下を追加してください:gitlab_rails['backup_gitaly_backup_path'] = '/path/to/gitaly-backup'
-
変更を有効にするために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 データをバックアップすることを確認します:
sudo gitlab-backup create SKIP=repositories
sudo -u git -H bundle exec rake gitlab:backup:create SKIP=repositories RAILS_ENV=production
Git リポジトリのデータを手動でディスクにバックアップするには、複数の方法が考えられます:
- Amazon EBS ドライブのスナップショットや LVM スナップショット + rsync などです。
- GitLab Geoを使い、Geoセカンダリサイトのリポジトリデータに依存します。
- 書き込みを防ぎ、Gitリポジトリデータをコピーします。
- リポジトリを読み取り専用にすることで、オンラインバックアップを作成します(実験的)。
書き込みを防止して Git リポジトリのデータをコピーします。
Git リポジトリは一貫した方法でコピーしなければなりません。矛盾や破損のイシューにつながる可能性があるからです。詳細については、イシュー#270422Provide に、潜在的な問題について説明した長い議論があります。
Git リポジトリのデータへの書き込みを防ぐには、2つの方法があります:
- メンテナンスモードを使用して、GitLabを読み取り専用状態にします。
-
リポジトリをバックアップする前にすべてのGitalyサービスを停止することで、明示的なダウンタイムを作成します:
sudo gitlab-ctl stop gitaly # execute git data copy step sudo gitlab-ctl start gitaly
コピーされるデータへの書き込みが禁止されている限り、どのような方法でもGitリポジトリのデータをコピーすることができます(不整合や破損の問題を防ぐため)。優先順位と安全性の観点から、推奨される方法は以下の通りです:
-
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
-
リポジトリのディレクトリ全体を別のサーバーや場所にコピーするには
tar
パイプを使用します. -
sftp
,scp
,cp
, またはその他のコピー方法を使用してください。
リポジトリを読み取り専用にすることによるオンラインバックアップ(実験的)
インスタンス全体のダウンタイムを必要とせずにリポジトリをバックアップする1つの方法は、基礎となるデータをコピーしながら、プログラムを使用してプロジェクトを読み取り専用にマークすることです。
これにはいくつかの欠点があります:
- リポジトリは、リポジトリのサイズに比例した期間、読み取り専用になります。
- 各プロジェクトを読み取り専用にするため、バックアップの完了に時間がかかり、矛盾が生じる可能性があります。たとえば、バックアップされる最初のプロジェクトとバックアップされる最後のプロジェクトで、利用可能な最後のデータの日付が異なる可能性があります。
- フォーク・ネットワークは、プール・リポジトリへの潜在的な変更を防ぐために、内部のプロジェクトがバックアップされる間、完全に読み取り専用にする必要があります。
Geo チームの Runbooks プロジェクトには、このプロセスを自動化しようとする実験的なスクリプトがあります。
トラブルシューティング
以下は、遭遇する可能性のある問題とその解決策です。
シークレットファイルが失われた場合
シークレットファイルをバックアップしていなかった場合、GitLabを再び正しく動作させるためにいくつかのステップを完了する必要があります。
シークレットファイルは、必要な機密情報を含むカラムの暗号化キーを保存する役割を担っています。鍵が失われた場合、GitLabはそれらのカラムを復号化することができず、以下の項目へのアクセスを妨げます:
CI/CD変数やRunner認証のようなケースでは、次のような予期せぬ動作が発生する可能性があります:
- ジョブが動かない
- 500エラー。
この場合、CI/CD変数とRunner認証のためのすべてのトークンをリセットする必要があります。トークンをリセットすると、プロジェクトにアクセスできるようになり、ジョブが再び実行されるようになります。
すべての値が復号化できることを確認
データベースに復号化できない値が含まれているかどうかは、Rakeタスクを使用することで確認できます。
バックアップを取る
紛失したシークレットファイルを回避するためには、GitLabのデータを直接修正する必要があります。
ユーザー二要素認証(2FA)を無効にします。
2FAを有効にしているユーザーはGitLabにサインインできません。その場合、全員の2FAを無効にし、その後ユーザーは2FAを再度有効にする必要があります。
CI/CD変数のリセット
-
データベースコンソールに入ります:
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
-
ci_group_variables
とci_variables
テーブルを調べてください:SELECT * FROM public."ci_group_variables"; SELECT * FROM public."ci_variables";
これらは削除する必要がある変数です。
-
すべての変数を削除します:
DELETE FROM ci_group_variables; DELETE FROM ci_variables;
-
もし、変数を削除したい特定のグループやプロジェクトがわかっていれば、
DELETE
に、それを指定するWHERE
ステートメントを含めることができます:DELETE FROM ci_group_variables WHERE group_id = <GROUPID>; DELETE FROM ci_variables WHERE project_id = <PROJECTID>;
変更を有効にするには、GitLab を再設定したり再起動したりする必要があるかもしれません。
ランナー登録トークンのリセット
-
データベースコンソールに入ります:
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
-
プロジェクト、グループ、インスタンス全体のすべてのトークンをクリアします:
最後の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;
保留中のパイプラインジョブのリセット
-
データベースコンソールに入ります:
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
-
保留中のジョブのトークンをすべてクリアします:
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、関連するメタデータがすべて削除されます。データを削除する前に、シークレットが根本的な原因であることを確認する必要があります。
-
データベースコンソールに入ります:
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
-
以下のテーブルを切り捨ててください:
-- 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 文字まで許可されます。
エラーを解決するためにファイル名を切り詰めます:
- データベースで追跡されていないリモートアップロードされたファイルのクリーンアップ。
- データベースのファイル名の切り捨て。
- バックアップ・タスクの再実行。
リモートアップロードされたファイルのクリーンアップ
既知のイシューにより、親リソースが削除された後もオブジェクトストアのアップロードが残ることがありました。このイシューは解決されました。
これらのファイルを修正するには、uploads
データベース テーブルで追跡されていない、ストレージ内にあるすべてのリモート アップロード ファイルをクリーンアップする必要があります。
-
GitLabデータベースに存在しない場合、紛失・発見ディレクトリに移動できるオブジェクトストアのアップロードファイルをすべてリストアップします:
bundle exec rake gitlab:cleanup:remote_upload_files RAILS_ENV=production
-
これらのファイルを削除し、参照されていないアップロードファイルを全て削除したい場合は、実行してください:
次のアクションは元に戻せません。bundle exec rake gitlab:cleanup:remote_upload_files RAILS_ENV=production DRY_RUN=false
データベースが参照するファイル名を切り捨てます。
問題の原因となっているデータベースによって参照されているファイルを切り捨てる必要があります。データベースが参照するファイル名は保存されています:
-
uploads
テーブル。 - 見つかった参照。他のデータベース・テーブルやカラムから見つかった参照。
- ファイルシステム上。
uploads
テーブルのファイル名を切り詰めます:
-
データベースコンソールに入ります:
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
-
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
テーブルの最後のレコードに達するまで、このプロセスを繰り返します。 -
-
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
テーブルの最後のレコードに達するまで繰り返します。 -
前のクエリからの新しいファイル名が期待されるものであることを確認します。前のステップで見つかったレコードを246文字に切り詰めたいことが確かであれば、以下を実行してください:
次のアクションは元に戻せません。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つの方法は、データベースをダンプし、親ディレクトリ名とファイル名を検索することです:
-
データベースをダンプするには、例として以下のコマンドを使用できます:
pg_dump -h /var/opt/gitlab/postgresql/ -d gitlabhq_production > gitlab-dump.tmp
-
その後、
grep
コマンドを使用して参照を検索できます。親ディレクトリとファイル名を組み合わせるとよいでしょう。例えばgrep public/alongfilenamehere.txt gitlab-dump.tmp
-
-
これらの長いファイル名を、
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
既存のバックアップ・ファイルを修正するには、以下の変更を行います:
- バックアップから次のファイルを抽出します:
db/database.sql.gz
. - ファイルを解凍するか、圧縮されたファイルを扱えるエディタを使用してください。
-
以下の行、または類似の行を削除してください:
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';
- 変更を保存し、ファイルを再圧縮します。
- 変更した
db/database.sql.gz
でバックアップファイルを更新します。