Private Docker Registry(プライベートレジストリ)の構築

はじめに

作成したDockerイメージのリポジトリとして有名なのはDocker hubがあります.しかしネットワークが制限されている場所では使用することが難しかったり,パブリックリポジトリとプライベートリポジトリがありますが無料会員の場合プライベートリポジトリは1つだけしか使えないなど制限も存在します. そこで,ローカルエリアネットワーク内にプライベートレジストリを作ってみました.またこの記事はある程度Dockerについての知識があることを前提に作っているので,Dockerやプライベートリポジトリについての解説は行いません.

構築

以下ではDockerがインストール済みの環境を用いて行きますので,あらかじめDockerをインストールしておいてください.本記事ではサーバ,クライアント共にUbuntu 16.04 LTSを使用しています.

プライベートリポジトリの構築

以下の公式ドキュメントに従って構築していきますので,適宜参照してください.

docs.docker.com

コンテナを用いて構築していきます.プライベートレジストリコンテナにマウントするボリュームはコンテナ作成後「/var/lib/registry」にイメージが保管されることを考慮して「/var/opt」を指定しています.コンテナをデプロイする際終了ステータスがnon-zeroになった時再起動するように設定しておきます. また今回は試験環境であり限られたエリア内でのみ使用し,外部公開しないためTLS認証による暗号化は行いませんが,それ以外の場合は必ず暗号化して構築してください.

#プライベートレジストリコンテナをデプロイする.
$ sudo docker run -d -p 5000:5000 --name registry --hostname registry \
 --restart on-failure:10 -v /var/local/volume:/var/lib/registry registry:2.3.0
be9249ab7652854fc08ddb0c0ad1af8d3a9c1bf17ca66c9122e762171466326d

これで完了です.

フロントエンドの構築

コンテナをデプロイすれば使用できるのですが,せっかくですのでフロントエンドも作っておきます.フロントエンドはdocker-registry-frontendを使用して構築していきます.以下の公式ドキュメントに従って構築していくので適宜参照してください.

github.com

以下のコマンド実行します.「e ENV_DOCKER_REGISTRY_HOST=xxx.xxx.xxx.xxx」の「xxx.xxx.xxx.xxx」には,サーバとして使用しているホストのプライベートIPアドレスを入力してください.また,「/etc/default/docker」に「DOCKER_OPTS="--insecure-registry xxx.xxx.xxx.xxx:5000"」を追加してください.

$ sudo docker run -d --name registry-frontend --hostname registry-frontend \
 --restart on-failure:10 -e ENV_DOCKER_REGISTRY_HOST=xxx.xxx.xxx.xxx \ 
-e ENV_DOCKER_REGISTRY_PORT=5000 -p 8080:80 konradkleine/docker-registry-frontend:v2
$ sudo docker ps
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS              PORTS                           NAMES
301bcfbd60bc        konradkleine/docker-registry-frontend:v2   "/bin/sh -c $START_S…"   4 minutes ago       Up 4 minutes        443/tcp, 0.0.0.0:8080->80/tcp   registry-frontend
be9249ab7652        registry:2.3.0                             "/bin/registry /etc/…"   25 minutes ago      Up 25 minutes       0.0.0.0:5000->5000/tcp          registry
$ vim /etc/default/docker
# Docker Upstart and SysVinit configuration file

#
# THIS FILE DOES NOT APPLY TO SYSTEMD
#
#   Please see the documentation for "systemd drop-ins":
#   https://docs.docker.com/engine/admin/systemd/
#

# Customize location of Docker binary (especially for development testing).
#DOCKERD="/usr/local/bin/dockerd"

# Use DOCKER_OPTS to modify the daemon startup options.
#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"
DOCKER_OPTS="--insecure-registry xxx.xxx.xxx.xxx:5000"

# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy="http://127.0.0.1:3128/"

# This is also a handy place to tweak where Docker's temporary files go.
#export DOCKER_TMPDIR="/mnt/bigdrive/docker-tmp"
$ sudo service docker restart

これでセットアップは完了です.ブラウザでサーバのプライベートipアドレス「xxx.xxx.xxx.xxxx:8080」に接続してください.以下のようなページが表示されるはずです.

docker-registry-frontend
docker-registry-frontend

使用

イメージをアップロードする際は以下のコマンドを実行してください.

$ sudo docker tag <イメージ名>:<タグ> <レジストリ設置しているサーバのipアドレス> \
:5000/<任意のリポジトリ名>/<イメージ名>:<タグ>
$ sudo docker images
REPOSITORY                              TAG                             IMAGE ID            CREATED             SIZE
dl_env                                  latest                          b0eeafa8df6d        14 hours ago        9.3GB
xxx.xxx.xxx.xxx:5000/k8s/dl_env         hoge                            b0eeafa8df6d        14 hours ago        9.3GB
$ sudo docker push xxx.xxx.xxx.xxx:5000/k8s/dl_env:hoge
The push refers to repository [xxx.xxx.xxx.xxx:5000/k8s/dl_env]
e428433c3f7c: Pushed 
334a36d32e08: Pushed 
02329ea76a91: Pushed 
e3078c762ee2: Pushed 
aa04522b497b: Pushed 
11966f162c9e: Pushed 
78b5aab0476b: Pushed 
f8f213d08b00: Pushed 
f8dda259a125: Pushed 
5159c055acb8: Pushed 
b8d56ef47379: Pushed 
4b894dd79dd5: Pushed 
1f8956b49964: Pushed 
9154b69eed62: Pushed 
33d281c6c667: Pushed 
ca1122f45652: Pushed 
585032098094: Pushed 
cb0856d33862: Pushed 
03a1cbfdd831: Pushed 
e579c4e796e4: Pushed 
b7ee80f86be3: Pushed 
aa7f8c8d5f39: Pushed 
48817fbd6c92: Pushed 
1b039d138968: Pushed 
7082d7d696f8: Pushed 
hoge: digest: sha256:hogehogehogehogehoge size: 5579

ブラウザで確認するとちゃんと追加されていることがわかります.

push_result
pushの結果

次にイメージをダウンロードしてみます.ダウンロードする前に先ほどタグ付けしたイメージを削除しておきます.

$ sudo docker rmi xxx.xxx.xxx.xxx:5000/k8s/dl_env:hoge
$ sudo docker pull xxx.xxx.xxx.xxx:5000/k8s/dl_env:hoge
iwai: Pulling from k8s/dl_env
Digest: sha256:hogehogehogehogehogehoge
Status: Downloaded newer image for xxx.xxx.xxx.xxx:5000/k8s/dl_env:hoge

以上で全て完了です.

トラブルシュート

別ホストからpushやpullができない場合があります.その場合は問題が起こっているホストの「/etc/docker/daemon.json」に

"insecure-registries":["xxx.xxx.xxx.xxx:5000"]

を追加すると良いようです. その後dockerを再起動してください.

$ systemctl restart docker

github.com

最後に

ネットワークの制限がなくてプライベートリポジトリをたくさん使いたい人はdocker hubの有料会員になるべきなのかもしれませんが,できない場合もあると思います.その際の参考になれば幸いです.