Docker | 2週間で実務レベルに到達するDocker学習:Webサーバ起動(実務の入口)(Day3)

Docker Docker
スポンサーリンク

Day3の深掘り:ポートフォワーディングとコンテナネットワークの本質

Day3でやったことは「nginxを起動してブラウザからアクセスする」でしたが、その裏ではかなり多くのことが起きています。
ここを深掘りすると、「なんとなく動いている」状態から「仕組みを理解してコントロールできる」状態に一段レベルアップできます。


ホストとコンテナは“別世界”という前提

ネットワーク的には別のマシンと考える

あなたのPC(ホスト)とコンテナは、ネットワーク的には「別のマシン」として扱われます。
同じPCの中にいるのに、論理的には別世界です。

コンテナの中には独自のIPアドレス空間があり、独自のポート番号の世界があります。
nginxはその「コンテナの世界」の80番ポートで待ち受けています。
しかし、そのままではホスト側から直接80番ポートに届きません。

ここで必要になるのが、ホストとコンテナの世界をつなぐ「橋」としてのポートフォワーディングです。


ポートとは何かを一度ちゃんと整理する

「同じ住所の中の部屋番号」というイメージ

IPアドレスが「建物の住所」だとしたら、ポート番号は「部屋番号」です。
同じPC(同じIPアドレス)の中で、複数のアプリが同時に通信できるのは、ポート番号で区別しているからです。

例えば、ブラウザから
http://localhost:8080
にアクセスするとき、ブラウザは「自分のPCの8080番ポートに行きたい」と言っています。
しかし、nginxはコンテナの中の80番ポートで待っています。
このズレを埋めるのが -p 8080:80 です。


-p 8080:80 の本当の意味をもう一段深く理解する

左側と右側の世界

-p 8080:80 の左側はホスト側、右側はコンテナ側です。
つまり、「ホストの8080番ポートに来た通信を、コンテナの80番ポートに転送する」というルールを作っています。

このとき、ブラウザはコンテナの存在を知りません。
ブラウザは「localhost:8080」に話しかけているだけで、その先でDockerがコンテナに橋渡ししているだけです。
この「コンテナの存在を意識させない」というのが、Dockerが実務で使いやすい理由の一つです。


ポート番号を変えたらどうなるか

例:-p 3000:80 にした場合

もし次のように起動したらどうなるでしょうか。

docker run -d -p 3000:80 nginx

この場合、コンテナの中でnginxが待っているポートは相変わらず80番ですが、
ホスト側からは http://localhost:3000 でアクセスすることになります。

つまり、「コンテナの中の設定は変えずに、外からの入口だけ変える」ことができます。
実務では、複数のコンテナを同時に動かすときに、ホスト側のポートを変えて使い分けることがよくあります。


複数のnginxコンテナを同時に動かすイメージ

ホスト側ポートが衝突すると起動できない

例えば、次の2つを同時に起動しようとするとします。

docker run -d -p 8080:80 nginx
docker run -d -p 8080:80 nginx

2つ目はエラーになります。
理由は、ホストの8080番ポートはすでに1つ目のコンテナが使っているからです。
同じ建物の同じ部屋番号を、二つの部屋に割り当てることはできません。

しかし、次のようにホスト側のポートを変えれば、同時に動かせます。

docker run -d -p 8080:80 nginx
docker run -d -p 8081:80 nginx

この場合、
1つ目は http://localhost:8080
2つ目は http://localhost:8081
でアクセスできます。
コンテナの中ではどちらも80番ポートで待っているのに、外からは別々に見える、というのがポイントです。


コンテナの中から見た世界

コンテナは「自分が世界の中心」だと思っている

コンテナの中に入って curl localhost などをすると、
それは「コンテナの中のlocalhost=コンテナ自身」を指します。
ホストのlocalhostとは別物です。

つまり、
ホストから見た localhost
コンテナから見た localhost
同じ言葉でも指している対象が違います。

この感覚が身につくと、「あれ?どっちのlocalhostだっけ?」という混乱が減ります。


セキュリティ視点で見るポートフォワーディング

不要なポートは開けない、という基本原則

ポートを開けるということは、「外部からの入口を増やす」ということです。
実務では、必要なポートだけを開け、不要なポートは絶対に公開しない、というのが基本です。

例えば、nginxの80番ポートは外部公開してもよいケースが多いですが、
データベースコンテナのポート(例:3306など)は、外部に公開せず、内部ネットワークだけで使うのが一般的です。

Dockerの -p は「外部に公開するポートを増やす操作」なので、
便利であると同時に、慎重に扱うべきスイッチでもあります。


よくあるつまずきポイントと考え方

ブラウザで開いても何も表示されない場合

まず確認すべきことは、コンテナが本当に動いているかどうかです。
docker ps で nginx コンテナが Up になっているかを確認します。
次に、ポート番号の指定ミスを疑います。
コマンドで -p 8080:80 としたのに、ブラウザで http://localhost:80 を開いていないか、などです。

それでもダメな場合は、ファイアウォールやセキュリティソフトがポートをブロックしている可能性もあります。
このあたりはOSや環境によって挙動が変わるので、「ネットワーク的にどこで止まっているか」を一つずつ切り分けていく癖をつけると、トラブルシューティング能力が上がります。


Day3のゴールの再定義:「ポートフォワーディングを説明できる」

ここまで深掘りしたうえで、Day3のゴールをもう一度言語化すると、次のようになります。

ホストとコンテナはネットワーク的に別世界であり、コンテナの中のポートにはそのままでは届かない。
-p ホストポート:コンテナポート という指定で、ホストの入口とコンテナの入口を橋渡しできる。
ブラウザはコンテナの存在を知らず、あくまでホストのポートにアクセスしているだけだが、その裏でDockerが転送している。
複数コンテナを動かすときは、ホスト側ポートを変えることで共存させられる。
ポートを開けることは入口を増やすことなので、セキュリティ的には必要最小限にするのが原則である。

ここまで自分の言葉で説明できれば、Day3は「実務の入口」というより、すでに「実務の基礎」をしっかり踏み込めているレベルです。

タイトルとURLをコピーしました