Docker イメージとコンテナの関係を理解する

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

はじめに

このチュートリアルは、Docker イメージとコンテナの関係を包括的に理解するためのものです。Docker イメージの構築、保存、管理、および Docker コンテナの作成、実行、監視に関する主要な概念を網羅しています。ネットワーク、ボリューム、Docker Compose を活用してマルチコンテナアプリケーションを構築およびデプロイする方法を学びます。このガイドの終わりまでに、Docker イメージとコンテナが連携してアプリケーションのデプロイと管理プロセスを効率化する仕組みを深く理解しているでしょう。

Docker 入門:Docker とは何か、そしてなぜ使うのか?

Docker は、開発者と IT プロフェッショナルがアプリケーションを一貫性と効率性を持って構築、デプロイ、管理するための強力なオープンソースプラットフォームです。ソフトウェアを標準化された方法でパッケージ化および配布することで、さまざまな環境でアプリケーションを開発、テスト、デプロイしやすくなります。

Docker とは何か?

Docker は、アプリケーションとその依存関係を軽量、ポータブル、自己完結型のユニットである Docker コンテナにパッケージ化できるコンテナ化プラットフォームです。これらのコンテナは簡単にデプロイ、スケール、管理でき、開発環境から本番環境まで、さまざまな環境でアプリケーションが確実に動作するようにします。

なぜ Docker を使うのか?

Docker を使用する主な利点は以下のとおりです。

  1. 一貫性と再現性: Docker は、アプリケーションとその依存関係が、基盤となるインフラストラクチャに関係なく同じ方法でパッケージ化およびデプロイされることを保証します。これにより、「私のマシンでは動作する」という問題を解消し、あるシステムでは動作するアプリケーションが別のシステムでは動作しないという問題を回避できます。

  2. スケーラビリティと柔軟性: Docker コンテナは軽量で、アプリケーションの需要の変動に対応しやすく、簡単にスケールアップまたはスケールダウンできます。さらに、Docker のモジュール設計により、アプリケーションの個々のコンポーネントを簡単に置き換えたり、アップデートしたりできます。これにより、システム全体の動作に影響を与えることなく、アプリケーションの個々のコンポーネントを更新できます。

  3. 開発者の生産性向上: Docker は、アプリケーションの構築、テスト、実行のための一貫した分離された環境を提供することで、開発およびデプロイプロセスを簡素化します。これにより、開発環境と本番環境の設定および維持に必要な時間と労力を削減できます。

  4. 効率的なリソース利用: Docker コンテナはホストオペレーティングシステムのカーネルを共有するため、迅速に起動および停止でき、従来の仮想マシンよりも少ないリソースを使用できます。これにより、コンピューティングリソースをより効率的に使用し、インフラストラクチャコストを削減できます。

  5. ポータビリティとデプロイの柔軟性: Docker コンテナは、開発者のラップトップから本番サーバーまで、さまざまな環境間で簡単に移動できます。基盤となるインフラストラクチャの違いを気にする必要はありません。これにより、オンプレミス、クラウド、ハイブリッド環境など、さまざまな環境でアプリケーションをデプロイおよび管理しやすくなります。

Docker を始めるには、システムに Docker エンジンをインストールする必要があります。このチュートリアルでは、Ubuntu 22.04 をホストオペレーティングシステムとして使用します。Ubuntu 22.04 に Docker をインストールするには、以下の手順に従います。

sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker

Docker がインストールされたら、以下のコマンドを実行してインストールを確認できます。

docker version

これにより、システムにインストールされている Docker のバージョンが表示されます。

Docker イメージの理解:イメージの構築、保存、プル

Docker イメージは、Docker コンテナの基盤です。コンテナを作成するために使用される読み取り専用のテンプレートです。このセクションでは、Docker イメージの構築、保存、プル方法を説明します。

Docker イメージの構築

Docker イメージを構築するには、Dockerfile を作成する必要があります。Dockerfile は、イメージの構築手順を含むテキストファイルです。ここでは、Nginx を使用したシンプルな Web サーバーを作成する例を示します。

