Dockerネットワーク

この講座では、Dockerのネットワーク機能について学びます。

  • Dockerネットワークの必要性と特徴
  • ネットワークドライバの種類(bridge・host・none)
  • ユーザ定義ネットワークの作成と管理
  • コンテナ間通信とDNS解決

1. Dockerネットワークとは

1.1 なぜDockerネットワークが必要なのか

コンテナは、それぞれが独立した環境として動作します。しかし、実際のアプリケーションでは、Webサーバがデータベースに接続したり、複数のマイクロサービスが連携したりと、コンテナ同士が通信する必要があります。

Dockerネットワークは、こうしたコンテナ間通信を安全かつ効率的に実現するための仕組みです。

1.2 Dockerネットワークの特徴

Dockerネットワークには、以下のような特徴があります。

コンテナ間の通信

1つ目は、コンテナ間の通信を可能にすることです。同じネットワークに属するコンテナ同士は、コンテナ名を使って互いに通信できます。

通信の分離

2つ目は、通信の分離です。異なるネットワークに属するコンテナ同士は、デフォルトでは通信できません。これにより、セキュリティを確保しつつ、必要な通信のみを許可できます。

DNSによる名前解決

3つ目は、DNSによる名前解決です。Dockerは内部DNSを持っており、コンテナ名でIPアドレスを自動的に解決してくれます。これにより、IPアドレスを意識することなく、コンテナ名で通信先を指定できます。

2. ネットワークの種類

Dockerの3種類のネットワークタイプの構成イメージを以下に示します。

graph TB
  subgraph bridge_net["bridge ネットワーク"]
    BC1[コンテナA] --- VB[仮想ブリッジ]
    BC2[コンテナB] --- VB
    VB -- "ポートマッピング(-p)" --- BH[ホストネットワーク]
  end

  subgraph host_net["host ネットワーク"]
    HC1[コンテナ] --- HH[ホストネットワークを共有]
  end

  subgraph none_net["none ネットワーク"]
    NC1[コンテナ(ネットワークなし)]
  end

Dockerには、用途に応じた複数のネットワークタイプが用意されています。ここで紹介するbridgehostnoneの3つは、Dockerをインストールした時点でデフォルトで作成されているネットワークです。

また、これらに加えて、docker network createコマンドを使って独自のネットワークを作成することもできます。独自ネットワークの作成方法については、後のセクションで詳しく説明します。

2.1 bridge(ブリッジ)

bridgeは、Dockerのデフォルトのネットワークタイプです。コンテナを起動する際に特にネットワークを指定しなければ、自動的にこのbridgeネットワークに接続されます。

bridgeネットワークでは、同じネットワーク内のコンテナ同士が通信でき、また-pオプションでポートを公開することで、ホストマシンからコンテナにアクセスすることもできます。

一般的な開発環境や、単一ホスト上で複数のコンテナを動かす場合に適しています。

2.2 host(ホスト)

hostネットワークは、コンテナがホストマシンのネットワークを直接使用するモードです。

このモードでは、コンテナはホストマシンと同じIPアドレスを持ち、ポートマッピング(-pオプション)なしで、コンテナ内のポートがそのままホストで公開されます。

ネットワークのオーバーヘッドがなくなるため高いパフォーマンスが得られますが、ポートの競合に注意が必要です。

2.3 none(なし)

noneネットワークは、コンテナにネットワーク接続を持たせないモードです。

完全に隔離された環境でコンテナを実行したい場合や、セキュリティ上の理由でネットワークアクセスを遮断したい場合に使用します。

2.4 ネットワーク種類のまとめ

種類 説明 用途
bridge デフォルトのネットワーク。同じネットワーク内のコンテナ同士が通信可能 一般的な開発環境、単一ホストでの複数コンテナ運用
host ホストマシンのネットワークを直接使用 高パフォーマンスが必要な場合
none ネットワーク接続なし 完全に隔離された環境が必要な場合

3. Dockerネットワークの操作

3.1 ネットワークの一覧表示

現在存在するDockerネットワークの一覧を表示するには、以下のコマンドを実行します。

docker network ls

実行すると、以下のような出力が表示されます。

NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
f6e5d4c3b2a1   host      host      local
1a2b3c4d5e6f   none      null      local

デフォルトでbridgehostnoneの3つのネットワークが存在していることが確認できます。

3.2 ネットワークの作成

独自のbridgeネットワークを作成するには、docker network createコマンドを使用します。

docker network create my-network

このコマンドで、my-networkという名前のbridgeネットワークが作成されます。

独自のネットワークを作成することで、以下のメリットがあります。

  • コンテナ名でのDNS名前解決が自動的に有効になる
  • 特定のコンテナグループを論理的に分離できる
  • ネットワークの設定をカスタマイズできる

Docker公式のBridge network driverでも「User-defined bridges provide automatic DNS resolution between containers. Containers on the default bridge network can only access each other by IP addresses, unless you use the --link option, which is considered legacy.」と明記されており、デフォルトのbridgeネットワークではIPアドレスでしか相互通信できないのに対し、ユーザ定義bridgeネットワークでは自動でDNS解決が有効になることが分かります。

3.3 コンテナをネットワークに接続する

コンテナを起動する際に、--networkオプションで接続するネットワークを指定できます。

docker container run -d --name web-server --network my-network nginx

このコマンドでは、my-networkに接続された状態でweb-serverという名前のnginxコンテナが起動します。

3.4 ネットワークの詳細確認

特定のネットワークの詳細情報を確認するには、docker network inspectコマンドを使用します。

docker network inspect my-network

