既存の Docker イメージを取得し、それをローカルでデプロイする

完了

Docker は、アプリケーションとサービスのデプロイを迅速かつ簡単に実現するテクノロジです。 Docker アプリは Docker イメージを使用して実行されます。 Docker イメージは、事前にパッケージ化された環境であり、アプリケーション コードと、コードが実行される環境が含まれます。

先ほど説明した企業シナリオでは、Docker を使用したアプリのパッケージ化と実行の実現可能性を調査する必要があります。 テスト用の Web アプリを実行するために、Docker イメージを構築してデプロイすることにします。

このユニットでは、Docker イメージに格納されているコンテナー化されたアプリの実行に関する概念とプロセスについて学習します。

Docker の概要

Docker は、コンテナー化されたアプリを実行するためのツールです。 コンテナー化されたアプリには、アプリと、それが実行される環境を構成するファイル システムが含まれます。 たとえば、コンテナー化されたアプリには、データベースとその他の関連するソフトウェア、およびアプリの実行に必要な構成情報が含まれている場合があります。

コンテナー化されたアプリでは、通常、同じアプリを実行するように構成された仮想マシンより占有領域がかなり小さくなっています。 占有領域が小さいのは、仮想マシンの場合は、オペレーティング システム全体と関連するサポート環境を提供する必要があるためです。 Docker コンテナーにはこのオーバーヘッドはありません。Docker では、ホスト コンピューターのオペレーティング システム カーネルを使用して、コンテナーに電力を供給するためです。 Docker イメージのダウンロードと起動では、同様の機能を提供する仮想マシンをダウンロードして実行するより高速でスペース効率が良くなります。

Docker で使用されるファイル セットと構成情報のセクションを含むイメージを構築することで、コンテナー化されたアプリを作成します。 イメージに基づいてコンテナーを起動するように Docker に要求して、アプリを実行します。 コンテナーの起動時に、Docker ではイメージ構成を使用して、コンテナー内で実行するアプリケーションを決定します。 Docker は、オペレーティング システムのリソースと必要なセキュリティを備えています。 そのため、複数のコンテナーを同時に実行し、分離された状態を "比較的" 維持できます。

重要

Docker は仮想マシンで利用可能な分離レベルを提供しません。 仮想マシンではハードウェア レベルで分離が実装されます。 Docker コンテナーは、基になるオペレーティング システムのリソースとライブラリを共有します。 しかし、Docker は、1 つのコンテナーがそのように構成されているのではない限り、別のコンテナーのリソースにアクセスすることはできないことを保証します。

ローカルで開発およびテストを行う場合は、デスクトップまたはノート PC で Docker を実行できます。 運用システムでは、多くのバリエーションの Linux および Microsoft Windows Server 2016 を含む、サーバー環境で Docker を利用できます。 また、多くのベンダーでクラウドの Docker がサポートされます。 たとえば、Azure Container Registry で Docker イメージを格納し、Azure Container Instances でコンテナーを実行できます。

このモジュールでは、ローカルで Docker を使い、イメージを構築して実行します。 次に、Azure Container Registry にイメージをアップロードし、それを Azure コンテナー インスタンス内で実行します。 このバージョンの Docker は、Docker イメージのローカルでの開発とテストに適しています。

Linux と Windows の Docker イメージ

Docker は元々 Linux 用に開発されたものですが、Windows をサポートするために拡張されています。 個々の Docker イメージは Windows ベースまたは Linux ベースですが、両方を同時に指定することはできません。 イメージのオペレーティング システムによって、コンテナー内で使用されるオペレーティング システムの環境が決まります。

Docker イメージの作成者が、Linux ベースと Windows ベースの両方のイメージで同様の機能を提供したい場合は、これらのイメージを別個に構築できます。 たとえば、Microsoft は、コンテナー化された ASP.NET Core アプリケーションの基礎として使用できる ASP.NET Core 環境を含む Windows および Linux の Docker イメージを提供しています。

