自己署名 SSL 証明書を使用した Docker レジストリの設定方法

DockerBeginner
オンラインで実践に進む

はじめに

Docker は、開発者や DevOps チームにとって不可欠なツールとなり、コンテナ化されたアプリケーションのシームレスなデプロイと管理を可能にしています。プライベート Docker レジストリを使用する場合、Docker クライアントとレジストリサーバー間の通信を保護することは、コンテナイメージを保護するために非常に重要です。

この実験(Lab)では、ローカル Docker レジストリをセットアップし、自己署名 SSL 証明書を使用してセキュリティを確保する方法を学びます。このアプローチは、開発環境、テスト、および信頼できる認証局から証明書を購入することなく、安全なレジストリが必要な学習シナリオに最適です。

このチュートリアルを終える頃には、安全な通信に HTTPS を使用する機能的な Docker レジストリが完成し、開発環境内で Docker イメージを安全にプッシュおよびプルできるようになります。

基本的な Docker レジストリのセットアップ

SSL で Docker レジストリを保護する前に、まず Docker レジストリとは何かを理解し、動作する基本的なレジストリをセットアップしましょう。

Docker レジストリとは?

Docker レジストリは、Docker コンテナイメージのストレージおよび配布システムです。これにより、次のことが可能になります。

  • Docker イメージを一元的に保存する
  • チームまたは組織とイメージを共有する
  • イメージへのアクセスを制御する
  • さまざまな環境でイメージからコンテナをデプロイする

Docker Hub は最もよく知られたパブリックレジストリですが、多くの組織にとって、セキュリティ、パフォーマンス、および制御のためにプライベートレジストリを持つことが不可欠です。

基本的なレジストリのセットアップ

まず、シンプルで安全でない Docker レジストリを実行することから始めましょう。

  1. レジストリデータを保存するためのディレクトリを作成します。

    mkdir -p ~/project/registry-data
  2. 公式イメージを使用して、基本的な Docker レジストリを実行します。

    docker run -d -p 5000:5000 --restart=always --name registry -v ~/project/registry-data:/var/lib/registry registry:2

    このコマンドは以下を行います。

    • レジストリコンテナをデタッチモード (-d) で実行します。
    • ホストのポート 5000 をコンテナのポート 5000 にマッピングします。
    • コンテナが停止した場合に自動的に再起動するように設定します。
    • コンテナに "registry" という名前を付けます。
    • 作成したディレクトリをレジストリデータを保存するためにマウントします。
  3. レジストリが実行されていることを確認します。

    docker ps

    次のような出力が表示されるはずです。

    CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS                    NAMES
    a7d8098de3a2   registry:2   "/entrypoint.sh /etc…"   5 seconds ago   Up 4 seconds   0.0.0.0:5000->5000/tcp   registry
  4. サンプルイメージをプッシュして、レジストリをテストします。

    まず、小さなイメージをプルします。

    docker pull hello-world

    ローカルレジストリ用にタグ付けします。

    docker tag hello-world localhost:5000/hello-world

    レジストリにプッシュします。

    docker push localhost:5000/hello-world

    レジストリにイメージがプッシュされていることを示す出力が表示されるはずです。

  5. 次のステップでセキュリティを確保する前に、レジストリコンテナを停止します。

    docker stop registry
    docker rm registry

この基本的なレジストリは機能しますが、大きな制限があります。それは HTTP を使用しており、安全ではありません。Docker クライアントは、デフォルトでは安全でないレジストリからのプッシュまたはプルを拒否します。次のステップでは、SSL を使用してレジストリを保護します。

自己署名 SSL 証明書の生成

Docker レジストリの基本を理解したので、自己署名 SSL 証明書を生成してセキュリティを確保しましょう。この証明書により、レジストリとの HTTPS 通信が可能になります。

自己署名証明書とは?

自己署名証明書は、信頼できる認証局 (CA) によって署名されていない SSL 証明書です。パブリックインターネットに公開されている本番環境には適していませんが、自己署名証明書は、開発、テスト、および内部アプリケーションに最適です。

証明書とキーの生成

