コンテナレジストリは、コンテナイメージをプッシュしたり、プルしたりするためのストORAGEカタログです。

開発者向けの公的や私的なレジストリが多く存在しています。Docker HubAmazon ECRGoogle Cloud Artifact Registryなどです。しかし、外部のベンダーに頼る代わりに、自分自身でイメージをホストしたいときがあります。これにより、レジストリの構成方法や、コンテナイメージをホストされる場所に対するコントロールができます。

この記事は、自ホストコンテナレジストリを設定する实战のチュートリアルであり、あなたに教えています。

目次

この記事を最大限に楽しむには、DockerやNGINXなどのツールに既に熟悉し、コンテナーの概念に一般的に理解していることが重要です。

コンテナー画像とは何か?

コンテナーレジストリーについて話す前に、まずコンテナー画像を理解してください。簡単に言うと、コンテナーを実行するためのすべてのファイル、ライブラリ、設定を含んだパッケージです。それはレイヤーに分割されていて、各レイヤーはファイルシステムの変更を追加、削除、修正する集合の設定を表します。

コンテナー画像を作成する最も一般的な方法は、Dockerfileを使用することです。

# 画像を構築
docker build -t pliutau/hello-world:v0 .

# ローカルで画像を確認
docker images
# レポジトリ    タグ       画像ID         作成日時          サイズ
# hello-world   latest    9facd12bbcdd   22秒前           11MB

これはあなたのローカルマシン上に保存されるコンテナイメージを作成します。しかし、このイメージを他の人たちに共有したい場合、または別のマシンで使用したい場合はどうしますか?これはコンテナレジストリが役立つ所です。

コンテナレジストリとは何でしょう?

コンテナレジストリは、コンテナイメージをプッシュおよびプルすることができるストORAGE カタログです。イメージはレポジトリに分けられます。レポジトリは同一の名前を持つ関連のあるイメージのコレクションです。たとえば、Docker Hubレジストリ上では、nginxはNGINXの異なるバージョンを含むレポジトリの名前です。

いくつかのレジストリはパブリックであり、これらにホストされるイメージはインターネット上の谁もがアクセスできます。Docker Hubのようなパブリックレジストリは、オープンソースプロジェクトをホストするのに適しています。

その一方、プライベートレジストリは、クラウド上またはプライベートサイト上にホストされる企業用コンテナイメージストORAGEにセキュリティとプライバシーを取り入れる手段を提供します。これらのプライベートレジストリには、高度なセキュリティ機能と技術サポートが通常含まれます。

プライベートレジストリの選択肢が増え続けています。Amazon ECRGCP Artifact RegistryGitHub Container Registryなどです。また、Docker Hubはプライベートレポジトリ機能も提供しています。

開発者としては、docker pushコマンドやdocker pullコマンドを使うときにコンテナレジストリと対話します。

docker push docker.io/pliutau/hello-world:v0

# Docker Hubの場合、レジストリ部分をスキップすることもできます
docker push pliutau/hello-world:v0

コンテナイメージURLの解剖学を見てみましょう:

docker pull docker.io/pliutau/hello-world:v0@sha256:dc11b2...
                |            |            |          |
                ↓            ↓            ↓          ↓
             registry    repository      tag       digest

コンテナレジストリをセルフホストしたい理由

AWSやGCPのようなプロバイダに依存する代わりに、自分自身でイメージをホストしたい場合があります。こうすることで、インフラストラクチャを内部で維持し、外部ベンダーへの依存を減らすことができます。

セルフホストレジストリは自社サーバー上で実行されるため、レジストリの構成方法やコンテナイメージのホスティング場所をより詳細に制御できます。

How to Self-host a Container Registry

利用可能なオープンソースのコンテナーレジストリソリューションがいくつかあります。最も人気のあるものはDockerによって公式にサポートされているもので、registryと呼ばれ、コンテナイメージとアーティファクトの保存と配布のための実装があります。

以下はサーバ上でレジストリを実行する主なステップです:

  • DockerとDocker Composeをサーバにインストールします。
  • レジストリコンテナを設定し実行します。
  • TLSを処理し、registryコンテナにリクエストを転送するためにNGINXを実行する。
  • SSL証明書をセットアップし、ドメインを設定する。

ステップ1: DockerとDocker Composeをサーバーにインストールする

Dockerをサポートしているサーバーであれば、どのサーバーでも使用できます。例えば、UbuntuのDigitalOcean Dropletを使うことができます。

neofetch

# OS:Ubuntu 20.04.6 LTS x86_64
# CPU:Intel Xeon (2) @ 2.200GHz
# Memory:3908MiB

VMの中に入ったら、DockerとDocker Composeをインストールしましょう。

# install docker engine and docker-compose
sudo snap install docker

# verify the installation
docker --version
docker-compose --version

