ホスト PC と Docker コンテナ間のインターフェースとポートの関係は何ですか?

ホスト PC と Docker コンテナ間のインターフェースとポートの関係は何ですか?

前提:

私は力を合わせようとしている最近の 学ぶネットワーク インターフェースとポートについて学び、その新しい学習内容を Docker と結び付けてみましょう。

この質問に関連して私が学んだことの簡単な要約:

  • 各コンピュータは、ネットワーク インターフェイスごとに 1 つずつ、複数の IP アドレスを持つことができます。
  • IP アドレスはコンピュータなどではなくインターフェースに割り当てられます。
  • ソケットは IP + ポートです。
  • 多くの場合、インターフェイスに IP アドレスを割り当てるのは DHCP です。

ソフトウェアを扱う多くの側面と同様に、私はまず、学んだ「儀式」に従って物事を進めます。なぜなら、「それがやり方だから」です。その後、時間と経験を積むにつれて、その理由を熟考し、探求し始めます。そこで、この新しい学習を Docker と結び付けたいと思います。

私が学んだ「儀式」は、コンテナ化されたアプリケーションがTCPソケットでリッスンしている場合、そのソケットのポートを「公開」して、そのポートでホストのインターフェースの1つに到着したトラフィックがコンテナに「転送」されるようにする必要があるということです。
たとえば、docker run -d -p 81:80 httpdWebブラウザを127.0.0.81に向けると、HTTP/TCP/IPトラフィックが「転送」されるように設定します。httpdコンテナのポート 80。

そのため、Web ブラウザを 127.0.0.1:81 に向けると、Apache の「It works!」メッセージが表示されます。

しかし、Web ブラウザを 127.0.0 に設定すると、2:81 または 127.0.0。16:81、Apache の「It works!」メッセージも表示されます。

リンクされた投稿から学んだように、DHCP は NIC のインターフェイスに IP アドレス 10.0.0.17 を割り当て、Web ブラウザを 10.0.0.17:81 に向けると、ここでも Apache の「It works!」メッセージが表示されます。
同じネットワーク上の別の PC の Web ブラウザを 10.0.0.17:81 に向けると、これも機能します。


質問:

私の主な質問docker run問題は、引数を実行すると、ホスト PC のどのインターフェイス (IP アドレス) のポートがホストからコンテナーに転送されるかということです-p。指摘した観察によると、答えは「すべてのインターフェイス」であるように見えますが、本当にそうでしょうか。

しかし、もっと広い意味で言えば、ホスト PC と Docker コンテナ間のインターフェースとポートの関係は何でしょうか?


私が試したこと

ヘルプテキストを読んでみましたdocker runが、そのテキストは-p私が尋ねている質問に関連付けることができるレベルではありません。

-p, --publish list コンテナのポートをホストに公開する

私はifconfig自分のPCのコンテキストで見て実行してみましたhttpdコンテナ。
ifconfigホストPC上:

$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:caff:fe23:f0f4  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ca:23:f0:f4  txqueuelen 0  (Ethernet)
        RX packets 3079  bytes 322688 (322.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6429  bytes 15942682 (15.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 17975  bytes 1557651 (1.5 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 17975  bytes 1557651 (1.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.17  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::5f8c:c301:a6a3:6e35  prefixlen 64  scopeid 0x20<link>
        ether f8:59:71:01:89:cf  txqueuelen 1000  (Ethernet)
        RX packets 1672559  bytes 2237440808 (2.2 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 726083  bytes 113598143 (113.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ifconfig競争中httpdコンテナ(私は でインストールしましたapt-get):

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 1326  bytes 8916833 (8.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1134  bytes 76866 (75.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

この質問を上記の出力の文脈に置くとifconfig、ホストPC上のインターフェースとDockerコンテナ内のインターフェースの関係は何でしょうか
ここ私の理解では、DHCP はホスト PC の NIC に 10.0.0.17 を割り当てました。しかし、172.17.0.3 はどこから来たのでしょうか?

答え1

[注意: ここでは 3 つの質問があるようですが、少なくともそのうちの 1 つは範囲が広すぎて、明確な回答が得られません。通常、SuperUser は、質問投稿ごとに 1 つの範囲を限定した質問のみをすると最もうまく機能します。]

私の主な質問は、docker run を -p 引数付きで実行したときに、ホスト PC のどのインターフェース (IP アドレス) のポートがホストからコンテナに転送されるかということです。指摘されている観察によると、答えは「すべてのインターフェース」のようですが、本当にそうでしょうか。

はい。

しかし、もっと広い意味で言えば、ホスト PC と Docker コンテナ間のインターフェースとポートの関係は何でしょうか?

これは、Docker のネットワーク ドキュメントを参照せずに適切に回答するには、少し範囲が広すぎます。Docker には、ホスト PC と Docker コンテナー間のインターフェイスとポートの関係を変更するさまざまなネットワーク オプションが含まれています。非常に柔軟性があります。

しかし、172.17.0.3 はどこから来るのでしょうか?

Dockerのデフォルトのネットワークモード、ブリッジネットワークは、ホスト上にソフトウェア ブリッジ (仮想イーサネット スイッチのような) を作成し、仮想ネットワーク インターフェイスを介してコンテナーをそのブリッジに接続します。これは、ホスト内にある小さな仮想イーサネット LAN のようなものです。次に、NAT (ホーム ゲートウェイ ルーターが使用するのとよく似ています) を使用して、コンテナーがホストを超えたネットワークに到達できるようにします。NAT は、172.17.0.0/16 サブネットをプライベート サブネットとして使用します。

Docker は、192.168.0.0/16、10.0.0.0/8、および 172 の残りの部分と同様に、RFC 1918 プライベート アドレス空間の一部であるため、そのサブネットを使用します。16.0.0/12

Docker は、そのサブネット内の静的アドレスを使用してコンテナをプログラム的に構成するようです (DHCP は不必要に複雑になります)。

関連情報