最終更新:

コンテナ通信の仕組み — localhost・名前・公開ポートを使い分ける


呼ぶ場所が違うと、行き先の書き方も違う

ホストのブラウザーからブラウザー127.0.0.1:8080ホストの公開口:8080hiyopen-web:80コンテナで待つWebサーバー同じbridgeの仲間から別のコンテナhttp://hiyopen-web:80名前で相手を見つけるhiyopen-web:80ホストの8080番は経由しない
Linux Dockerのユーザー定義bridgeでの例です。左の公開口は127.0.0.1へ限定し、右は同じネットワーク内の名前を使います。
ひよこ ひよこ
ホストのブラウザーと、別のコンテナからだと呼び方が違うの?
ペンギン先生 ペンギン先生
違うことがあるよ。まずLinuxのDockerでユーザー定義bridgeを使う例を見よう。ホストからは公開したポートへ、同じネットワークのコンテナからは相手の名前と内部ポートへ接続できる。hostモードや同じPod内のように、名前空間を共有する構成とは分けて考えるんだ。
ひよこ ひよこ
名前空間…?独立してるのにどうやって外と繋がるの?
ペンギン先生 ペンギン先生
この構成ではvethペアを使うよ。1本の仮想LANケーブルの両端に似た2つのインターフェースで、片側をコンテナ、もう片側をホストに置く。片方が停止するとペアのリンクも停止するから、作るだけで必ず通信できるわけではない。IP設定や経路、ファイアウォールも関係するよ。
ひよこ ひよこ
なるほど、仮想のケーブルで繋いでるんだ!じゃあコンテナ同士はどうやって話すの?
ペンギン先生 ペンギン先生
既定のbridgeネットワークでは、ホスト側のvethがdocker0という仮想スイッチにつながる。同じブリッジのコンテナ間は通常IPアドレスで通信できるよ。アプリ用にユーザー定義のbridgeを作ると、名前で相手を見つけるDNSも使える。docker0には同じ自動名前解決はないんだ。
ひよこ ひよこ
じゃあ外部からコンテナにアクセスするときの「-p 8080:80」ってどういう仕組みなの?
ペンギン先生 ペンギン先生
既定のNAT構成では、ホストのTCP 8080番への通信をコンテナの80番へ転送する設定だよ。LinuxではDockerがファイアウォールの規則を作るけれど、バックエンドはiptablesだけとは限らない。ホストIPを省くと既定では全ホストアドレスに公開されるので、外部から届く可能性がある点に注意しよう。
ひよこ ひよこ
Kubernetesになると、さらにネットワークが複雑になるって聞くけど…
ペンギン先生 ペンギン先生
基本はPodごとにIPを持ち、意図的なネットワーク分離がなければ、Pod同士がNATなしで通信できるモデルだよ。同じPod内はlocalhostで通信する。Serviceは入れ替わるPodへの安定した接続先を提供し、外部公開にはGatewayやIngressなどが使われる。NetworkPolicyで通信を制限することもあるんだ。
ひよこ ひよこ
それを実現してるのがCNIプラグインってやつ?
ペンギン先生 ペンギン先生
CNIは、コンテナの実行基盤とネットワークプラグインが、接続の追加・削除などをやりとりするための仕様だよ。KubernetesのLinux環境でも広く使われる。通信の実現方法やNetworkPolicyへの対応はプラグイン次第なので、CNI対応だけで必要な機能が全部そろうとは限らないんだ。
ひよこ ひよこ
オーバーレイネットワークって具体的にはどういう仕組みなの?
ペンギン先生 ペンギン先生
既存のネットワークの上に仮想ネットワークを重ねる仕組みだよ。一例のVXLANは、EthernetフレームをUDPのパケットに包んで送り、受信側で取り出す。封筒を別の封筒に入れる感じだね。ただし、すべてのコンテナ通信がVXLANを使うわけではなく、ルーティングでつなぐ構成もあるよ。
ひよこ ひよこ
eBPFを使うCiliumなら、通信の処理は全部カーネルの中で済むの?
ペンギン先生 ペンギン先生
全部ではないよ。CiliumはeBPFでカーネル内の転送やL3/L4のポリシー処理を行う一方、HTTPなどのL7処理にはユーザー空間のEnvoyプロキシも使うんだ。性能は構成や負荷によるので、eBPFを使えばどんな規模でも高速、とまでは言えないよ。