Docker がインストールされた Linux コンピューターでは、Linux コンテナーのみを実行できます。 Docker がインストールされた Windows コンピューターでは、両方の種類のコンテナーを実行できます。 Windows は、Linux システムを実行する仮想マシンを使用することで両方を実行し、その仮想 Linux システムを使用して Linux コンテナーを実行します。

このモジュールでは、Linux ベースのイメージを構築して実行します。

Docker レジストリと Docker Hub

Docker イメージはレジストリ で格納され、使用可能になります。 レジストリは、コンテナー イメージをアップロードおよびダウンロードするために Docker を接続できる Web サービスです。 最も有名なレジストリは Docker Hub であり、これはパブリック レジストリです。 多くの個人や組織はイメージを Docker Hub に発行します。これらのイメージは、デスクトップ、サーバー、またはクラウドで実行されている Docker を使って、ダウンロードして実行できます。 Docker Hub アカウントを作成し、そこにイメージを無料でアップロードできます。

レジストリは、一連のリポジトリ として整理されます。 各リポジトリには、共通名と、通常は同じ目的と機能を共有する、複数の Docker イメージが含まれています。 通常、これらのイメージにはさまざまなバージョンがあり、タグで識別されます。 このメカニズムを使用することで、互換性の理由から複数のバージョンのイメージを発行して保持できます。 イメージをダウンロードして実行する場合、そのイメージに対してレジストリ、リポジトリ、バージョン タグを指定する必要があります。 タグはテキスト ラベルであり、独自のバージョン番号付けシステムを使用できます (v1.0、v1.1、v1.2、v2.0 など)。

たとえば、ASP.NET Core ランタイム Docker イメージを使用するとします。 このイメージは、次の 2 つのバージョンで使用できます。

  • 8.0 (長期サポート): mcr.microsoft.com/dotnet/aspnet:8.0
  • 6.0 (長期サポート): mcr.microsoft.com/dotnet/aspnet:6.0

今度は .NET Core サンプルの Docker イメージを使用するとしましょう。 この場合、次の 4 つのバージョンから選択できます。

  • mcr.microsoft.com/dotnet/samples:dotnetapp
  • mcr.microsoft.com/dotnet/samples:dotnetapp-chiseled
  • mcr.microsoft.com/dotnet/samples:aspnetapp
  • mcr.microsoft.com/dotnet/samples:aspnetapp-chiseled

Note

1 つのイメージに複数のタグを割り当てることができます。 慣例により、最新バージョンのイメージには、そのバージョン番号を記述するタグに加え、latest タグが割り当てられます。 新しいバージョンのイメージをリリースする場合は、新しいイメージを参照するために latest タグを再割り当てできます。

リポジトリはイメージのプライバシーの単位でもあります。 イメージを共有したくない場合は、リポジトリをプライベートにすることができます。 イメージを共有する他のユーザーにアクセスを許可することができます。

Docker Hub を参照してイメージをプルする

Note

以下のセクションの例を完了したり、コードを実行したりする必要はありません。 それは次のユニットで行います。

多くの場合、コンテナー化するアプリの種類に厳密に一致するイメージが Docker Hub にあることがわかります。 そのようなイメージをダウンロードして、独自のアプリケーション コードで拡張することができます。

Docker Hub には、数千ものイメージが含まれています。 コマンド ラインまたは Docker Hub の Web サイトから Docker を使用して、レジストリの検索と参照ができます。 Web サイトでは、種類と発行元別にイメージを検索、フィルター、選択できます。 次の図は、検索ページの例を示しています。

さまざまなコンテナー イメージを一覧表示する Docker Hub の検索ページを示すスクリーンショット。

イメージを取得するには、docker pull コマンドをイメージ名を使用して指定します。 既定では、ユーザーがリポジトリ名だけを指定した場合、Docker Hub 上のそのリポジトリから latest としてタグ付けされたイメージを、Docker がダウンロードします。 コマンドを変更して、異なるタグや異なるリポジトリからプルすることができます。 この例では、mcr.microsoft.com/dotnet/samples:aspnetapp リポジトリから aspnetapp というタグを持つイメージをフェッチします。 このイメージには、単純な ASP.NET Core Web アプリが含まれています。

Note

