のぴぴのメモ

自分用のLinuxとかの技術メモ

EC2(Amazon Linux2)にprivateなdocker registryの作るメモ

1.はじめに

検証用にプライベートなdocker registryをAWS EC2上のAmazon Linux2に作った時のメモです。レジストリを立てて、別のサーバからdockerイメージをpush/pullして確認するまでを記録しています。
内容は、こちらの記事を参考にしています。

2.セットアップ手順

2.1 前提環境

雑な絵ですが、こんな感じの構成を作ります。
f:id:nopipi:20180721192454p:plain
このメモの前提となる構成は以下の通りです。

  • OS:Amazon Linux2 (AMI ID: amzn2-ami-hvm-2.0.20180622.1-x86_64-gp2)
  • docker registryを動かすインスタンスのNW構成:
    • プライベートDNS: ip-10-203-64-60.ec2.internal
    • パブリックIPを付与またはNATGWでインターネットアクセスを可能にする
    • セキュリティグループで、tcp:443ポート(https)、tcp:22ポート(ssh作業用)の通信ができるよう設定する
  • key pairs

2.2 dockerのセットアップ

プライベートdocker registryをインストールするインスタンスsshログインして、下記の記事の手順でdockerをセットアップします。
nopipi.hatenablog.com

dockerレジストリ用のディレクトリ作成

レジストリ用に以下の構造のディレクトリを作成します。

/home/docker/
         └── registry
             ├── certs
             └── data

ディレクトリの作成と確認手順はこちらですl

sudo mkdir -p /home/docker/registry/{certs,data}
find /home/docker/

2.3 SSLの自己証明書(オレオレ証明書)の作成

検証用なのでオレオレ証明書で勘弁してもらいます。opensslコマンドの途中で聞かれる内容は、とりあえず全てデフォルト(リターン)とします。

openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt
  • オプション説明
    • req : 証明書署名要求(CSR)の管理
      • "-newkey rsa:4096": 4096bitのRSA形式の秘密鍵を同時に作成する
      • "-nodes" : 秘密鍵を暗号化しない
      • "-sha256" :
      • "-keyout domain.key" : 秘密鍵のファイル名を、"domain.key"にする
      • "-x509" : x509の証明書を出力する
      • "-days 365" : 証明書の有効期間を365日にする。
      • "-out domain.crt”: 証明書のファイル名を、"domain.crt"にする。

作成した秘密鍵(domain.key)と、サーバ証明書(domain.crt)をレジストリディレクトリに移動します。

sudo mv domain.key /home/docker/registry/certs/
sudo mv domain.crt /home/docker/registry/certs/

2.4 dockerレジストリの起動

レジストリのイメージ登録とコンテナの実行を同時に行います。

cd /home/docker/registry
docker run -d \
 --restart=always \
 --name docregistry \
 -v `pwd`/certs:/certs \
 -v `pwd`/data:/var/lib/registry \
 -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
 -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
 -e REGISTRY_STORAGE_DELETE_ENABLED=True \
 -p 443:443 \
 registry:2
  • オプション説明
    • "-d": コンテナのバックグラウンド実行
    • "--restart=always" : 再起動ポリシー設定。コンテナダウン時は常にコンテナ再起動を試みる。
    • "--name" : コンテナ名称
    • "-v xxx" : コンテナのVolume機能の設定
    • "-e xxx" : コンテナ内の環境変数設定
    • "-p 443:443" : コンテナの公開ポート設定。コンテナの443portを外部の443portで見せる
    • "registry:2" : レジストリのimage。docker runの中で、docker hubからpullされる

dockerイメージを確認します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
registry            2                   b2b03e9146e1        2 weeks ago         33.3MB

registryコンテナが実行されているか確認します。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
ddd75d47e43a        registry:2          "/entrypoint.sh /etc…"   16 seconds ago      Up 16 seconds       0.0.0.0:443->443/tcp, 5000/tcp   docregistry

3.クライアントからdockerイメージをpushしてみる

