GitLab
docker
GitLab-CI
GitLab-CI-Runner
More than 1 year has passed since last update.

GitLab Container Registry

GitLab Advent Calendar 2016 の九日目は Docker Image のレジストリである GitLab Container Registry の紹介をしたいと思います。

概要

ビルドした Docker Image を Docker Hub にプッシュされている方は多いのではないでしょうか?

GitLab CE/EE には GitLab Container Registry が統合されており、Docker Hub と同じように Docker Image を保管することができます。もちろんこの機能は GitLab.com でも使うことができます。

公式の Docker Hub を使ってもいいのですが、GitLab Container Registry を個人的におすすめする理由はいくつかあります。

まず第一に、社内にサーバーを立てて社内で使う Container Registry が構築できることです。(構築方法は四日目の記事、GitLab をインストールしよう! (omnibus package) をご覧ください)

第二に、GitLab.com でプライベートでも無料で使えるからです。(価格については八日目の hiroponz さんの記事、GitHub.com・BitBucket.org・GitLab.comの月額料金比較 + α をご覧ください)

第三に、GitLab に完全に統合されているからです。アカウントに GitLab のものが使えるのはもちろんですが、GitLab CI ともうまく統合されており、トークンやパスワードを設定することなしに CI から Docker Image をプッシュすることができます。面倒な操作の必要がないのももちろんですが、トークンを設定する必要がない分安心感があります。

使い方

パソコンに Docker Engine がインストールされていることとします。

GitLab.com 編

まずは GitLab.com で使ってみましょう!

GitLab.com にログインして、プロジェクトを作成してください。デフォルトで Container Registry は有効化されていますので、すぐに使いはじめることができます。

Registry タブをクリックすると、まだひとつも Docker Image が登録されていないことが分かります。しかも、使い方まで書いてあるので非常に便利ですね! (この記事の意味って一体...)

gitlab1.png

書かれている通り、まずはログインをします。GitLab.com のアカウント名とパスワードを入力してください。

$ docker login registry.gitlab.com

次に Docker Image を作ってプッシュしてみます。Dockerfile を書くのは面倒ですので、今回は別の方法を使います。

$ docker pull hello-world
$ docker tag hello-world registry.gitlab.com/masakura/docker-sample
$ docker push registry.gitlab.com/masakura/docker-sample

ページをリロードすると latest イメージが作成されました!

gitlab2.png

ちなみに Docker Image 名の右のコピーボタンをクリックすると、docker pull コマンドとセットで Docker Image 名がクリップボードにコピーされます。覚えておくと便利だと思います。

このような形で、GitLab はプロジェクトに一つだけ Docker Image を保管することができます。

GitLab CE 編

GitLab CE で GitLab Container Registry を使う場合は、機能を有効化する必要があります。有効化の方法は四日目の記事、GitLab をインストールしよう! (omnibus package) をご覧ください。

FQDN が GitLab.com と異なりますので、Docker Image 名やログインする Docker ホスト名が変わるくらいであとは GitLab.com と同じように使うことができます。

ところで、社内のサーバーに GitLab CE をインストールする場合、SSL を使わないことがよくあると思います。(個人的にはよくないと思うのですが...)

Docker Engine は SSL でない Container Registry には接続できません。以下のように接続に失敗します。証明書の購入をおすすめします。

$ docker login registry.example.com
Username: root 
Password: 
Error response from daemon: Get https://registry.example.com/v1/users/: dial tcp 192.168.42.65:443: getsockopt: connection refused

ですが、どうしても SSL を有効に出来ない場合、Docker Engine の設定の insecure-registry に Container Registry の名前を設定するとアクセスできるようになります。

Linux で Docker Engine を動作させている場合は、/etc/systemd/system/docker.service.d/local.conf ファイルを作成し、systemctl daemon-reload のあとサービスを再起動してください。

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry=registry.example.com
$ sudo systemctl daemon-reload
$ sudo service docker restart

今度は無事ログインできました!

$ docker login registry.example.com
Username: root
Password: 
Login Succeeded

設定の変更方法については Control and configure Docker with systemd をご覧ください。

