Docker コンテナ間の接続性をテストする方法

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

はじめに

Docker コンテナは、現代のアプリケーション開発と展開における基本的な要素となっています。複数のコンテナを扱う際、それらの間の適切な接続性を確保することは、アプリケーションが正常に機能するために不可欠です。

この実験では、Docker コンテナ間の接続性を検証し、トラブルシューティングする方法を学びます。まず、基本的な Docker コンテナの概念から始め、テスト用のコンテナをセットアップし、その後、コンテナ間のネットワーク接続をチェックし診断するための様々な方法を探ります。

このチュートリアルを終えると、コンテナ化されたアプリケーションにおける接続性の問題を自信を持ってテスト、検証、解決することができるようになります。

この実験では学習のためにインターネット接続が必要ですので、Pro ユーザーのみが VM を起動できます。アカウントを Pro にアップグレードする

テスト用の Docker コンテナのセットアップ

コンテナ間の接続性をテストする前に、いくつかのコンテナを作成する必要があります。このステップでは、2 つの簡単な Docker コンテナをセットアップし、基本的な Docker コマンドについて学びます。

Docker コンテナの理解

Docker コンテナは、軽量で独立したパッケージであり、アプリケーションを実行するために必要なすべてのもの(コード、ランタイム、システムツール、ライブラリ、設定)を含んでいます。コンテナはホストマシンの OS カーネルを共有しますが、孤立した環境で実行されます。

テスト用コンテナの作成

まず、Ubuntu イメージに基づいて 2 つの簡単なコンテナを作成しましょう。これらのコンテナを使用して、この実験全体でそれらの間の接続性をテストします。

まず、最初のコンテナを作成しましょう。

docker run -d --name container1 ubuntu:22.04 sleep infinity

次に、2 番目のコンテナを作成します。

docker run -d --name container2 ubuntu:22.04 sleep infinity

コンテナを実行する

コマンドパラメータの説明:

  • -d:コンテナをデタッチドモード(バックグラウンド)で実行します
  • --name:コンテナに名前を割り当てます
  • ubuntu:22.04:使用する Docker イメージ(Ubuntu 22.04 バージョン)
  • sleep infinity:コンテナを無限期に実行するコマンド

コンテナが正常に実行されていることを確認する

コンテナが正常に実行されているかどうかを確認するには、次のコマンドを使用します。

docker ps

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

CONTAINER ID   IMAGE          COMMAND            CREATED         STATUS         PORTS     NAMES
f8d97c645cce   ubuntu:22.04   "sleep infinity"   5 seconds ago   Up 4 seconds             container2
a2c516a57cb8   ubuntu:22.04   "sleep infinity"   18 seconds ago  Up 17 seconds            container1

両方のコンテナが一覧に表示されない場合は、正常に起動していない可能性があります。再度作成してみることができます。

ネットワークツールのインストール

デフォルトでは、Ubuntu コンテナイメージは非常に最小限であり、必要なネットワークツールが含まれていません。両方のコンテナにこれらのツールをインストールしましょう。

container1 用:

docker exec container1 apt-get update
docker exec container1 apt-get install -y iputils-ping net-tools iproute2 curl

container2 用:

docker exec container2 apt-get update
docker exec container2 apt-get install -y iputils-ping net-tools iproute2 curl

これらのコマンドは:

  1. docker execを使用して、実行中のコンテナ内でコマンドを実行します
  2. apt-get updateでパッケージリストを更新します
  3. ネットワークツール(ping 用のiputils-ping、netstat 用のnet-tools、ip コマンド用のiproute2、およびcurl)をインストールします

これで、次のステップでコンテナ間の接続性テストが可能になりました。

Docker ネットワークの理解

Docker コンテナはネットワークを介して相互に通信します。Docker ネットワーキングがどのように機能するかを理解することは、コンテナ間の接続性をテストしてトラブルシューティングするために不可欠です。

Docker ネットワークの基本

Docker をインストールすると、自動的にいくつかのデフォルトネットワークが作成されます。最も一般的に使用されるものは以下の通りです。

  • bridge:ネットワークが指定されていない場合、コンテナが接続するデフォルトのネットワーク
  • host:コンテナがホストのネットワークを直接使用します(隔離なし)
  • none:コンテナはネットワークアクセスがありません

システム上のネットワークを確認しましょう。

docker network ls

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

NETWORK ID     NAME      DRIVER    SCOPE
1b95853bf83b   bridge    bridge    local
91199fc6ad2e   host      host      local
1078d2c781b6   none      null      local

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

デフォルトでは、両方のコンテナはデフォルトのブリッジネットワークに接続されています。このネットワークを確認しましょう。

docker network inspect bridge