dockerのクライアントとなる別のサーバから、プライベートdocker registryへのimageのpush、pullを確認します。

3.1 httpsの接続確認

まずは素のhttpsで、クライアントから、プライベートdocker registryにアクセス可能かを確認します。

(1)サーバ証明書のコピー

プライベートdocker registry用に作成したサーバ証明書を、クライアントにコピーします。ssh ログインするときに"-A"オプションを利用するとsshの鍵を自動でforwardingしてくれるので、クライアントのインスタンス秘密鍵を置く必要がありません。(今回の話からは脱線するので、詳しくはこちらを参照)
MACの場合でデフォルトの秘密鍵を利用する場合は、こんな感じでログインします。

ssh -A ec2-user@[クライアントのDNS or IP]
scp ec2-user@ip-10-203-64-60.ec2.internal:/home/docker/registry/certs/domain.crt .
(2)https接続確認

curl でコピーしたサーバ証明書を指定して、プライベートdocker registryにアクセスしてエラーにならなければOKです。

$ curl --cacert domain.crt https://ip-10-203-64-60.ec2.internal/v2/_catalog

3.2 dockerへのサーバ証明書登録

コピーしたサーバ証明書をdockerの設定ディレクトリに格納します。
格納は、下記ルールに基づいて格納します。

この/etc/dockerディレクトリは、root権限がないと移動することもできないので、rootにチェンジして作業します。

$ sudo -i
# cd /etc/docker/
# mkdir certs.d
# cd certs.d/
# mkdir ip-10-203-64-60.ec2.internal
# cp /home/ec2-user/domain.crt /etc/docker/certs.d/ip-10-203-64-60.ec2.internal/ca.crt
# exit
$ 

サーバ証明書の登録方法は他にもあります。詳細は、公式ドキュメントまたはこちらのQiitaを参照してください。

3.3 プライベートレジストリへのイメージのpushとpull

動作確認として、docker hubからubuntuのコンテナイメージをpullしてきて、プライベートdockerレジストリに登録してみます。

(1)イメージのpullとtag作成

ubuntuのイメージをpullしてきて、プライベートdockerレジストリ登録用のtagを作成します。

docker pull ubuntu:16.04
docker tag ubuntu:16.04 ip-10-203-64-60.ec2.internal/my-ubuntu
docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
ubuntu                                   16.04               e13f3d529b1a        4 days ago          115MB
ip-10-203-64-60.ec2.internal/my-ubuntu   latest              e13f3d529b1a        4 days ago          115MB
(2)イメージのpush

プライベートdocker registryにイメージをpushします。

docker push ip-10-203-64-60.ec2.internal/my-ubuntu
The push refers to repository [ip-10-203-64-60.ec2.internal/my-ubuntu]
709bdd00b1a4: Pushed 
07b9c3c04cbd: Pushed 
6eaddaf493f1: Pushed 
a0e188d0e278: Pushed 
711e4cb62f50: Pushed 
latest: digest: sha256:0d06090fff94c0a3640729c7ef7e6b36ad5b41bec600cc2be92739c90d204243 size: 1357

pushしたイメージが登録されているか、プライベートdocker registryのカタログを参照します。

[ec2-user@ip-10-203-128-109 ~]$ curl --cacert domain.crt https://ip-10-203-64-60.ec2.internal/v2/_catalog
{"repositories":["my-ubuntu"]}
(3)イメージのpull

まず確認のため、ローカルにあるdockerイメージを削除します。

$ docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
ubuntu                                   16.04               e13f3d529b1a        4 days ago          115MB
ip-10-203-64-60.ec2.internal/my-ubuntu   latest              e13f3d529b1a        4 days ago          115MB

$ docker rmi e13f3d529b1a e13f3d529b1a

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

プライベートdocker registryから、イメージをpullして確認します。

$ docker pull ip-10-203-64-60.ec2.internal/my-ubuntu

$ docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
ip-10-203-64-60.ec2.internal/my-ubuntu   latest              e13f3d529b1a        4 days ago          115MB