広く使用されている暗号化ツールキットである OpenSSL を使用して、証明書を作成します。

  1. 証明書を保存するためのディレクトリを作成します。

    mkdir -p ~/project/registry-certs
    cd ~/project/registry-certs
  2. 秘密鍵を生成します。

    openssl genrsa -out registry.key 2048

    このコマンドは、2048 ビット RSA 秘密鍵を生成します。成功した場合、出力は表示されません。

  3. 秘密鍵を使用して、証明書署名要求 (CSR) を作成します。

    openssl req -new -key registry.key -out registry.csr

    証明書に含める情報を入力するように求められます。

    Country Name (2 letter code) [AU]:US
    State or Province Name (full name) [Some-State]:California
    Locality Name (eg, city) []:San Francisco
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Company
    Organizational Unit Name (eg, section) []:IT
    Common Name (e.g. server FQDN or YOUR name) []:localhost
    Email Address []:admin@example.com

    注:Common Name には、ローカルマシンでレジストリに接続するため、localhost を入力します。

    また、以下も尋ねられます。

    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:

    Enter キーを押して、これらを空白のままにすることができます。

  4. CSR を使用して、自己署名証明書を生成します。

    openssl x509 -req -days 365 -in registry.csr -signkey registry.key -out registry.crt

    このコマンドは、365 日間有効な自己署名証明書を作成します。

    次のような出力が表示されるはずです。

    Signature ok
    subject=C = US, ST = California, L = San Francisco, O = Example Company, OU = IT, CN = localhost, emailAddress = admin@example.com
    Getting Private key
  5. 証明書とキーファイルが作成されたことを確認します。

    ls -l

    3 つのファイルが表示されるはずです。

    total 12
    -rw-r--r-- 1 labex labex 1220 [date] registry.crt
    -rw-r--r-- 1 labex labex 1054 [date] registry.csr
    -rw-r--r-- 1 labex labex 1679 [date] registry.key

これで、Docker レジストリを保護するために必要なファイルが揃いました。次のステップでは、HTTPS 通信にこの証明書を使用するようにレジストリを構成します。

SSL 証明書を使用した Docker レジストリの設定

自己署名証明書ができたので、安全な通信のために SSL を使用するように Docker レジストリを設定できます。

安全なレジストリのセットアップ

  1. まず、レジストリ用のシンプルな設定ファイルを作成しましょう。このファイルは、HTTPS 設定を指定します。

    mkdir -p ~/project/registry-config
    cd ~/project/registry-config
    nano config.yml
  2. ファイルに次の設定を追加します。

    version: 0.1
    storage:
      filesystem:
        rootdirectory: /var/lib/registry
    http:
      addr: 0.0.0.0:5000
      tls:
        certificate: /certs/registry.crt
        key: /certs/registry.key

    この設定は、レジストリに次のことを指示します。

    • ストレージにファイルシステムを使用する
    • ポート 5000 のすべてのインターフェースでリッスンする
    • 証明書とキーを使用して TLS (HTTPS) を使用する
  3. Ctrl+X、次に Y、次に Enter を押して保存して終了します。

  4. 次に、SSL 証明書を使用してレジストリを実行しましょう。

    docker run -d -p 5000:5000 --restart=always --name registry \
      -v ~/project/registry-data:/var/lib/registry \
      -v ~/project/registry-certs:/certs \
      -v ~/project/registry-config/config.yml:/etc/docker/registry/config.yml \
      registry:2

    このコマンドは以下を行います。

    • 証明書とキーのディレクトリをマウントします。
    • 設定ファイルをマウントします。
    • 先ほど作成した同じデータディレクトリを使用します。
  5. レジストリが実行されていることを確認します。

    docker ps

    レジストリコンテナが実行されていることを示す出力が表示されるはずです。

証明書を信頼するように Docker クライアントを設定する

デフォルトでは、Docker クライアントは自己署名証明書を信頼しません。Docker に証明書を信頼するように指示する必要があります。

  1. Docker が信頼できる証明書を保存するためのディレクトリを作成します。

    sudo mkdir -p /etc/docker/certs.d/localhost:5000
  2. このディレクトリに証明書をコピーします。

    sudo cp ~/project/registry-certs/registry.crt /etc/docker/certs.d/localhost:5000/ca.crt
  3. 変更を反映するために、Docker サービスを再起動します。

    sudo systemctl restart docker

    完了するまでに数秒かかる場合があります。

  4. Docker を再起動するとレジストリコンテナが停止するため、もう一度起動しましょう。

    docker start registry
  5. レジストリが再び実行されていることを確認します。

    docker ps