まずは「ブラウザーから」と「別のコンテナから」を分ける

WebアプリとAPIをコンテナで動かすとき、相手の呼び方は、どこからアクセスするかで変わります。LinuxのDockerでユーザー定義bridgeを使う構成を、最初の例にしましょう。

呼ぶ側この例で使う行き先意味
ホストのブラウザー127.0.0.1:8080ホストへ公開した入口
同じネットワークのコンテナweb:80名前で見つけるWebコンテナ
Webコンテナの中localhostそのネットワーク名前空間の中

ホストの8080番と、コンテナの80番は別です。コンテナのlocalhostが、いつもホストマシンを指すわけではありません。 同じPod内のように名前空間を共有する構成もあるので、どの環境を扱っているかを確認します。

公開ポートの指定を読む

Linuxコンテナを扱うDockerが導入済みで、ホストの8080番が空いている場合の練習例です。既存の同名ネットワークやコンテナがないことを確認してから、自分専用の名前で作ります。

docker network create hiyopen-net
docker run -d --name hiyopen-web \
  --network hiyopen-net \
  -p 127.0.0.1:8080:80 nginx:stable-alpine

ホストのブラウザーでhttp://127.0.0.1:8080/を開くと、起動したNginxのページへアクセスできます。-pは「ホストのIP:ホストのポート:コンテナのポート」です。ホストIPを省略した公開指定は、既定では全ホストアドレスへ公開され得ます。練習では公開範囲を明示しましょう。

同じユーザー定義bridgeに接続した別のコンテナからなら、名前hiyopen-webで相手を見つけ、コンテナ側の80番へ接続できます。ホストへ公開する8080番は、この内部通信のために必須ではありません。最初の表のwebは説明用の名前で、このコマンドで作る名前はhiyopen-webです。

終わったら、この練習で作ったものだけを片付けます。共有環境のコンテナやネットワークを一括削除するコマンドは使いません。

docker stop hiyopen-web
docker rm hiyopen-web
docker network rm hiyopen-net

これらはローカル練習用の例です。Docker 28より前にはlocalhost公開の到達範囲に既知の注意点があり、経路・Dockerの版・ネットワーク設定も公式資料で確認してください。

もう少し詳しく:仮想の配線をたどる

Linuxのbridge構成では、ネットワーク名前空間でインターフェースや経路を分け、vethペアでホスト側へつなぎます。ホスト側の端点はブリッジへ接続されます。ただしIP設定、経路、ファイアウォールも通信の成立に関わります。

既定bridgeのdocker0と、ユーザー定義bridgeは同じ名前解決ではありません。後者にはコンテナ名などの自動DNSがあり、相手を名前で呼びやすくなります。hostモードではホストのネットワークを共有します。Docker DesktopではLinux環境の層もあるので、図のLinuxホストの構造をそのままWindowsの物理ネットワークと同一視しないでください。

Kubernetesでは、Podが通信の単位になる

同じPod内のコンテナは通常ネットワーク名前空間を共有し、localhostで通信できます。別Pod間は、意図的な分離がない場合、NATなしで通信できるモデルです。Serviceは入れ替わるPodへの安定した接続先を提供します。

CNIは実行基盤とネットワークプラグインのやりとりの仕様で、接続を実現する方式やNetworkPolicyへの対応はプラグインで異なります。VXLANのようにUDPへ包む構成も、ルーティングを使う構成もあります。

CiliumではeBPFによるカーネル内の処理だけでなく、L7機能にEnvoyプロキシも使います。コンテナ通信のすべてが同じ方式・同じ性能になるわけではありません。

覚え方と次の一歩

「コンテナネットワーク」って出てきたら「分けた実行環境をつなぐ、仮想の配線と行き先の設定」と思えばだいたいOK!

通信が届かないときは、呼ぶ側、名前、ポート、公開範囲を順に確認しましょう。Nginx入門やDocker入門と一緒に、最初の1ページを返すところから試せます。

参考資料

訂正履歴

  • 2026-10-05:名前空間の共有と通信条件、公開ポートの範囲を補足し、CiliumのL7処理をカーネル内とした誤りと性能の一般化を修正。