このユニットの例は、さまざまな Docker コマンドの構文を示すためのものです。 このユニットの参照中に、これらのコマンドを実行する必要はありません。 このユニットに続く演習で、Docker を直接操作する手順を説明します。

docker pull mcr.microsoft.com/dotnet/samples:aspnetapp

イメージをフェッチすると、Docker ではローカルにそれを格納し、コンテナーを実行するために使用できるようにします。 docker image list コマンドを使用して、ローカル レジストリのイメージを表示することができます。

docker image list

出力は次の例のようになります。

REPOSITORY TAG IMAGE ID CREATED SIZE
mcr.microsoft.com/dotnet/samples   aspnetapp           6e2737d83726        6 days ago          263MB

その他の多くの Docker コマンド内でイメージを参照するには、イメージ名 ID を使用することができます。

Docker コンテナーを実行する

docker run コマンドを使用して、コンテナーを起動します。 名前または ID で実行するイメージを指定します。 イメージをまだ docker pull していない場合は、Docker で自動的に行われます。

docker run mcr.microsoft.com/dotnet/samples:aspnetapp

この例のコマンドは、次のメッセージで応答します。

warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
 No XML encryptor configured. Key {d8e1e1ea-126a-4383-add9-d9ab0b56520d} may be persisted to storage in unencrypted form.
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.

このイメージには Web アプリが含まれているため、現在、HTTP ポート 80 に到着する要求をリッスンしています。 ただし、Web ブラウザーを開き、http://localhost:80 に移動した場合、アプリは表示されません。

既定では、Docker で受信ネットワーク要求をコンテナーに到達させることはできません。 ご利用のコンピューターの特定のポート番号をコンテナー内の特定のポート番号に割り当てるように Docker に指示する必要があります。その場合、-p オプションを docker run に追加します。 この命令により、指定されたポートのコンテナーへのネットワーク要求が有効になります。

また、このイメージの Web アプリは、コマンド ラインから対話形式で使用するためのものではありません。 これを起動する場合は、Docker でバックグラウンドで起動し、単に実行されるようにする必要があります。 バックグラウンドで Web アプリを起動するように Docker に指示するには、-d フラグを使用します。

以下の例に示すように、Ctrl + C キーを押してイメージを停止し、再起動します。

docker run -p 8080:80 -d mcr.microsoft.com/dotnet/samples:aspnetapp

このコマンドでは、コンテナー内のポート 80 が、ご利用のコンピューター上のポート 8080 にマップされます。 ブラウザーで http://localhost:8080 ページにアクセスすると、サンプルの Web アプリが表示されます。

ブラウザーで実行中のサンプル Web アプリを示すスクリーンショット。

コンテナーとファイル

実行中のコンテナーでそのイメージ内のファイルに変更が加えられた場合、それらの変更は、変更が行われたコンテナーにのみ存在します。 コンテナーの状態を維持するための特定の手順を行わない限り、これらの変更はコンテナーが削除されると失われます。 同様に、同じイメージに基づき同時に実行される複数のコンテナーを使用する場合、イメージ内のファイルは共有されません。 各コンテナーには独立した独自のコピーがあります。 あるコンテナーがファイルシステムに書き込むデータはすべて、他のコンテナーにとっては不可視です。

書き込み可能なボリュームをコンテナーに追加することはできます。 ボリュームとは、コンテナーがマウントできるファイルシステムを表し、コンテナー内で実行されているアプリケーションで利用可能になります。 コンテナーの停止時にボリューム内のデータは保持され、複数のコンテナーで同じボリュームを共有できます。 ボリュームの作成と使用の詳細は、このモジュールの範囲外です。

Docker でデプロイされたアプリケーションのイメージ ファイルシステムに変更を加える必要がないようにすることをお勧めします。 これは、失っても差し支えない一時ファイルにのみ使用してください。

Docker コンテナーを管理する

docker ps コマンドを使用して、アクティブなコンテナーを表示することができます。

docker ps

