Edited at

Docker Registryを使って個人プライベートコンテナリポジトリを作成する

More than 3 years have passed since last update.


はじめに

基本的には、公式ドキュメント通りに進めば行けるのですが、

Basic認証でハマったので、一通り手順を公開します。

Deploying a registry server


環境


  • Docker version 1.9.1

  • docker-compose version 1.5.2


構成

下がファイル郡の構成となります。

+ registry

+ auth
- htpasswd
+ certs
- domain.crt
- domain.key
- docker-compose.yml

サーバ側は192.168.33.40でdocker registryを起動して、

そこに対して各サーバからイメージの送信・取得を行っていきます。

                          docker registry

[192.168.33.20] <---> [192.168.33.40]
docker push/pull


オレオレ証明書作成

Docker Registryは通信の際にHTTPSを使用するので、証明書を作成します。

個人で使用するので自己証明書で代用します。

Country Nameなど入力項目がありますが、ほぼ空で大丈夫です。

Common Nameの箇所だけサーバのIPかドメインなどを入れてやります。

$ mkdir -p certs

$ openssl req \
> -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
> -x509 -days 365 -out certs/domain.crt
Generating a 4096 bit RSA private key
..........................+++
................................+++
unable to write 'random state'
writing new private key to 'domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:192.168.33.40
Email Address []:


証明書を作業用サーバに保存

作成した証明書を作業用サーバに保存してやります。

$ sudo mkdir -p /etc/docker/certs.d/192.168.33.40:5000

$ cd /etc/docker/certs.d/192.168.33.40:5000/
$ scp core@192.168.33.40:/path/to/certs/domain.crt ./ca.crt

これをしておかないと、bad certificate となってしまいます。

$ docker login 192.168.33.40:5000

Error response from daemon: invalid registry endpoint https://192.168.33.40:5000/v0/: unable to ping registry endpoint https://192.168.33.40:5000/v0/
v2 ping attempt failed with error: Get https://192.168.33.40:5000/v2/: dial tcp 192.168.33.40:5000: i/o timeout
v1 ping attempt failed with error: Get https://192.168.33.40:5000/v1/_ping: dial tcp 192.168.33.40:5000: i/o timeout. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 192.168.33.40:5000` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/192.168.33.40:5000/ca.crt


Basic認証用ファイル作成

以下のコマンドでhtpasswdファイルを作成します。

$ htpasswd -Bbn suzuki password > auth/htpasswd

この際オプションに注意!必ず -B オプションを付けてBcryptを利用して暗号化するようにします。

これを付けてやらないと以下の様にdocker loginコマンド実行時に認証エラーとなってしまいます。

[masa@localhost]% docker login 192.168.33.40:5000

Username: suzuki
Password:
Email:
Error response from daemon: no successful auth challenge for https://192.168.33.40:5000/v2/ - errors: [basic auth attempt to https://192.168.33.40:5000/v2/ realm "Registry Realm" failed with status: 401 Unauthorized]


docker-compose

毎回docker runでオプション付けて起動するのは面倒なので、

docker-composeを使用してやります。

volumesの項目のパスは適宜変更してやります。


docker-compose.yml

registry:

restart: always
image: registry:2
ports:
- 5000:5000
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- /path/to/registry/data:/var/lib/registry
- /path/to/registry/certs:/certs
- /path/to/registry/auth:/auth


Registry起動

ではコンテナリポジトリを起動します。

[192.168.33.40]$ docker-compose up -d

起動したら、作業用サーバでログインしてます。

[192.168.33.20]$ docker login 192.168.33.40:5000

Username: suzuki
Password:
Email:
WARNING: login credentials saved in /home/suzuki/.docker/config.json
Login Succeeded

ログインに成功したので、イメージを送信してみます。

[192.168.33.20]$ docker pull busybox

[192.168.33.20]$ docker tag busybox 192.168.33.40:5000/test
[192.168.33.20]$ docker rmi 192.168.33.40:5000/test
[192.168.33.20]$ docker pull 192.168.33.40:5000/test


ログインに失敗する場合

ここまでで docker login に失敗してしまう場合は以下をお試し下さい。


OSレベルでの証明書をセット

以下のドキュメントを参考に各OSに設定して下さい。

ここではCentOS7での例を実行しています。

Configuring Docker Trusted Registry

https://docs.docker.com/docker-trusted-registry/configuration/

[192.168.33.20]$ cp certs/domain.crt /etc/pki/ca-trust/source/anchors/192.168.33.40.crt

[192.168.33.20]$ update-ca-trust enable
[192.168.33.20]$ update-ca-trust
[192.168.33.20]$ systemctl restart docker


証明作成時にsubjectAltNameを付ける

[192.168.33.20]$ vi /etc/pki/tls/openssl.conf

[ v3_ca ]
subjectAltName = IP:192.168.33.40

[192.168.33.20]$ openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
[192.168.33.20]$ cp certs/domain.crt /etc/docker/192.168.33.40:5000/ca.crt
[192.168.33.20]$ systemctl restart docker

作成した証明書は registry を起動するサーバにもコピーします。


おわりに

個人用にプライベートなコンテナリポジトリが気軽に手入ります。

本格的な運用の際にはAmazon EC2 Container Registryなどを使用するのが管理が楽ですね。


参考