🧮

Docker プライベートレジストリを試す

2025/02/01に公開

概要

Dockerイメージを利用して Dockerのプライベートリポジトリを試します。

参考
https://distribution.github.io/distribution/

環境

Raspberry Pi 上の KVM で Docker12 を動かし、その中で Docker を動かす。

Docker のインストール

公式記載の通り。

sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run --rm hello-world

Docker レジストリを動かす

compose.yaml を用意する。

compose.yaml
services:
  # docker run -d -p 5000:5000 -v /work/vol:/var/lib/registry -name registry registry
  registry:                                                                                                                                                                                                          image: registry:latest
    ports:
      - 5000:5000
    volumes:
      - /work/vol:/var/lib/registry

コンテナを起動する。

$ sudo docker compose up -d

起動したことを確認

$ sudo docker compose ps
NAME              IMAGE             COMMAND                  SERVICE    CREATED              STATUS              PORTS
work-registry-1   registry:latest   "/entrypoint.sh /etc_"   registry   About a minute ago   Up About a minute   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp

Push してみる

hello-world:latest を hello-world:test としてプライベートリポジトリにプッシュしてみたい。

$ sudo docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    f1f77a0f96b7   9 days ago      5.2kB
registry      latest    d8876582179f   16 months ago   25MB

タグを付ける

$ sudo docker tag hello-world:latest localhost:5000/hello-world:test

$ sudo docker images
REPOSITORY                   TAG       IMAGE ID       CREATED         SIZE
hello-world                  latest    f1f77a0f96b7   9 days ago      5.2kB
localhost:5000/hello-world   test      f1f77a0f96b7   9 days ago      5.2kB
registry                     latest    d8876582179f   16 months ago   25MB

プッシュする

$ sudo docker push localhost:5000/hello-world:test
The push refers to repository [localhost:5000/hello-world]
98a92b28c9b8: Pushed
test: digest: sha256:d2b712d831f1cc89d997457109d01fb7ca4dd1d39a363d9f2f9426958a0ca44a size: 524

確認

$ curl http://localhost:5000/v2/_catalog
{"repositories":["hello-world"]}

$ curl http://localhost:5000/v2/hello-world/tags/list
{"name":"hello-world","tags":["test"]}

ローカルファイルを確認

$ du -sh /work/vol
148K    /work/vol

$ find /work/vol -type f -exec ls -l {} \;
-rw-r--r-- 1 root root 71 Jan 31 23:00 /work/vol/docker/registry/v2/repositories/hello-world/_manifests/tags/test/current/link
-rw-r--r-- 1 root root 71 Jan 31 23:00 /work/vol/docker/registry/v2/repositories/hello-world/_manifests/tags/test/index/sha256/d2b712d831f1cc89d997457109d01fb7ca4dd1d39a363d9f2f9426958a0ca44a/link
-rw-r--r-- 1 root root 71 Jan 31 23:00 /work/vol/docker/registry/v2/repositories/hello-world/_manifests/revisions/sha256/d2b712d831f1cc89d997457109d01fb7ca4dd1d39a363d9f2f9426958a0ca44a/link
-rw-r--r-- 1 root root 71 Jan 31 23:00 /work/vol/docker/registry/v2/repositories/hello-world/_layers/sha256/f1f77a0f96b7251d7ef5472705624e2d76db64855b5b121e1cbefe9dc52d0f86/link
-rw-r--r-- 1 root root 71 Jan 31 23:00 /work/vol/docker/registry/v2/repositories/hello-world/_layers/sha256/c9c5fd25a1bdc181cb012bc4fbb1ab272a975728f54064b7ae3ee8e77fd28c46/link
-rw-r--r-- 1 root root 3156 Jan 31 23:00 /work/vol/docker/registry/v2/blobs/sha256/c9/c9c5fd25a1bdc181cb012bc4fbb1ab272a975728f54064b7ae3ee8e77fd28c46/data
-rw-r--r-- 1 root root 524 Jan 31 23:00 /work/vol/docker/registry/v2/blobs/sha256/d2/d2b712d831f1cc89d997457109d01fb7ca4dd1d39a363d9f2f9426958a0ca44a/data
-rw-r--r-- 1 root root 562 Jan 31 23:00 /work/vol/docker/registry/v2/blobs/sha256/f1/f1f77a0f96b7251d7ef5472705624e2d76db64855b5b121e1cbefe9dc52d0f86/data

Pull してみる

タグをつけたイメージを削除する

$ sudo docker rmi localhost:5000/hello-world:test
Untagged: localhost:5000/hello-world:test
Untagged: localhost:5000/hello-world@sha256:d2b712d831f1cc89d997457109d01fb7ca4dd1d39a363d9f2f9426958a0ca44a

$ sudo docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    f1f77a0f96b7   10 days ago     5.2kB
registry      latest    d8876582179f   16 months ago   25MB

プルする

$ sudo docker pull localhost:5000/hello-world:test
test: Pulling from hello-world
Digest: sha256:d2b712d831f1cc89d997457109d01fb7ca4dd1d39a363d9f2f9426958a0ca44a
Status: Downloaded newer image for localhost:5000/hello-world:test
localhost:5000/hello-world:test

