- コンテナレジストリの有効化
- コンテナレジストリドメイン設定
- コンテナレジストリをサイト全体で無効にします。
- 新しいプロジェクトのコンテナレジストリをサイト全体で無効にします。
- コンテナレジストリのストレージ設定
- レジストリ内部ポートの変更
- プロジェクトごとのコンテナレジストリの無効化
- GitLab を認証エンドポイントとして外部コンテナレジストリを使用します。
- コンテナレジストリ通知の設定
- 今すぐクリーンアップポリシーを実行
- コンテナレジストリのガベージコレクション
- GitLab とレジストリが別々のノードで実行されるように設定します(Linux パッケージのインストール)。
- GitLabコンテナレジストリのアーキテクチャ
- サードパーティのレジストリからのマイグレーション
- トラブルシューティング
GitLabコンテナレジストリの管理
GitLabコンテナレジストリを使えば、全てのプロジェクトがDockerイメージを保存する独自のスペースを持つことができます。
Dockerレジストリについて詳しくはDockerドキュメントをご覧ください。
このドキュメントは管理者向けのガイドです。GitLabコンテナレジストリの使い方はユーザードキュメントをご覧ください。
コンテナレジストリの有効化
コンテナレジストリを有効にする手順は、使用するインストールの種類によって異なります。
Linux パッケージのインストール
Linuxパッケージを使ってGitLabをインストールした場合、コンテナレジストリはデフォルトで利用可能な場合とそうでない場合があります。
コンテナレジストリは自動的に有効化され、GitLabドメイン、ポート5050、組み込みのLet’s Encryptインテグレーションを使っている場合は利用可能です。
そうでない場合は、コンテナレジストリは有効になっていません。有効にするには
- GitLabドメインに対して設定するか、または
- 別のドメインに設定することもできます。
コンテナレジストリは、デフォルトでは HTTPS で動作します。HTTP を使用することもできますが、これは推奨されません。これを実装したい場合は、安全でないレジストリのドキュメントを読んでください。
セルフコンパイルによるインストール
GitLab インストールをセルフコンパイルした場合は、次のようになります:
- インストールするGitLabのバージョンに対応するイメージを使ってレジストリをデプロイする必要があります(例:
registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:v3.15.0-gitlab
)。 - インストールが完了したら、
gitlab.yml
でレジストリの設定を行います。 -
lib/support/nginx/registry-ssl
にあるNGINX設定ファイルのサンプルを使用し、host
、port
、TLS証明書のパスに一致するように編集します。
gitlab.yml
の内部は次のとおりです:
registry:
enabled: true
host: registry.gitlab.example.com
port: 5005
api_url: http://localhost:5000/
key: config/registry.key
path: shared/registry
issuer: gitlab-issuer
どこに:
パラメータ | 説明 |
---|---|
enabled |
true false GitLabのレジストリを有効に false します。false デフォルトでは false . |
host | レジストリが実行され、ユーザーが使用できるホストURL。 |
port | 外部のレジストリ・ドメインがリッスンするポート。 |
api_url | レジストリが公開している内部 API URL。デフォルトはhttp://localhost:5000 です。外部のDockerレジストリを設定する場合を除き、これを変更しないでください。 |
key | レジストリのrootcertbundle のペアである秘密鍵の場所。token auth設定のドキュメントをお読みください。 |
path | これは、レジストリのrootdirectory で指定されているのと同じディレクトリでなければなりません。ストレージ設定のドキュメントを参照ください。このパスは、GitLabユーザー、Webサーバーユーザー、レジストリユーザーが読めるようにする必要があります。詳しくは#configure-storage-for-the-container-registryを参照ください。 |
issuer | これは、レジストリのissuer で設定したものと同じ値でなければなりません。トークン認証設定のドキュメントをお読みください。 |
GitLabをソースからインストールした場合、レジストリのinitファイルは同梱されません。したがって、レジストリの設定を変更した場合、GitLabを再起動してもレジストリは再起動されません。その方法についてはアップストリームのドキュメントを読んでください。
最低限、レジストリの設定がサービスとしてcontainer_registry
、レルムとしてhttps://gitlab.example.com/jwt/auth
:
auth:
token:
realm: https://gitlab.example.com/jwt/auth
service: container_registry
issuer: gitlab-issuer
rootcertbundle: /root/certs/certbundle
auth
が設定されていない場合、ユーザーは認証なしでDockerイメージを引き出すことができます。コンテナレジストリドメイン設定
レジストリの外部ドメインは、以下のいずれかの方法で設定できます:
- 既存の GitLab ドメインを使用します。レジストリはポートでリッスンし、GitLabからのTLS証明書を再利用します。
- 完全に別のドメインを使用し、そのドメイン用に新しいTLS証明書を使用します。
コンテナレジストリにはTLS証明書が必要なため、コストがかかる場合があります。
コンテナレジストリを初めて設定する前に、この点を考慮してください。
既存のGitLabドメインでコンテナレジストリを設定します。
コンテナレジストリが既存のGitLabドメインを使用するように設定されている場合、ポート上でコンテナレジストリを公開することができます。この方法では、既存のGitLab TLS証明書を再利用することができます。
GitLabドメインがhttps://gitlab.example.com
、内部へのポートが5050
、コンテナレジストリを設定する場合:
- Linux パッケージのインストールを使用している場合は、
gitlab.rb
を編集してください。 - セルフコンパイルのインストールを使用している場合は、
gitlab.yml
を編集してください。
レジストリがリッスンするポート ( デフォルトでは5000
) とは異なるポートを選択してください。
gitlab_rails['registry_port']
(デフォルトでは5000
)に記載されているポートではなく、registry_external_url
に記載されているポートからのトラフィックを許可するように設定する必要があります。-
/etc/gitlab/gitlab.rb
には、レジストリの URL と、GitLab が使用している既存の TLS 証明書と鍵へのパスを記述してください:registry_external_url 'https://gitlab.example.com:5050'
registry_external_url
は既存の GitLab URL の下で HTTPS をリッスンしていますが、ポートは異なります。TLS 証明書が
/etc/gitlab/ssl/gitlab.example.com.crt
になく、鍵が/etc/gitlab/ssl/gitlab.example.com.key
にない場合は、以下の行のコメントを外してください:registry_nginx['ssl_certificate'] = "/path/to/certificate.pem" registry_nginx['ssl_certificate_key'] = "/path/to/certificate.key"
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
を使って検証します:
openssl s_client -showcerts -servername gitlab.example.com -connect gitlab.example.com:5050 > cacert.pem
証明書プロバイダがCAバンドル証明書を提供する場合は、それをTLS証明書ファイルに追加します。
管理者は、コンテナレジストリが5678
のような任意のポートをリッスンすることを望むかもしれません。しかし、レジストリとアプリケーションサーバーは、ポート80
と443
のみをリッスンする AWS アプリケーションロードバランサーの背後にあります。管理者はregistry_external_url
のポート番号を削除することができ、HTTP または HTTPS が想定されます。そして、ロードバランサーをポート80
または443
から任意のポートにレジストリにマップするルールが適用されます。ユーザがコンテナレジストリのdocker login
の例に依存している場合、これはインポートです。以下はその例です:
registry_external_url 'https://registry-gitlab.example.com'
registry_nginx['redirect_http_to_https'] = true
registry_nginx['listen_port'] = 5678
-
/home/git/gitlab/config/gitlab.yml
を開き、registry
エントリを見つけ、以下の設定で構成します:registry: enabled: true host: gitlab.example.com port: 5050
- ファイルを保存してGitLab を再起動すると、変更が有効になります。
- NGINXにも関連する変更を加えます(ドメイン、ポート、TLS証明書のパス)。
これで、ユーザーは GitLab の認証情報を使ってコンテナレジストリにサインインできるようになります:
docker login gitlab.example.com:5050
コンテナレジストリの独自ドメイン設定
レジストリが独自のドメインを使用するように設定されている場合、その特定のドメイン用のTLS証明書が必要です(例えば、registry.example.com
)。既存の GitLab ドメインのサブドメインでホストしている場合は、ワイルドカード証明書が必要になるかもしれません。例えば、*.gitlab.example.com
はregistry.gitlab.example.com
と一致するワイルドカードで、*.example.com
とは異なります。
手動で生成されたSSL証明書(こちらで説明)と同様に、LinuxパッケージのインストールではLet’s Encryptによって自動生成された証明書もサポートされています。
コンテナレジストリをhttps://registry.gitlab.example.com
でアクセスできるようにするとします。
-
TLS 証明書と鍵を
/etc/gitlab/ssl/registry.gitlab.example.com.crt
と/etc/gitlab/ssl/registry.gitlab.example.com.key
に配置し、それらの権限が正しいことを確認します:chmod 600 /etc/gitlab/ssl/registry.gitlab.example.com.*
-
TLS証明書を配置したら、
/etc/gitlab/gitlab.rb
:registry_external_url 'https://registry.gitlab.example.com'
registry_external_url
はHTTPSでリッスンしています。 -
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
ワイルドカード証明書を使用している場合は、URLに加えて証明書へのパスを指定する必要があります。この場合、/etc/gitlab/gitlab.rb
のようになります:
registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/certificate.pem"
registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/certificate.key"
-
/home/git/gitlab/config/gitlab.yml
を開き、registry
エントリを見つけ、以下の設定で構成します:registry: enabled: true host: registry.gitlab.example.com
- ファイルを保存してGitLab を再起動すると、変更が有効になります。
- NGINXにも関連する変更を加えます(ドメイン、ポート、TLS証明書のパス)。
これで、ユーザーは GitLab の認証情報を使ってコンテナレジストリにサインインできるようになるはずです:
docker login registry.gitlab.example.com
コンテナレジストリをサイト全体で無効にします。
以下の手順でレジストリを無効化しても、既存のDockerイメージは削除されません。Dockerイメージの削除はレジストリアプリケーション自体で処理されます。
-
/etc/gitlab/gitlab.rb
を開き、registry['enable']
をfalse
に設定します:registry['enable'] = false
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
/home/git/gitlab/config/gitlab.yml
を開き、registry
エントリを見つけ、enabled
をfalse
に設定します:registry: enabled: false
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
新しいプロジェクトのコンテナレジストリをサイト全体で無効にします。
コンテナレジストリを有効にすると、すべての新規プロジェクトで利用できるようになります。この機能を無効にして、プロジェクトのオーナーが自分でコンテナレジストリを有効にするには、以下の手順に従います。
-
/etc/gitlab/gitlab.rb
を編集し、以下の行を追加します:gitlab_rails['gitlab_default_projects_features_container_registry'] = false
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
/home/git/gitlab/config/gitlab.yml
を開き、default_projects_features
エントリを見つけ、container_registry
がfalse
になるように設定します:## Default project features settings default_projects_features: issues: true merge_requests: true wiki: true snippets: false builds: true container_registry: false
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
トークンの持続時間を増やす
GitLabでは、コンテナレジストリのトークンは5分ごとに失効します。トークンの有効期間を長くするには
- 左のサイドバーで、Search を選択するか、次のページに進んでください。
- Admin Areaを選択します。
- 左サイドバーで、Settings > CI/CDを選択します。
- コンテナレジストリを展開します。
- Authorization token duration (minutes)] で、値を更新します。
- 変更を保存を選択します。
コンテナレジストリのストレージ設定
ストレージドライバを設定することで、コンテナレジストリに様々なストレージバックエンドを使用するように設定できます。デフォルトでは、GitLabコンテナレジストリはファイルシステムドライバの設定を使用するように設定されています。
サポートされているドライバは以下の通りです:
ドライバー | 説明 |
---|---|
filesystem | ローカルファイルシステム上のパスを使用 |
azure | Microsoft Azure Blob Storage |
gcs | Googleクラウドストレージ |
s3 | Amazon Simple Storage Service。正しいS3権限スコープでストレージバケットを設定してください。 |
swift | OpenStack Swiftオブジェクトストレージ |
oss | アリユンOSS |
ほとんどのS3互換サービス(MinIOなど)はコンテナレジストリで動作するはずですが、AWS S3のサポートのみを保証しています。サードパーティのS3実装の正しさを保証できないため、イシューをデバッグすることはできますが、問題がAWS S3バケットに対して再現可能でない限り、レジストリにパッチを当てることはできません。
個々のドライバの設定オプションについてはDockerレジストリのドキュメントを参照してください。
ファイルシステムを使用
ファイルシステムに画像を保存したい場合は、コンテナレジストリの保存パスを変更することができます。
このパスにアクセスできます:
- コンテナレジストリデーモンを実行しているユーザー。
- GitLab を実行しているユーザー。
GitLab、レジストリ、ウェブサーバのすべてのユーザーがこのディレクトリにアクセスできる必要があります。
Linuxパッケージのインストールでイメージが保存されるデフォルトの場所は/var/opt/gitlab/gitlab-rails/shared/registry
です。変更するには
-
/etc/gitlab/gitlab.rb
を編集します:gitlab_rails['registry_path'] = "/path/to/registry/storage"
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
セルフコンパイルしたインストールでイメージが保存されるデフォルトの場所は/home/git/gitlab/shared/registry
です。変更するには
-
/home/git/gitlab/config/gitlab.yml
を開き、registry
エントリーを見つけ、path
の設定を変更します:registry: path: shared/registry
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
オブジェクトストレージの使用
オブジェクトストレージに画像を保存したい場合は、コンテナレジストリのストレージドライバを変更します。
GitLab でのオブジェクトストレージの使用について、詳しくはこちらをご覧ください。
Linux パッケージインストール用のs3
とgcs
ストレージドライバの設定
以下の設定手順は、s3
およびgcs
ストレージドライバ用です。その他のストレージドライバもサポートされています。
Linux パッケージインストール用にs3
ストレージドライバを設定するには:
-
/etc/gitlab/gitlab.rb
を編集します:registry['storage'] = { 's3' => { 'accesskey' => 's3-access-key', 'secretkey' => 's3-secret-key-for-access-key', 'bucket' => 'your-s3-bucket', 'region' => 'your-s3-region', 'regionendpoint' => 'your-s3-regionendpoint' } }
静的な認証情報を使用しないようにするには、IAMロールを使用し、
accesskey
とsecretkey
を省略します。IAMプロファイルがDockerによって文書化された権限に従っていることを確認してください。registry['storage'] = { 's3' => { 'bucket' => 'your-s3-bucket', 'region' => 'your-s3-region' } }
AWS S3 VPCエンドポイントで使用する場合は、
regionendpoint
をVPCエンドポイントのアドレスに設定し、pathstyle
をfalseに設定します:registry['storage'] = { 's3' => { 'accesskey' => 's3-access-key', 'secretkey' => 's3-secret-key-for-access-key', 'bucket' => 'your-s3-bucket', 'region' => 'your-s3-region', 'regionendpoint' => 'your-s3-vpc-endpoint', 'pathstyle' => false } }
-
regionendpoint
は、MinIOなどのS3互換サービスを設定する場合、またはAWS S3 VPCエンドポイントを使用する場合にのみ必要です。 -
your-s3-bucket
は存在するバケツの名前でなければならず、サブディレクトリを含めることはできません。 -
pathstyle
bucket_name.host/object
の代わりにhost/bucket_name/object
形式のパスを使用するには、true を設定します。AWS S3 の場合は false を設定します。
S3 APIからの503エラーを避けるために、S3への接続にレート制限を設定することができます。これを行うには、
maxrequestspersecond
をS3 リクエストレート閾値内の数値に設定します:registry['storage'] = { 's3' => { 'accesskey' => 's3-access-key', 'secretkey' => 's3-secret-key-for-access-key', 'bucket' => 'your-s3-bucket', 'region' => 'your-s3-region', 'regionendpoint' => 'your-s3-regionendpoint', 'maxrequestspersecond' => 100 } }
-
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
Linux パッケージインストール用にgcs
ストレージドライバを設定するには:
-
/etc/gitlab/gitlab.rb
を編集します:registry['storage'] = { 'gcs' => { 'bucket' => 'BUCKET_NAME', 'keyfile' => 'PATH/TO/KEYFILE', # If you have the bucket shared with other apps beyond the registry, uncomment the following: # 'rootdirectory' => '/gcs/object/name/prefix' } }
GitLabは全てのパラメータをサポートしています。
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
セルフコンパイルによるインストール
ストレージドライバの設定は、Dockerレジストリのデプロイ時に作成したレジストリ設定YAMLファイルで行います。
s3
ストレージドライバの例です:
storage:
s3:
accesskey: 's3-access-key' # Not needed if IAM role used
secretkey: 's3-secret-key-for-access-key' # Not needed if IAM role used
bucket: 'your-s3-bucket'
region: 'your-s3-region'
regionendpoint: 'your-s3-regionendpoint'
cache:
blobdescriptor: inmemory
delete:
enabled: true
your-s3-bucket
は存在するバケツの名前でなければならず、サブディレクトリを含めることはできません。
ダウンタイムなしでオブジェクトストレージにマイグレーション
sync
のオペレーションを推奨します。コンテナレジストリを停止せずにストレージをマイグレーションするには、コンテナレジストリを読み取り専用モードに設定します。大規模インスタンスでは、Container Registryをしばらくの間読み取り専用モードにする必要があるかもしれません。この間、コンテナレジストリからプルすることはできますが、プッシュすることはできません。
- オプション:マイグレーションするデータ量を減らすには、ガベージコレクションツールをダウンタイムなしで実行します。
-
この例では、
aws
CLI を使用します。CLIを設定したことがない場合は、sudo aws configure
を実行して認証情報を設定する必要があります。管理者でないユーザーはコンテナレジストリフォルダにアクセスできない可能性が高いため、必ずsudo
を使用してください。クレデンシャルの設定を確認するには、ls
を実行してすべてのバケットを一覧表示します。sudo aws --endpoint-url https://your-object-storage-backend.com s3 ls
バックエンドに AWS を使用している場合は、
--endpoint-url
は必要ありません。 -
aws
CLIcp
またはsync
コマンドなどで、初期データを S3 バケットにコピーします。バケット内部のトップレベルフォルダはdocker
フォルダにしてください。sudo aws --endpoint-url https://your-object-storage-backend.com s3 sync registry s3://mybucket
データ量が多い場合は、同期オペレーションを並行して行うことでパフォーマンスが向上する可能性があります。 - 最後のデータ同期を行うために、コンテナレジストリを
read-only
モード にし、GitLab を再設定します。 -
最初のデータロード以降に行われた変更を S3 バケットに同期し、移行先のバケットに存在するが移行元には存在しないファイルを削除します:
sudo aws --endpoint-url https://your-object-storage-backend.com s3 sync registry s3://mybucket --delete --dryrun
コマンドが期待通りに実行されることを確認したら、
--dryrun
フラグを外してコマンドを実行します。この--delete
フラグは、コピー先には存在するがコピー元には存在しないファイルを削除します。ソースと宛先を入れ替えると、レジストリ内のすべてのデータが削除されます。 -
これら2つのコマンドによって返されるファイルカウントを見て、すべてのコンテナレジストリファイルがオブジェクトストレージにアップロードされたことを確認します:
sudo find registry -type f | wc -l
sudo aws --endpoint-url https://your-object-storage-backend.com s3 ls s3://mybucket --recursive | wc -l
これらのコマンドの出力は、
_uploads
ディレクトリとサブディレクトリの内容を除いて一致するはずです。 - ストレージにS3バケットを使用するようにレジストリを設定します。
- 変更を有効にするには、レジストリを
read-write
モードに戻し、GitLab を再設定します。
Azure オブジェクトストレージへの移行
GitLab 16.0ではストレージドライバのデフォルト設定が変更される予定です。
/
。混乱を避けるために、今すぐ現在の設定にtrimlegacyrootprefix: false
。詳しくはコンテナレジストリ設定ドキュメントをご覧ください。
既存のファイルシステムまたは別のオブジェクトストレージプロバイダーから Azure Object Storage に移行する場合は、標準のルートディレクトリを使用するようにレジストリを設定する必要があります。レジストリ設定の Azure ストレージドライバセクションでtrimlegacyrootprefix: true
を設定して構成します。この設定を行わないと、Azure ストレージドライバは、ルートパスの最初のセクションとして/
ではなく//
を使用し、マイグレーションしたイメージにアクセスできなくなります。
registry['storage'] = {
'azure' => {
'accountname' => 'accountname',
'accountkey' => 'base64encodedaccountkey',
'container' => 'containername',
'rootdirectory' => '/azure/virtual/container',
'trimlegacyrootprefix' => true
}
}
storage:
azure:
accountname: accountname
accountkey: base64encodedaccountkey
container: containername
rootdirectory: /azure/virtual/container
trimlegacyrootprefix: true
デフォルトでは、Azure Storage Driver はcore.windows.net
レルムを使用します。azure
セクションで、realm
に別の値を設定できます(たとえば、Azure Government Cloud の場合は、core.usgovcloudapi.net
)。詳細については、Dockerドキュメントを参照してください。
ストレージドライバのリダイレクトを無効にします。
デフォルトでは、リモートバックエンドで設定されたレジストリにアクセスするユーザーは、ストレージドライバのデフォルトバックエンドにリダイレクトされます。例えば、レジストリはs3
ストレージドライバを使って設定することができます。このドライバはGitLabサーバの負荷を軽減するためにリクエストをリモートのS3バケットにリダイレクトします。
しかし、通常公開サーバーにアクセスできない内部ホストで使われるレジストリにとって、この動作は望ましくありません。リダイレクトとプロキシダウンロードを無効にするには、次のようにdisable
フラグを true に設定します。これにより、すべてのトラフィックが常にレジストリサービスを経由するようになります。この結果、セキュリティは向上しますが (ストレージのバックエンドが公開されていないため、攻撃されにくくなります)、パフォーマンスは低下します (すべてのトラフィックがサービスを経由してリダイレクトされます)。
-
/etc/gitlab/gitlab.rb
を編集します:registry['storage'] = { 's3' => { 'accesskey' => 's3-access-key', 'secretkey' => 's3-secret-key-for-access-key', 'bucket' => 'your-s3-bucket', 'region' => 'your-s3-region', 'regionendpoint' => 'your-s3-regionendpoint' }, 'redirect' => { 'disable' => true } }
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
レジストリ設定の YAML ファイルに
redirect
フラグを追加します:storage: s3: accesskey: 'AKIAKIAKI' secretkey: 'secret123' bucket: 'gitlab-registry-bucket-AKIAKIAKI' region: 'your-s3-region' regionendpoint: 'your-s3-regionendpoint' redirect: disable: true cache: blobdescriptor: inmemory delete: enabled: true
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
暗号化されたS3バケット
デフォルトでSSE-S3またはSSE-KMS暗号化が有効になっているS3バケットに対して、AWS KMSでサーバーサイド暗号化を使用できます。カスタマーマスターキー(CMK)とSSE-C暗号化は、リクエストごとに暗号化キーを送信する必要があるため、サポートされていません。
SSE-S3の場合、レジストリ設定でencrypt
オプションを有効にする必要があります。この方法はGitLabのインストール方法によって異なります。あなたのインストール方法に合ったこちらの手順に従ってください。
-
/etc/gitlab/gitlab.rb
を編集します:registry['storage'] = { 's3' => { 'accesskey' => 's3-access-key', 'secretkey' => 's3-secret-key-for-access-key', 'bucket' => 'your-s3-bucket', 'region' => 'your-s3-region', 'regionendpoint' => 'your-s3-regionendpoint', 'encrypt' => true } }
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
レジストリ設定の YAML ファイルを編集します:
storage: s3: accesskey: 'AKIAKIAKI' secretkey: 'secret123' bucket: 'gitlab-registry-bucket-AKIAKIAKI' region: 'your-s3-region' regionendpoint: 'your-s3-regionendpoint' encrypt: true
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
ストレージの制限
ストレージの制限はありませんので、ユーザーは任意のサイズのDockerイメージを無限にアップロードすることができます。この設定は将来のリリースで設定可能になるはずです。
レジストリ内部ポートの変更
レジストリサーバーは、デフォルトで localhost のポート5000
を待ち受けます。 これは、レジストリサーバーが接続を受け付けるべきアドレスです。以下の例では、レジストリのポートを5010
に設定します。
-
/etc/gitlab/gitlab.rb
を開き、registry['registry_http_addr']
を設定します:registry['registry_http_addr'] = "localhost:5010"
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
レジストリ・サーバーの設定ファイルを開き、
http:addr
の値を編集します:http: addr: localhost:5010
-
ファイルを保存し、レジストリサーバーを再起動します。
プロジェクトごとのコンテナレジストリの無効化
GitLabインスタンスでレジストリが有効になっているが、プロジェクトでは必要ない場合は、プロジェクトの設定からレジストリを無効にすることができます。
GitLab を認証エンドポイントとして外部コンテナレジストリを使用します。
外部のコンテナレジストリを使用する場合、コンテナレジストリに関連するいくつかの機能が使用できなくなったり、固有のリスクが発生したりする可能性があります。
インテグレーションを機能させるには、外部レジストリが GitLab と認証するために JSON Web Token を使用するように設定する必要があります。外部レジストリのランタイム設定には、以下のエントリが必要です:
auth:
token:
realm: https://gitlab.example.com/jwt/auth
service: container_registry
issuer: gitlab-issuer
rootcertbundle: /root/certs/certbundle
これらのエントリがないと、レジストリログインはGitLabで認証できません。GitLabはまた、registry.example.com/group/project/image-name:tag
やregistry.example.com/group/project/my/image-name:tag
のようなプロジェクト階層下のネストしたイメージ名を認識せず、registry.example.com/group/project:tag
のみを認識します。
Linux パッケージのインストール
GitLab を外部コンテナレジストリの認証エンドポイントとして使うことができます。
-
/etc/gitlab/gitlab.rb
を開き、必要な設定を行います:gitlab_rails['registry_enabled'] = true gitlab_rails['registry_api_url'] = "https://<external_registry_host>:5000" gitlab_rails['registry_issuer'] = "gitlab-issuer"
-
gitlab_rails['registry_enabled'] = true
はGitLab Container Registryの機能と認証エンドポイントを有効にするために必要です。これを有効にしても、GitLabにバンドルされているコンテナレジストリサービスは起動しません。 -
gitlab_rails['registry_api_url'] = "http://<external_registry_host>:5000"
は、レジストリがインストールされているホストに合わせて変更する必要があります。また、内部レジストリがTLSを使用するように設定されている場合は、https
を指定する必要があります。詳しくはDockerレジストリのドキュメントをご覧ください。
-
-
GitLabと外部コンテナレジストリが安全に通信するためには、証明鍵と鍵のペアが必要です。証明書と鍵のペアを作成し、外部コンテナレジストリに公開証明書 (
rootcertbundle
) を設定し、GitLabに秘密鍵を設定する必要があります。そのためには、/etc/gitlab/gitlab.rb
に以下を追加します:# registry['internal_key'] should contain the contents of the custom key # file. Line breaks in the key file should be marked using `\n` character # Example: registry['internal_key'] = "---BEGIN RSA PRIVATE KEY---\nMIIEpQIBAA\n" # Optionally define a custom file for a Linux package installation to write the contents # of registry['internal_key'] to. gitlab_rails['registry_key_path'] = "/custom/path/to/registry-key.key"
reconfigure が実行されるたびに、
registry_key_path
で指定されたファイルにinternal_key
で指定された内容が入力されます。ファイルが指定されていない場合、Linuxパッケージのインストールはデフォルトで/var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key
。 -
GitLab Container Registry ページに表示されるコンテナレジストリ URL を変更するには、以下の設定を行います:
gitlab_rails['registry_host'] = "registry.gitlab.example.com" gitlab_rails['registry_port'] = "5005"
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
セルフコンパイルによるインストール
-
/home/git/gitlab/config/gitlab.yml
を開き、registry
の設定を編集します:## Container Registry registry: enabled: true host: "registry.gitlab.example.com" port: "5005" api_url: "https://<external_registry_host>:5000" path: /var/lib/registry key: /path/to/keyfile issuer: gitlab-issuer
これらのパラメーターの意味については、こちらをお読みください。
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
コンテナレジストリ通知の設定
コンテナレジストリは、レジストリで発生したイベントに応じて Webhook 通知を送信するように設定できます。
コンテナレジストリの通知設定オプションの詳細については、Docker Registry notifications documentation を参照してください。
コンテナレジストリには複数のエンドポイントを設定できます。
Linux パッケージインストール用の通知エンドポイントを設定するには、以下の手順に従います:
-
/etc/gitlab/gitlab.rb
を編集します:registry['notifications'] = [ { 'name' => 'test_endpoint', 'url' => 'https://gitlab.example.com/notify', 'timeout' => '500ms', 'threshold' => 5, 'backoff' => '1s', 'headers' => { "Authorization" => ["AUTHORIZATION_EXAMPLE_TOKEN"] } } ]
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
通知エンドポイントの設定は、Dockerレジストリをデプロイしたときに作成したレジストリ設定YAMLファイルで行います。
使用例:
notifications:
endpoints:
- name: alistener
disabled: false
url: https://my.listener.com/event
headers: <http.Header>
timeout: 500
threshold: 5
backoff: 1000
今すぐクリーンアップポリシーを実行
- 正しいレジストリURLを指すように、Sidekiqノードの
gitlab.rb
ファイルを設定します。 -
registry.key
ファイルを各Sidekiqノードにコピーします。
詳細については、Sidekiq設定ページを参照してください。
特定のプロジェクトによって使用されるコンテナレジストリのディスク容量を削減するために、管理者はクリーンアップポリシーを設定し、ガベージコレクションを実行することができます。
プロジェクト別レジストリディスク使用量
各プロジェクトのディスク使用量を調べるには、GitLab Railsコンソールで以下を実行します:
projects_and_size = [["project_id", "creator_id", "registry_size_bytes", "project path"]]
# You need to specify the projects that you want to look through. You can get these in any manner.
projects = Project.last(100)
projects.each do |p|
project_total_size = 0
container_repositories = p.container_repositories
container_repositories.each do |c|
c.tags.each do |t|
project_total_size = project_total_size + t.total_size unless t.total_size.nil?
end
end
if project_total_size > 0
projects_and_size << [p.project_id, p.creator.id, project_total_size, p.full_path]
end
end
# print it as comma separated output
projects_and_size.each do |ps|
puts "%s,%s,%s,%s" % ps
end
クリーンアップポリシーを実行してイメージタグを削除するには、GitLab Railsコンソールで以下のコマンドを実行します:
# Numeric ID of the project whose container registry should be cleaned up
P = <project_id>
# Numeric ID of a user with Developer, Maintainer, or Owner role for the project
U = <user_id>
# Get required details / objects
user = User.find_by_id(U)
project = Project.find_by_id(P)
policy = ContainerExpirationPolicy.find_by(project_id: P)
# Loop through each container repository
project.container_repositories.find_each do |repo|
puts repo.attributes
# Start the tag cleanup
puts Projects::ContainerRepository::CleanupTagsService.new(container_repository: repo, current_user: user, params: policy.attributes.except("created_at", "updated_at")).execute
end
スケジュールでクリーンアップを実行することもできます。
コンテナレジストリのガベージコレクション
コンテナ・レジストリはかなりの量のストレージ・スペースを使用する可能性があり、ストレージの使用量を減らしたいと思うかもしれません。列挙したオプションの中では、タグの削除が最も効果的なオプションです。ただし、タグの削除だけでは画像レイヤーは削除されず、基礎となる画像マニフェストがタグなしで残されるだけです。
より効果的に領域を解放するために、コンテナレジストリにはガベージコレクタがあり、参照されていないレイヤーと(オプションで)タグ付けされていないマニフェストを削除することができます。
ガベージコレクタを起動するには、gitlab-ctl
が提供するregistry-garbage-collect
コマンドを使用します。
gitlab-ctl
モードに設定[し、gitlab-ctl
gitlab-ctl
を[バイパスするgitlab-ctl
ことができます。ガベージコレクションの実行に必要な時間は、コンテナレジストリのデータサイズに比例します。
前提条件:
- LinuxパッケージまたはGitLab Helmチャートを使ってGitLabをインストールしている必要があります。
コンテンツアドレス対応レイヤーを理解する
次の例では、まず画像を作成します:
# This builds a image with content of sha256:111111
docker build -t my.registry.com/my.group/my.project:latest .
docker push my.registry.com/my.group/my.project:latest
ここで、:latest
を新しいバージョンで上書きします:
# This builds a image with content of sha256:222222
docker build -t my.registry.com/my.group/my.project:latest .
docker push my.registry.com/my.group/my.project:latest
現在、:latest
タグはsha256:222222
のマニフェストを指しています。レジストリのアーキテクチャにより、このデータはmy.registry.com/my.group/my.project@sha256:111111
イメージを取り込む際にもアクセス可能ですが、:latest
タグから直接アクセスすることはできません。
参照されないレイヤーの削除
イメージレイヤーはコンテナレジストリストレージの大部分を占めます。イメージマニフェストがレイヤーを参照していない場合、レイヤーは参照されていないと見なされます。参照されていないレイヤーはコンテナレジストリのガベージコレクタのデフォルトターゲットです。
設定ファイルのデフォルトの場所を変更していない場合は、実行してください:
sudo gitlab-ctl registry-garbage-collect
コンテナレジストリの場所を変更した場合config.yml
:
sudo gitlab-ctl registry-garbage-collect /path/to/config.yml
また、タグ付けされていないマニフェストと参照されていないレイヤーをすべて削除して、追加のスペースを回復することもできます。
タグなしマニフェストおよび参照なしレイヤーの削除
デフォルトでは、コンテナレジストリのガベージコレクタはタグ付けされていないイメージを無視します。ユーザーはタグ付けされていないイメージをダイジェストでプルし続けることができます。ユーザーは将来的にイメージを再タグ付けし、GitLab UIとAPIで再び見えるようにすることもできます。
タグ付けされていない画像や、その画像から参照されているレイヤーを気にしないのであれば、それらをすべて削除することができます。registry-garbage-collect
コマンドで-m
フラグを使います:
sudo gitlab-ctl registry-garbage-collect -m
タグなし画像の削除に不安がある場合は、レジストリデータをバックアップしてから行ってください。
ダウンタイムなしでガベージコレクションを実行
コンテナレジストリをオンラインに保ちながらガベージコレクションを実行するには、レジストリを読み取り専用モードにして、組み込みのgitlab-ctl registry-garbage-collect
コマンドをバイパスします。
コンテナレジストリを読み取り専用モードにしている間は、イメージをプルすることはできますが、プッシュすることはできません。コンテナレジストリは、ガベージコレクションの全期間、読み取り専用モードのままでなければなりません。
デフォルトでは、レジストリの保存パスは /var/opt/gitlab/gitlab-rails/shared/registry
です。
読み取り専用モードを有効にするには
-
/etc/gitlab/gitlab.rb
で、読み取り専用モードを指定します:registry['storage'] = { 'filesystem' => { 'rootdirectory' => "<your_registry_storage_path>" }, 'maintenance' => { 'readonly' => { 'enabled' => true } } }
-
GitLab を保存して再設定します:
sudo gitlab-ctl reconfigure
このコマンドはコンテナレジストリを読み込み専用モードにします。
-
次に、ガベージコレクトコマンドのいずれかを起動します:
# Remove unreferenced layers sudo /opt/gitlab/embedded/bin/registry garbage-collect /var/opt/gitlab/registry/config.yml # Remove untagged manifests and unreferenced layers sudo /opt/gitlab/embedded/bin/registry garbage-collect -m /var/opt/gitlab/registry/config.yml
このコマンドはガベージコレクションを開始します。完了するまでの時間は、レジストリデータサイズに比例します。
-
完了したら、
/etc/gitlab/gitlab.rb
、読み書きモードに戻してください:registry['storage'] = { 'filesystem' => { 'rootdirectory' => "<your_registry_storage_path>" }, 'maintenance' => { 'readonly' => { 'enabled' => false } } }
-
GitLab を保存して再設定します:
sudo gitlab-ctl reconfigure
スケジュールによるガベージコレクションの実行
レジストリのガベージコレクションは、レジストリが使用されていない週に定期的に実行するのが理想的です。最も簡単な方法は、週に一度定期的に実行する新しいcrontabジョブを追加することです。
/etc/cron.d/registry-garbage-collect
にファイルを作成します:
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# Run every Sunday at 04:05am
5 4 * * 0 root gitlab-ctl registry-garbage-collect
タグ付けされていないマニフェストと参照されていないレイヤーを削除するために、-m
フラグを追加するとよいでしょう。
ガベージコレクションの停止
ガベージコレクションの停止が予想される場合は、ガベージコレクションをダウンタイムなしで実行する で説明したように、手動でガベージコレクションを実行する必要があります。ガベージコレクションを停止するには、Control+Cを押します。
そうでなければ、中断するとgitlab-ctl
レジストリサービスがダウンしたままになる可能性が gitlab-ctl
あります。この場合、gitlab-ctl
システム上でガベージコレクションプロセスそのものを見つけ、 gitlab-ctl
コマンドによってレジストリサービスを再び立ち上げられるようにするgitlab-ctl
必要が gitlab-ctl
あります。
また、プロセスのマーク段階では、進行状況や結果を保存する方法はありません。blobが削除され始めると、永続的な処理が行われます。
GitLab とレジストリが別々のノードで実行されるように設定します(Linux パッケージのインストール)。
デフォルトでは、パッケージは両方のサービスが同じノード上で動作していることを前提としています。GitLabとレジストリを別々のノードで動作させるには、レジストリとGitLabで別々の設定が必要です。
レジストリの設定
GitLabとは別にレジストリを実行するために、/etc/gitlab/gitlab.rb
で設定するオプションを以下に示します:
-
registry['registry_http_addr']
デフォルトはプログラムで設定します。ウェブサーバ(またはLB)から到達可能である必要があります。 -
registry['token_realm']
デフォルトはプログラムで設定します。認証に使うエンドポイントを指定します。通常は GitLab URL です。このエンドポイントはユーザーによって到達可能である必要があります。 -
registry['http_secret']
ランダム文字列。状態を署名するためのランダムなデータで、改ざんを防ぐためにクライアントに保存されます。 -
registry['internal_key']
デフォルトは自動生成。GitLabがトークンに署名するために使用するキーの内容。キーはレジストリサーバで作成されますが、そこでは使用されません。 -
gitlab_rails['registry_key_path']
デフォルトはプログラムによって設定されます。これはinternal_key
の内容がディスクに書き込まれるパスです。 -
registry['internal_certificate']
デフォルトは自動的に生成されます。GitLabがトークンに署名するために使用する証明書の内容。 -
registry['rootcertbundle']
デフォルトはプログラムによって設定されます。証明書へのパス。internal_certificate
の内容がディスクに書き込まれるパスです。 -
registry['health_storagedriver_enabled']
デフォルトはプログラムで設定します。構成されたストレージドライバのヘルスチェックを有効にするかどうかを設定します。 -
gitlab_rails['registry_issuer']
デフォルト値。この設定はレジストリとGitLabで同じにする必要があります。
GitLab の設定
GitLabをレジストリから切り離して実行するために、/etc/gitlab/gitlab.rb
で設定するオプションを以下に示します:
-
gitlab_rails['registry_enabled']
をtrue
に設定する必要があります。 この設定は、レジストリ API リクエストを許可するように GitLab に合図を送ります。 -
gitlab_rails['registry_api_url']
デフォルトはプログラムで設定します。これは内部で使用されるレジストリURLで、ユーザーが操作する必要はありません。registry['registry_http_addr']
with scheme. -
gitlab_rails['registry_host']
例えば、registry.gitlab.example
。スキームなしのレジストリエンドポイントで、エンドユーザーに表示されるアドレスです。 -
gitlab_rails['registry_port']
.エンドユーザーに表示されるレジストリエンドポイントポート。 -
gitlab_rails['registry_issuer']
はレジストリ設定の発行者と一致しなければなりません。 -
gitlab_rails['registry_key_path']
レ ジ ス ト リ 側で証明書に一致す る キーへのパス。 -
gitlab_rails['internal_key']
GitLab がトークンの署名に使用するキーの内容。
GitLabコンテナレジストリのアーキテクチャ
GitLabレジストリはユーザーが自分のDockerイメージを保存するために使うものです。そのため、レジストリはクライアントフェイシング、つまりウェブサーバ(またはロードバランサ、略してLB)上に直接公開されます。
上の図で説明した流れです:
- ユーザーがクライアント上で
docker login registry.gitlab.example
を実行します。これはポート443でウェブサーバー(またはLB)に到達します。 - Webサーバは、レジストリバックエンドプールに接続します(デフォルトでは、ポート5000を使用)。ユーザーが有効なトークンを提供していないため、レジストリは 401 HTTP コードとトークンを取得するための URL (
token_realm
from Registry configuration) を返します。これは GitLab API を指しています。 - DockerクライアントはGitLab APIに接続し、トークンを取得します。
- APIはトークンをレジストリキーで署名し、Dockerクライアントに渡します。
- DockerクライアントはAPIから受け取ったトークンで再度ログインします。これでDockerイメージをプッシュしたりプルしたりできるようになります。
参考https://docs.docker.com/registry/spec/auth/token/
GitLabとレジストリ間の通信
レジストリには内部でユーザーを認証する方法がないので、GitLabに認証情報の検証を依存しています。レジストリとGitLabの接続はTLSで暗号化されています。鍵は GitLab がトークンに署名するために使い、証明書はレジストリがその署名を検証するために使います。デフォルトでは、すべてのインストールに対して自己署名証明書キーペアが生成されます。これは必要に応じて上書きすることができます。
GitLabはレジストリ秘密鍵を使ってレジストリとやり取りします。レジストリへのリクエストが発信されると、新しい短命(10分)の名前空間限定トークンが生成され、秘密鍵で署名されます。レジストリは、その署名が設定に指定されたレジストリ証明書と一致することを確認し、オペレーションを許可します。GitLabのバックグラウンドジョブ処理(Sidekiqを通して)もレジストリとやり取りします。これらのジョブはレジストリに直接話しかけて画像の削除を処理します。
サードパーティのレジストリからのマイグレーション
GitLabでの外部コンテナレジストリの使用はGitLab 15.8で非推奨となり、GitLab 16.0でサポート終了となりました。詳細は非推奨のお知らせをご覧ください。
GitLab 16.0ではインテグレーションは無効にはなっていませんが、デバッグやイシュー修正のサポートは提供されなくなりました。さらに、インテグレーションはもはや開発されておらず、新機能も強化されていません。サードパーティのレジストリ機能は、新しいGitLabコンテナレジストリバージョンがセルフマネージドで利用可能になった後、完全に削除されるかもしれません(エピック5521を参照)。GitLab Container Registryのみがサポートされる予定です。
このセクションでは、サードパーティレジストリから GitLab Container Registry にマイグレーションする管理者のためのガイダンスを示します。使用しているサードパーティのコンテナレジストリがここに記載されていない場合は、フィードバックイシューに使用例を記載してください。
以下で提供するすべての手順について、まずはテスト環境で試してみてください。本番環境で再現する前に、すべてが期待通りに動作することを確認してください。
Dockerディストリビューション・レジストリ
Docker Distribution RegistryはCNCFに寄贈され、現在はDistribution Registryとして知られています。このレジストリはGitLab Container Registryがベースにしているオープンソースの実装です。GitLabコンテナレジストリは、サポートされているすべてのストレージバックエンドを含め、ディストリビューションレジストリによって提供される基本的な機能と互換性があります。GitLab Container Registryにマイグレーションするには、このページの指示に従って、ディストリビューションレジストリと同じストレージバックエンドを使用することができます。GitLab Container Registryはディストリビューションレジストリと同じ設定を受け入れる必要があります。
トラブルシューティング
以下のセクションに入る前に、基本的なトラブルシューティングについて説明します:
-
DockerクライアントとGitLabサーバーのシステムクロックが(NTPなどで)同期されていることを確認してください。
-
S3-backedレジストリを使用している場合は、IAM権限とS3認証情報(リージョンを含む)が正しいか再確認してください。詳細については、サンプルのIAMポリシーを参照してください。
-
レジストリのログ (
/var/log/gitlab/registry/current
など) と GitLab のプロダクションログ (/var/log/gitlab/gitlab-rails/production.log
など) にエラーがないか確認しましょう。そこに手がかりがあるかもしれません。
コンテナレジストリでの自己署名証明書の使用
コンテナレジストリで自己署名証明書を使用している場合、CIジョブ中に以下のようなイシューが発生する可能性があります:
Error response from daemon: Get registry.example.com/v1/users/: x509: certificate signed by unknown authority
コマンドを実行するDockerデーモンは、認識されたCAによって署名された証明書を期待します。
GitLabはコンテナレジストリで自己署名証明書を使うことをサポートしていませんが、Dockerデーモンに自己署名証明書を信頼するように指示し、Dockerデーモンをマウントし、GitLab Runnerのconfig.toml
ファイルにprivileged = false
。privileged = true
の設定はDockerデーモンよりも優先されます:
[runners.docker]
image = "ruby:2.6"
privileged = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
これに関する追加情報:イシュー18239。
Docker ログインに失敗しました:信頼できないキーで署名されたトークン
レジストリが GitLabの認証に依存している場合 レジストリが有効なログイン試行の認証に失敗すると、次のようなエラーメッセージが表示されます:
# docker login gitlab.company.com:4567
Username: user
Password:
Error response from daemon: login attempt to https://gitlab.company.com:4567/v2/ failed with status: 401 Unauthorized
さらに具体的には、/var/log/gitlab/registry/current
のログファイルにこのようなメッセージが表示されます:
level=info msg="token signed by untrusted key with ID: "TOKE:NL6Q:7PW6:EXAM:PLET:OKEN:BG27:RCIB:D2S3:EXAM:PLET:OKEN""
level=warning msg="error authorizing context: invalid token" go.version=go1.12.7 http.request.host="gitlab.company.com:4567" http.request.id=74613829-2655-4f96-8991-1c9fe33869b8 http.request.method=GET http.request.remoteaddr=10.72.11.20 http.request.uri="/v2/" http.request.useragent="docker/19.03.2 go/go1.12.8 git-commit/6a30dfc kernel/3.10.0-693.2.2.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/19.03.2 \(linux\))"
GitLabはレジストリの認証トークンを暗号化するために、証明書キーペアの両側の内容を使用しています。このメッセージは、これらの内容が一致していないことを意味します。
どのファイルが使用されているか確認してください:
-
grep -A6 'auth:' /var/opt/gitlab/registry/config.yml
## Container Registry Certificate auth: token: realm: https://gitlab.my.net/jwt/auth service: container_registry issuer: omnibus-gitlab-issuer --> rootcertbundle: /var/opt/gitlab/registry/gitlab-registry.crt autoredirect: false
-
grep -A9 'Container Registry' /var/opt/gitlab/gitlab-rails/etc/gitlab.yml
## Container Registry Key registry: enabled: true host: gitlab.company.com port: 4567 api_url: http://127.0.0.1:5000 # internal address to the registry, is used by GitLab to directly communicate with API path: /var/opt/gitlab/gitlab-rails/shared/registry --> key: /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key issuer: omnibus-gitlab-issuer notification_secret:
これらのopenssl
コマンドの出力は一致するはずで、証明鍵と鍵のペアが一致していることを証明します:
/opt/gitlab/embedded/bin/openssl x509 -noout -modulus -in /var/opt/gitlab/registry/gitlab-registry.crt | /opt/gitlab/embedded/bin/openssl sha256
/opt/gitlab/embedded/bin/openssl rsa -noout -modulus -in /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key | /opt/gitlab/embedded/bin/openssl sha256
証明書の2つの断片が一致しない場合は、ファイルを削除し、gitlab-ctl reconfigure
を実行してペアを再生成します。ペアは、/etc/gitlab/gitlab-secrets.json
に既存の値がある場合は、それを使用して再作成されます。新しいペアを生成するには、gitlab-ctl reconfigure
を実行する前に、/etc/gitlab/gitlab-secrets.json
のregistry
セクションを削除します。
自動生成された自己署名ペアを独自の証明書で上書きし、その内容が一致していることを確認した場合は、/etc/gitlab/gitlab-secrets.json
の「レジストリ」セクションを削除して、gitlab-ctl reconfigure
を実行できます。
AWS S3 で大きなイメージをプッシュすると GitLab レジストリのエラーが発生します。
GitLab レジストリで AWS S3 を使用している場合、大きなイメージをプッシュするとエラーが発生することがあります。レジストリのログで以下のエラーを確認してください:
level=error msg="response completed with error" err.code=unknown err.detail="unexpected EOF" err.message="unknown error"
このエラーを解決するには、レジストリ設定でchunksize
を指定してください。25000000
(25 MB) と50000000
(50 MB) の間の値から始めてください。
-
/etc/gitlab/gitlab.rb
を編集します:registry['storage'] = { 's3' => { 'accesskey' => 'AKIAKIAKI', 'secretkey' => 'secret123', 'bucket' => 'gitlab-registry-bucket-AKIAKIAKI', 'chunksize' => 25000000 } }
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
config/gitlab.yml
を編集します:storage: s3: accesskey: 'AKIAKIAKI' secretkey: 'secret123' bucket: 'gitlab-registry-bucket-AKIAKIAKI' chunksize: 25000000
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
古いDockerクライアントのサポート
GitLabに同梱されているDockerコンテナレジストリは、デフォルトでschema1マニフェストを無効にします。古い Docker クライアント(1.9 以前)を使用している場合、イメージのプッシュでエラーが発生する可能性があります。詳しくはイシュー4145をご覧ください。
後方互換性のための設定オプションを追加することができます。
-
/etc/gitlab/gitlab.rb
を編集します:registry['compatibility_schema1_enabled'] = true
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
レジストリをデプロイしたときに作成した YAML 設定ファイルを編集します。次のスニペットを追加します:
compatibility: schema1: enabled: true
-
変更を反映させるためにレジストリを再起動します。
Docker接続エラー
Docker接続エラーは、グループ名、プロジェクト名、ブランチ名のいずれかに特殊文字が含まれている場合に発生する可能性があります。特殊文字には以下のようなものがあります:
- 先頭のアンダースコア
- 末尾ハイフン/ダッシュ
- ダブルハイフン/ダッシュ
これを回避するには、グループパスを変更したりプロジェクトパスを変更したりブランチ名を変更したりします。もうひとつの方法は、インスタンスレベルでこれを防ぐプッシュルールを作成することです。
画像のプッシュエラー
画像をプッシュしようとするとエラーや「リトライ」ループが発生するが、docker login
は正常に動作する場合、NGINXによってレジストリに転送されるヘッダに問題がある可能性があります。推奨されるNGINXのデフォルト設定ではこの問題が解決されるはずですが、SSLがサードパーティのリバースプロキシにオフロードされているカスタム設定では発生する可能性があります。
この問題はDockerプロジェクトのイシューで議論されており、簡単な解決策はレジストリで相対URLを有効にすることです。
-
/etc/gitlab/gitlab.rb
を編集します:registry['env'] = { "REGISTRY_HTTP_RELATIVEURLS" => true }
-
ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
-
レジストリをデプロイしたときに作成した YAML 設定ファイルを編集します。次のスニペットを追加します:
http: relativeurls: true
-
ファイルを保存してGitLab を再起動すると、変更が有効になります。
レジストリデバッグサーバーを有効にします。
コンテナレジストリデバッグサーバーを使用して、問題を診断できます。デバッグエンドポイントは、メトリクスと健全性を監視し、プロファイリングを実行できます。
オプションのデバッグサーバーは、gitlab.rb
設定でレジストリデバッグアドレスを設定することで有効にできます。
registry['debug_addr'] = "localhost:5001"
設定を追加した後、変更を適用するためにGitLabを再設定してください。
curl を使ってデバッグサーバーにデバッグ出力を要求します:
curl "localhost:5001/debug/health"
curl "localhost:5001/debug/vars"
古いスキーマv1 Dockerイメージへのアクセス
schema V1イメージマニフェストを含む、DockerレジストリAPI V1のサポートが終了しました:
GitLabコンテナレジストリからv1イメージをプッシュまたはプルすることができなくなりました。
GitLab 13.9へのアップグレードに先立ち、GitLab Container Registryにv1イメージをアップグレード(Dockerが推奨する手順)しなかった場合、これらのイメージにはアクセスできなくなります。これらのイメージをプルしようとすると、このエラーが表示されます:
Error response from daemon: manifest invalid: Schema 1 manifest not supported
セルフマネージド GitLab インスタンスでは、GitLab コンテナレジストリをv3.0.0-gitlab
よりも低いバージョンに一時的にダウングレードすることで、これらのイメージへのアクセスを取り戻すことができます。これらのイメージへのアクセスを取り戻すには、以下の手順に従ってください:
- コンテナレジストリを
v2.13.1-gitlab
にダウングレードします。 - v1イメージをアップグレードします。
- コンテナレジストリのダウングレードを元に戻します。
イメージのアップグレード処理中に、レジストリを読み取り専用モードにする必要はありません。v3.0.0-gitlab
以降に導入された新機能に依存していないことを確認してください。こ の よ う な機能は、 ア ッ プグ レー ド 処理中は利用で き ません。詳しくはレジストリの変更履歴をご覧ください。
以下の項では、各インストール方法の詳細について説明します。
Helmチャートのインストールの場合:
-
image.tag
の設定パラメータをv2.13.1-gitlab
で上書きしてください。 - 再起動します。
- イメージのアップグレード)の手順を実行します。
-
image.tag
パラメータを以前の値に戻します。
その他のレジストリ設定の変更は必要ありません。
Linuxパッケージ・インストールの場合:
-
GitLab 13.9+に同梱されているレジストリ・バイナリを
v3.0.0-gitlab
より前のものに一時的に置き換えてください。そのためには、v2.13.1-gitlab
のような、GitLabコンテナ・レジストリ用のDockerイメージの前のバージョンを引っ張ってきてください。そして、このイメージの内部から/bin/registry
にあるregistry
バイナリを取得します:id=$(docker create registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:v2.13.1-gitlab) docker cp $id:/bin/registry registry-2.13.1-gitlab docker rm $id
-
/opt/gitlab/embedded/bin/registry
にある Linux パッケージのインストールに組み込まれているバイナリをregistry-2.13.1-gitlab
に置き換えてください。Linux パッケージに埋め込まれている元のバイナリをバックアップしておき、イメージのアップグレード手順を実行した後に復元してください。バイナリを置き換える前にレジストリサービスを停止し、置き換えた直後にレジストリサービスを開始する必要があります。レジストリ設定の変更は必要ありません。
registry
のバイナリを探し、Linux パッケージのインストールで説明したように、v3.0.0-gitlab
から取得したバイナリに一時的に置き換えてください。必ず元のレジストリバイナリをバックアップしておき、イメージのアップグレード手順を実行した後で復元してください。
イメージのアップグレード
v1イメージをアップグレードするには、Dockerが推奨する手順に従ってください。最も簡単な方法は、v1.12以上のDockerクライアントを使用して、イメージをプルしてレジストリに再度プッシュすることです。Dockerはイメージをレジストリにプッシュする前に自動的に変換します。これでv1イメージがv2イメージとして利用できるようになります。
名前が空のタグ
AWS DataSyncを使用してレジストリデータを S3 バケットへ、または S3 バケット間でコピーする場合、宛先バケット内の各コンテナリポジトリのルートパスに空のメタデータオブジェクトが作成されます。これにより、レジストリはそのようなファイルを GitLab UI や API に名前のないタグとして表示されると解釈します。詳細については、このイシューを参照してください。
この問題を解決するには、2つのうちの1つを行います:
-
AWS CLI
rm
コマンドを使用して、影響を受ける各リポジトリのルートから空のオブジェクトを削除します。末尾の/
に特に注意し、--recursive
オプションを使用しないようにしてください:aws s3 rm s3://<bucket>/docker/registry/v2/repositories/<path to repository>/
-
AWS CLI
sync
コマンドを使用して、レジストリデータを新しいバケットにコピーし、それを使用するようにレジストリを設定します。これにより、空のオブジェクトが残ります。
高度なトラブルシューティング
具体的な例を使って、S3のセットアップに関する問題を診断する方法を説明します。
クリーンアップポリシーの調査
クリーンアップポリシーでタグが削除されたり削除されなかったりした理由がわからない場合は、Railsコンソールから以下のスクリプトを実行してポリシーを一行ずつ実行してください。これはポリシーの問題を診断するのに役立ちます。
repo = ContainerRepository.find(<project_id>)
policy = repo.project.container_expiration_policy
tags = repo.tags
tags.map(&:name)
tags.reject!(&:latest?)
tags.map(&:name)
regex_delete = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex}\\z")
regex_retain = ::Gitlab::UntrustedRegexp.new("\\A#{policy.name_regex_keep}\\z")
tags.select! { |tag| regex_delete.match?(tag.name) && !regex_retain.match?(tag.name) }
tags.map(&:name)
now = DateTime.current
tags.sort_by! { |tag| tag.created_at || now }.reverse! # Lengthy operation
tags = tags.drop(policy.keep_n)
tags.map(&:name)
older_than_timestamp = ChronicDuration.parse(policy.older_than).seconds.ago
tags.select! { |tag| tag.created_at && tag.created_at < older_than_timestamp }
tags.map(&:name)
- スクリプトは削除するタグのリストを作成します (
tags
)。 -
tags.map(&:name)
は削除するタグのリストを表示します。これは長いオペレーションになるかもしれません。 - 各フィルターの後、
tags
のリストをチェックし、破棄するタグが含まれているかどうかを確認します。
プッシュ中の予期しない403エラー
ユーザーが S3-backed レジストリを有効にしようとしました。docker login
。しかし、画像をプッシュすると、出力が表示されました:
The push refers to a repository [s3-testing.myregistry.com:5050/root/docker-test/docker-image]
dc5e59c14160: Pushing [==================================================>] 14.85 kB
03c20c1a019a: Pushing [==================================================>] 2.048 kB
a08f14ef632e: Pushing [==================================================>] 2.048 kB
228950524c88: Pushing 2.048 kB
6a8ecde4cc03: Pushing [==> ] 9.901 MB/205.7 MB
5f70bf18a086: Pushing 1.024 kB
737f40e80b7f: Waiting
82b57dbc5385: Waiting
19429b698a22: Waiting
9436069b92a3: Waiting
error parsing HTTP 403 response body: unexpected end of JSON input: ""
このエラーは曖昧で、403がGitLab Railsアプリケーションから来ているのか、Dockerレジストリから来ているのか、それとも他の何かから来ているのかがはっきりしません。この場合、ログインが成功したことはわかっているので、おそらくクライアントとレジストリ間の通信を調べる必要があるでしょう。
Dockerクライアントとレジストリ間のREST APIはDockerドキュメントに記載されています。通常、Wiresharkやtcpdumpを使ってトラフィックをキャプチャし、どこで問題が発生したかを確認します。しかし、Dockerクライアントとサーバ間の通信はすべてHTTPSで行われるため、秘密鍵がわかっていてもトラフィックを素早く復号化するのは少々困難です。代わりに何ができるでしょうか?
1つの方法は、安全でないレジストリを設定することでHTTPSを無効にすることです。これはセキュリティホールを引き起こす可能性があり、ローカルでのテストにのみ推奨されます。本番システムでこのようなことができない、あるいはしたくない場合は、Man-in-the-Middle Proxyの略であるmitmproxyを使うという方法もあります。
mitmproxy
mitmproxyを使うと、クライアントとサーバーの間にプロキシを置き、 すべてのトラフィックを検査することができます。この機能を使うには、システムが mitmproxy SSL 証明書を信頼する必要があります。
以下のインストール手順は、Ubuntu を実行していることを前提としています:
- mitmproxy をインストールします。
-
mitmproxy --port 9000
を実行して証明書を生成します。CTRL-C を入力して終了します。 -
~/.mitmproxy
から証明書をシステムにインストールします:sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy-ca-cert.crt sudo update-ca-certificates
成功すると、証明書が追加されたことが出力されます:
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.
証明書が正しくインストールされていることを確認するには、以下を実行します:
mitmproxy --port 9000
このコマンドは、ポート9000
で mitmproxy を実行します。別のウィンドウで次のコマンドを実行します:
curl --proxy "http://localhost:9000" "https://httpbin.org/status/200"
すべてが正しく設定されていれば、mitmproxy ウィンドウに情報が表示され、curl コマンドによるエラーは発生しません。
プロキシを使用した Docker デーモンの実行
Dockerがプロキシ経由で接続するには、適切な環境変数でDockerデーモンを起動する必要があります。最も簡単な方法は、Dockerをシャットダウンしてから(例えばsudo initctl stop docker
)、Dockerを手動で実行することです。rootで実行します:
export HTTP_PROXY="http://localhost:9000"
export HTTPS_PROXY="https://localhost:9000"
docker daemon --debug
このコマンドはDockerデーモンを起動し、すべての接続をmitmproxy経由でプロキシします。
Docker クライアントの実行
mitmproxyとDockerが起動したので、サインインしてコンテナイメージをプッシュしてみましょう。これを行うには root として実行する必要があるかもしれません。例えば
docker login s3-testing.myregistry.com:5050
docker push s3-testing.myregistry.com:5050/root/docker-test/docker-image
上の例では、mitmproxy ウィンドウに次のようなトレースが表示されます:
上の画像は
- 最初のPUTリクエストは201ステータスコードで問題なく通過しました。
- 201はクライアントをS3バケットにリダイレクトしました。
- AWSバケットへのHEADリクエストは403 Unauthorizedをレポーターしました。
これは何を意味するのでしょうか?これは、S3ユーザーがHEADリクエストを実行するための正しい権限を持っていないことを強く示唆しています。解決策:IAM権限をもう一度確認してください。正しい権限が設定されると、エラーは消えます。
gitlab-registry.key
が見つからないため、コンテナリポジトリの削除ができません。
GitLab インスタンスのコンテナレジストリを無効にして、コンテナリポジトリを持つプロジェクトを削除しようとすると、以下のエラーが発生します:
Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key
この場合は、以下の手順に従ってください:
-
gitlab.rb
のコンテナレジストリのインスタンスワイド設定を一時的に有効にします:gitlab_rails['registry_enabled'] = true
- ファイルを保存し、変更を有効にするためにGitLab を再設定してください。
- もう一度削除を試してください。
それでも一般的な方法でリポジトリを削除できない場合は、GitLab Rails コンソールを使ってプロジェクトを強制的に削除することができます:
# Path to the project you'd like to remove
prj = Project.find_by_full_path(<project_path>)
# The following will delete the project's container registry, so be sure to double-check the path beforehand!
if prj.has_container_registry_tags?
prj.container_repositories.each { |p| p.destroy }
end