1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1. はじめに

こんにちは。株式会社ジールの @yszdh です。

この記事では、以下の内容を図解を交えながら説明します。

  • コンテナのネットワークがどのような仕組みで動いているか
  • docker-composeのコンテナが互いに通信できる理由
  • bridge / host / none / overlay の4つのネットワークモードの違いと使い分け

対象読者

  • Dockerを使い始めたばかりの方
  • docker rundocker-compose は使えるが、ネットワークの仕組みがよくわからない方

※ Docker Swarm / Kubernetes などマルチホスト環境のネットワーク(Overlayモード)の詳細は本記事のスコープ外です。

検証環境

この記事では、以下の環境で動作確認しています。

  • OS: Ubuntu 24.04.4 LTS
  • Docker Engine: 29.5.0
  • Docker Compose: v5.1.3

2. コンテナのネットワークはどう動いているのか

image.png

ネットワークNamespace の概念説明

Dockerコンテナは起動時にNetwork Namespace(ネットワーク名前空間)を作成します。
各コンテナは独立したネットワーク空間を持つため、ネットワーク設定を分けて管理できます。

ただし、Dockerのネットワークに接続されていなければ、コンテナ同士は通信できません。
通信するには、どこかのネットワークに接続される必要があります。

docker0vetheth0 の関係図

docker0
Dockerには最初から bridge というデフォルトネットワークがあり、Linux上では通常 docker0 という仮想ブリッジとして見えます。
これはスイッチのような役割を持ち、デフォルト bridge に接続されたコンテナ同士の通信を中継します。

複数コンテナがdocker0へ接続されることで通信できるようになります。

vethペア
コンテナとホスト側のブリッジをつなぐために使われるのが vethペア です。
コンテナ起動時に自動で作成され、片方がコンテナ内、もう片方がホスト側に配置されます。

eth0
コンテナの中からは、vethペアの片方が eth0 という名前のネットワークインターフェースとして見えます。
つまり、コンテナ内では eth0 を通じて外部ネットワークと通信します。

image.png

3. docker composedocker run の違い

docker compose で起動したコンテナ同士は通信できますが、docker run で別に起動したコンテナとは、そのままでは名前解決できないことがあります。

docker compose は専用のbridgeネットワークを自動生成する

docker compose up を実行すると、専用の ユーザー定義 bridge ネットワーク が自動で作成されます。

WSL 上の Linux ファイルシステム で実行します。

事前に以下のファイル構成を用意します。

C:\Users\<ユーザー名>\test_docker_network
├── docker-compose.yaml
└── nginx
    └── index.html

ディレクトリ作成、移動

mkdir -p /mnt/c/Users/<USER>/test_docker_network
cd /mnt/c/Users/<USER>/test_docker_network

nginx/index.html

hello world

docker-compose.yaml

services:
  nginx:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      - ./nginx:/usr/share/nginx/html:ro

  ubuntu:
    image: ubuntu
    command: sleep infinity

① docker compose でコンテナを起動し、専用ネットワークが自動生成されることを確認する

コマンド

docker compose -f docker-compose.yaml -p docker_network up -d

出力結果

[+] up 3/3
 ✔ Network docker_network_default    Created
 ✔ Container docker_network-nginx-1  Started
 ✔ Container docker_network-ubuntu-1 Started

コンテナが起動していることを確認

docker ps

yamlに記載したコンテナが起動していることを確認

出力結果

CONTAINER ID   IMAGE     COMMAND                  CREATED        STATUS          PORTS                                 NAMES
xxxxxxxxxxxx   nginx     "/docker-entrypoint.…"   xxxxxxxxxxxx   xxxxxxxxxxxxx   0.0.0.0:8080->80/tcp, [::]:80->80/tcp   docker_network-nginx-1
xxxxxxxxxxxx   ubuntu    "sleep infinity"         xxxxxxxxxxxx   xxxxxxxxxxxxx                                         docker_network-ubuntu-1

② ネットワーク一覧を表示し、専用ネットワークの存在を確認する

コマンド

docker network ls

出力結果

NETWORK ID     NAME                     DRIVER    SCOPE
xxxxxxxxxxxx   bridge                   bridge    local
xxxxxxxxxxxx   docker_network_default   bridge    local
xxxxxxxxxxxx   host                     host      local
xxxxxxxxxxxx   none                     null      local