これで、Docker レジストリは自己署名証明書を使用して HTTPS を使用するように設定され、Docker クライアントは localhost:5000 に接続するときにこの証明書を信頼するように設定されました。

安全な Docker レジストリのテスト

SSL を使用して Docker レジストリが実行されているので、イメージをプッシュおよびプルしてテストしましょう。これにより、すべてが正しく動作していることを確認できます。

サンプルイメージでのテスト

  1. まず、テストに使用するサンプルイメージをプルしましょう。

    docker pull alpine:latest

    Docker が Alpine Linux イメージをダウンロードしていることを示す出力が表示されるはずです。

  2. 安全なレジストリ用にイメージにタグを付けます。

    docker tag alpine:latest localhost:5000/alpine:latest

    このコマンドは、ローカルレジストリを指す新しいタグを作成します。

  3. イメージを安全なレジストリにプッシュします。

    docker push localhost:5000/alpine:latest

    イメージレイヤーがレジストリにプッシュされていることを示す出力が表示されるはずです。

    The push refers to repository [localhost:5000/alpine]
    213ec9aee27d: Pushed
    latest: digest: sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f size: 528
  4. レジストリからプルしていることを確認するために、ローカルイメージを削除します。

    docker rmi localhost:5000/alpine:latest
    docker rmi alpine:latest
  5. 安全なレジストリからイメージをプルします。

    docker pull localhost:5000/alpine:latest

    Docker がレジストリからイメージをダウンロードしていることを示す出力が表示されるはずです。

    latest: Pulling from alpine
    213ec9aee27d: Pull complete
    Digest: sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f
    Status: Downloaded newer image for localhost:5000/alpine:latest
    localhost:5000/alpine:latest

レジストリの内容の検証

Docker Registry API を使用して、レジストリの内容を調べてみましょう。

  1. レジストリ内のすべてのリポジトリを一覧表示します。

    curl -X GET https://localhost:5000/v2/_catalog --cacert ~/project/registry-certs/registry.crt

    次のような出力が表示されるはずです。

    { "repositories": ["alpine", "hello-world"] }

    これは、レジストリにプッシュしたすべてのイメージを示しています。

  2. alpine リポジトリのすべてのタグを一覧表示します。

    curl -X GET https://localhost:5000/v2/alpine/tags/list --cacert ~/project/registry-certs/registry.crt

    次のような出力が表示されるはずです。

    { "name": "alpine", "tags": ["latest"] }

達成したことの理解

行ったことを確認しましょう。

  1. 自己署名 SSL 証明書を使用して HTTPS で Docker レジストリを設定しました。
  2. この証明書を信頼するように Docker クライアントを設定しました。
  3. 安全なレジストリとの間でイメージを正常にプッシュおよびプルしました。

この設定は以下を提供します。

  • 暗号化された通信: Docker クライアントとレジストリ間で転送されるすべてのデータは暗号化されます。
  • 認証の基盤: SSL は、認証を実装するための最初のステップです。
  • Docker クライアントの互換性: Docker クライアントは、デフォルトで、localhost 以外のレジストリには HTTPS が必要です。

これで、この安全なレジストリを開発およびテストのニーズに使用できます。本番環境では、自己署名証明書の代わりに、信頼できる認証局からの証明書を通常使用します。

まとめ

おめでとうございます!自己署名 SSL 証明書を使用して、安全な Docker レジストリを正常に設定しました。達成したことは次のとおりです。

  1. 基本的な Docker レジストリを設定し、その目的と機能を理解しました。
  2. レジストリを保護するための自己署名 SSL 証明書を生成しました。
  3. 証明書を使用して HTTPS を使用するように Docker レジストリを設定しました。
  4. 自己署名証明書を信頼するように Docker クライアントを設定しました。
  5. イメージをプッシュおよびプルすることにより、安全なレジストリを正常にテストしました。

これらのスキルにより、開発およびテスト環境用の安全なプライベートレジストリを作成できます。プライベートレジストリを使用すると、Docker イメージの保存場所とアクセスできるユーザーを制御できます。一方、SSL 暗号化により、データが送信中に安全に保たれます。

本番環境では、通常、信頼できる認証局からの証明書を使用しますが、設定プロセスは、この実験で学習した内容とほぼ同様です。

これで、独自のプロジェクトと開発ワークフローで安全な Docker レジストリを自信を持って実装し、コンテナ化されたアプリケーションのセキュリティを強化できます。