レジストリ・サーバのデプロイ

Docker 1.6.0 以上のインストール が必要です。

ローカルホスト上で実行

レジストリを開始します。

docker run -d -p 5000:5000 --restart=always --name registry registry:2

これで Docker と使えるようになりました。

Docker Hub からイメージを手に入れ、自分のレジストリ上にタグ付けします。

docker pull ubuntu && docker tag ubuntu localhost:5000/ubuntu

… それからイメージに送信します。

docker push localhost:5000/ubuntu

… そして、レジストリから取得し直します。

docker pull localhost:5000/ubuntu

レジストリを停止するには、次のようにします。

docker stop registry && docker rm -v registry

ストレージ

デフォルトでは、ホスト・ファイルシステム上の docker volume にレジストリのデータが保管されます。ローカル・ファイルシステムをストレージに使う場合は、ボリュームに対する適切な理解が必要です。

特に、レジストリのデータにより簡単にアクセスするため、ボリュームの場所を指定する場合があるでしょう。それには、次のように実行します。

docker run -d -p 5000:5000 --restart=always --name registry \
  -v `pwd`/data:/var/lib/registry \
  registry:2

代替手段

ローカル・ファイルシステムの替わりに、他のストレージ・バックエンド の利用を考えても良いでしょう。 ストレージの設定オプション で別のストレージ・バックエンドを設定できます。

これらのストレージを使うと、レジストリのスケールを簡単にし、ストレージの冗長性と可用性機能を活用できます。

ドメインでレジストリを実行

localhost 上で実行するだけでなく、多くの人はレジストリを広く使いたいと思うでしょう。実現するには、Docker エンジンで TLS を使って安全にする必要があります。TLS の概念はウェブサーバに SSL 設定をするのと非常に似ています。

証明書の取得

ここでは自分のドメインを myregistrydomain.com であると想定し、対象のレジストリ上のホストに対して DNS レコードが示されているものとします。まずは CA から証明書(certificate)を取得します。

certs ディレクトリを作成します。

mkdir -p certs

それから、自分の crt ファイルを certs/domain.crt に移動・名称変更し、自分の鍵ファイルを certs/domain.key とします。

次のステップに進む前にレジストリを停止します。それから、レジストリを TLS を有功にして再起動します。

docker run -d -p 5000:5000 --restart=always --name registry \
  -v `pwd`/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

これで他の Docker ホストから、レジストリに対して接続できるようになります。

docker pull ubuntu
docker tag ubuntu myregistrydomain.com:5000/ubuntu
docker push myregistrydomain.com:5000/ubuntu
docker pull myregistrydomain.com:5000/ubuntu

補足

証明書の発行機関は 中間証明書(intermediate certificate) を提供する場合があります。このような場合、証明書と中間証明書を1つのファイル形式にまとめる必要があります。作業は cat コマンドで行えます。

cat domain.crt intermediate-certificates.pem > certs/domain.crt

別の方法

まれにしかアドバイスしませんが、自己証明書を使いたい場合や、安全ではない方法でレジストリを動かしたいかもしれません。詳細は こちら をご覧ください。

負荷分散の検討

ロードバランサを使った負荷の分散を行う手法は、TLS を無効化しますが、高い可用性を提供します。負荷分散の設定の全般については、このドキュメントの範囲外です。ここでは手順をスムーズに進めるための検討事項を扱います。

最も重要な点は、ロードバランサへのクラスタ登録には、同じ共通リソースが登録されている必要があります。つまり、現時点のレジストリのバージョンでは、以下の項目が同じでなくてはいけません。

  • ストレージ・ドライバ

  • HTTP ソケット

  • Redis キャッシュ(設定した場合は)

もしも何かが違うと、レジストリはリクエストの処理で問題を起こします。たとえば、ファイルシステム・ドライバを使うときは、全てのレジストリ・インスタンスは同じファイルシステムのルートにアクセスできる必要があります。つまり、同じマシン上に存在する必要性を意味します。s3 や azure のような別のドライバの場合は、同じリソースにアクセスできるようにすべきであり、個々の設定を共有することになります。 HTTP ソケット コーディネートのアップロードを、同じインスタンス間で行う必要もあります。異なった redis インスタンスを設定しても動作しますが(この記事を書いている時点では)、最適ではありません。インスタンスが共有されないことで、バックエンドに対する多くの直接リクエストが発生するかもしれません。

