GitLabコンテナレジストリのガーベジコレクションを行ってストレージを解放する方法
GitLabのコンテナレジストリは、Dockerイメージを保存する便利な場所を提供します。時間が経つにつれて、コンテナレジストリは追加される層が増えるにつれてディスクスペースを消費する可能性があります。重複したデータを削除することでストレージを解放する方法を紹介します。
コンテナレジストリを使用すると、Dockerイメージをプロジェクトのソースコードと一緒に保存できます。レジストリに大きなイメージを保持している場合、ストレージコストが予想以上に急増することがあります。GitLabは、冗長になっても各レイヤーを無期限に保持します。
クリーンアップポリシーの設定
ストレージスペースを回復するための最初のステップは、コンテナレジストリのクリーンアップポリシーを設定することです。クリーンアップポリシーは各プロジェクトに個別に適用されます。これは、各コードベースに合わせて保持期間をカスタマイズできることを意味します。
GitLabでプロジェクトを訪れ、サイドバーの「設定」リンクをクリックしてください。「CI/CD」カテゴリに切り替え、ページの下部近くにある「イメージタグのクリーンアップ」セクションを展開します。
「有効」ボタンをオンの位置に切り替えて、クリーンアップポリシーを有効にします。次に、ポリシーを実行するタイミングを選択します - 「毎日」は良いデフォルトです。
次のセクション「これらのタグを保持する」では、クリーンアップポリシーが無視するタグを定義できます。「最新のものを保持する」と「一致するタグを保持する」という2つのオプションは互いに独立しています。保持することを選択できます。
devそして
nightly、最新の5つのタグに補足されます。latestタグは常に含まれ、設定されたタグに加えて使用されます。
次のセクション「これらのタグを削除」は、削除するタグのホワイトリストを定義しています。正規表現パターンに一致しないタグは手を加えません。「指定されたよりも古いタグを削除」の値を調整して、各タグの最大寿命を設定し、クリーンアップされる前にその期間を決定します。作業が完了したら、緑の「保存」ボタンをクリックしてください。
APIを使用して
ウェブUIを通じてクリーンアップポリシーを適用することは、すぐに面倒になる可能性があります。複数のプロジェクトを変更する場合は、代わりにAPIを使用してください。
curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <access_token>" --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":"","name_regex_delete":".*","name_regex_keep":"latest' "https://gitlab.example.com/api/v4/projects/<project_id>"
GitLabのプロファイルページに移動して、APIアクセスのトークンを生成する必要があります。そのトークンを上記のコマンドで<access_token>として使用してください。URLをプロジェクトに合わせて調整してください - プロジェクトIDはGitLab内のプロジェクトページで見つけることができます。
上記のコマンドを実行すると、毎月実行され、14日以上前のイメージをクリーンアップするレジストリクリーンアップポリシーが適用されます。latest タグと、最も最近のタグ(keep_n)は保持され、その他は削除の対象となります(.*)。
クリーンアップ政策の影響
クリーンアップポリシーは、設定した基準に基づいて画像のタグを解除します。タグはコンテナレジストリから削除されます。それらはあなたのプロジェクトのコンテナレジストリ画面には表示されず、Dockerクライアントによってプルすることもできなくなります。
画像のタグを外すことは、実際に削除することとは異なります。ただし、クリーンアップポリシーはデータをリサイクルしないため、使用されていないタグを整理した後でも高いストレージ使用量が見られる場合があります。
これは、イメージレイヤーがあなたのGitLabサーバーに残り、将来の参照のためにキャッシュされるからです。データを完全に削除するには、次にコンテナレジストリのガーベジコレクション手順を実行する必要があります。
ゴミ収集
ガーベジコレクションを実行すると、タグにリンクされていないすべての画像レイヤーが削除されます。これにより、クリーンアップポリシーによってタグ付けが解除された画像が削除されます。また、新しいバージョンのタグをプッシュしたときに冗長になった古いレイヤーも処分される可能性があります。
ゴミ収集はGitLabのコマンドラインインターフェースを通じて手動で呼び出す必要があります。SSH経由でGitLabサーバーに接続し、次のコマンドを実行してください:
sudo gitlab-ctl registry-garbage-collectゴミ収集プロセスが実行されます。コンテナレジストリ内の未使用タグは再利用されます。ゴミ収集は、あなたの全体のGitLabインスタンスにおける未タグ付けのイメージを探します。
クリーンアップポリシーを最初に実行したと仮定すると、現在、ストレージ使用量の健全な減少が見られるはずです。頻繁に使用されるGitLabインストールで初めてガーベジコレクションを実行する場合は、数ギガバイトのスペースを回復できたかもしれません。
タグのないマニフェストとレイヤーの削除
タグ付けされていないイメージマニフェストや参照されていないレイヤーも削除するようにガーベジコレクションに指示することで、さらに多くのスペースを回収できます。これはより破壊的な操作ですが、通常は期待される結果です。
sudo gitlab-ctl registry-garbage-collect -m-m フラグを追加すると、タグ付きイメージマニフェストに直接関連付けられていないレイヤーが削除されます。これにより、キャッシュされたレイヤーや中間ビルドステップが失われることになります。
デフォルトでは、DockerとGitLabコンテナレジストリは、作成されたすべてのレイヤーを保持します。たとえそれらがもはや参照されていなくてもです。つまり、タグを持っていなくても、ユニークなコンテンツアドレッサブル識別子を使用して以前に知られていたレイヤーを常に取得できるということです。
これが、これらのレイヤーをデフォルトで削除できない理由です。コマンドを実行する前に、その影響を理解しておく必要があります。特に、一部のワークフローでは深刻な結果をもたらす可能性があります。それでも、-mスイッチを使用することはしばしば望ましいです。これにより、はるかに多くのディスクスペースが解放され、タグ名を使用して画像を参照するだけであれば副作用はないはずです。
スケジュールに従ったガーベジコレクションの実行
クリーンアップポリシーは、設定した頻度で自動的に実行されます。ガーベジコレクションはデフォルトで設定されていないため、最初の実行でストレージ利用率が大幅に削減される可能性があります。
定期的にガーベジコレクションを実行するには、システムのcrontabにコマンドを追加する必要があります。毎週月曜日の午前2時にガーベジコレクションを実行するために、次の内容で/etc/cron.d/registry-garbage-collectionというファイルを作成します:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 2 * * 1 root gitlab-ctl registry-garbage-collect
ガーベジコレクションの限界
ガーベジコレクションに要する時間は、削除するデータの量によって異なります。ガーベジコレクションを実行している間は、コンテナレジストリサービスを停止する必要があります。つまり、プロセスが完了するまでユーザーはイメージをプルまたはプッシュできません。
ダウンタイムの影響を軽減するために、レジストリを読み取り専用モードに切り替え、コマンドを実行した後、書き込み可能モードに戻すことができます。レジストリは常に稼働していることができますが、ユーザーはイメージをプッシュすることができなくなります。さらに、モードの切り替えにはGitLabの「再構成」が必要です(sudo gitlab-ctl reconfigure)。これ自体も、インストールの設定に応じてダウンタイムを引き起こす可能性があります。
次の行を/etc/gitlab/gitlab.rbで編集する必要があります:
registry['storage'] = {
'maintenance' => {
'readonly' => {
'enabled' => true
}
}
}
コマンド sudo gitlab-ctl reconfigure を実行し、その後、ガーベジコレクションのコマンドのいずれかを使用してください。完了したら、gitlab.rb の enabled 行を false に戻して読み取り専用モードを無効にし、その後再度 GitLab を再構成してください。