FROM nginx:latest
COPY index.html /usr/share/nginx/html/
EXPOSE 80

このイメージを構築するには、次のコマンドを使用します。

docker build -t my-nginx-image .

このコマンドは、Dockerfile の指示に基づいて、my-nginx-image という名前の新しいイメージを作成します。

Docker イメージの保存

Docker イメージは、Docker レジストリに保存できます。レジストリは、Docker イメージの中央リポジトリです。最も一般的なパブリックレジストリは Docker Hub ですが、プライベートレジストリも設定できます。

Docker Hub にイメージをプッシュするには、まず Docker Hub アカウントにログインする必要があります。

docker login

次に、イメージに Docker Hub のユーザー名とタグを付け、レジストリにプッシュします。

docker tag my-nginx-image username/my-nginx-image:latest
docker push username/my-nginx-image:latest

Docker イメージのプル

レジストリから Docker イメージをプルするには、docker pullコマンドを使用できます。たとえば、Docker Hub から最新の Nginx イメージをプルするには、次のコマンドを使用します。

docker pull nginx:latest

プライベートレジストリからイメージをプルするには、レジストリの URL を指定します。

docker pull private-registry.example.com/my-image:latest

イメージを取得したら、次のセクションで説明する Docker コンテナを作成するために使用できます。

Docker コンテナの作成と管理:コンテナの実行、停止、監視

Docker イメージの基本的な理解ができたところで、Docker コンテナの作成と管理方法を見ていきましょう。

Docker コンテナの実行

Docker イメージから新しいコンテナを作成するには、docker runコマンドを使用します。たとえば、nginx:latestイメージから新しい Nginx コンテナを作成するには、次のコマンドを使用します。

docker run -d -p 80:80 --name my-nginx-container nginx:latest

このコマンドは次のことを行います。

  • -d: デタッチモード(バックグラウンド)でコンテナを実行
  • -p 80:80: ホストのポート 80 をコンテナのポート 80 にマッピング
  • --name my-nginx-container: コンテナに名前「my-nginx-container」を割り当てる
  • nginx:latest: nginx:latestイメージを使用してコンテナを作成

コンテナの停止と削除

実行中のコンテナを停止するには、docker stopコマンドを使用します。

docker stop my-nginx-container

停止したコンテナを削除するには、docker rmコマンドを使用します。

docker rm my-nginx-container

コンテナの監視

コンテナの状態を監視するには、docker psコマンドを使用します。これにより、実行中のすべてのコンテナのリストが表示されます。

docker ps

実行中のコンテナのログを表示するには、docker logsコマンドを使用します。

docker logs my-nginx-container

コンテナのリアルタイムのリソース使用状況を確認するには、docker statsコマンドを使用します。

docker stats my-nginx-container

Docker コンテナの作成、管理、監視方法を理解することで、Docker プラットフォームを使用してアプリケーションを効果的にデプロイおよび管理できます。

コンテナのネットワークと接続:ポートの公開、コンテナの連携、ネットワークモード

Docker は、コンテナ間の接続と通信、ホストシステムおよび外部ネットワークとの通信を可能にする柔軟なネットワークシステムを提供します。このセクションでは、Docker でのネットワーク管理方法を説明します。

ポートの公開

コンテナを実行すると、-pまたは--publishフラグを使用して、コンテナの内部ポートをホストシステムに公開できます。これにより、外部システムがコンテナ内部で実行されているサービスにアクセスできるようになります。

たとえば、ホストシステムのポート 80 を公開する Nginx コンテナを実行するには、次のコマンドを使用します。

docker run -d -p 80:80 nginx:latest

これにより、ホストシステムのポート 80 がコンテナ内部のポート 80 にマッピングされます。

コンテナの連携

Docker は、コンテナを連携させることも可能です。これにより、コンテナ同士が通信できるようになります。これは、Web アプリケーションとデータベースなど、複数のコンテナが相互に作用する必要がある場合に便利です。

