コンテナイメージの依存プロキシ
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
コンテナイメージ用のGitLab依存プロキシは、頻繁にアクセスするアップストリームイメージに使用可能なローカルプロキシです。
CI/CDの場合、依存プロキシはリクエストを受信し、プルスルーキャッシュとして機能し、レジストリからアップストリームイメージを返します。
前提要件
コンテナイメージの依存プロキシを使用するには、GitLabインスタンスで有効にする必要があります。デフォルトで有効になっていますが、管理者はオフにすることができます。
サポートされているイメージとパッケージ
次のイメージとパッケージがサポートされています。
| イメージ/パッケージ | GitLabバージョン |
|---|---|
| Docker | 14.0+ |
予定されている追加機能のリストについては、方向性のページをご覧ください。
グループの依存プロキシを有効または無効にする
グループの依存プロキシを有効または無効にするには、次の手順に従います:
- 左側のサイドバーで、検索または移動先を選択して、グループを見つけます。
- 設定 > パッケージとレジストリを選択します。
- 依存プロキシセクションを展開します。
- プロキシを有効にするには、Enable Proxy(プロキシを有効にする)をオンにします。オフにするには、切替をオフにします。
この設定は、グループの依存プロキシにのみ影響します。GitLabインスタンス全体の依存プロキシのオン/オフを切り替えることができるのは管理者のみです。
コンテナイメージの依存プロキシを表示する
コンテナイメージの依存プロキシを表示するには、次の手順に従います:
- 左側のサイドバーで、検索または移動先を選択して、グループを見つけます。
- 操作 > 依存プロキシを選択します。
依存プロキシはプロジェクトでは利用できません。
Dockerイメージに依存プロキシを使用する
GitLabをDockerイメージのソースとして使用できます。
前提要件:
- イメージはDocker Hubに保存されている必要があります。
コンテナイメージの依存プロキシで認証する
コンテナイメージの依存プロキシは、グループに関連付けられた領域にDockerイメージを保存するため、認証する必要があります。
プライベートレジストリからイメージを使用する手順に従いますが、registry.example.com:5000を使用する代わりに、ポートgitlab.example.comなしでGitLabドメインを使用します。
管理者モードは、コンテナイメージの依存プロキシで認証する際に適用されません。管理者モードが有効になっている管理者が、admin_modeスコープなしでパーソナルアクセストークンを作成した場合、管理者モードが有効になっていても、そのトークンは機能します。
たとえば、手動でサインインするには次を実行します:
echo "$CONTAINER_REGISTRY_PASSWORD" | docker login gitlab.example.com --username my_username --password-stdin次のものを使用して認証できます:
- GitLabユーザー名とパスワード。
- GitLab CLI。
- パーソナルアクセストークン。
- グループデプロイトークン。
- グループのグループアクセストークン。
トークンには、次のいずれかのスコープを設定する必要があります:
api: APIへのフルアクセスを許可します。read_registry: コンテナレジストリへの読み取り専用アクセスを許可します。write_registry: コンテナレジストリへの読み取り/書き込みアクセスを許可します。read_virtual_registry: 依存プロキシを介したコンテナイメージへの読み取り専用アクセス(プル)を許可します。write_virtual_registry: 依存プロキシを介したコンテナイメージへの読み取りアクセス(プル)、書き込みアクセス(プッシュ)、および削除アクセスを許可します。
コンテナイメージの依存プロキシで認証する場合、次の条件を満たす必要があります:
read_virtual_registryスコープを持つトークンには、read_registryスコープも含まれている必要があります。write_virtual_registryスコープを持つトークンには、write_registryスコープも含まれている必要があります。
パーソナルアクセストークンまたはユーザー名とパスワードを使用してコンテナイメージの依存プロキシにアクセスするユーザーは、イメージのプル元のグループに対して少なくともゲストロールを持っている必要があります。
コンテナイメージの依存プロキシは、Docker v2トークン認証フローに従い、プルリクエストに使用するJWTをクライアントに発行します。認証の結果として発行されるJWTは、一定時間後に期限切れになります。トークンの期限が切れると、ほとんどのDockerクライアントは認証情報を保存し、それ以上の操作なしに自動的に新しいトークンを要求します。
トークンの有効期限を設定することも可能です。GitLab.comでは、有効期限は15分です。
SAML SSO
SSOの適用が有効になっている場合、ユーザーはコンテナイメージの依存プロキシを介してイメージをプルする前に、SSOを介してサインインする必要があります。
SSOの適用は自動マージにも影響します。自動マージがトリガーされる前にSSOセッションが期限切れになった場合、マージパイプラインは依存プロキシを介してイメージをプルできません。
CI/CD内で認証する
Runnerはコンテナイメージの依存プロキシに自動的にサインインします。依存プロキシを介してプルするには、定義済み変数のいずれかを次のように使用します:
CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIXは、トップレベルグループを介してプルします。CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIXは、サブグループ、またはプロジェクトが存在する直接グループを介してプルします。
最新のalpineイメージをプルする例は、次のとおりです:
# .gitlab-ci.yml
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine:latest使用できる追加の定義済みCI/CD変数もあります。例は次のとおりです:
CI_DEPENDENCY_PROXY_USER: 依存プロキシにログインするためのCI/CDユーザー。CI_DEPENDENCY_PROXY_PASSWORD: 依存プロキシにログインするためのCI/CDパスワードCI_DEPENDENCY_PROXY_SERVER: 依存プロキシにログインするためのサーバー。CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX: トップレベルグループから依存プロキシを介してイメージをプルするためのイメージプレフィックス。CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX: プロジェクトが属する直接グループまたはサブグループから依存プロキシを介してイメージをプルするためのイメージプレフィックス。
CI_DEPENDENCY_PROXY_SERVER、CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX、およびCI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIXにはサーバーポートが含まれます。依存プロキシパスを明示的に含める場合、ポートを含めずに依存プロキシに手動でログインしていない限り、次のようにポートを含める必要があります:
docker pull gitlab.example.com:443/my-group/dependency_proxy/containers/alpine:latest依存プロキシを使用してイメージをビルドする場合の例:
# Dockerfile
FROM gitlab.example.com:443/my-group/dependency_proxy/containers/alpine:latest# .gitlab-ci.yml
image: docker:20.10.16
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
services:
- docker:20.10.16-dind
build:
image: docker:20.10.16
before_script:
- echo "$CI_DEPENDENCY_PROXY_PASSWORD" | docker login $CI_DEPENDENCY_PROXY_SERVER -u $CI_DEPENDENCY_PROXY_USER --password-stdin
script:
- docker build -t test .カスタムCI/CD変数を使用して、パーソナルアクセストークンまたはデプロイトークンを保存およびアクセスすることもできます。
Docker Hubで認証する
デフォルトでは、依存プロキシはDocker Hubからイメージをプルするときに認証情報を使用しません。Docker Hubの認証情報をトークンで設定できます。
Docker Hubでの認証には、次のものを使用できます:
- Docker Hubのユーザー名とパスワード。
- この方法は、シングルサインオン(SSO)を強制するDocker Hub組織とは互換性がありません。
- Docker Hubのパーソナルアクセストークン。
- Docker Hubの組織アクセストークン。
認証情報を設定する
グループの依存プロキシに対してDocker Hubの認証情報を設定するには、次の手順に従います:
左側のサイドバーで、検索または移動先を選択して、グループを見つけます。
設定 > パッケージとレジストリを選択します。
依存プロキシセクションを展開します。
Enable Proxy(プロキシを有効にする)をオンにします。
Docker Hubでの認証で、次のように認証情報を入力します:
- アイデンティティには、ユーザー名または組織名(組織アクセストークン用)を入力します。
- シークレットには、パスワード、パーソナルアクセストークン、または組織アクセストークンを入力します。
両方のフィールドを入力するか、両方を空のままにする必要があります。両方のフィールドが空である場合、Docker Hubへのリクエストは認証されないままになります。
GraphQL APIを使用して認証情報を設定する
GraphQL APIを使用して、依存プロキシの設定でDocker Hubの認証情報を設定するには、次の手順に従います:
GraphiQLに移動します:
- GitLab.comの場合は、
https://gitlab.com/-/graphql-explorerを使用します。 - GitLab Self-Managedの場合は、
https://gitlab.example.com/-/graphql-explorerを使用します。
- GitLab.comの場合は、
GraphiQLで、次のミューテーションを入力します:
mutation { updateDependencyProxySettings(input: { enabled: true, identity: "<identity>", secret: "<secret>", groupPath: "<group path>" }) { dependencyProxySetting { enabled identity } errors } }各設定項目の意味は次のとおりです:
<identity>は、ユーザー名(パスワードまたはパーソナルアクセストークン用)または組織名(組織アクセストークン用)です。<secret>は、パスワード、パーソナルアクセストークン、または組織アクセストークンです。<group path>は、依存プロキシがあるグループのパスです。
Play(再生)を選択します。
結果ペインでエラーがないか確認します。
認証情報を検証する
依存プロキシで認証したら、Dockerイメージをプルして、Docker Hubの認証情報を次のように確認します:
docker pull gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest認証が成功すると、Docker Hub使用状況ダッシュボードにアクティビティーが表示されます。
Dockerイメージを依存プロキシキャッシュに保存する
Dockerイメージを依存プロキシストレージに保存するには、次の手順に従います:
左側のサイドバーで、検索または移動先を選択して、グループを見つけます。
操作 > 依存プロキシを選択します。
依存プロキシのイメージプレフィックスをコピーします。
次のコマンドのいずれかを使用します。これらの例では、イメージは
alpine:latestです。ダイジェストでイメージをプルして、プルするイメージのバージョンを正確に指定することもできます。
イメージを
.gitlab-ci.ymlファイルに追加して、タグでイメージをプルします:image: gitlab.example.com/groupname/dependency_proxy/containers/alpine:latestイメージを
.gitlab-ci.ymlファイルに追加して、ダイジェストでイメージをプルします:image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine@sha256:c9375e662992791e3f39e919b26f510e5254b42792519c180aad254e6b38f4dcDockerイメージを手動でプルします:
docker pull gitlab.example.com/groupname/dependency_proxy/containers/alpine:latestURLを
Dockerfileに追加します:FROM gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest
GitLabはDocker HubからDockerイメージをプルし、blobをGitLabサーバーにキャッシュします。次回同じイメージをプルすると、GitLabはDocker Hubからイメージに関する最新情報を取得しますが、GitLabサーバーから既存のblobを提供します。
ストレージ使用量を削減する
コンテナイメージの依存プロキシでストレージ使用量を削減する方法については、依存プロキシのストレージ使用量を削減するを参照してください。
Docker Hubのレート制限と依存プロキシ
依存プロキシを使用してDocker Hubのレート制限を回避する方法をご覧ください。
Docker Hubは、プルにレート制限を適用します。GitLabのCI/CD設定でDocker Hubからのイメージを使用している場合、ジョブが実行されるたびにプルとしてカウントされることがあります。この制限を回避するために、代わりに依存プロキシキャッシュからイメージをプルできます。
イメージをプルすると(docker pullのようなコマンドを使用するか、.gitlab-ci.ymlファイルでimage: foo:latestを使用)、Dockerクライアントはリクエストのコレクションを作成します:
- イメージマニフェストがリクエストされます。マニフェストには、イメージのビルド方法に関する情報が含まれています。
- マニフェストを使用して、Dockerクライアントは(blobとも呼ばれる)レイヤーのコレクションを1つずつリクエストします。
Docker Hubのレート制限は、マニフェストに対するGETリクエストの数に基づいています。依存プロキシは、特定イメージのマニフェストとblobの両方をキャッシュするため、再度リクエストするときにDocker Hubに接続する必要はありません。
キャッシュされたタグ付きイメージが古くなっているかどうかをGitLabが確認する方法
alpine:latestのようなイメージタグを使用している場合、イメージは時間の経過とともに変化します。変更されるたびに、マニフェストには、リクエストするblobに関するさまざまな情報が含まれます。依存プロキシは、マニフェストが変更されるたびに新しいイメージをプルするのではなく、マニフェストが古くなった場合にのみチェックします。
Dockerは、イメージマニフェストに対するHEADリクエストをレート制限にカウントしません。alpine:latestに対してHEADリクエストを行い、ヘッダーで返されるダイジェスト(チェックサム)値を表示し、マニフェストが変更されたかどうかを判断できます。
依存プロキシは、すべてのリクエストをHEADリクエストから開始します。マニフェストが古くなっている場合にのみ、新しいイメージがプルされます。
たとえば、パイプラインが5分ごとにnode:latestをプルする場合、依存プロキシはイメージ全体をキャッシュし、node:latestが変更された場合にのみ更新します。そのため、6時間でイメージに対して(Docker Hubのレート制限を超える量である)360件のリクエストを行う代わりに、(マニフェストがその間に変更されない限りは)プルリクエストを1回行います。
Docker Hubのレート制限を確認する
Docker Hubへのリクエスト数と残りのリクエスト数が気になる場合は、Runnerから、またはCI/CDスクリプトで次のコマンドを実行できます:
# Note, you must have jq installed to run this command
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq --raw-output .token) && curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1 | grep --ignore-case RateLimit
...出力は次のようになります:
RateLimit-Limit: 100;w=21600
RateLimit-Remaining: 98;w=21600この例では、6時間で合計100回のプル制限があり、残り98回プルが可能であることを示しています。
CI/CDジョブでレート制限を確認する
この例は、jqとcurlがインストールされたイメージを使用するGitLab CI/CDジョブを示しています:
hub_docker_quota_check:
stage: build
image: alpine:latest
tags:
- <optional_runner_tag>
before_script: apk add curl jq
script:
- |
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq --raw-output .token) && curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1トラブルシューティング
認証エラー: 「HTTP Basic: Access Denied」
依存プロキシに対して認証するときにHTTP Basic: Access deniedエラーが発生した場合は、2要素認証のトラブルシューティングガイドを参照してください。
依存プロキシの接続エラー
サービスエイリアスが設定されていない場合、docker:20.10.16イメージはdindサービスを見つけることができず、次のようなエラーがスローされます:
error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such hostこれは、次のようにDockerサービスのサービスエイリアスを設定することで解決できます:
services:
- name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:18.09.7-dind
alias: dockerCI/CDジョブから依存プロキシへの認証時の問題
GitLab Runnerは、依存プロキシに対して自動的に認証を行います。ただし、基盤となるDockerエンジンは、引き続き承認解決プロセスの対象となります。
認証メカニズムの設定ミスにより、HTTP Basic: Access deniedおよび403: Access forbiddenエラーが発生する可能性があります。
ジョブログで、依存プロキシに対する認証に使用される認証メカニズムを表示できます:
Authenticating with credentials from $DOCKER_AUTH_CONFIGAuthenticating with credentials from /root/.docker/config.jsonAuthenticating with credentials from job payload (GitLab Registry)想定される認証メカニズムを使用していることを確認してください。
イメージのプル時のNot Foundまたは404エラー
これらのエラーは、ジョブを実行しているユーザーが、依存プロキシグループに対して最低限のゲストロールさえ持っていないことを示している可能性があります:
ERROR: gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest: not found failed to solve with frontend dockerfile.v0: failed to create LLB definition: gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest: not foundERROR: Job failed: failed to pull image "gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest" with specified policies [always]: Error response from daemon: error parsing HTTP 404 response body: unexpected end of JSON input: "" (manager.go:237:1s)
Access deniedと同様のケースでエラーメッセージを改善するための作業の詳細については、イシュー354826を参照してください。
依存プロキシからイメージを実行するときのexec format error
この問題はGitLab 16.3で解決されました。16.2以前のGitLab Self-Managedインスタンスの場合は、インスタンスを16.3に更新するか、以下に記載されている回避策を使用できます。
このエラーは、GitLab 16.2以前のARMベースのDockerインストールで依存プロキシを使用しようとすると発生します。依存プロキシは、特定のタグを持つイメージをプルするときに、x86_64アーキテクチャのみをサポートします。
回避策として、イメージのSHA256を指定して、依存プロキシに別のアーキテクチャを強制的にプルさせることができます:
docker pull ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/library/docker:20.10.3@sha256:bc9dcf5c8e5908845acc6d34ab8824bca496d6d47d1b08af3baf4b3adb1bd8feこの例では、bc9dcf5c8e5908845acc6d34ab8824bca496d6d47d1b08af3baf4b3adb1bd8feはARMベースのイメージのSHA256です。
バックアップを復元後のMissingFileエラー
MissingFileまたはCannot read fileエラーが発生した場合、バックアップアーカイブにgitlab-rails/shared/dependency_proxy/の内容が含まれていないことが原因である可能性があります。
この既知の問題を解決するには、rsync、scp、または同様のツールを使用して、影響を受けるファイルまたはgitlab-rails/shared/dependency_proxy/フォルダー構造全体を、バックアップのソースとなったGitLabインスタンスからコピーできます。
データが不要な場合は、次のコマンドでデータベースエントリを削除できます:
gitlab-psql -c "DELETE FROM dependency_proxy_blobs; DELETE FROM dependency_proxy_blob_states; DELETE FROM dependency_proxy_manifest_states; DELETE FROM dependency_proxy_manifests;"