この docker_network_default は、Compose が自動作成した ユーザー定義 bridge ネットワーク です。
デフォルト bridge の bridge や、docker0 とは別のものです。

コンテナ名でアクセスできる仕組み(DNSの役割)

Dockerでは、同じネットワークに所属するコンテナ同士は、コンテナ名で通信できます。
たとえば curl nginx:80 を実行すると、Docker の内部DNSが nginx という名前を IP アドレスに変換します。

この名前解決があるため、IPアドレスを意識せずにコンテナへアクセスできます。

コンテナ同士の通信を確認する

③ docker composeコンテナ内からコンテナ名でnginxにアクセスできることを確認する

ubuntuコンテナにはcurlが含まれていないため、先にインストールします。
docker exec -it docker_network-ubuntu-1 sh でコンテナに入った後、# になっていればコンテナ内に入っています。

コマンド

docker exec -it docker_network-ubuntu-1 sh

# になった状態(コンテナ内)で apt update などを実行します。

apt update && apt install -y curl
curl nginx

yamlにて定義したコンテナをcomposeにて起動し、ubuntuコンテナの中から、nginxの名前だけでアクセスできていることを確認できます。

出力結果

hello world

※確認後はexitで出る

exit

④ nginxコンテナと、ubuntuコンテナが専用ネットワークに所属していることを確認する

コマンド

docker inspect docker_network-nginx-1 | grep -i network
docker inspect docker_network-ubuntu-1 | grep -i network

出力結果

"NetworkMode": "docker_network_default"

同じネットワークに属しているため、コンテナ名で接続が可能です。

docker run で起動したコンテナは繋がらない

docker run でネットワークを指定せずに起動したコンテナは、デフォルトの bridge ネットワークに接続されます。

一方、Compose で起動したコンテナは、Compose が自動生成した docker_network_default ネットワークに接続されます。
そのため、所属ネットワークが異なると、名前解決できずにアクセスできません。

⑤ testコンテナを起動する

コマンド

docker run -d --name test --rm ubuntu sleep 500

⑥ コンテナが起動していることを確認する

コマンド

docker ps

出力例

CONTAINER ID   IMAGE     COMMAND        STATUS        NAMES
xxxxxxxxxxxx   ubuntu    "sleep 500"    Up xx sec     test

⑦ docker runコンテナがデフォルトのbridgeネットワークに所属していることを確認する

コマンド

docker inspect test | grep -i network

出力結果

"NetworkMode": "bridge"

Compose の nginx コンテナが所属する docker_network_default と、docker run で起動した test コンテナが所属する bridge は別のネットワークです。
そのため、test コンテナから nginx という名前は解決できません。

⑧ test コンテナに入り、curl をインストールしてから nginx へアクセスする

コマンド

docker exec -it test sh

# になった状態(コンテナ内)で実行します。

apt update && apt install -y curl
curl nginx

curl nginxを実行してもdocker composeにて起動したコンテナとはネットワークが異なるため、curl コンテナ名では結果が得られません。

出力例

curl: (6) Could not resolve host: nginx

※確認後はexitで出る

exit

4. 4つのネットワークモード

Dockerには主に4つのネットワークモードが存在します。

  1. bridge
  2. host
  3. none
  4. overlay

それぞれ用途や通信方式が異なります。

4-1. bridge

image.png

Docker のデフォルトネットワークはこの bridge で、docker0 として見えます。
コンテナは docker0 に接続され、同じ bridge 上のコンテナ同士で通信できます。
また、ホスト側からはポートマッピングを使ってコンテナへアクセスできます。

① コンテナを起動

コマンド

docker run --rm -d --name nginx_bridge -p 8081:80 nginx

② コンテナが起動していることを確認する

コマンド

docker ps

出力例

CONTAINER ID   IMAGE     COMMAND                  STATUS        PORTS                                 NAMES
xxxxxxxxxxxx   nginx     "/docker-entrypoint.…"   Up xx sec     0.0.0.0:8081->80/tcp, [::]:8081->80/tcp   nginx_bridge

③ コンテナのIPアドレスを確認する

コマンド

docker inspect nginx_bridge | grep -i ipaddress

出力例

"IPAddress": "172.17.x.x"

④ docker0のGatewayを確認し、同じIPレンジであることを確認する

コマンド

docker network inspect bridge | grep -i gateway

出力例

"Gateway": "172.17.x.x"