$ sudo docker images
REPOSITORY                   TAG       IMAGE ID       CREATED         SIZE
hello-world                  latest    f1f77a0f96b7   10 days ago     5.2kB
localhost:5000/hello-world   test      f1f77a0f96b7   10 days ago     5.2kB
registry                     latest    d8876582179f   16 months ago   25MB

異なるホストからアクセス

なにも考えず接続してみた

異なるホストから 192.168.11.15:5000 へアクセスして利用する。

$ curl http://192.168.11.15:5000/v2/_catalog
{"repositories":["hello-world"]}

タグを付ける

$ sudo docker tag hello-world:latest 192.168.11.15:5000/hello-world:oldest

$ sudo docker images | grep hello-world
192.168.11.15:5000/hello-world   oldest                    ee301c921b8a   21 months ago   9.14kB
hello-world                      latest                    ee301c921b8a   21 months ago   9.14kB

プッシュを試みるが、エラーとなる。

$ sudo docker push 192.168.11.15:5000/hello-world:oldest
The push refers to repository [192.168.11.15:5000/hello-world]
Get "https://192.168.11.15:5000/v2/": http: server gave HTTP response to HTTPS client

対応方法としては、以下の2パターンがある

  • セキュアではない通信を許可する。
  • https化する。

ここでは後者を選択。手っ取り早く自己署名証明書を利用することにする。
リバースプロキシ等の利用もいったん考えない。

レジストリ側で設定変更

証明書作成

# mkdir /work/vol/certs

# openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 -subj /CN=192.168.11.15 -keyout server.key -out server.crt -addext 'subjectAltName = IP:192.168.11.15'

# ls -l
total 8
-rw-r--r-- 1 root root 1123 Feb  1 02:52 server.crt
-rw------- 1 root root 1704 Feb  1 02:52 server.key

compose.yaml を修正

compose.yaml
services:
  # docker run -d -p 5000:5000 -v /vol:/var/lib/registry -name registry registry
  registry:
    image: registry:latest
    ports:
      - 5000:5000
    volumes:
      - /work/vol:/var/lib/registry
    environment:
      - REGISTRY_HTTP_TLS_CERTIFICATE=/var/lib/registry/certs/server.crt
      - REGISTRY_HTTP_TLS_KEY=/var/lib/registry/certs/server.key

更新を反映

$ sudo docker compose up -d
[+] Running 1/1
 _ Container work-registry-1  Started                   

再度接続を試みる

接続テスト

$ curl -k https://192.168.11.15:5000/v2/_catalog
{"repositories":["hello-world"]}

信頼するCAの情報を保存(dockerdの再起動は不要)

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

$ ls -l /etc/docker/certs.d/192.168.11.15\:5000/ca.crt
-rw-r--r-- 1 root root 1147 Feb  1 15:32 /etc/docker/certs.d/192.168.11.15:5000/ca.crt

プッシュしてみる

$ sudo docker push 192.168.11.15:5000/hello-world:oldest
The push refers to repository [192.168.11.15:5000/hello-world]
12660636fe55: Pushed
oldest: digest: sha256:a8ea96bb64d60208d6a56712042d1cf58aa4a7d3751b897b9320b0813c81cbb4 size: 524

結果確認

$ curl -k https://192.168.11.15:5000/v2/hello-world/tags/list
{"name":"hello-world","tags":["test","oldest"]}

認証設定

本稿では割愛するが、プライベートリポジトリを外に置いてインターネット経由で利用するなら認証を設定したいところ。
(気が向いたら追記する)

プロキシとして利用してみる

参考
https://distribution.github.io/distribution/recipes/mirror/
https://docs.docker.com/docker-hub/image-library/mirror/

フェッチするコンテナをキャッシュする。

設定追加

compose.yaml に以下のように設定を追加。

$ diff -u compose.yaml*
--- compose.yaml        2025-02-07 08:31:07.633794885 +0900
+++ compose.yaml.000    2025-02-07 07:36:25.536494351 +0900
@@ -9,4 +9,3 @@
     environment:
       - REGISTRY_HTTP_TLS_CERTIFICATE=/var/lib/registry/certs/server.crt
       - REGISTRY_HTTP_TLS_KEY=/var/lib/registry/certs/server.key
-      - REGISTRY_PROXY_REMOTEURL="https://registry-1.docker.io"

設定を追加したらデプロイしなおす

$ sudo docker compose up -d

クライアント側設定

プロキシを利用するように daemon.json に以下を追加。ファイルがなければ新規作成。

/etc/docker/daemon.json
{
  "registry-mirrors": ["https://192.168.11.14:5000"]
}

設定反映のため dockerd 再起動

$ sudo systemctl restat docker

設定が反映されたことを確認

$ sudo docker info | grep -A 1 -i mirror
 Registry Mirrors:
  https://192.168.11.14:5000/

確認

実際にイメージをプルして成功することを確認。

$ sudo docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
4d2547c08499: Pull complete
1529751f7538: Pull complete
bbefd32e7dcb: Pull complete
47cc26834fb6: Pull complete
aba9a01aa562: Pull complete
25ef5805725b: Pull complete
f6eaf43e06b3: Pull complete
Digest: sha256:91734281c0ebfc6f1aea979cffeed5079cfe786228a71cc6f1f46a228cde6e34
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

プロキシ側で以下を実行しておくと、ログが流れる。

$ sudo docker compose logs -f registry
GitHubで編集を提案

Discussion