- プロジェクトのコンテナレジストリを有効にします。
- GitLab内からコンテナレジストリを制御
- GitLab Container Registry のイメージを使用します。
- GitLabコンテナレジストリへの認証
- ローカルマシンからのイメージのビルドとプッシュ
- GitLab CI/CDを使用したイメージのビルドとプッシュ
- 画像の削除
- 清掃方針
- コンテナレジストリを使ってHelm Chartsを保存します。
- 制限事項
- GitLabコンテナレジストリのトラブルシューティング
GitLabコンテナレジストリ
- GitLab 8.8で導入されました。
- GitLab 8.9で、1.10より前のDockerバージョンをサポートするために、Dockerレジストリマニフェスト
v1
のサポートが追加されました。- GitLab 8.12から、アカウントで2FAを有効にしている場合、GitLabのコンテナレジストリにログインするためにパスワードの代わりに個人アクセストークンを渡す必要があります。
- GitLab 9.1で複数レベルのイメージ名のサポートが追加されました。
- グループレベルのコンテナレジストリはGitLab 12.10から導入されました。
- 画像リポジトリ名による検索はGitLab 13.0で導入されました。
DockerコンテナレジストリがGitLabにインテグレーションされたことで、すべてのプロジェクトはDockerイメージを保存するための独自のスペースを持つことができます。
Docker レジストリについての詳細はhttps://docs.docker.com/registry/introduction/をご覧ください。
プロジェクトのコンテナレジストリを有効にします。
プロジェクトのサイドバーにPackages & Registries > Container Registryの項目が見つからない場合は、GitLabインスタンスで有効になっていません。 管理ドキュメントに従って、管理者にGitLab Container Registryを有効にするよう依頼してください。
GitLab.comを使用している場合、これはデフォルトで有効になっているので、すぐにレジストリを使い始めることができます。 現在、GitLab.comのレジストリには、リポジトリのサイズ制限の一部としてソフトな(10GBの)サイズ制限があります。
GitLab インスタンスを有効にしたら、プロジェクトのコンテナレジストリを有効にします:
- プロジェクトの「設定」>「一般」ページを開きます。
- Visibility, project features, permissionsセクションを展開し、プロジェクトのコンテナレジストリ機能を有効にします。 新規プロジェクトの場合、デフォルトで有効になっている可能性があります。 既存のプロジェクト(GitLab 8.8以前)の場合、明示的に有効にする必要があります。
- 変更を有効にするには、[Save changes]を押します。 これで、サイドバーに[Packages & Registries] > [Container Registry]リンクが表示されます。
GitLab内からコンテナレジストリを制御
GitLabはシンプルなコンテナレジストリ管理パネルを提供しています。 この管理パネルはプロジェクトとグループの両方で利用できます。
プロジェクトのコンテナレジストリ管理
プロジェクトの{パッケージ} パッケージとレジストリ>コンテナレジストリに移動します。
この見解は
- プロジェクトに属するすべてのイメージリポジトリを表示します。
- イメージリポジトリを名前でフィルタリングできるようにします。
- 1つまたは複数の画像リポジトリを削除できます。
- 画像リポジトリの詳細ページに移動できます。
- ログイン、ビルド、プッシュのための最も一般的なコマンドをクイックスタートのドロップダウンに表示します。
- オプションで、このプロジェクトでクリーンアップポリシーが有効になっている場合、バナーが表示されます。
グループのコンテナレジストリの管理
グループの{パッケージ} パッケージとレジストリ>コンテナレジストリに移動します。
この見解は
- このグループに属するプロジェクトのすべての画像リポジトリを表示します。
- 1つまたは複数のイメージリポジトリを削除できるようにします。
- 特定の画像リポジトリの詳細ページに移動できるようにします。
画像リポジトリ詳細ページ
画像リポジトリの名前をクリックすると、詳細が表示されます。
この見解
- すべての画像リポジトリの詳細を表示します。
- 画像リポジトリのすべてのタグを表示します。
- タグのパスを素早くコピーすることができます(タグ名の近くにあるクリップボードボタンをクリックしてください)。
- 1つまたは複数のタグを削除できます。
GitLab Container Registry のイメージを使用します。
GitLab Container Registry でホストされているイメージからコンテナをダウンロードして実行するには、docker run
を使用します:
docker run [options] registry.example.com/group/project/image [arguments]
Dockerコンテナの実行に関する詳細は、Dockerのドキュメントを参照してください。
GitLabコンテナレジストリへの認証
プロジェクトのメニューからPackages & Registries > Container Registryを選ぶと、GitLab の認証情報を使ってコンテナレジストリにログインする手順が表示されます。
例えば、レジストリのURLがregistry.example.com
の場合、次のようにログインできます:
docker login registry.example.com
プロジェクトが非公開の場合、作成者の認証が必要になります。 これには2つの方法があります:
どちらも最低限必要なスコープはread_registry
。
トークンの使用例:
docker login registry.example.com -u <username> -p <token>
ローカルマシンからのイメージのビルドとプッシュ
イメージのビルドと公開は簡単です。 GitLab でホストしている名前空間とプロジェクト名のレジストリ URL を使っていることを確認しましょう:
docker build -t registry.example.com/group/project/image .
docker push registry.example.com/group/project/image
あなたの画像には次のような名前が付けられます:
<registry URL>/<namespace>/<project>/<image>
GitLabは3レベルまでのイメージリポジトリ名をサポートしています。 以下のイメージタグの例が有効です:
registry.example.com/group/project:some-tag
registry.example.com/group/project/image:latest
registry.example.com/group/project/my/image:rc1
GitLab CI/CDを使用したイメージのビルドとプッシュ
ローカルマシンからイメージをビルドしてプッシュすることもできますが、コンテナレジストリの真の威力は、GitLab CI/CDと組み合わせたときに発揮されます。 そうすれば、作成したDockerイメージからプロジェクトのテスト、ビルド、最終的なデプロイを含むワークフローを作成し、あらゆるプロセスを自動化することができます。
詳細に入る前に、いくつか知っておいていただきたいことがあります:
- コマンドを実行する前に、コンテナ・レジストリに対する認証を行う必要があります。複数のジョブがこのレジストリに依存している場合は、
before_script
。 -
docker build --pull
を使用すると、キャッシュが古い場合に備えて、ビルドする前にベースイメージの変更を取得します。 少し時間はかかりますが、ベースイメージのセキュリティパッチがないまま立ち往生することはなくなります。 - 各
docker run
の前に明示的にdocker pull
を実行すると、ビルドされたばかりの最新の画像がフェッチされます。これは、画像をローカルにキャッシュする複数の Runner を使っている場合に特に重要です。 image タグに Git SHA を使うことで、各ジョブが一意になり、古い画像が存在することがなくなるので、この必要はなくなります。 しかし、依存関係が変更された後で指定したコミットを再ビルドすると、古い画像が存在する可能性があります。 - 複数のジョブが同時に進行している場合、
latest
タグに直接ビルドすることは避けたいものです。
GitLab CI/CDによるコンテナレジストリへの認証
GitLab CI/CD経由でコンテナレジストリに認証するには、プロジェクトの可視性に応じて3つの方法があります。
すべてのプロジェクトで利用可能ですが、公開プロジェクトに適しています:
-
特別な
CI_REGISTRY_USER
変数の使用: この変数で指定されたユーザーは、プロジェクトに接続されたレジストリにプッシュするために作成されます。 そのパスワードはCI_REGISTRY_PASSWORD
変数で自動的に設定されます。 これにより、Dockerイメージのビルドとデプロイを自動化することができ、レジストリへの読み書きアクセスが可能になります。 これはエフェメラルなので、1つのジョブに対してのみ有効です。 次の例はそのまま使用することができます:docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
非公開プロジェクトや内部プロジェクト向け:
-
個人アクセストークンの使用: プロジェクトが非公開の場合、個人アクセストークンを作成して使用することができます:
- 読み出し(プル)アクセスの場合、スコープは
read_registry
であるべきです。 - リード/ライト(プル/プッシュ)アクセスには、
api
を使用します。
以下の例の
<username>
と<access_token>
を置き換えてください:docker login -u <username> -p <access_token> $CI_REGISTRY
- 読み出し(プル)アクセスの場合、スコープは
-
GitLabデプロイトークンを使う:非公開プロジェクトで特別なデプロイトークンを作成して使うことができます。 これはレジストリへの読み取り専用(プル)アクセスを提供します。 一度作成すれば、特別な環境変数を使うことができ、GitLab CI/CDがそれらを埋めてくれます。 次の例はそのまま使うことができます:
docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
GitLab CI/CDによるコンテナレジストリの例
RunnerでDocker-in-Dockerを使用している場合、.gitlab-ci.yml
はこのようになります:
build:
image: docker:19.03.11
stage: build
services:
- docker:19.03.11-dind
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY/group/project/image:latest .
- docker push $CI_REGISTRY/group/project/image:latest
ハードコーディングを避けるために、他の変数を利用することもできます:
build:
image: docker:19.03.11
stage: build
services:
- docker:19.03.11-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
ここで、$CI_REGISTRY_IMAGE
は、このプロジェクトに関連付けられているレジストリのアドレスに解決されます。$CI_COMMIT_REF_NAME
はブランチ名やタグ名に解決され、ブランチ名にはスラッシュを含めることができるため(たとえば、feature/my-feature)、$CI_COMMIT_REF_SLUG
を画像タグとして使用する方が安全です。これは、画像タグにはスラッシュを含めることができないためです。また、$IMAGE_TAG
という独自の変数を宣言し、script
セクションで入力の手間を省くために、この2つを組み合わせています。
以下は、タスクを 4 つのパイプラインステージに分割し、並行して実行される 2 つのテストを含む、より精巧な例です。build
はコンテナレジストリに保存され、後続のステージで使用されます。必要なときにイメージをダウンロードします。master
への変更もlatest
としてタグ付けされ、アプリケーション固有のデプロイスクリプトを使用してデプロイされます:
image: docker:19.03.11
services:
- docker:19.03.11-dind
stages:
- build
- test
- release
- deploy
variables:
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
script:
- docker build --pull -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
test1:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/tests
test2:
stage: test
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker run $CONTAINER_TEST_IMAGE /script/to/run/another/test
release-image:
stage: release
script:
- docker pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE
only:
- master
deploy:
stage: deploy
script:
- ./deploy.sh
only:
- master
docker pull
を明示的に呼び出しています。image:
を使ってビルドしたイメージを暗黙的にプルし、DockerまたはKubernetesのexecutorを使いたい場合は、以下を確認してください。 pull_policy
がalways
に設定されていることを確認してください。コンテナレジストリからのDocker-in-Dockerイメージの使用
Docker-in-Dockerで独自のDockerイメージを使用したい場合は、Docker-in-Dockerセクションの手順に加えて、いくつか必要なことがあります:
- レジストリを指すように
image
とservice
を更新します。 - サービスエイリアスを追加します。
以下は、.gitlab-ci.yml
の例です:
build:
image: $CI_REGISTRY/group/project/docker:19.03.11
services:
- name: $CI_REGISTRY/group/project/docker:19.03.11-dind
alias: docker
stage: build
script:
- docker build -t my-docker-image .
- docker run my-docker-image /script/to/run/tests
サービス・エイリアスの設定を忘れると、docker:19.03.11
イメージはdind
サービスを見つけられず、以下のようなエラーが発生します:
error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host
画像の削除
コンテナレジストリから画像を削除する方法は複数あります。
GitLabからイメージを削除します。
GitLabからイメージを削除するには:
- プロジェクトまたはグループの{パッケージ} パッケージとレジストリ>コンテナレジストリに移動します。
-
コンテナレジストリのページから、削除するコンテナを選択できます:
- ごみ箱の赤いアイコンをクリックして、リポジトリ全体とそれに含まれるすべてのタグを削除します。
- リポジトリに移動し、削除したいタグの横にある赤い{削除} ゴミ箱アイコンをクリックして、タグを個別または一括で削除します。
-
ダイアログボックスで、タグの削除をクリックします。
APIを使った画像の削除
イメージの削除処理を自動化したい場合は、GitLabがAPIを提供しています。 詳しくは、以下のエンドポイントを参照してください:
GitLab CI/CDを使ったイメージの削除
次の例では、build
、およびclean
の2つのステージを定義しています。build_image
ジョブはブランチのDockerイメージを構築し、delete_image
ジョブはそれを削除します。reg
実行可能ファイルはダウンロードされ、$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG
環境変数に一致するイメージを削除するために使用されます。
この例を使用するには、IMAGE_TAG
変数を必要に応じて変更してください:
stages:
- build
- clean
build_image:
image: docker:19.03.11
stage: build
services:
- docker:19.03.11-dind
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
only:
- branches
except:
- master
delete_image:
image: docker:19.03.11
stage: clean
services:
- docker:19.03.11-dind
variables:
IMAGE_TAG: $CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG
REG_SHA256: ade837fc5224acd8c34732bf54a94f579b47851cc6a7fd5899a98386b782e228
REG_VERSION: 0.16.1
before_script:
- apk add --no-cache curl
- curl --fail --show-error --location "https://github.com/genuinetools/reg/releases/download/v$REG_VERSION/reg-linux-amd64" --output /usr/local/bin/reg
- echo "$REG_SHA256 /usr/local/bin/reg" | sha256sum -c -
- chmod a+x /usr/local/bin/reg
script:
- /usr/local/bin/reg rm -d --auth-url $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $IMAGE_TAG
only:
- branches
except:
- master
reg
リリースをダウンロードし、delete_image
ジョブで定義されたREG_SHA256
とREG_VERSION
変数を変更することで、コード例を更新することができます。クリーンアップポリシーによる画像の削除
プロジェクトごとにクリーンアップポリシーを作成し、古いタグやイメージがコンテナレジストリから定期的に削除されるようにすることができます。
清掃方針
特定のプロジェクトで、不要になったタグを削除したい場合、クリーンアップポリシーを作成することができます。 ポリシーが適用されると、正規表現パターンに一致するタグが削除されます。 基本となるレイヤーと画像は残ります。
どのタグにも関連付けられなくなった基礎となるレイヤーと画像を削除するには、インスタンス管理者は、-m
スイッチを使用してガベージコレクションを使用できます。
container_expiration_policies_enable_historic_entries
をtrueに設定することで有効にすることができます。内在するリスクに注意してください。クリーンアップポリシーアルゴリズムは、与えられたリポジトリのすべてのタグをリストに集めることから始まり、削除するタグだけが残るまで、そこからタグを除外するプロセスを経ます:
- 指定したリポジトリのすべてのタグをリストに収集します。
-
latest
というタグをリストから除外します。 -
name_regex
を評価し,リストからマッチしない名前を除外します。 - マニフェストを持たない(オプションの一部ではない)タグを除外します。
- 残りのタグを
created_date
で注文。 -
keep_n
(保持するタグの数)の値に基づいて、N個のタグをリストから除外します。 -
older_than
(クリーンアップ間隔)値よりも新しいタグをリストから除外します。 -
name_regex_keep
(保存する画像)の値と一致するタグをリストから除外します。 - 最後に、リスト内の残りのタグがコンテナレジストリから削除されます。
UIによるプロジェクトのクリーンアップポリシーの管理
プロジェクトのクリーンアップポリシーを管理するには、 Settings > CI/CD > Container Registry tag cleanuppolicyに移動します。
UIでは以下の設定が可能です:
- クリーンアップポリシー:クリーンアップポリシーを有効または無効にします。
- クリーンアップ間隔:タグが削除されない期間。
- クリーンアップスケジュール:タグをチェックするcronジョブの実行頻度。
- 保持するタグの数: 各画像に対して_常に_保持するタグの数。
-
この正規表現パターンにマッチする名前のDockerタグは期限切れになります:どのタグをクリーンアップすべきかを決定するために使用される正規表現です。 すべてのタグをクリーンアップの対象にするには、デフォルト値の
.*
を使用します。 -
この正規表現パターンにマッチする名前のDockerタグが保存されます:どのタグが保存されるべきかを決定するために使用される正規表現。 すべてのタグを保存するには、デフォルト値の
.*
を使用します。
クリーンアップポリシーのトラブルシューティング
以下のメッセージが表示されたら
“クリーンアップ・ポリシーの更新中に何か問題が発生しました”
正規表現パターンが有効であることを確認してください。
Rubularを使って正規表現をチェックすることができます。 一般的な正規表現パターンの例をご覧ください。
APIによるプロジェクトのクリーンアップポリシーの管理
GitLab APIを使ってクリーンアップポリシーを設定、更新、無効化することができます。
例:
-
すべてのタグを選択、画像ごとに最低1つのタグを保持、14日以上前のタグをクリーンアップ、月に1回実行、
master
という名前の画像を保存、ポリシーは有効:curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <your_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":".*-master"}}' 'https://gitlab.example.com/api/v4/projects/2'
詳細はAPIドキュメントを参照してください。
外部コンテナレジストリとの併用
外部コンテナレジストリを使用する場合、プロジェクトでクリーンアップポリシーを実行すると、パフォーマンス上のリスクがあります。 大量のタグ(数千)を削除するポリシーをプロジェクトで実行する場合、ポリシーを実行するGitLabバックグラウンドジョブがバックアップされたり、完全に失敗したりする可能性があります。 GitLab 12.8より前に作成されたプロジェクトのコンテナクリーンアップポリシーを有効にするのは、クリーンアップされるタグの量が最小限であると確信がある場合のみにすることをお勧めします。
正規表現パターンの例
クリーンアップ・ポリシーは、正規表現パターンを使用して、UIとAPIの両方で、保存または削除するタグを決定します。
以下は正規表現パターンの例です:
-
すべてのタグに一致します:
.*
-
v
で始まるタグにマッチします:v.+
-
master
を含むタグにマッチします:master
-
v
で始まるタグ、master
を含むタグ、release
を含むタグのいずれかにマッチします:(?:v.+|master|release)
コンテナレジストリを使ってHelm Chartsを保存します。
Helm v3のローンチに伴い、コンテナレジストリを使ってHelm Chartを保存できるようになりました。 しかし、Dockerによってメタデータが渡され保存される方法のため、GitLabがこのデータを解析してパフォーマンス基準を満たすことはできません。このエピックでは、Helm Chartをサポートするためにコンテナレジストリのアーキテクチャを更新します。
上記の課題については、こちらをご覧ください。
制限事項
- 既存のコンテナレジストリリポジトリの移動や名前の変更は、イメージをプッシュした後はサポートされていません。 イメージには署名が含まれており、署名にはリポジトリ名が含まれているからです。 コンテナレジストリでリポジトリの移動や名前の変更をするには、既存のイメージをすべて削除する必要があります。
- GitLab 12.10以前では、
latest
タグと同じイメージIDを使用しているタグは、クリーンアップポリシーによって削除されません。
GitLabコンテナレジストリのトラブルシューティング
docker 接続エラー
グループ名、プロジェクト名、ブランチ名のいずれかに特殊文字が含まれていると、Docker接続エラーが発生することがあります。 特殊文字には次のようなものがあります:
- 先頭のアンダースコア
- 末尾のハイフン/ダッシュ
これを回避するには、グループパスを変更したり、プロジェクトパスを変更したり、ブランチ名を変更したりします。
GitLabサーバー管理者としてのトラブルシューティング
GitLabコンテナレジストリのトラブルシューティングには、ほとんどの場合、GitLabサーバーへの管理者権限が必要です。
コンテナレジストリのトラブルシューティング方法をお読みください。
パスの変更やプロジェクトの移動ができない
プロジェクトのパスを変更したり、プロジェクトを新しいネームスペースに移動しようとすると、以下のエ ラーが発生することがあります:
- “コンテナレジストリにタグが存在するため、プロジェクトを移管できません。”
- “少なくとも 1 つのプロジェクトがコンテナ・レジストリにタグを持っているため、名前空間を移動できません。”
このイシューは、プロジェクトのコンテナレジストリにイメージがある場合に発生します。 パスを変更したりプロジェクトを転送したりする前に、これらのイメージを削除または移動する必要があります。
以下の手順では、これらのサンプルプロジェクト名を使用します:
- 現在のプロジェクトのために:
example.gitlab.com/org/build/sample_project/cr:v2.9.1
- 新しいプロジェクトのために:
example.gitlab.com/new_org/build/new_sample_project/cr:v2.9.1
ご自身のURLを使って、以下のステップを完了してください:
-
Dockerイメージをコンピュータにダウンロードします:
docker login example.gitlab.com docker pull example.gitlab.com/org/build/sample_project/cr:v2.9.1
-
新しいプロジェクト名に合わせて画像の名前を変更します:
docker tag example.gitlab.com/org/build/sample_project/cr:v2.9.1 example.gitlab.com/new_org/build/new_sample_project/cr:v2.9.1
- UIまたはAPIを使用して、両方のプロジェクトの画像を削除します。 画像がキューに入れられ、削除されるまでに時間がかかる場合があります。
- 設定]>[一般]を開き、[詳細設定]を展開して、パスを変更するか、プロジェクトを転送します。
-
画像を復元します:
docker push example.gitlab.com/new_org/build/new_sample_project/cr:v2.9.1
詳細はイシューをご覧ください。