皆さん、こんにちは。GMOクラウドの縞子です。
今回は Docker Registryを ALTUS の仮想サーバーにインストールし、プライベート レジストリ サーバーとして設定してみましたのでその手順を紹介します。
Ⅰ. Docker Registry とは?
Docker Registry とは、Docker イメージを保存し配布するサーバー サイド アプリケーションです。このようなシステムとして、Docker Hub という Docker 社公式レジストリが存在します。Docker Hub は無料で利用でき、各種ベンダーやコミュニティの公式イメージがここに公開されており、さらには自身が独自に作成した Docker イメージをここにアップロードすることも可能です。
また、商用サポートも行う Docker Trusted Registry というサービスも用意されていますが、「Docker イメージの保管先を厳密にコントロールしたい」「イメージの配布方法についても完全に管理したい」場合は、自身が管理するサーバー上で Docker Registry コンテナを実行し、プライベート レジストリとして利用することができます。
Ⅱ. Docker Registry コンテナを実行する前の準備
Docker Registry コンテナを実行するに当たって、ALTUS Basic シリーズ上で次の2台の仮想サーバー(以降VMとします)を用意し、その内1台のVMにオブジェクト ストレージをディスクとしてマウントします。
Ⅱ-Ⅰ. ALTUS Basic シリーズ上に VM を作成する
■ VM 1
- 役割: Docker Registry ホスト/Docker ホスト
- テンプレート: Ubuntu12.0464bit 20140926
- サーバープラン: m1.small (CPU 1 コア、メモリ 2 GB)
- ROOT ディスク サイズ: 20.00 GB
- アフィニティグループ: 指定しない
- ファイアーウォール通信許可設定: 受信規則にて社内 LAN および VM 2 のグローバル IP アドレスに対し TCP 22 および 5000 番ポートを開放(※1)
- VMにグローバル IP アドレスを割り当てる(※2)
- オブジェクト ストレージをマウント(※手順は後述します)
- testuser というアカウントを作成(sudo -s で昇格権限を持てるように設定する)
■ VM 2
- 役割: Docker ホスト(Registry クライアント)
- テンプレート: Ubuntu12.0464bit 20140926
- サーバープラン: m1.small (CPU 1 コア、メモリ 2 GB)
- ROOT ディスク サイズ: 20.00 GB
- アフィニティグループ: 指定しない
- ファイアーウォール通信許可設定: 受信規則にて社内 LAN と VM 1 のグローバル IP アドレスに対し TCP 22番ポートを開放(※1)
- VMにグローバル IP アドレスを割り当てる(※2)
- testuser というアカウントを作成(sudo -s で昇格権限を持てるように設定する)
- ※1. ファイアーウォールの受信規則の設定は、コンソールガイド - セキュリティグループの設定 - STEP1 受信規則の追加を参照ください。
- ※2. IP アドレスの割り当ては、コンソールガイド - スタティックNATの設定を参照ください。
Ⅱ-Ⅱ. VM 1 にオブジェクト ストレージをマウントする
今回は Docker Registry のレジストリ データ保管先として、ALTUS のオブジェクトストレージ(※現在提供終了)を利用します。Docker Registry のストレージには Local Posix Filesystem(Posix に準拠したファイルシステム)や、AWS S3、Azure および OpenStack Swift など各種クラウド ストレージが利用できます。
ALTUS のオブジェクトストレージは s3fs ツールにより通常のディスク(つまり Local Posix Filesystem)として扱うことができ、また 3 分散の保存形式で耐障害性が高いため、データ保全性が求められるレジストリ データ保管先に向いています。
オブジェクト ストレージの利用方法および VM へのマウント手順詳細は、s3fsコマンドでオブジェクトストレージを仮想サーバーのディスクとして活用しようにて紹介しましたので、こちらを参照ください。
今回は s3cmd ツールで「myregistry」というバケットをオブジェクト ストレージに作成し、それを s3fs ツールで VM 1の「/mnt/docker/registry」ディレクトリにマウントします。
# s3fs myregistry /mnt/docker/registry ¥
-o nonempty -o allow_other ¥
-o url=https://inter-st.gmocloud.com ¥
-o passwd_file=/etc/s3fs/s3fspasswd
各 VM とオブジェクトストレージの構成イメージは以下のようになります。
Ⅲ.Docker エンジンのインストール
VM 1 と VM 2 の両方に Docker エンジンをインストールします。
現時点 Ubuntu 12.04 では次の手順でインストール可能ですが、Docker エンジンのバージョンアップに伴い、こちらの手順が変更される可能性があります。インストールされる際は公式サイトのインストール手順を確認することをお勧めします。
また、CentOS や Mac OS X など他の OS に Docker エンジンをインストールする際も、上記の公式サイトを参考にインストールしてください。
■手順
(1) VM1 と VM 2 のそれぞれにターミナルエミュレーターで SSH ログオンし、次のコマンドを実行します。
$ sudo -s
# apt-get update
# apt-get upgrade -y
# apt-get install -y linux-image-generic-lts-trusty
上のコマンドにて linux-image-generic-lts-trusty をインストールします。インストールに先だってパッケージ管理情報とインストール済みの各パッケージを更新しておきます。
(2) VM をコンソールから再起動します。VM の再起動手順はコンソールガイド - 仮想サーバーの再起動を参照ください。
(3) VM が再起動した後 curl コマンドをインストールし、Docker エンジンをインストールします。
$ sudo -s
# apt-get install -y curl
# curl -sSL https://get.docker.com/ | sh
Ⅳ. サーバー証明書の用意
リモートから Docker Registry サーバーにアクセスし Docker イメージを pull/push する場合は原則として(※)HTTPS で通信します。認証局(CA)から取得したサーバー証明書(*.crt)および秘密鍵ファイル(*.key)がある場合はそちらを Docker Registry コンテナ内にコピーします。
※ HTTP 通信も可能であり、Docker 社公式サイトにその手順も記載されていますが、セキュリティの観点から HTTPS で通信することが推奨されています。
もしサーバー証明書が手元に無い場合は、開発・検証用として自己証明書を作成し使用することも可能です。ただし、自己証明書を使う場合は CA による認証がなされないため、レジストリ クライアント側の規定フォルダーにあらかじめ証明書(*.crt)をコピーしておく必要があります。
うーん、ややこしいですね…。
要は Docker Registry ホストを実行する際には、次のステップが必要とご理解ください。
(1) サーバー証明書および秘密鍵ファイルを用意する。もし CA から取得した正式なものが無い場合は自己証明書を作成して使用することもできる。
(2) 自己証明書の場合は、サーバー証明書を Docker Registry クライアントの規定フォルダーにあらかじめコピーしておく。
(3) Docker Registry コンテナの実行時、コンテナ内にサーバー証明書および秘密鍵ファイルをセットする。
以下にそれぞれのステップについて詳しく紹介します。
Ⅳ-Ⅰ. サーバー証明書と秘密鍵ファイルを用意する
● CA から取得した正式なサーバー証明書および秘密鍵ファイルがある場合
VM 1 に SSH ログオンして $HOME/certs フォルダーを作成し、証明書と秘密鍵ファイルをその certs フォルダーにコピーします。
$ cd
$ mkdir certs
SCP や SFTP コマンドなどで VM 1 の $HOME/certs フォルダーに *.crt と *.key ファイルをコピーしてください。
● 自己証明書を作成する場合
VM 1 に SSH ログオンし、以下のコマンドを実行します。
$ sudo -s
# apt-get install openssl -y
# cd && mkdir 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
(中略)
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:{都道府県名を入力(例: Tokyo)}
Locality Name (eg, city) []:{市町村名を入力(例: Shibuya-ku)}
Organization Name (eg, company) [Internet Widgits Pty Ltd]:{会社名を入力(例: GMO Cloud)}
Organizational Unit Name (eg, section) []:{組織名を入力(例: Development Div.)}
Common Name (e.g. server FQDN or YOUR name) []:{サーバーのドメイン名を入力(例: dockerregistry001.aaa.bbb.com)}
Email Address []:{電子メールアドレスを入力}
-----
# ls certs
domain.crt domain.key // 証明書と秘密鍵が作成されていれば OK です
Ⅳ-Ⅱ. サーバー証明書を Docker Registry クライアントにコピーする
こちらの操作は、自己証明書を使用する場合にのみ実行します。
VM 1 にあるサーバー証明書(*.crt)を、VM 1 および VM 2 上の規定のフォルダーにコピーします(VM 1 と VM 2 の両方ともレジストリ クライアントとして使用します)。
なお、以下の例ではサーバー証明書名を domain.crt とします。
● VM 1 上での操作
$ sudo -s
# cd /etc/docker/
# mkdir -p certs.d/{VM 1 のドメイン名}:5000
# cd certs.d/{VM 1 のドメイン名}:5000
# cp ~/certs/domain.crt ca.crt
# chown root:root ca.crt
# cd ~/certs
# scp *.crt testuser@{VM 2 のグローバル IP アドレス}:/home/testuser/
● VM 2 上での操作
$ sudo -s
# ls /home/testuser/*.crt
domain.crt // VM 1 からコピーした証明書があることを確認します。
# cd /etc/docker/
# mkdir -p certs.d/{VM 1 のドメイン名}:5000
# cd certs.d/{VM 1 のドメイン名}:5000
# cp /home/testuser/domain.crt ca.crt
# chown root:root ca.crt
Ⅳ-Ⅲ. Docker Registry コンテナ内にサーバー証明書および秘密鍵ファイルをセットする
Docker Registry コンテナを実行する際、オプションでサーバー証明書と秘密鍵をコンテナ内に配置します。Registry コンテナの実行は次の章で紹介しますので、ここではスキップします。
Ⅴ.Docker Registry コンテナの実行
ではいよいよ Docker Registry コンテナ イメージを Docker Hub から pull し実行します。
現時点 (2015/09/24) の最新版は 2.1.1 でしたので、こちらを pull します。
VM 1 上で次のように Docker run コマンドを実行しコンテナを起動します。
$ sudo -s
# cd
# docker run -d -p 5000:5000 --restart=always ¥
--name registry ¥
-v /mnt/docker/registry:/var/lib/registry ¥
-v `pwd`/certs:/certs ¥
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt ¥
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key ¥
registry:2.1.1
※補足:コマンド オプションについて
- -d オプション: バックグラウンド実行(デーモン化)を指定
- -p オプション: コンテナの TCP 5000 番ポートとホストの TCP 5000 番ポートをバインディング
- --restart オプション: always を指定し、コンテナ終了時に自動的に再起動するように設定
- --name オプション: コンテナ名を registry に設定
- 1つ目の -v オブション: VM 1 の /mnt/docker/registry をコンテナの /var/lib/registry にマウント
- 2つ目の -v オプション: VM 1 に保存したサーバー証明書と秘密鍵ファイル保存ディレクトリをコンテナ内の /certs にマウント
- 1つ目の -e オプション: 環境変数 REGISTRY_HTTP_TLS_CERTIFICATE を /certs/domain.crt に設定
- 2つ目の -e オプション: 環境変数 REGISTRY_HTTP_TLS_KEY を /certs/domain.key に設定
エラーが表示されなければ正常にコンテナが起動しているはずですが、念のためステータスを確認します。
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
{コンテナ ID} registry:2.1.1 "/bin/registry /etc/d" 2 seconds ago Up 1 seconds 0.0.0.0:5000->5000/tcp registry
STATUS が "Up" となっていますので、正常起動しています。
Ⅵ.プライベート レジストリへ Docker イメージを push/pull する
VM 1 上で実行しているプライベート レジストリに対し、Docker イメージの push/pull が可能かテストしてみます。
まず、VM 1 上で Docker Hub から docker/whalesay イメージを pull し、"{VM 1 のドメイン名}/whalesay" というタグを付けてプライベート レジストリに push します。
● VM 1 上での操作
# docker pull docker/whalesay
# docker tag docker/whalesay {VM 1 のドメイン名}:5000/whalesay
# docker push {VM 1 のドメイン名}:5000/whalesay
エラーが表示されなければ push は成功です。
次に VM 2 で {VM 1 のドメイン名}:5000/whalesay を pull します
● VM 2 上での操作
# docker pull {VM 1 のドメイン名}:5000/whalesay
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
{VM 1 のドメイン名}:5000/whalesay latest {イメージ ID} 4 months ago 247 MB
イメージを pull できています。試しにこの whalesay を実行してみましょう!
# docker run {VM 1 のドメイン名}:5000/whalesay cowsay boo
下のような画像が表示されましたら、pull した Docker コンテナが正常に起動できています。
なお、レジストリに登録されたイメージ一覧は、GET リクエストにて取得可能であり Web ブラウザにて次の URL を入力して確認できます。
https://{VM 1 のドメイン名}:5000/v2/_catalog
ブラウザに次のように表示されます。
{"repositories":["whalesay"]}
Ⅶ.最後に
Ⅰ 章の冒頭でも書きましたが、Docker レジストリとして Docker Hub や Docker Trusted Registry が用意されており、これらを使う方が運用やメンテナンスの面で楽です。
自分で Docker Registry を使ってプライベート レジストリを構築することは、今回紹介しましたようにやや煩雑な手間が必要ですし、運用コストもかかりますので、開発・検証のための環境もしくは、どうしてもインターネットに接続させたくない環境として利用するもののように思いました。