導入
この章のハイライトです。同じユーザー定義ネットワークに繋いだコンテナは、相手の名前だけで通信できます。IP アドレスを調べる必要はありません。実際に2つのコンテナを繋いで、名前で ping が通ることを体験しましょう。そして、既定の bridge では通らないことも対比で確かめます。
説明
まず専用ネットワーク appnet を作り、そこに2つのコンテナ web と api を --network で繋いで起動します。
docker network create appnet
docker run -d --network appnet --name web nginx
docker run -d --network appnet --name api node:20
--network appnet が「このコンテナを appnet に繋ぐ」という指定です。両方が同じ appnet にいるので、web の中から api という名前で通信できます。コンテナの中でコマンドを実行する docker exec(第3章)で試してみましょう。
docker exec web ping api
api の名前がちゃんと IP(172.20.0.x など)に解決され、ping が通ります。IP を一切指定していないのに、名前だけで届いた——これが埋め込み DNS の力です。
sequenceDiagram
participant W as web コンテナ
participant DNS as Docker 埋め込みDNS
participant A as api コンテナ
W->>DNS: 「api」のIPは?
DNS-->>W: 172.20.0.4 です
W->>A: 172.20.0.4 へ通信
A-->>W: 応答
対比のため、既定の bridge にいるコンテナを1つ作って、同じことを試してみます。
docker run -d --name lonely nginx
docker exec web ping lonely
今度は bad address(名前を解決できない)と出ます。lonely は既定 bridge、web は appnet と、別のネットワークにいるからです。ここから2つの重要な教訓が読み取れます。
flowchart TD
A["同じユーザー定義ネットワーク"] --> A2["✅ 名前で通信できる"]
B["ネットワークが違う<br/>/既定のbridge"] --> B2["❌ 名前で通信できない"]
- 名前で通信したいコンテナは、同じユーザー定義ネットワークに繋ぐ。
- ネットワークを分けることは、そのまま“通信できない壁”になる。DB を専用ネットワークに隔離すれば、無関係なコンテナからは触れません(第8章の Linux ファイアウォールと同じ「必要なものだけ繋ぐ」発想です)。
やってみよう
- 上の3行(
network create→webを appnet で起動 →apiを appnet で起動)を実行し、docker exec web ping apiで名前解決が通ることを確認しましょう。 docker run -d --name lonely nginx(既定bridge)を作り、docker exec web ping lonelyが通らないことを対比で見てください。