Docker コンテナをホストネットワークを使用するように設定する方法

DockerDockerBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

Docker コンテナは、ホストシステムに干渉することなくアプリケーションを実行する分離された環境です。デフォルトでは、Docker はコンテナのトラフィックを分離するために仮想ネットワークを作成しますが、場合によってはコンテナがホストのネットワークを直接使用するように設定することが必要になることがあります。

この実験では、Docker コンテナをホストネットワークを使用するように設定する方法を学びます。デフォルトのブリッジネットワーキングとホストネットワーキングの違いを調べ、ホストネットワーキングを使用するタイミングを理解し、実際の例を実装してその利点を直接体験します。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/SystemManagementGroup(["System Management"]) docker(("Docker")) -.-> docker/NetworkOperationsGroup(["Network Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ls("List Containers") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/rm("Remove Container") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/SystemManagementGroup -.-> docker/prune("Remove Unused Docker Objects") docker/NetworkOperationsGroup -.-> docker/network("Manage Networks") subgraph Lab Skills docker/run -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} docker/ls -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} docker/ps -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} docker/rm -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} docker/exec -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} docker/inspect -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} docker/prune -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} docker/network -.-> lab-415202{{"Docker コンテナをホストネットワークを使用するように設定する方法"}} end

Docker ネットワークタイプの理解

コンテナをホストネットワークを使用するように設定する前に、Docker で利用可能なさまざまなネットワークタイプを調べ、それらの目的を理解しましょう。

利用可能な Docker ネットワークの確認

まず、システム上のデフォルトの Docker ネットワークを調べましょう。

  1. LabEx 環境でターミナルを開きます。

  2. 次のコマンドを実行して、すべての Docker ネットワークをリスト表示します。

docker network ls

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

NETWORK ID     NAME      DRIVER    SCOPE
1234567890ab   bridge    bridge    local
0987654321cd   host      host      local
abcdef123456   none      null      local

Docker は 3 つのデフォルトネットワークを提供しています。

  • bridge: コンテナのデフォルトネットワーク
  • host: ホストのネットワークを直接使用する
  • none: ネットワークなし (コンテナは分離される)

デフォルトのブリッジネットワークの理解

ネットワークを指定せずにコンテナを実行すると、Docker はそれをデフォルトのブリッジネットワークに接続します。これにより、各コンテナに仮想ネットワークインターフェイスが作成され、コンテナ同士および外部ネットワークとの通信が可能になります。

実際に動作を確認してみましょう。

  1. デフォルトのブリッジネットワークでシンプルな nginx コンテナを実行します。
docker run --name nginx-bridge -d -p 8080:80 nginx:alpine
  1. コンテナのネットワーク設定を確認します。
docker inspect nginx-bridge --format '{{json .NetworkSettings.Networks}}' | jq

コンテナがブリッジネットワークに接続され、独自の IP アドレスを持っていることを示す出力が表示されるはずです。

  1. マッピングされたポートにリクエストを送信して、コンテナがホストからアクセス可能であることを確認します。
curl http://localhost:8080

nginx のウェルカムページの HTML コンテンツが表示されるはずです。

これは、ブリッジネットワークがどのように機能するかを示しています。コンテナは独自の IP アドレスを持ち、コンテナ内のポート 80 がホスト上のポート 8080 にマッピングされています。

ホストネットワークモードでコンテナを実行する

ここでは、ホストネットワークを使用してコンテナを実行する方法を調べ、ブリッジネットワークとの違いを理解しましょう。

ホストネットワークの使用

ホストネットワークモードを使用すると、コンテナはホストのネットワーク名前空間を直接共有します。これは以下のことを意味します。

  • コンテナはホストの IP アドレスを使用します。
  • ポートマッピングは必要ありません。
  • コンテナはホスト上のすべてのネットワークインターフェイスにアクセスできます。
  • コンテナがホストで既に使用されているポートを使用しようとすると、ポート競合が発生する可能性があります。

ホストネットワーキングでコンテナを実行してみましょう。

  1. 前の nginx コンテナを停止して削除し、ポート 80 を解放します。
docker stop nginx-bridge
docker rm nginx-bridge
  1. 次に、ホストネットワークを使用して新しい nginx コンテナを実行します。
docker run --name nginx-host --network host -d nginx:alpine

コンテナがホストのネットワークスタックを直接使用するため、ポートマッピング用の -p フラグを指定する必要がないことに注意してください。

  1. コンテナのネットワーク設定を確認します。
docker inspect nginx-host --format '{{json .NetworkSettings.Networks}}' | jq

コンテナがホストネットワークに接続されていることがわかります。

  1. ホストのポート 80 で直接 nginx サーバーにアクセスします。
curl http://localhost:80

nginx のウェルカムページの HTML コンテンツが表示されるはずです。

違いの理解

2 つのアプローチを比較してみましょう。

  1. ブリッジネットワーキング (デフォルト) の場合:

    • コンテナは独自の IP アドレスを持ちます。
    • コンテナのサービスにアクセスするにはポートマッピングが必要です。
    • 分離のための追加のネットワークレイヤーがあります。
    • 分離によりセキュリティが高くなります。
  2. ホストネットワーキングの場合:

    • コンテナはホストの IP アドレスを使用します。
    • ポートマッピングは必要ありません。
    • ホストのネットワークインターフェイスに直接アクセスできます。
    • ネットワーク性能が向上します。
    • コンテナとホストの間の分離が少なくなります。

ネットワーク性能と動作の比較

ここでは、Docker のブリッジネットワーキングとホストネットワーキングの実際の違いを確認するためにいくつかのテストを実行しましょう。

ネットワーク性能のテスト

まず、ブリッジネットワーキングを使用するコンテナとホストネットワーキングを使用するコンテナを作成し、それらの性能を比較します。

  1. 前の nginx コンテナを停止して削除します。
docker stop nginx-host
docker rm nginx-host
  1. ブリッジネットワーキングを使用する新しいコンテナを作成して性能をテストします。
docker run --name bridge-test -d --network bridge nginx:alpine
  1. ホストネットワーキングを使用する別のコンテナを作成します。
docker run --name host-test -d --network host nginx:alpine
  1. docker exec を使用して、各コンテナで簡単なネットワークテストを実行します。

ブリッジネットワークのコンテナの場合:

docker exec bridge-test sh -c "time wget -q -O /dev/null http://google.com"

ホストネットワークのコンテナの場合:

docker exec host-test sh -c "time wget -q -O /dev/null http://google.com"

実行時間を比較してください。通常、ホストネットワークのコンテナは追加のネットワークレイヤーを回避するため、わずかに性能が良くなります。

ネットワークインターフェイスの調査

両方のコンテナのネットワークインターフェイスを調査しましょう。

  1. ブリッジネットワークのコンテナの場合:
docker exec bridge-test ip addr show

このコンテナがホストから分離された独自のネットワークインターフェイスを持っていることがわかります。

  1. ホストネットワークのコンテナの場合:
docker exec host-test ip addr show

このコンテナがホストシステムとまったく同じネットワークインターフェイスを持っていることに気づくでしょう。これにはすべての物理ネットワークインターフェイスが含まれます。

  1. ホストのネットワークインターフェイスと比較します。
ip addr show

ホストネットワークのコンテナのインターフェイスは、ホストシステムのものと一致するはずです。

ポート競合の理解

ホストネットワーキングを使用する場合、コンテナがホストで既に使用されているポートを使用しようとすると、ポート競合が発生する可能性があります。

  1. すべての実行中のコンテナを停止して削除します。
docker stop bridge-test host-test
docker rm bridge-test host-test
  1. ホストでポート 8080 を使用するサービスを起動します。
python3 -m http.server 8080 &
  1. ホストネットワーキングを使用し、同じくポート 8080 を使用しようとするコンテナを実行してみます。
docker run --name conflict-test --network host -d -p 8080:80 nginx:alpine

ホストでポート 8080 が既に使用されているため、エラーが表示されるはずです。

  1. Python HTTP サーバーをクリーンアップします。
kill %1

これは、ホストネットワーキングの潜在的な欠点の 1 つを示しています。ホストとのポート競合に注意する必要があります。

ホストネットワーキングの実用的なユースケース

ここでは、ホストネットワーキングが有益な実用的なユースケースをいくつか探り、実際の例を実装しましょう。

ホストネットワーキングを使用するタイミング

ホストネットワーキングは、以下のシナリオで特に有用です。

  1. パフォーマンスが重要なアプリケーション:ネットワークパフォーマンスが重要で、ブリッジネットワーキングのオーバーヘッドを回避したい場合。

  2. ネットワーク監視ツール:ホスト上のネットワークトラフィックをキャプチャまたは分析する必要があるアプリケーション。

  3. 複数のポートを使用するアプリケーション:多数のポートまたは動的なポート割り当てを使用するサービスがある場合。

  4. ハードウェアネットワークインターフェイスへのアクセス:コンテナが物理ネットワークインターフェイスに直接アクセスする必要がある場合。

ホストネットワーキングを使用したネットワーク監視ツールの実装

実用的な例を実装してみましょう。ホストのネットワークインターフェイスにアクセスする必要があるシンプルなネットワーク監視コンテナです。

  1. まず、ホストネットワーキングを使用してネットワーク監視ツールを実行します。
docker run --name netmon --network host -d alpine:latest sleep infinity

このコンテナは無期限に実行され、内部でコマンドを実行できるようになります。

  1. 次に、コンテナ内でいくつかのネットワークトラフィックをキャプチャしましょう。
docker exec netmon sh -c "apk add --no-cache tcpdump && tcpdump -c 10 -i any -n"

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

  • コンテナ内に tcpdump ツールをインストールします。
  • 任意のインターフェイスから 10 個のパケットをキャプチャします。
  • 数値出力を表示します(ホスト名解決は行いません)。

ホストネットワーキングを使用しているため、コンテナはホストのすべてのネットワークインターフェイスに直接アクセスできます。

  1. 特定のホストサービスへのトラフィックをキャプチャできるかどうかを確認しましょう。
## 新しいターミナルウィンドウを開き、いくつかのトラフィックを生成します
curl http://localhost:80 &

## 元のターミナルで、次のコマンドを実行します
docker exec netmon sh -c "apk add --no-cache tcpdump && tcpdump -c 5 -i any port 80 -n"

コンテナがポート 80 の HTTP トラフィックをキャプチャしているのが見えるはずです。

これは、ホストネットワーキングがコンテナにホストのネットワークインターフェイスにアクセスしてトラフィックをキャプチャすることを可能にすることを示しています。これはブリッジネットワーキングではより困難です。

Docker Compose ファイルでのホストネットワーキングの使用

Docker Compose を使用する人は、docker-compose.yml ファイルでサービスがホストネットワーキングを使用するように設定できます。

version: "3"
services:
  web:
    image: nginx:alpine
    network_mode: "host"

この設定により、web サービスはホストのネットワークスタックを使用するようになります。

セキュリティに関する考慮事項とベストプラクティス

Docker コンテナでホストネットワーキングを使用する際には、セキュリティ上の影響を理解し、ベストプラクティスに従うことが重要です。

ホストネットワーキングのセキュリティ上の影響

ホストネットワーキングを使用すると、コンテナとホストシステムの間の隔離性が低下します。これにはいくつかのセキュリティ上の影響があります。

  1. ネットワーク隔離性の低下:ホストネットワーキングを使用するコンテナは、ホスト上のすべてのネットワークインターフェイスとポートにアクセスできます。

  2. 潜在的なポート競合:コンテナ内のサービスがホスト上で実行されているサービスと競合する可能性があります。

  3. 攻撃対象範囲の拡大:コンテナが侵害された場合、攻撃者はホストネットワークにより直接的にアクセスできる可能性があります。

ホストネットワーキングを使用する際のベストプラクティス

ホストネットワーキングを使用する際には、以下のベストプラクティスに従ってください。

  1. コンテナの権限を制限する:ホストネットワーキングを使用する場合でも、最小特権の原則に従います。
## ホストネットワーキングを使用し、機能を削除してコンテナを実行する
docker run --name secure-host-net --network host --cap-drop ALL --cap-add NET_ADMIN -d alpine:latest sleep infinity
  1. 必要な場合のみホストネットワーキングを使用する:ホストネットワーキングは、本当に必要なコンテナにのみ使用し、デフォルトの選択肢として使用しないでください。

  2. 定期的なセキュリティ監査を行う:ホストネットワーキングを使用するコンテナを、潜在的なセキュリティ問題についてより注意深く監視します。

  3. 可能な場合は読み取り専用のファイルシステムを使用する

## ホストネットワーキングと読み取り専用のファイルシステムでコンテナを実行する
docker run --name readonly-host-net --network host --read-only -d alpine:latest sleep infinity
  1. 使用していないコンテナをクリーンアップする
## すべての停止したコンテナを削除する(クリーンアップ)
docker container prune -f

実験環境のクリーンアップ

この実験中に作成したすべてのコンテナをクリーンアップしましょう。

## すべてのコンテナをリストする
docker ps -a

## すべての実行中のコンテナを停止する
docker stop $(docker ps -q) 2> /dev/null || true

## すべてのコンテナを削除する
docker rm $(docker ps -a -q) 2> /dev/null || true

## すべてのコンテナが削除されたことを確認する
docker ps -a

これらのコマンドを実行した後、コンテナがリストされていないことが表示されるはずです。

ブリッジネットワーキングとホストネットワーキングの選択タイミング

各ネットワークタイプをいつ使用するかをまとめます。

ブリッジネットワーキング(デフォルト)を使用する場合:

  • コンテナ間の隔離が必要な場合
  • ポートマッピングを精密に制御する必要がある場合
  • アプリケーションがホストネットワークインターフェイスに直接アクセスする必要がない場合
  • セキュリティが最優先事項である場合

ホストネットワーキングを使用する場合:

  • ネットワークパフォーマンスが重要な場合
  • ホストネットワークインターフェイスに直接アクセスする必要がある場合
  • コンテナが多数のポートまたは動的なポート割り当てを使用する必要がある場合
  • ネットワークトラフィックを監視する必要がある場合
  • コンテナがホストと同じ IP アドレスを持つように見せる必要がある場合

まとめ

この実験では、以下のことを学びました。

  • Docker のブリッジネットワーキングとホストネットワーキングの違い
  • --network host フラグを使用してホストネットワーキングで Docker コンテナを実行する方法
  • ブリッジネットワーキングに比べたホストネットワーキングのパフォーマンス上の利点
  • ホストネットワーキングが有益な実用的なユースケース
  • ホストネットワーキングを使用する際のセキュリティに関する考慮事項とベストプラクティス

ホストネットワーキングは、コンテナとホストの間のネットワーク隔離をなくし、コンテナがホストのネットワークインターフェイスに直接アクセスできるようにします。これにより、パフォーマンスが向上し、設定が簡素化され、ネットワーク監視ツールなどの特定のタイプのアプリケーションが適切に機能することが可能になります。

ホストネットワーキングは一定の利点を提供しますが、隔離性が低下し、セキュリティ上の懸念が生じる可能性があることを忘れないでください。常にベストプラクティスに従い、ユースケースが必要とする場合にのみホストネットワーキングを使用してください。