このコマンドで、ネットワークに接続されているコンテナの一覧や、IPアドレスの割り当て状況などを確認できます。

3.5 ネットワークの削除

不要になったネットワークを削除するには、以下のコマンドを実行します。

docker network rm my-network

なお、コンテナが接続されているネットワークは削除できません。先にコンテナを停止・削除するか、ネットワークから切断する必要があります。

3.6 まとめ(コマンド一覧)

最後に、今回登場したコマンドを下記表にまとめておきます。

コマンド 説明
docker network ls ネットワークの一覧を表示
docker network create <ネットワーク名> 新しいネットワークを作成
docker container run --network <ネットワーク名> 指定したネットワークに接続してコンテナを起動
docker network inspect <ネットワーク名> ネットワークの詳細情報を確認
docker network rm <ネットワーク名> ネットワークを削除

4. ハンズオン:コンテナ間通信を体験しよう

ここでは、2つのコンテナを同じネットワークに接続し、コンテナ名を使って通信できることを確認します。

今回のハンズオンはまず、独自のDockerネットワークを作成します。次に、そのネットワークに接続した状態で、Webサーバ用のコンテナ(nginx)と、通信テスト用のコンテナ(alpine)の2つを起動します。そして、テスト用コンテナからWebサーバコンテナに対して、コンテナ名を使ってリクエストを送信し、通信できることを確認します。

4.1 ネットワークの作成

まず、ハンズオン用のネットワークを作成します。

docker network create my-network

ネットワークが作成されたことを確認するために、一覧を表示してみましょう。

docker network ls

以下のように、my-networkが追加されていることが確認できます。

NETWORK ID     NAME         DRIVER    SCOPE
a1b2c3d4e5f6   bridge       bridge    local
f6e5d4c3b2a1   host         host      local
xxxxxxxxxxxx   my-network   bridge    local
1a2b3c4d5e6f   none         null      local

4.2 コンテナの起動

テスト用に2つのコンテナを起動します。1つ目はnginxのWebサーバ、2つ目は通信テスト用のalpineコンテナです。

どちらのコンテナも--networkオプションでmy-networkに所属させます。これにより、同じネットワーク内のコンテナ同士がコンテナ名で通信できるようになります。

なお、nginxalpineはDocker Hubで公開されている公式イメージです。ローカルに存在しない場合は、自動的にDocker Hubからダウンロードされます。

docker container run -d --name web-container --network my-network nginx
オプション 設定の基準
-d - Webサーバをバックグラウンドで常時起動させるため
--name web-container 通信先としてコンテナ名で指定できるようにするため
--network my-network 作成したネットワークに接続し、コンテナ間通信を可能にするため
docker container run -d --name client-container --network my-network alpine sleep infinity
オプション 設定の基準
-d - バックグラウンドでコンテナを起動するため
--name client-container コンテナを識別しやすくするため
--network my-network web-containerコンテナと同じネットワークに接続し、通信できるようにするため
💡 ポイント
alpineイメージは、実行するコマンドを指定しないとすぐに終了してしまいます。-dオプションでバックグラウンド起動しても、実行するプロセスがなければコンテナは停止します。

sleep infinityを指定することで、コンテナ内で無限に待機するプロセスが動き続け、コンテナを起動状態に維持できます。これにより、後からdocker container execでコンテナに接続できるようになります。

4.3 ネットワークの詳細確認

2つのコンテナがmy-networkに接続されていることを確認しましょう。

docker network inspect my-network

出力結果のContainersセクションに、web-containerclient-containerが表示されていれば、正しくネットワークに接続されています。

"Containers": {
    "xxxx": {
        "Name": "web-container",
        ...
    },
    "yyyy": {
        "Name": "client-container",
        ...
    }
}

4.4 コンテナへの接続

起動したalpineコンテナに接続し、シェルを起動します。

docker container exec -it client-container sh
オプション 設定の基準
-it - コンテナ内で対話的にコマンドを実行するため

このコマンドを実行すると、alpineコンテナのシェルに入ります。

4.5 コンテナ名での通信確認

alpineコンテナのシェル内で、以下のコマンドを実行して、web-containerコンテナに対してリクエストを送信します。

wget -qO- http://web-container

web-containerというコンテナ名だけで通信先を指定していますが、DockerのDNS機能により自動的にIPアドレスが解決され、nginxのデフォルトページが表示されます。

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

このように、同じネットワーク内であれば、コンテナ名を使って簡単に通信できることが確認できました。

シェルを終了するには、exitと入力します。

4.6 不要リソースの削除

ハンズオンが終わったら、作成したリソースを削除します。

まず、起動中のコンテナを停止し、削除します。

docker container stop web-container client-container
docker container rm web-container client-container

次に、docker network rmコマンドで作成したネットワークを削除します。

docker network rm my-network

最後に、ネットワークが削除されたことを確認します。

docker network ls

my-networkが一覧から消えていれば、削除は完了です。

NETWORK ID     NAME      DRIVER    SCOPE
a1b2c3d4e5f6   bridge    bridge    local
f6e5d4c3b2a1   host      host      local
1a2b3c4d5e6f   none      null      local

5. まとめ

この講座では、Dockerネットワークについて学びました。

  • Dockerネットワークは、コンテナ間の通信を実現する仕組みである
  • ネットワークタイプには、bridge(デフォルト)、hostnoneがある
  • docker network create独自のネットワークを作成できる
  • 同じネットワーク内のコンテナは、コンテナ名で通信できる
  • Dockerの内部DNSにより、IPアドレスを意識せずにコンテナ間通信が可能