2 つのコンテナを連携するには、コンテナ実行時に--linkフラグを使用します。

docker run -d --name my-db-container postgres:latest
docker run -d --name my-app-container --link my-db-container:db my-app-image

この例では、my-app-containerはホスト名dbを使用してmy-db-containerにアクセスできます。

ネットワークモード

Docker は、コンテナがネットワークに接続される方法を決定する、いくつかのネットワークモードをサポートしています。

  1. Bridge: これはデフォルトのネットワークモードで、コンテナは仮想ブリッジネットワークに接続され、互いに、およびホストシステムと通信できます。
  2. Host: このモードでは、コンテナはホストシステムのネットワークスタックを共有し、コンテナとホスト間のネットワーク分離が効果的に取り除かれます。
  3. None: このモードでは、コンテナのネットワークを無効にし、ネットワークから分離します。
  4. Overlay: このモードでは、コンテナが複数の Docker ホスト間で通信できるため、マルチホスト、分散アプリケーションの作成が可能になります。

コンテナを実行する際に、--networkフラグを使用してネットワークモードを指定できます。

docker run -d --network host nginx:latest

Docker のネットワーク機能を理解することで、コンテナ間、および外部システムとの接続と通信を効果的に行うことができます。

Docker ボリュームによるデータの永続化:コンテナ内データの保存と管理

デフォルトでは、Docker コンテナ内に保存されたデータは一時的なもので、コンテナの停止または削除時に失われます。データを永続化するには、Docker のボリューム機能を使用します。これは、ホストシステムのディレクトリをコンテナにマウントすることで実現します。

Docker ボリュームとは

Docker ボリュームは、コンテナのファイルシステム外部でデータを保存および管理する方法です。アプリケーションデータ、設定ファイル、またはコンテナのライフサイクルを超えて永続化する必要があるその他のデータにボリュームを使用できます。

ボリュームは、docker volume コマンドを使用して作成および管理できます。たとえば、新しいボリュームを作成するには:

docker volume create my-data-volume

コンテナへのボリュームのマウント

コンテナにボリュームをマウントするには、docker run コマンドを実行する際に -v または --mount フラグを使用できます。たとえば、Nginx コンテナを実行し、ボリュームを /usr/share/nginx/html ディレクトリにマウントするには:

docker run -d -p 80:80 -v my-data-volume:/usr/share/nginx/html nginx:latest

この例では、my-data-volume ボリュームがコンテナ内の /usr/share/nginx/html ディレクトリにマウントされます。このディレクトリに書き込まれたデータは、ボリュームに保存され、コンテナが停止または削除されても永続化されます。

ボリュームの管理

システム上のすべてのボリュームを一覧表示するには、docker volume ls コマンドを使用します。

docker volume ls

特定のボリュームの詳細を確認するには、docker volume inspect コマンドを使用します。

docker volume inspect my-data-volume

ボリュームが不要になった場合は、docker volume rm コマンドを使用して削除できます。

docker volume rm my-data-volume

Docker ボリュームを使用することで、アプリケーションデータが個々のコンテナのライフサイクルを超えて永続化されるため、アプリケーションの管理とスケーリングが容易になります。

Dockerfile とイメージの最適化:効率的な Docker イメージの作成

Dockerfile は Docker イメージ構築の基盤です。Docker イメージの作成手順、ベースイメージ、アプリケーションコード、必要な依存関係などを記述します。このセクションでは、効率的な Dockerfile の記述方法と Docker イメージの最適化方法を説明します。

Dockerfile の理解

Dockerfile は、Docker イメージ構築のための指示を記述したテキストファイルです。Dockerfile の各指示は、最終的なイメージのレイヤーに対応します。以下は Dockerfile の例です。

FROM ubuntu:22.04
RUN apt-get update && apt-get install -y nginx
COPY index.html /usr/share/nginx/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