正常なヘッダを得ることは非常に重要です。全てのレスポンスに対するリクエストは「/v2/」url スペースの下で行われます。 Docker-Distribution-API-Version ヘッダに対する値は「registry/2.0」のような値であり、これは 4xx 系ノレスポンスと同等です。このヘッダにより、Docker エンジンは迅速に認証領域を確認でき、必要があればバージョン1のレジストリを無効化できます。

一連の考えに於いて、ユーザは X-Forwarded-Proto, X-Forwarded-ForHosts ヘッダに「クライアント側」の値を適切に送る必要があります。これがうまくいかないと、レジストリは内部のホスト名に対してリダイレクトされるか、https から http へといったダウングレードされてしまうでしょう。

適切に安全に設定されたレジストリであれば、「/v2/」エンドポイントに証明書なくアクセスしようとしても、「401」を返します。この応答には WWW-Authenticate チャレンジを含んでおり、ベーシック認証やトークン・サービスといった認証のガイドラインを提供します。ロードバランサがヘルスチェックを持っていれば、401 レスポンスは正常であり、そのほかはダウンしているとみなすような設定をすることを推奨します。レジストリに対する設定を確実に行わないと、認証の問題によってレジストリが保護されず、晒されてしまう問題が起こり得ます。もしも Amazon の Elastic Load Balancer のような洗練されていないロードバランサを使う場合は、正常を示すレスポンス・コードを変更できません。ヘルスチェックは直接「/」をチェックするので、常に 200 OK レスポンスを返すためです。

アクセス制限

安全なローカルのネットワーク上でレジストリを動かす場合を除き、レジストリは常にアクセス制御を実装したほうが良いでしょう。

内蔵のベーシック認証

アクセス制限を行うのに一番簡単な方法は、ベーシック認証を通す方法です(これはウェブサーバのベーシック認証の仕組みと非常に似ています)。

警告

安全ではないレジストリ(insecure registry)では認証が 使えません 。動作のためには TLS の設定を第一に 行う必要があります。

まずはパスワード・ファイルを作成し、ユーザ「testuser」、パスワード「testpassword」のエントリを1行追加します。

mkdir auth
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd

次の手順に進む前に、レジストリを一度停止します。それから再起動します。

docker run -d -p 5000:5000 --restart=always --name registry \
  -v `pwd`/auth:/auth \
  -e "REGISTRY_AUTH=htpasswd" \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -v `pwd`/certs:/certs \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  registry:2

これで、次のように実行できます。

docker login myregistrydomain.com:5000

あとは、認証されたユーザがイメージの送信・受信ができます。

捕捉

X509 エラーが表示されるのは、たいて自己署名した証明書を使おうとしている場合です。 docker デーモンを適切に設定する のに失敗しています。

別の方法

  1. レジストリの前にプロキシがあるよう設計されたネットワークでも、ベーシック認証を通過できるようにしたいと思うでしょう。このようなパターンには、 レシピ例 をご覧ください。

  1. あるいは、レジストリが delegated 認証をサポートしている場合は、特定のユーザを信頼されたトークンを持つサーバに転送します。この手法は投資がとりわけ必要であり、完全に ACL を設定したい場合や、認証システム全体と認証システムを通してレジストリを統合したい場合に役立つでしょう。

バックグラウンドの情報についてはこちら から、設定情報の詳細はこちら から参照できます。

認証サービスやサードパーティー製の機能を活用するには、自分自身で実装する必要があるのをご注意ください。

Docker Compose で管理

レジストリの設定がより複雑になると、非常に退屈なものになってしまいます。

レジストリの操作を簡単にするのに、 Docker Compose を使うことを推奨します。

以下は簡単な 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/data:/var/lib/registry
    - /path/certs:/certs
    - /path/auth:/auth

警告

/path のディレクトリ部分は、先ほど certsauth を置いた場所に置き換えてください。

レジストリの起動はとてもシンプルです。

docker-compose up -d

次へ

以下のセクションで、より詳細かつ高度な情報をご覧いただけます。

参考

Deploying a registry server

https://docs.docker.com/registry/deploying/