出力には、コンテナーの状態 (実行中の場合は Up、終了済みの場合は Exited)、イメージが起動されたときに指定されたコマンドライン フラグなどの他の値、およびその他の情報が含まれます。 Docker では同時に同じイメージから複数のコンテナーを実行できるため、各コンテナーには一意の ID と、人間が判読できる一意の名前が割り当てられます。 個々のコンテナーを管理するために使用されるほとんどの Docker コマンドでは、ID または名前を使用して特定のコンテナーを参照できます。

以下の出力では、2 つのコンテナーを確認できます。 PORTS フィールドに示されているのは、ID が elegant_ramanujan のコンテナーであり、ご利用のコンピューター上のポート 8080 にマップされた、Docker ホスト上のポート 80 で実行中のイメージであることです。 youthful_heisenberg インスタンスは、イメージの前の実行のコンテナーです。 COMMAND フィールドには、イメージのアプリケーションを起動するためにコンテナーで実行されたコマンドが示されています。 この場合、どちらのコンテナーでも dotnet aspnetapp.dll となります。 両方のコンテナーで同じイメージが実行されるため、コンテナーのイメージ ID も同じです。

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57b9587583e3        mcr.microsoft.com/dotnet/core/samples:aspnetapp   "dotnet aspnetapp.dll"   42 seconds ago      Up 41 seconds       0.0.0.0:8080->80/tcp   elegant_ramanujan
d27071f3ca27        mcr.microsoft.com/dotnet/core/samples:aspnetapp   "dotnet aspnetapp.dll"   5 minutes ago      Up 5 minutes       0.0.0.0:8081->80/tcp   youthful_heisenberg

Note

docker psdocker container ls のショートカットです。 これらのコマンドの名前は、Linux ユーティリティの psls に基づいており、実行中のプロセスとファイルをそれぞれリストします。

コンテナー ID を指定して、docker stop コマンドでアクティブなコンテナーを停止することができます。

docker stop elegant_ramanujan

docker ps を再度実行すると、elegant_ramanujan コンテナーが出力に表示されなくなったことがわかります。 コンテナーはまだ存在していますが、実行中のプロセスはホストされなくなります。 -a フラグを含めることで、docker ps の出力に停止されたコンテナーを含めることができます。

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57b9587583e3        mcr.microsoft.com/dotnet/core/samples:aspnetapp   "dotnet aspnetapp.dll"   2 minutes ago       Exited (0) 21 seconds ago                       elegant_ramanujan
d27071f3ca27        mcr.microsoft.com/dotnet/core/samples:aspnetapp   "dotnet aspnetapp.dll"   7 minutes ago      Up 7 minutes       0.0.0.0:8081->80/tcp   youthful_heisenberg

docker start コマンドを使用して、停止されたコンテナーを再起動することができます。 コンテナーのメイン プロセスが新たに開始します。

docker start elegant_ramanujan

通常、コンテナーが停止したら、その削除も行う必要があります。 コンテナーを削除すると、残されたすべてのリソースがクリーンアップされます。 コンテナーを削除すると、そのイメージ ファイルシステム内で加えられた変更はすべて完全に失われます。

docker rm elegant_ramanujan

実行中のコンテナーは削除できませんが、docker rm コマンドに -f フラグを追加することで、コンテナーを強制的に停止して削除することができます。 これはコンテナーを停止して削除する簡単な方法ですが、コンテナー内のアプリで正常なシャットダウンが必要ではない場合にのみ使用してください。

docker container rm -f elegant_ramanujan

Docker イメージを削除する

docker image rm コマンドを使用して、ローカル コンピューターからイメージを削除することができます。 削除するイメージのイメージ ID を指定します。 次の例では、サンプル Web アプリのイメージを削除します。

docker image rm mcr.microsoft.com/dotnet/core/samples:aspnetapp

イメージを削除するには、イメージを実行しているコンテナーを事前に終了する必要があります。 イメージがまだコンテナーで使用されている場合、次のようなエラー メッセージが表示されます。 この例では、youthful_hesienburg コンテナーでまだイメージが使用されているため、エラーが発生しています。

Error response from daemon: conflict: unable to delete 575d85b4a69b (cannot be forced) - image is being used by running container c13165988cfe