この Dockerfile は、ubuntu:22.04 ベースイメージに基づいて新しいイメージを作成し、Nginx をインストールし、index.html ファイルを Nginx の Web ルートにコピーし、ポート 80 を公開し、Nginx サーバーの起動コマンドを設定します。

イメージ最適化テクニック

効率的な Docker イメージを作成するには、以下の最適化テクニックを使用できます。

  1. 最小限のベースイメージの使用: alpinescratch などの最小限のベースイメージから始めることで、最終的なイメージサイズを削減できます。
  2. マルチステージビルドを活用: ビルド環境と実行環境を分離するマルチステージビルドを使用することで、最終的なイメージサイズを削減できます。
  3. レイヤーキャッシュの最適化: Docker のレイヤーキャッシュを活用するように Dockerfile の指示を配置することで、ビルドプロセスを大幅に高速化できます。
  4. 不要なパッケージの回避: アプリケーションの実行に必要なパッケージと依存関係のみをインストールし、使用後は削除します。
  5. .dockerignore の使用: 不要なファイルやディレクトリをビルドコンテキストから除外するための .dockerignore ファイルを作成することで、Docker デーモンに送信するデータ量を削減できます。
  6. ビルドアーティファクトの圧縮: ソースコードや依存関係などの大きなビルドアーティファクトを圧縮してからイメージにコピーすることで、イメージサイズを削減できます。

これらのベストプラクティスに従うことで、サイズが小さく、ビルドとデプロイが高速な効率的で最適化された Docker イメージを作成できます。

Docker Compose: マルチコンテナアプリケーションの定義と実行

Docker Compose は、マルチコンテナアプリケーションを定義および実行するためのツールです。アプリケーションのサービス、ネットワーク、ボリュームを宣言的に定義することで、複数の Docker コンテナの管理とオーケストレーションを簡素化します。

Docker Compose とは

Docker Compose は、アプリケーションを構成するサービスを記述する YAML ベースの構成ファイルです。異なるコンテナ間の関係、およびそれらのデプロイと管理方法を定義できます。

以下は、Web サーバーとデータベースを持つシンプルな Web アプリケーションを定義する docker-compose.yml ファイルの例です。

version: "3"
services:
  web:
    build: .
    ports:
      - "80:80"
    depends_on:
      - db
  db:
    image: postgres:12
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data:

この構成は、webdb の 2 つのサービスを定義しています。web サービスは、現在のディレクトリにある Dockerfile から構築され、ホスト上のポート 80 を公開します。db サービスは postgres:12 イメージを使用し、特定のデータベース名、ユーザー名、パスワードを持つ PostgreSQL データベースを設定します。また、ボリュームをマウントしてデータベースデータを永続化します。

Docker Compose の使用

Docker Compose を使用する手順は次のとおりです。

  1. プロジェクトディレクトリに docker-compose.yml ファイルを作成します。
  2. YAML ファイルにサービスとその構成を定義します。
  3. docker-compose up コマンドを実行してアプリケーションを起動します。
docker-compose up -d

これにより、docker-compose.yml ファイルで定義されたすべてのサービスがバックグラウンドで起動します。

アプリケーションを管理するためのその他の Docker Compose コマンドも使用できます。

  • docker-compose down: コンテナ、ネットワーク、ボリュームを停止および削除します。
  • docker-compose ps: 実行中のコンテナを一覧表示します。
  • docker-compose logs: 実行中のコンテナのログを表示します。

Docker Compose を使用することで、複雑なマルチコンテナアプリケーションを簡単に管理およびデプロイできます。これは、Docker ツールボックスにおける強力なツールです。

まとめ

このチュートリアルでは、Docker イメージとコンテナの重要な違いと関係性について学びました。Docker イメージの構築、保存、プル、そして Docker コンテナの作成、実行、管理の方法を理解しました。また、ネットワーク、ボリューム、Docker Compose を活用してマルチコンテナアプリケーションを構築およびデプロイする方法も学びました。この知識があれば、Docker の力を効果的に活用して、アプリケーションのデプロイと管理のワークフローを効率化できます。