コンテナの IP が 172.17.x.x の範囲になっていることから、デフォルト bridge ネットワークに所属していることが分かります。

4-2. host

image.png

host モードでは、コンテナがホストのネットワーク名前空間をそのまま共有します。
そのため、コンテナ専用の IP アドレスは割り当てられません。

また、ホストのネットワークを直接使うため、-p によるポートマッピングは不要です。

① コンテナを起動する

コマンド

docker run --network=host --rm -d --name net_host busybox sleep 3600

② コンテナが起動していることを確認

docker ps

出力例

CONTAINER ID   IMAGE     COMMAND        STATUS        NAMES
xxxxxxxxxxxx   busybox   "sleep 3600"   Up xx sec     net_host

③ コンテナのIPアドレスを確認する

コマンド

docker inspect net_host | grep -i ipaddress

出力結果

"IPAddress": ""

④ Gatewayを確認する

コマンド

docker network inspect host | grep -i gateway

出力結果

(出力なし)

host ネットワークでは、bridge のような Gateway は表示されません。

⑤ コンテナ内からネットワークインターフェースを確認する

まず、ホスト側のネットワークインターフェースを確認します。

ip addr

次に、host モードで起動したコンテナ内からも確認します。

docker exec net_host ip addr

出力例

1: lo: <LOOPBACK,UP,LOWER_UP> ...
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> ...
4: br-xxxx: <BROADCAST,MULTICAST,UP,LOWER_UP> ...

host モードではコンテナがホストのネットワーク名前空間を共有するため、ホスト側で見えるネットワークインターフェースと同じものが、コンテナ内からも表示されます。

確認ポイント
ホスト側の

lo
eth0
docker0
br-bc227ceb5004
veth...

と同じようなインターフェースが、コンテナ側にも表示されることです。

4-3. none

image.png

none モードでは、外部ネットワークに接続するためのインターフェースが作成されません。
そのため、コンテナは外部と通信できません。

① コンテナを起動する

コマンド

docker run --network=none --rm -d --name nginx_none nginx

② コンテナが起動していることを確認する

コマンド

docker ps

出力例

CONTAINER ID   IMAGE     COMMAND                  STATUS        PORTS     NAMES
xxxxxxxxxxxx   nginx     "/docker-entrypoint.…"   Up xx sec               nginx_none

③ IPアドレスが付与されていないことを確認する

コマンド

docker inspect nginx_none | grep -i ipaddress

出力結果

"IPAddress": ""

④ Gatewayを確認する

コマンド

docker network inspect none | grep -i gateway

出力結果

(出力なし)

IP アドレスも Gateway も割り当てられないため、none モードでは外部との通信ができません。

4-4. overlay(紹介のみ)

image.png

overlay は、複数の Docker ホスト間で通信するためのネットワークです。
単一ホスト内で使う bridgehost と違い、overlay は複数ホストをまたいだ通信を実現するための仕組みです。

位置づけ
Docker のネットワークは、大きく次の 2 つに分けて考えられます。

  • Single Host Networking
    • bridge
    • host
    • none
  • Multi Host Networking
    • overlay

5. ネットワークの操作コマンド

コマンド 説明
docker network ls ネットワーク一覧を表示
docker network create --driver bridge <名前> bridgeネットワークを作成
docker network rm <名前> ネットワークを削除
docker run --network=<モード名> ... ネットワークを指定してコンテナ起動
docker inspect <コンテナ名> コンテナのネットワーク情報を確認

6. 後片付け(クリーンアップ)

検証で作成したコンテナとネットワークを削除します。

docker compose で起動したコンテナとネットワークを削除

docker compose -p docker_network down

docker run で起動したコンテナを停止・削除

docker stop nginx_bridge net_host nginx_none

docker run 時に --rm を付けていないコンテナは、停止後も残るため明示的に削除します。
--rm 付きで起動した test コンテナは停止時に自動削除されています。

7. まとめ

この記事では、Dockerネットワークの基本的な仕組みと4つのネットワークモードについて解説しました。

  • コンテナはNetwork Namespaceで隔離されており、docker0・vethペア・eth0を通じて通信します。
  • docker compose は専用のbridgeネットワークを自動生成するため、コンテナ間でコンテナ名による通信が可能です。

参考

本記事を作成するうえで、以下の資料を参考にさせていただきました。


株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。

ご興味がある方は是非下記のリンクをご覧ください:

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?