また、Docker for WindowsDocker for Mac をお使いの方は設定画面から insecure-registry を追加してください。

でも、これらの設定を Container Registry の利用者全員にお願いするのはとても面倒ですよね! ですので、証明書を買ってきて設定したほうが楽だと思います!

GitLab CI 編

続いて GitLab CI から Docker Image を Container Registry にプッシュする方法です。GitLab.com を使います。

GitLab CI は .gitlab-ci.yml ファイルにスクリプトを用意するだけで使うことができます。さらに、テンプレートも用意されていますので、簡単に使うことができます。

先ほど作ったプロジェクトのダッシュボードに README というリンクがありますので、それをクリックして Commit Changes で保存しましょう! (中身はなしで構いません)

続いて、Repository タブの + -> New file ボタンをクリックし Dockerfile ファイルを作成してください。ファイルの内容は以下の一行だけで構いません。

FROM nginx

Commit Changes ボタンで保存します。

再度プロジェクトのダッシュボードに戻って、Set Up CI ボタンをクリックします。Choose a GitLab CI Yaml Template から Docker を選びます。

gitlab3.png

こんな感じです。

# This file is a template, and might need editing before it works on your project.
# Official docker image.
image: docker:latest

services:
  - docker:dind

build:
  stage: build
  script:
    - docker login -u "gitlab-ci-token" -p "$CI_BUILD_TOKEN" $CI_REGISTRY
    - docker build --pull -t "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME" .
    - docker push "$CI_REGISTRY_IMAGE:$CI_BUILD_REF_NAME"

Commit Changes ボタンをクリックしてしばらく待つと...

gitlab4.png

できました!

docker login のスクリプトで、CI でのビルドごとに生成されるトークンを使ってログインしていることが分かります。つまり、GitLab CI + GitLab Container Registry の組み合わせでは、ユーザー名やパスワードを設定する必要がなく、安全で簡単に使えることが分かると思います。

注意点

Docker Image 名は小文字のみ

Docker Image には大文字や多くの記号を使うことができません。このため、GitLab のプロジェクト名とグループ名 (もしくはユーザー名) を小文字に変換されたものが Docker Image 名に使われています。

大文字小文字だけが違うプロジェクトを作った場合、Container Registry は共有されてしまうようです。(流石に、大文字小文字だけが違うグループは作れないようですので、赤の他人に Docker Image を取られることはなさそうですが...)

Docker Image を消すと同じ Image ID のが全て消える

GitLab Container Registry から Docker Image を消すと、同じ Image ID の Docker Image が全て消えます。

パスワードを設定しておく必要がある

主に GitLab.com のお話ですが、GitHub などの外部認証を使ってログインされている方はパスワードが未設定な状態となります。パスワードを設定するまでは docker login ができないと思われます。

Docker in Docker で overlayfs を使う

GitLab CI で Docker Image をビルドする方法を紹介しました。こちらは Docker in Docker という Docker 社公式の方法を使ったものです。

ですが、GitLab のドキュメント、Using Docker Build の中の Using the OverlayFS driver でパフォーマンスの問題が言及されています。

By default, when using docker:dind, Docker uses the vfs storage driver which copies the filesystem on every run. This is a very disk-intensive operation which can be avoided if a different driver is used, for example overlay.

デフォルトではストレージドライバーに vfs が使われるためディスクに厳しく、overlayfs を使ったほうがいいと書かれています。

GitLab.com では .gitlab-ci.yml ファイルに少し書き足すだけで、overlayfs が使われるようになります。

variables:
  DOCKER_DRIVER: overlay

終わり

ちょっと長くなりましたけど、GitLab Container Registry で Docker Image を活用する方法はいかがだったでしょうか? こういったものが GitLab で完結して利用できるのはとても便利で、気に入ってしまいました!

追記

GitLab 8.14 から Support for private container registries in GitLab CI builds にあるとおり、プライベートプロジェクトの Container Registry の Docker Image を指定してビルドできるようになったようです。

プライベートプロジェクトではビルド用のカスタム Docker Image も公開したくないと思います。そういう時に非常に有用だと思います。