私のシナリオ:私のDockerベースのサービスに、WebからIPが呼び出しているIPを認識させたい(アプリケーションの要件)。
私はdocker 1.12.2を備えたクラウドVPS、debian jessieで実行しています。
冗長モードでnc
を使用してポート8080
を開きます。
docker run --rm -p "8080:8080" centos bash -c "yum install -y nc && nc -vv -kl -p 8080"
たとえば、VPSにはexample.com
というドメインがあり、他のマシンからは、IPがあるとしましょうdead:::::beef
呼び出します
nc example.com 8080
serverは言う:
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Listening on :::8080
Ncat: Listening on 0.0.0.0:8080
Ncat: Connection from 172.17.0.1.
Ncat: Connection from 172.17.0.1:49799.
172.17.0.1
はserver'sローカルネットワーク上にあり、もちろん私のクライアントとは何の関係もありません。実際には:
docker0 Link encap:Ethernet HWaddr ....
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
コンテナをホストネットワークモードで起動した場合
docker run --rm --net=Host -p "8080:8080" centos bash -c "yum install -y nc && nc -vv -kl -p 8080"
そして再び私のサーバーを呼び出します
nc example.com 8080
私は期待した結果を得ます:
Ncat: Connection from dead:::::beef.
Ncat: Connection from dead:::::beef:55650.
私の質問は:
nc
は、コールがdockerデーモンのIPからのものであることだけを確認します。documentation によると、デフォルトのドライバー(つまり、--net=Host
でdocker run
を指定しない場合)はbridge
ネットワークドライバーです。
ドッカーがIPアドレスを「マスク」することではなく、bridged
とHost
のネットワークモードがどのように異なるかについてです。
Dockerに関しては、ブリッジネットワークはソフトウェアブリッジを使用して、同じブリッジネットワークに接続されたコンテナーが通信できるようにし、そのブリッジネットワークに接続されていないコンテナーからの分離を提供します。 Dockerブリッジドライバーは自動的にルールをホストマシンにインストールするため、異なるブリッジネットワーク上のコンテナーは互いに直接通信できません。
Dockerは分離されたネットワークを作成するため、ブリッジされたネットワーク内の各コンテナが通信できるようになります(あなたの場合はdocker0
)。そのため、デフォルトでは、Dockerホストのコンテナーはこのネットワーク内で通信します。
もうすでに理解しているかもしれませんが、はい172.17.0.1
はdocker0
ネットワークのデフォルトルートですが、これはパケットを宛先に転送するルーターとして機能しないため、 netcatの出力からのソース。
実際、Dockerホストでss -tulnp
を実行することでこれを確認できます。ポート8080でリッスンしているプロセスがdockerであることがわかります。
一方、 Host ネットワーキングドライバーを使用すると、コンテナーとホストが分離されません。これを確認するには、Dockerホストでss -tulnp
を実行します。 Dockerの代わりにソケットでリッスンしているプロセスが表示されます(この場合、nc
が表示されます)。