Step 2: Configure and run the registry container

Next we need to configure our registry container.以下のcompose.yamlファイルは、イメージを格納するボリュームとパスワードファイルを格納するボリュームを持つレジストリコンテナを作成します。

services:
  registry:
    image: registry:latest
    environment:
      REGISTRY_AUTH: htpasswd
      REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
      REGISTRY_AUTH_HTPASSWD_PATH: /auth/registry.password
      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
    volumes:
      # パスワードファイルをマウントする
      - ./registry/registry.password:/auth/registry.password
      # データディレクトリをマウントする
      - ./registry/data:/data
    ports:
      - 5000

REGISTRY_AUTH_HTPASSWD_PATHで定義されたパスワードファイルは、 Registryから画像をプッシュまたはプルする際に、ユーザーの認証を行うために使用されます。私たちはhtpasswdコマンドを使用してパスワードファイルを作成する必要があります。また、画像を格納するフォルダを作成する必要があります。

mkdir -p ./registry/data

# htpasswdをインストールする
sudo apt install apache2-utils

# パスワードファイルを作成します。 username: busy, password: bee
htpasswd -Bbn busy bee > ./registry/registry.password

今は Registryコンテナを起動することができます。このメッセージを表示すると、すべてが正しく動作していることが示されます。

docker-compose up

# 成功の場合、こんなような出力が表示されます。
# registry | level=info msg="listening on [::]:5000"

ステップ3: TLSを処理するためにNGINXを実行する

前述のように、NGINXを使用してTLSを処理し、リクエストをRegistryコンテナにフォワードすることができます。

Docker Registryは有効な信頼されたSSL証明書を必要とします。Let’s Encryptを使用したり、手動で取得したりできます。サーバーにドメイン名が指されていることを確認してください(私の場合はregistry.pliutau.com)。デモのためには、certbotを使用して証明書を取得し、./nginx/certsディレクトリに配置しました。

compose.yaml ファイルに以下のサービスを追加することで、Docker Registryをコンテナ内で運行させているため、NGINXをコンテナ内でも運行することができます。

services:
  registry:
    # ...
  nginx:
    image: nginx:latest
    depends_on:
      - registry
    volumes:
      # Nginx 設定をマウント
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      # Let's Encryptから取得した証明書をマウント
      - ./nginx/certs:/etc/nginx/certs
    ports:
      - "443:443"

私の nginx.conf ファイルは以下のようになります。

worker_processes auto;

events {
    worker_connections 1024;
}

http {
    upstream registry {
        server registry:5000;
    }

    server {
        server_name registry.pliutau.com;
        listen 443 ssl;

        ssl_certificate /etc/nginx/certs/fullchain.pem;
        ssl_certificate_key /etc/nginx/certs/privkey.pem;

        location / {
            # 大きな画像のための重要な設定
            client_max_body_size                1000m;

            proxy_pass                          http://registry;
            proxy_set_header  Host              $http_host;
            proxy_set_header  X-Real-IP         $remote_addr;
            proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Proto $scheme;
            proxy_read_timeout                  900;
        }
    }
}

準備完了!

これらのステップの後、 registry および Nginx コンテナを実行することができます。

docker-compose up

次に、クライアント側で registry から画像をプッシュしたり、プルしたりする準備ができます。しかし、まずは registry にログインする必要があります。

docker login registry.pliutau.com

# ユーザー名: busy
# パスワード: bee
# ログインに成功しました

次に、自ホストしている registry に画像を構築してプッシュする準備をするでしょう。

docker build -t registry.pliutau.com/pliutau/hello-world:v0 .

docker push registry.pliutau.com/pliutau/hello-world:v0
# v0: digest: sha256:a56ea4... size: 738

サーバー上で、data フォルダにアップロードされた画像を確認することができます。

ls -la ./registry/data/docker/registry/v2/repositories/

その他のオプション

上記の例に従って、Kubernetes 上で registry を実行することもできます。また、Docker や Kubernetes に互換性のあるアドバンシストントな managed registry サービス Harbor を使用することもできます。Harbor は開源の registry で、高度なセキュリティ機能を提供しています。

また、自ホストされたレジストリにUIを设けたい場合、joxit/docker-registry-uiのようなプロジェクトを使用し、別のコンテナ内で実行することができます。

結論

自ホストされたコンテナレジストリは、レジストリの完全なコントロールを持つことを可能にし、デプロイの方法についての情報を取得することができます。同様に、レジストリの保守と安全性のコストも付随します。

自ホストされたレジストリを実行する理由は何でもあまり、今ではその方法を理解できました。ここから、異なるオプションを比較し、最适合の需要に合わせたものを選択することができます。

このデモの完全なソースコードはGitHub上にあります。また、我们的YouTube频道で動画で見ることもできます。