このコマンドは、ブリッジネットワークに関する詳細情報を表示します。これには、それに接続されているコンテナとそれらの IP アドレスが含まれます。出力の中で、「Containers」セクションを探して、container1 と container2 がそれぞれの IP アドレスとともに表示されていることを確認しましょう。

コンテナの IP アドレスを見つける

コンテナの接続性を扱うためには、コンテナに割り当てられた IP アドレスを知る必要があります。この情報を見つける方法はいくつかあります。

docker inspectを使用する場合:

docker inspect --format='{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1

またはコンテナ内から:

docker exec container1 hostname -i

両方のコンテナの IP アドレスをメモしましょう。

docker exec container1 hostname -i
docker exec container2 hostname -i

出力には、各コンテナの IP アドレスが表示されます。これは通常、デフォルトのブリッジネットワーク上では172.17.0.xから始まります。

カスタム Docker ネットワークの作成

デフォルトのブリッジネットワークはコンテナ間の通信を可能にしますが、カスタムネットワークを作成することで、より良い隔離と組み込みの DNS 解決機能(コンテナは IP ではなく名前で相互に到達できる)が提供されます。

カスタムブリッジネットワークを作成しましょう。

docker network create --driver bridge my-network

次に、既存のコンテナをこの新しいネットワークに接続しましょう。

docker network connect my-network container1
docker network connect my-network container2

コンテナが新しいネットワークに接続されていることを確認できます。

docker network inspect my-network

これで、コンテナはデフォルトのブリッジネットワークとカスタムのmy-networkの両方に接続されています。次のステップでは、それらの間の接続性をテストします。

コンテナ間の基本的な接続性のテスト

コンテナをセットアップしてネットワークに接続したので、それらの間の接続性をテストすることができます。コンテナが相互に通信できることを検証するために、いくつかの方法を使用します。

Ping を使用した接続性のテスト

基本的なネットワーク接続性をテストする最も簡単な方法は、対象ホストに ICMP エコー要求を送信するpingコマンドを使用することです。

IP アドレスを使用して container1 から container2 に ping を送信しましょう。

## まず、container2のIPアドレスを取得する
CONTAINER2_IP=$(docker exec container2 hostname -i)
echo "Container2 IP: $CONTAINER2_IP"

## CONTAINER2_IPの最初のIPアドレスを取得する
CONTAINER2_IP=$(echo $CONTAINER2_IP | cut -d' ' -f1)
echo "Container2 IP: $CONTAINER2_IP"

## 次に、container1からcontainer2にpingを送信する
docker exec container1 ping -c 4 $CONTAINER2_IP

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

PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.095 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.067 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.090 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.087 ms
--- 172.17.0.3 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.067/0.085/0.095/0.000 ms

DNS 解決のテスト

カスタム Docker ネットワークの利点の 1 つは、自動的な DNS 解決を提供することで、コンテナが名前で相互に到達できるようにすることです。

コンテナ名で ping を送信して DNS 解決をテストしましょう。

docker exec container1 ping -c 4 container2

これは、両方のコンテナが DNS 解決を提供するカスタムのmy-network上にあるため機能するはずです。前のテストと同様の ping 応答が表示されるはずですが、コンテナ名を使用して IP を代わりに使用します。

curl を使用した HTTP 接続性のテスト

Web サービスを実行するアプリケーションの場合、HTTP 接続性をテストする必要があることがよくあります。container2 に簡単な HTTP サーバーをセットアップし、container1 からそれに接続することをテストしましょう。

まず、container2 に基本的な HTTP サーバーを起動しましょう。

docker exec container2 apt-get install -y python3
docker exec -d container2 bash -c "echo 'Hello from container2' > /index.html && cd / && python3 -m http.server 8080"

サーバーが起動するまで数秒待った後、container1 から接続をテストします。

docker exec container1 curl -s http://container2:8080

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

Hello from container2

これは、container1 が DNS 解決にコンテナ名を使用して container2 の HTTP サービスに接続できることを確認しています。

異なる方法での接続テスト

他のツールを使用して接続性をテストする方法を知ることも役立ちます。特定のポートが開いているかどうかを確認するためにnc(netcat)を使用してみましょう。

## container1にnetcatがインストールされていることを確認する
docker exec container1 apt-get install -y netcat

## container2のHTTPサーバーへの接続をテストする
docker exec container1 nc -zv container2 8080

接続が成功したことを示す出力が表示されるはずです。

