- 前提条件
- グループの依存プロキシの有効化または無効化
- 依存プロキシを見る
- Dockerイメージには依存プロキシを使用します。
- ストレージ使用量の削減
- Docker Hubのレート制限と依存プロキシ
- トラブルシューティング
依存プロキシ
GitLab 依存プロキシは、頻繁にアクセスするアップストリームイメージに使用できるローカルプロキシです。
CI/CD の場合、依存プロキシはリクエストを受けてレジストリからアップストリームイメージを返し、プルスルーキャッシュとして機能します。
前提条件
依存プロキシを使うには、GitLabインスタンスで有効になっている必要があります。デフォルトでは有効になっていますが、管理者はオフにすることができます。
サポートされているイメージとパッケージ
以下のイメージとパッケージがサポートされています。
イメージ/パッケージ | GitLabバージョン |
---|---|
Docker | 11.11+ |
今後の追加予定については、ディレクションページをご覧ください。
グループの依存プロキシの有効化または無効化
GitLab 15.0 で必須ロールが開発者からメンテナーに変更されました。
グループの依存プロキシを有効または無効にするには:
- 左のサイドバーで、Search(検索)を選択するか、Go to(移動)を選択してグループを探します。
- 設定 > パッケージとレジストリを選択します。
- 依存プロキシ]セクションを展開します。
- プロキシを有効にするには、[プロキシを有効にする] をオンにします。オフにするには、トグルをオフにします。
この設定はグループの依存プロキシにのみ影響します。GitLab インスタンス全体の依存プロキシのオン/オフを切り替えることができるのは管理者のみです。
依存プロキシを見る
依存プロキシを表示します:
- 左のサイドバーで、Search(検索)を選択するか、Go to(移動)を選択してグループを探します。
- オペレーション]→[依存プロキシ]を選択します。
依存プロキシはプロジェクトでは使用できません。
Dockerイメージには依存プロキシを使用します。
DockerイメージのソースとしてGitLabを使うことができます。
前提条件:
- イメージはDocker Hubに保存する必要があります。
依存プロキシによる認証
依存プロキシはあなたのグループに関連付けられたスペースにDockerイメージを保存するため、依存プロキシに対して認証を行う必要があります。
非公開レジストリからイメージを使用する手順に従ってください。ただし、registry.example.com:5000
を使用する代わりに、ポートgitlab.example.com
を使用せずに GitLab ドメインを使用してください。
例えば、手動でサインインする場合:
docker login gitlab.example.com --username my_username --password my_password
を使用して認証できます:
- GitLab のユーザー名とパスワード。
- スコープを
read_registry
とwrite_registry
に設定した個人アクセストークン。 - スコープが
read_registry
およびwrite_registry
に設定されたグループデプロイトークン。 - スコープが
read_registry
およびwrite_registry
に設定された、グループのアクセストークン。
個人アクセストークンまたはユーザ名とパスワードを使用して依存プロキシにアクセスするユーザは、イメージをプルするグループのゲストロール以上を持っている必要があります。
依存プロキシはDocker v2のトークン認証フローに従い、プルリクエストに使用するJWTをクライアントに発行します。認証の結果発行されたJWTは、しばらくすると失効します。トークンの有効期限が切れると、ほとんどのDockerクライアントは認証情報を保存し、それ以上アクションを起こさなくても自動的に新しいトークンを要求します。
トークンの有効期限は設定可能です。GitLab.comでは、有効期限は15分です。
SAML SSO
SSO が有効になっている場合、ユーザーは依存プロキシ経由でイメージをプルする前に、SSO でサインインする必要があります。
CI/CD 内での認証
ランナーは自動的に依存プロキシにサインインします。依存プロキシを経由するには、定義済みの変数のいずれかを使用します:
-
CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX
を使用します。 -
CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX
は、プロジェクトが存在するサブグループ、または直接のグループを通してプルします。
例:最新のアルペン画像をプル
# .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:
- docker login -u $CI_DEPENDENCY_PROXY_USER -p $CI_DEPENDENCY_PROXY_PASSWORD $CI_DEPENDENCY_PROXY_SERVER
script:
- docker build -t test .
カスタム CI/CD 変数を使用して、個人のアクセストークンやデプロイトークンを保存したりアクセスしたりすることもできます。
依存プロキシキャッシュへのDockerイメージの保存
Docker イメージを依存プロキシストレージに保存します:
- 左のサイドバーで、Search(検索)を選択するか、Go to(移動)を選択してグループを探します。
- オペレーション]→[依存プロキシ]を選択します。
- 依存プロキシ画像のプレフィックスをコピーします。
- 以下のコマンドのいずれかを使用します。これらの例では、イメージは
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:c9375e662992791e3f39e919b26f510e5254b42792519c180aad254e6b38f4dc
-
手動でDockerイメージをプルします:
docker pull gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest
-
Dockerfile
にURLを追加します:FROM gitlab.example.com/groupname/dependency_proxy/containers/alpine:latest
-
GitLabはDocker HubからDockerイメージをプルし、GitLabサーバにblobをキャッシュします。次に同じイメージをプルするとき、GitLabはDocker Hubからイメージの最新情報を取得しますが、GitLabサーバから既存のblobを提供します。
ストレージ使用量の削減
依存プロキシで使用するストレージを削減する方法については、「依存プロキシのストレージ使用量を削減する」を参照してください。
Docker Hubのレート制限と依存プロキシ
GitLab 13.7 で導入されました。
Docker Hubのレート制限を回避するための依存プロキシの使い方をご覧ください。
2020年11月、DockerはDocker Hubからのプルリクエストにレート制限を導入しました。GitLabCI/CD設定でDocker Hubからのイメージを使用している場合、ジョブが実行されるたびにプルリクエストとしてカウントされる可能性があります。この制限を回避するために、代わりに依存プロキシキャッシュからイメージをプルすることができます。
イメージをプルすると(docker pull
や、.gitlab-ci.yml
ファイルではimage: foo:latest
のようなコマンドを使用します)、Docker クライアントはリクエストのコレクションを作成します:
- イメージマニフェストが要求されます。マニフェストには、イメージのビルド方法に関する情報が含まれています。
- マニフェストを使用して、Dockerクライアントはブロブとも呼ばれるレイヤーのコレクションを1つずつ要求します。
Docker Hubのレート制限は、マニフェストに対するGETリクエスト数に基づいています。依存プロキシは指定されたイメージのマニフェストとブロブの両方をキャッシュするため、再度要求する際にDocker Hubに連絡する必要はありません。
GitLabは、キャッシュされたタグ付きイメージが古いかどうかをどのように知るのですか?
alpine:latest
のような画像タグを使っている場合、画像は時間とともに変化します。変更されるたびに、マニフェストにはリクエストするブロブに関する異なる情報が含まれます。依存プロキシは、マニフェストが変更されるたびに新しいイメージをプルするのではなく、マニフェストが古くなったときにのみチェックします。
Dockerはイメージマニフェストに対するHEADリクエストをレート制限にカウントしません。alpine:latest
に対して HEAD リクエストを行い、ヘッダで返されるダイジェスト(チェックサム)値を表示して、マニフェストが変更されたかどうかを判断できます。
依存プロキシはすべてのリクエストを HEAD リクエストで開始します。マニフェストが古くなった場合、そのときだけ新しいイメージがプルされます。
例えば、パイプラインがnode:latest
5分ごとに node:latest
プルする場合node:latest
、依存プロキシはイメージ全体をキャッシュし、 node:latest
変更がnode:latest
あった場合のみ更新 node:latest
します。そのため、6時間に360回のイメージのプルリクエストがある(Docker Hubのレート制限を超える)代わりに、その間にマニフェストが変更されない限り、プルリクエストは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: アクセス拒否”
依存プロキシに対する認証時に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: docker
CI/CDジョブから依存プロキシへの認証時のイシュー
GitLab Runnerは依存プロキシに対して自動的に認証を行います。しかし、基盤となるDockerエンジンはまだその作成者の認証解決プロセスに従います。
認証メカニズムの設定を誤ると、HTTP Basic: Access denied
や403: Access forbidden
エラーが発生する可能性があります。
ジョブログを使用して、依存プロキシに対する認証に使用された認証メカニズムを表示できます:
Authenticating with credentials from $DOCKER_AUTH_CONFIG
Authenticating with credentials from /root/.docker/config.json
Authenticating with credentials from job payload (GitLab Registry)
期待される認証メカニズムを使用していることを確認してください。
Not Found
または、404
画像を引き出す際にエラーが発生します。
このようなエラーは、ジョブを実行しているユーザーが依存プロキシグループに最低限Guestロールを持っていないことを示している可能性があります:
- ```plaintext 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 found ```
-
ERROR: 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.2以前のARMベースのDockerインストールで依存プロキシを使用しようとすると発生します。依存プロキシは、特定のタグを持つイメージをプルする際に x86_64 アーキテクチャのみをサポートします。
回避策として、依存プロキシに異なるアーキテクチャをプルさせるためにイメージの SHA256 を指定することができます:
docker pull ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/library/docker:20.10.3@sha256:bc9dcf5c8e5908845acc6d34ab8824bca496d6d47d1b08af3baf4b3adb1bd8fe
この例では、bc9dcf5c8e5908845acc6d34ab8824bca496d6d47d1b08af3baf4b3adb1bd8fe
が ARM ベースのイメージの SHA256 です。