AWS S3を保存先としたプライベートなDocker Registryを公式コンテナから簡単導入

タイトルの通り。作業メモです。

テスト用イメージ作成

テストで利用するイメージを作ります。

Dockerfile作って。

cat <<EOF > Dockerfile
from alpine:latest
ENTRYPOINT ["echo","myimage"]
EOF

ビルドして。

docker build --no-cache -t myimage .

ビルドされた内容を確認して、

$ docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
myimage                       latest              1c2b9867a0f5        4 seconds ago       3.97 MB

実行確認します。 echo myimage されています。

$ docker run myimage
myimage

このイメージを使い回しながらregistryの導入の確認をしていきます。

registryのダウンロード

Doker Registryはこちらの公式イメージを利用します。

https://hub.docker.com/_/registry/

まず、イメージをダウンロードします。これ書いている時点で最新の 2.6.2 を利用します。

docker pull registry:2.6.2
$ docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
registry                      2.6.2               28525f9a6e46        3 weeks ago         33.2 MB

registryを起動してみます。

docker run -d --name registry -p 5000:5000 registry:2.6.2 
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
ee40c1fa8bc0        registry:2.6.2      "/entrypoint.sh /e..."   4 seconds ago       Up 4 seconds        0.0.0.0:5000->5000/tcp   adoring_ardinghelli

PORTもListenになっているのが確認できました。

$ ss -tan '( sport == 5000 )'
State      Recv-Q Send-Q Local Address:Port            Peer Address:Port
LISTEN     0      128          :::5000                   :::*

イメージをS3へ保存する設定

registryに登録されたイメージがS3に保存されるように設定します。以下を参考に行います。

Configuring a registry | Docker Documentation

公式のDocker Registryのイメージは以下の設定ファイル含んだ形でビルドされています。

github.com

この設定ファイルを元に、 strage の向き先をAWS S3に変更します。

こちらを読み換えて使います。

  s3:
    accesskey: awsaccesskey
    secretkey: awssecretkey
    region: us-west-1
    bucket: bucketname
    rootdirectory: /s3/object/name/prefix

rootdirectoryで設定した値の下にディレクトリが掘られていく形になります。例えば、 /s3/object/name/prefix/docker/registry/... のような形です。

以下のような設定になるので、このファイルを適当なフォルダ(今回は /path/to/config_aws.yml )に保存します。

version: 0.1
log:
  fields:
    service: registry
storage:
  delete:
    enabled: true
  cache:
    blobdescriptor: inmemory
  s3:
    accesskey: <accesskey>
    secretkey: <awssecretkey>
    region: ap-northeast-1
    bucket: otomo-test01
    rootdirectory: /myregistry/host01
http:
  addr: :5000
  headers:
    X-Content-Type-Options: [nosniff]
health:
  storagedriver:
    enabled: true
    interval: 10s
    threshold: 3

設定ファイルを置き換える形でregistryコンテナ起動します。

docker run -d -p 5000:5000 --name registry \
             -v /path/to/config_aws.yml:/etc/docker/registry/config.yml \
             registry:2.6.2

イメージをRegistry経由でS3にPush

上でテスト用に作ったイメージをPushしてみます。

$ docker tag myimage:latest localhost:5000/testrepo/myimage:latest
$ docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/testrepo/myimage   latest              11cdafc8a607        9 minutes ago       3.97 MB

Pushが正常に完了しました。

$ docker push localhost:5000/testrepo/myimage:latest
The push refers to a repository [localhost:5000/testrepo/myimage]
5bef08742407: Pushed
latest: digest: sha256:e96fd1e0a12a0794a20e1951ee8b4ab8001c2c11aca65fd36869b24e46265561 size: 528

S3の画面見ると設定通りディレクトリが作成されているのがわかります。

先ほどローカルに保存されていたイメージ削除してから、

docker rmi localhost:5000/testrepo/myimage:latest

docker pullして docker runで実行も問題ありません。

$ docker pull localhost:5000/testrepo/myimage:latest
Unable to find image 'localhost:5000/testrepo/myimage:latest' locally
latest: Pulling from testrepo/myimage
Digest: sha256:e96fd1e0a12a0794a20e1951ee8b4ab8001c2c11aca65fd36869b24e46265561
Status: Downloaded newer image for localhost:5000/testrepo/myimage:latest
$ docker run localhost:5000/testrepo/myimage:latest
myimage

S3に保存したイメージを新規の別のコンテナからも利用できるか

S3接続設定ファイルで起動していたregistryコンテナを削除します。

docker rm -f registry

先ほどpullしたイメージも削除します。

docker rmi -f localhost:5000/testrepo/myimage:latest

S3接続設定ファイルを利用せずにregistryコンテナを起動します。

docker run -d -p 5000:5000 --name registry registry:2.6.2

当然イメージはpullできません。

$ docker pull localhost:5000/testrepo/myimage:latest
Pulling repository localhost:5000/testrepo/myimage
Error: image testrepo/myimage:latest not found

もう一回削除。

$ docker rm -f registry

今度はS3接続設定ファイルでもう一度コンテナを起動します。これで先ほどS3に保存された情報にアクセスできるはずです。

$ docker run -d -p 5000:5000 --name registry \
             -v /path/to/config_aws.yml:/etc/docker/registry/config.yml \
             registry:2.6.2

ちゃんとS3からイメージ取れているみたいです。

$ docker run localhost:5000/testrepo/myimage:latest
Unable to find image 'localhost:5000/testrepo/myimage:latest' locally
latest: Pulling from testrepo/myimage
Digest: sha256:e96fd1e0a12a0794a20e1951ee8b4ab8001c2c11aca65fd36869b24e46265561
Status: Downloaded newer image for localhost:5000/testrepo/myimage:latest
myimage

別ホストからdocker pullする

ここからは余談ですが、別ホストからDocker pullしようとすると以下のようなエラーが出ます。

$ docker pull 192.168.10.1:5000/testrepo/myimage:latest
Error response from daemon: Get https://192.168.10.1:5000/v1/_ping: http: server gave HTTP response to HTTPS client

httpsの設定すればいいのですが、内部でしか使わないのでhttp通信だけで良い場合は以下のように回避可能です。

insecure-registriesにregistryコンテナが起動しているホストを追加。

cat <<EOF > /etc/docker/daemon.json
{"insecure-registries":["192.168.10.1:5000"] }
EOF

Dockerデーモンの再起動。

/etc/init.d/docker restart

これでpullできるようになります。