Connection to container2 (172.18.0.3) 8080 port [tcp/*] succeeded!

これらのテストは、コンテナがネットワークレベル(ping)とアプリケーションレベル(HTTP)の両方で相互に通信できることを確認しています。

コンテナ接続性の問題のトラブルシューティング

接続性の問題がない場合は、このステップを飛ばしても構いません。

コンテナ間の接続性をテストする方法を理解したので、一般的な接続性の問題をどのようにトラブルシューティングするかを探ってみましょう。

一般的な接続性の問題

Docker コンテナネットワークを扱う際、いくつかの一般的な問題に遭遇する可能性があります。

  1. 適切なルーティングがない異なるネットワーク上のコンテナ
  2. ファイアウォールまたはセキュリティグループの設定によりトラフィックがブロックされる
  3. アプリケーションが期待される IP/ポートでリッスンしていない
  4. ネットワーク構成エラー
  5. DNS 解決の問題

これらの潜在的な問題それぞれに対するトラブルシューティング手順を見ていきましょう。

ネットワーク構成の確認

まず、コンテナのネットワーク構成を確認しましょう。

## container1のネットワークインターフェイスを表示する
docker exec container1 ip addr show

## container2のネットワークインターフェイスを表示する
docker exec container2 ip addr show

出力には、各コンテナ内のすべてのネットワークインターフェイスが表示されます。接続された各 Docker ネットワークは、割り当てられた IP アドレスとともにethインターフェイスとして表示されます。

ネットワークルートの確認

コンテナ内のルーティング構成を確認しましょう。

docker exec container1 route -n

これは、container1 のルーティングテーブルを表示し、ネットワークトラフィックがどこに向けられるかを示します。

リッスンポートの確認

アプリケーションが適切に接続を待ち受けているかどうかを判断するには、次のコマンドを使用します。

docker exec container2 netstat -tuln

これは、すべての TCP および UDP のリッスンポートを表示します。私たちの HTTP サーバーはポート 8080 でリッスンしているはずです。

tcpdump による診断

より詳細なネットワークトラフィック分析のために、tcpdumpを使用してパケットをキャプチャして分析することができます。

## container1にtcpdumpをインストールする
docker exec container1 apt-get install -y tcpdump dnsutils

## 10秒間パケットをキャプチャする
docker exec container1 timeout 10 tcpdump -i eth0 -n

これが実行されている間、別のターミナルを開き、いくつかのトラフィックを生成します。

docker exec container1 ping -c 3 container2

tcpdump の出力に ICMP パケットがキャプチャされていることが見えるはずです。

Docker DNS 解決の確認

コンテナ間の DNS 解決に問題がある場合は:

## DNS構成を確認する
docker exec container1 cat /etc/resolv.conf

## DNS解決をテストする
docker exec container1 nslookup container2

ネットワーク問題のシミュレーション

container1 をカスタムネットワークから一時的に切断することで、接続性の問題をシミュレートしましょう。

## container1をmy-networkから切断する
docker network disconnect my-network container1

## 名前でpingを試してみる(失敗するはず)
docker exec container1 ping -c 2 container2

共有ネットワークから切断された後、container1 が container2 を名前で解決できなくなったため、ping が失敗するはずです。

再接続しましょう。

## container1をmy-networkに再接続する
docker network connect my-network container1

## 接続性が回復したことを確認する
docker exec container1 ping -c 2 container2

これで ping が再び機能するはずで、名前解決が機能するためにはコンテナが同じネットワーク上にある必要があることが示されます。

トラブルシューティングチェックリスト

コンテナの接続性の問題に直面した場合、このチェックリストに従ってください。

  1. コンテナが実行されていることを確認するdocker ps
  2. 同じネットワーク上にあることを確認するdocker network inspect <network>
  3. IP アドレスが割り当てられていることを確認するdocker inspect <container>
  4. 基本的な接続性(ping)をテストするdocker exec <container> ping <target>
  5. アプリケーションがリッスンしていることを確認するdocker exec <container> netstat -tuln
  6. DNS 解決が機能していることを確認するdocker exec <container> nslookup <target>
  7. ファイアウォールの問題を探すdocker exec <container> iptables -L
  8. コンテナのログを確認するdocker logs <container>

この体系的なアプローチを使用することで、ほとんどのコンテナ接続性の問題を特定して解決することができます。

まとめ

この実験では、Docker コンテナ間の接続性をテストしてトラブルシューティングする方法を学びました。以下のことができました。

  • Docker コンテナを作成し、ネットワーキングのために設定する
  • デフォルトおよびカスタムネットワークを含む Docker ネットワーキングの基本を学ぶ
  • コンテナ間の基本的な接続性をテストするためにさまざまなツールを使用する(ping、curl、netcat)
  • 一般的な接続性の問題を調べ、体系的なトラブルシューティング手法を学ぶ

これらのスキルは、Docker ベースのアプリケーションを開発および保守する際、特に複数のコンテナが相互に通信する必要があるマイクロサービスアーキテクチャにおいて不可欠です。

さらなる学習のために、マルチコンテナアプリケーション用の Docker Compose、コンテナオーケストレーション用の Docker Swarm または Kubernetes、およびマルチホスト展開用のオーバレイネットワークのようなより高度なネットワーキング概念を探求することができます。